diff -Nru lxc-0.8.0~rc1/CONTRIBUTING lxc-1.0.0~alpha1/CONTRIBUTING --- lxc-0.8.0~rc1/CONTRIBUTING 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/CONTRIBUTING 2013-09-10 22:22:00.000000000 +0000 @@ -1,5 +1,5 @@ - Contributing to this project + Contributing to this project ---------------------------- @@ -40,6 +40,30 @@ list. Use https://lists.sourceforge.net/lists/listinfo/lxc-devel to subscribe to the list. + +Licensing for new files: +------------------------ + +LXC is made of files shipped under a few different licenses. + +Anything that ends up being part of the LXC library needs to be released +under LGPLv2.1+ or a license compatible with it (though the latter will +only be accepted for cases where the code originated elsewhere and was +imported into LXC). + +Language bindings for the libraries need to be released under LGPLv2.1+. + +Anything else (non-libaries) needs to be Free Software and needs to be +allowed to link with LGPLv2.1+ code (if needed). LXC upstream prefers +LGPLv2.1+ or GPLv2 for those. + + +When introducing a new file into the project, please make sure it has a +copyright header making clear under which license it's being released +and if it doesn't match the criteria described above, please explain +your decision on the lxc-devel mailing-list when submitting your patch. + + Developer Certificate of Origin: -------------------------------- @@ -81,7 +105,6 @@ then you just add a line saying - Signed-off-by: Random J Developer + Signed-off-by: Random J Developer -using your real name (sorry, no pseudonyms or anonymous -contributions.) \ No newline at end of file +using your real name (sorry, no pseudonyms or anonymous contributions.) diff -Nru lxc-0.8.0~rc1/COPYING lxc-1.0.0~alpha1/COPYING --- lxc-0.8.0~rc1/COPYING 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/COPYING 2013-09-03 18:26:12.000000000 +0000 @@ -1,5 +1,5 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA @@ -10,7 +10,7 @@ as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] - Preamble + Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public @@ -112,7 +112,7 @@ former contains code derived from the library, whereas the latter must be combined with the library in order to run. - GNU LESSER GENERAL PUBLIC LICENSE + GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other @@ -146,7 +146,7 @@ on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. - + 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an @@ -432,7 +432,7 @@ of all derivatives of our free software and of promoting the sharing and reuse of software generally. - NO WARRANTY + NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. @@ -455,7 +455,7 @@ SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - END OF TERMS AND CONDITIONS + END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries @@ -500,5 +500,3 @@ Ty Coon, President of Vice That's all there is to it! - - diff -Nru lxc-0.8.0~rc1/INSTALL lxc-1.0.0~alpha1/INSTALL --- lxc-0.8.0~rc1/INSTALL 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/INSTALL 2013-09-03 18:26:12.000000000 +0000 @@ -10,8 +10,8 @@ Basic Installation ================== -Briefly, the shell commands `./configure; make; make install' should -configure, build, and install this package. The following +Briefly, the shell commands `./autogen.sh; ./configure; make; make install' +should configure, build, and install this package. The following more-detailed instructions are generic; see the `README' file for instructions specific to this package. diff -Nru lxc-0.8.0~rc1/MAINTAINERS lxc-1.0.0~alpha1/MAINTAINERS --- lxc-0.8.0~rc1/MAINTAINERS 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/MAINTAINERS 2013-09-10 22:22:00.000000000 +0000 @@ -6,7 +6,7 @@ ---------- Person : Daniel Lezcano -Mail patches to : dlezcano@fr.ibm.com +Mail patches to : daniel.lezcano@free.fr Mailing lists : lxc-devel@sourceforge.net, containers@lists.osdl.org Web page : lxc.sourceforge.net -GIT location : http://lxc.git.sourceforge.net/ +GIT location : git://lxc.git.sourceforge.net/gitroot/lxc/lxc diff -Nru lxc-0.8.0~rc1/Makefile.am lxc-1.0.0~alpha1/Makefile.am --- lxc-0.8.0~rc1/Makefile.am 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/Makefile.am 2013-09-10 22:22:00.000000000 +0000 @@ -2,15 +2,34 @@ ACLOCAL_AMFLAGS = -I config -SUBDIRS = src templates doc -DIST_SUBDIRS = config src templates doc -EXTRA_DIST = autogen.sh lxc.spec CONTRIBUTING MAINTAINERS ChangeLog +SUBDIRS = config src templates doc hooks +DIST_SUBDIRS = config src templates doc hooks +EXTRA_DIST = \ + autogen.sh \ + lxc.spec \ + CONTRIBUTING \ + MAINTAINERS \ + runapitests.sh -pcdatadir = $(datadir)/pkgconfig +RPMARGS = + +if ENABLE_LUA +RPMARGS += --with lua +endif + +if ENABLE_PYTHON +RPMARGS += --with python +endif + +pcdatadir = $(libdir)/pkgconfig pcdata_DATA = lxc.pc +install-data-local: + $(MKDIR_P) $(DESTDIR)$(LXCPATH) + $(MKDIR_P) $(DESTDIR)$(localstatedir)/cache/lxc + ChangeLog:: @touch ChangeLog rpm: dist - rpmbuild --clean -ta --define "ksrc ${LINUX_DIR}" ${distdir}.tar.gz + rpmbuild --clean -ta ${distdir}.tar.gz $(RPMARGS) diff -Nru lxc-0.8.0~rc1/Makefile.in lxc-1.0.0~alpha1/Makefile.in --- lxc-0.8.0~rc1/Makefile.in 2012-03-01 23:04:43.000000000 +0000 +++ lxc-1.0.0~alpha1/Makefile.in 2013-09-10 22:30:08.000000000 +0000 @@ -1,9 +1,8 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. +# Makefile.in generated by automake 1.13.3 from Makefile.am. # @configure_input@ -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -18,6 +17,51 @@ # Makefile.am VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -36,31 +80,57 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ +@ENABLE_LUA_TRUE@am__append_1 = --with lua +@ENABLE_PYTHON_TRUE@am__append_2 = --with python subdir = . -DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ - $(srcdir)/Makefile.in $(srcdir)/lxc.pc.in \ - $(srcdir)/lxc.spec.in $(top_srcdir)/configure AUTHORS COPYING \ - ChangeLog INSTALL NEWS TODO +DIST_COMMON = INSTALL NEWS README AUTHORS ChangeLog \ + $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(top_srcdir)/configure $(am__configure_deps) \ + $(srcdir)/lxc.pc.in $(srcdir)/lxc.spec.in \ + $(top_srcdir)/doc/legacy/lxc-ls.sgml.in \ + $(top_srcdir)/src/lxc/legacy/lxc-ls.in COPYING TODO \ + $(top_srcdir)/config/compile $(top_srcdir)/config/config.guess \ + $(top_srcdir)/config/config.sub \ + $(top_srcdir)/config/install-sh $(top_srcdir)/config/missing ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/config/acinclude.m4 \ - $(top_srcdir)/config/linux.m4 $(top_srcdir)/configure.ac + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/src/config.h -CONFIG_CLEAN_FILES = lxc.pc lxc.spec +CONFIG_CLEAN_FILES = lxc.pc lxc.spec doc/legacy/lxc-ls.sgml \ + src/lxc/legacy/lxc-ls CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = SOURCES = DIST_SOURCES = -RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ - html-recursive info-recursive install-data-recursive \ - install-dvi-recursive install-exec-recursive \ - install-html-recursive install-info-recursive \ - install-pdf-recursive install-ps-recursive install-recursive \ - installcheck-recursive installdirs-recursive pdf-recursive \ - ps-recursive uninstall-recursive +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ @@ -82,22 +152,52 @@ am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } am__installdirs = "$(DESTDIR)$(pcdatadir)" DATA = $(pcdata_DATA) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive -AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ - $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ - distdir dist dist-all distcheck +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + cscope distdir dist dist-all distcheck +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags +CSCOPE = cscope DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ - { test ! -d "$(distdir)" \ - || { find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ - && rm -fr "$(distdir)"; }; } + if test -d "$(distdir)"; then \ + find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -rf "$(distdir)" \ + || { sleep 5 && rm -rf "$(distdir)"; }; \ + else :; fi +am__post_remove_distdir = $(am__remove_distdir) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ @@ -125,10 +225,15 @@ reldir="$$dir2" DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best +DIST_TARGETS = dist-gzip distuninstallcheck_listfiles = find . -type f -print +am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ + | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +APPARMOR_LIBS = @APPARMOR_LIBS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ @@ -159,19 +264,31 @@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBDIR = @LIBDIR@ +LIBEXECDIR = @LIBEXECDIR@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ -LINUX_DIR = @LINUX_DIR@ -LINUX_SRCARCH = @LINUX_SRCARCH@ LOCALSTATEDIR = @LOCALSTATEDIR@ +LOGPATH = @LOGPATH@ LTLIBOBJS = @LTLIBOBJS@ +LUA_CFLAGS = @LUA_CFLAGS@ +LUA_INSTALL_CMOD = @LUA_INSTALL_CMOD@ +LUA_INSTALL_LMOD = @LUA_INSTALL_LMOD@ +LUA_LIBS = @LUA_LIBS@ +LUA_VERSION = @LUA_VERSION@ +LXCHOOKDIR = @LXCHOOKDIR@ LXCINITDIR = @LXCINITDIR@ LXCPATH = @LXCPATH@ LXCROOTFSMOUNT = @LXCROOTFSMOUNT@ LXCTEMPLATEDIR = @LXCTEMPLATEDIR@ +LXC_DEFAULT_CONFIG = @LXC_DEFAULT_CONFIG@ +LXC_DISTRO_CONF = @LXC_DISTRO_CONF@ LXC_GENERATE_DATE = @LXC_GENERATE_DATE@ +LXC_GLOBAL_CONF = @LXC_GLOBAL_CONF@ +LXC_USERNIC_CONF = @LXC_USERNIC_CONF@ +LXC_USERNIC_DB = @LXC_USERNIC_DB@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +NEWUIDMAP = @NEWUIDMAP@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ @@ -181,8 +298,19 @@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PREFIX = @PREFIX@ -SETCAP = @SETCAP@ +PYTHON = @PYTHON@ +PYTHONDEV_CFLAGS = @PYTHONDEV_CFLAGS@ +PYTHONDEV_LIBS = @PYTHONDEV_LIBS@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +SECCOMP_LIBS = @SECCOMP_LIBS@ +SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ @@ -207,10 +335,11 @@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ +db2xman = @db2xman@ docdir = @docdir@ +docdtd = @docdtd@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ -have_docbook = @have_docbook@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ @@ -228,9 +357,13 @@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ @@ -240,15 +373,22 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ ACLOCAL_AMFLAGS = -I config -SUBDIRS = src templates doc -DIST_SUBDIRS = config src templates doc -EXTRA_DIST = autogen.sh lxc.spec CONTRIBUTING MAINTAINERS ChangeLog -pcdatadir = $(datadir)/pkgconfig +SUBDIRS = config src templates doc hooks +DIST_SUBDIRS = config src templates doc hooks +EXTRA_DIST = \ + autogen.sh \ + lxc.spec \ + CONTRIBUTING \ + MAINTAINERS \ + runapitests.sh + +RPMARGS = $(am__append_1) $(am__append_2) +pcdatadir = $(libdir)/pkgconfig pcdata_DATA = lxc.pc all: all-recursive .SUFFIXES: -am--refresh: +am--refresh: Makefile @: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ @@ -286,10 +426,17 @@ cd $(top_builddir) && $(SHELL) ./config.status $@ lxc.spec: $(top_builddir)/config.status $(srcdir)/lxc.spec.in cd $(top_builddir) && $(SHELL) ./config.status $@ +doc/legacy/lxc-ls.sgml: $(top_builddir)/config.status $(top_srcdir)/doc/legacy/lxc-ls.sgml.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +src/lxc/legacy/lxc-ls: $(top_builddir)/config.status $(top_srcdir)/src/lxc/legacy/lxc-ls.in + cd $(top_builddir) && $(SHELL) ./config.status $@ install-pcdataDATA: $(pcdata_DATA) @$(NORMAL_INSTALL) - test -z "$(pcdatadir)" || $(MKDIR_P) "$(DESTDIR)$(pcdatadir)" @list='$(pcdata_DATA)'; test -n "$(pcdatadir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pcdatadir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pcdatadir)" || exit 1; \ + fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ @@ -303,27 +450,28 @@ @$(NORMAL_UNINSTALL) @list='$(pcdata_DATA)'; test -n "$(pcdatadir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - test -n "$$files" || exit 0; \ - echo " ( cd '$(DESTDIR)$(pcdatadir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(pcdatadir)" && rm -f $$files + dir='$(DESTDIR)$(pcdatadir)'; $(am__uninstall_files_from_dir) # This directory's subdirectories are mostly independent; you can cd -# into them and run `make' without going through this Makefile. -# To change the values of `make' variables: instead of editing Makefiles, -# (1) if the variable is set in `config.status', edit `config.status' -# (which will cause the Makefiles to be regenerated when you run `make'); -# (2) otherwise, pass the desired values on the `make' command line. -$(RECURSIVE_TARGETS): - @fail= failcom='exit 1'; \ - for f in x $$MAKEFLAGS; do \ - case $$f in \ - *=* | --[!k]*);; \ - *k*) failcom='fail=yes';; \ - esac; \ - done; \ +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ @@ -338,57 +486,12 @@ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" -$(RECURSIVE_CLEAN_TARGETS): - @fail= failcom='exit 1'; \ - for f in x $$MAKEFLAGS; do \ - case $$f in \ - *=* | --[!k]*);; \ - *k*) failcom='fail=yes';; \ - esac; \ - done; \ - dot_seen=no; \ - case "$@" in \ - distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ - *) list='$(SUBDIRS)' ;; \ - esac; \ - rev=''; for subdir in $$list; do \ - if test "$$subdir" = "."; then :; else \ - rev="$$subdir $$rev"; \ - fi; \ - done; \ - rev="$$rev ."; \ - target=`echo $@ | sed s/-recursive//`; \ - for subdir in $$rev; do \ - echo "Making $$target in $$subdir"; \ - if test "$$subdir" = "."; then \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || eval $$failcom; \ - done && test -z "$$fail" -tags-recursive: - list='$(SUBDIRS)'; for subdir in $$list; do \ - test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ - done -ctags-recursive: - list='$(SUBDIRS)'; for subdir in $$list; do \ - test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ - done +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ @@ -404,12 +507,7 @@ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ + $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ @@ -421,15 +519,11 @@ $$unique; \ fi; \ fi -ctags: CTAGS -CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique @@ -438,9 +532,31 @@ here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" +cscope: cscope.files + test ! -s cscope.files \ + || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) +clean-cscope: + -rm -f cscope.files +cscope.files: clean-cscope cscopelist +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + -rm -f cscope.out cscope.in.out cscope.po.out cscope.files distdir: $(DISTFILES) $(am__remove_distdir) @@ -476,13 +592,10 @@ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ - test -d "$(distdir)/$$subdir" \ - || $(MKDIR_P) "$(distdir)/$$subdir" \ - || exit 1; \ - fi; \ - done - @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ @@ -511,36 +624,36 @@ || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz - $(am__remove_distdir) + $(am__post_remove_distdir) dist-bzip2: distdir - tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 - $(am__remove_distdir) + tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 + $(am__post_remove_distdir) -dist-lzma: distdir - tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma - $(am__remove_distdir) +dist-lzip: distdir + tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz + $(am__post_remove_distdir) dist-xz: distdir - tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz - $(am__remove_distdir) + tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz + $(am__post_remove_distdir) dist-tarZ: distdir tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z - $(am__remove_distdir) + $(am__post_remove_distdir) dist-shar: distdir shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz - $(am__remove_distdir) + $(am__post_remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) - $(am__remove_distdir) + $(am__post_remove_distdir) -dist dist-all: distdir - tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz - $(am__remove_distdir) +dist dist-all: + $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' + $(am__post_remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another @@ -551,8 +664,8 @@ GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ - *.tar.lzma*) \ - lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\ + *.tar.lz*) \ + lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ @@ -562,9 +675,9 @@ *.zip*) \ unzip $(distdir).zip ;;\ esac - chmod -R a-w $(distdir); chmod a+w $(distdir) - mkdir $(distdir)/_build - mkdir $(distdir)/_inst + chmod -R a-w $(distdir) + chmod u+w $(distdir) + mkdir $(distdir)/_build $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ @@ -572,6 +685,7 @@ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build \ && ../configure --srcdir=.. --prefix="$$dc_install_base" \ + $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ @@ -595,13 +709,21 @@ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 - $(am__remove_distdir) + $(am__post_remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: - @$(am__cd) '$(distuninstallcheck_dir)' \ - && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ + @test -n '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: trying to run $@ with an empty' \ + '$$(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + $(am__cd) '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ @@ -635,10 +757,15 @@ installcheck: installcheck-recursive install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi mostlyclean-generic: clean-generic: @@ -671,7 +798,7 @@ info-am: -install-data-am: install-pcdataDATA +install-data-am: install-data-local install-pcdataDATA install-dvi: install-dvi-recursive @@ -719,31 +846,34 @@ uninstall-am: uninstall-pcdataDATA -.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ - install-am install-strip tags-recursive - -.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ - all all-am am--refresh check check-am clean clean-generic \ - ctags ctags-recursive dist dist-all dist-bzip2 dist-gzip \ - dist-lzma dist-shar dist-tarZ dist-xz dist-zip distcheck \ - distclean distclean-generic distclean-tags distcleancheck \ - distdir distuninstallcheck dvi dvi-am html html-am info \ - info-am install install-am install-data install-data-am \ - install-dvi install-dvi-am install-exec install-exec-am \ - install-html install-html-am install-info install-info-am \ - install-man install-pcdataDATA install-pdf install-pdf-am \ - install-ps install-ps-am install-strip installcheck \ - installcheck-am installdirs installdirs-am maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ - pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \ - uninstall-pcdataDATA +.MAKE: $(am__recursive_targets) install-am install-strip +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ + am--refresh check check-am clean clean-cscope clean-generic \ + cscope cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \ + dist-gzip dist-lzip dist-shar dist-tarZ dist-xz dist-zip \ + distcheck distclean distclean-generic distclean-tags \ + distcleancheck distdir distuninstallcheck dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-data-local install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pcdataDATA \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic pdf pdf-am ps ps-am tags \ + tags-am uninstall uninstall-am uninstall-pcdataDATA + + +install-data-local: + $(MKDIR_P) $(DESTDIR)$(LXCPATH) + $(MKDIR_P) $(DESTDIR)$(localstatedir)/cache/lxc ChangeLog:: @touch ChangeLog rpm: dist - rpmbuild --clean -ta --define "ksrc ${LINUX_DIR}" ${distdir}.tar.gz + rpmbuild --clean -ta ${distdir}.tar.gz $(RPMARGS) # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff -Nru lxc-0.8.0~rc1/README lxc-1.0.0~alpha1/README --- lxc-0.8.0~rc1/README 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/README 2013-09-10 22:22:00.000000000 +0000 @@ -7,7 +7,7 @@ kernel. It provides the resource management through the control groups aka process containers and resource isolation through the namespaces. - The linux containers, lxc, aims to use these new functionnalities to pro- + The linux containers, lxc, aims to use these new functionalities to pro- vide an userspace container object which provides full resource isolation and resource control for an applications or a system. @@ -29,11 +29,29 @@ You can browse the up to the minute source code and change history online. http://lxc.git.sourceforge.net + For an even more bleeding edge experience, you may want to look at the + staging branch where all changes aimed at the next release land before + getting pulled into the master branch. + http://github.com/lxc/lxc + For detailed build instruction refer to INSTALL and man lxc man page but a short command line should work: - ./configure && make && sudo make install && sudo lxc-setcap + ./autogen.sh && ./configure && make && sudo make install preceded by ./autogen.sh if configure do not exist yet. +Troubleshooting: + + If the ./autogen.sh script shows the following message: "aclocal: not found", + you are likely missing the "automake" package. Make sure it's installed and + try again. + + If the ./configure script gives you the following message: + "configure: error: Please install the libcap development files." + you are likely missing the "libcap-dev" package. + The configure script will usually give you hints as to what you are missing, + looking for those in your package manager will usually give you the package + that you need to install. + Getting help: when you find you need help, you can check out one of the two @@ -48,7 +66,33 @@ lxc is developed and tested on Linux since kernel mainline version 2.6.27 (without network) and 2.6.29 with network isolation. - is compiled with gcc, and supports i686, x86_64, ppc, ppc64, S390 archi. + It's compiled with gcc, and should work on most architectures as long as the + required kernel features are available. This includes (but isn't limited to): + i686, x86_64, ppc, ppc64, S390, armel and armhf. AUTHOR Daniel Lezcano + +Seccomp with LXC +---------------- + +To restrict a container with seccomp, you must specify a profile which is +basically a whitelist of system calls it may execute. In the container +config file, add a line like + +lxc.seccomp = /var/lib/lxc/q1/seccomp.full + +I created a usable (but basically worthless) seccomp.full file using + +cat > seccomp.full << EOF +1 +whitelist +EOF +for i in `seq 0 300`; do + echo $i >> seccomp.full +done +for i in `seq 1024 1079`; do + echo $i >> seccomp.full +done + + -- Serge Hallyn Fri, 27 Jul 2012 15:47:02 +0600 diff -Nru lxc-0.8.0~rc1/TODO lxc-1.0.0~alpha1/TODO --- lxc-0.8.0~rc1/TODO 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/TODO 2013-07-08 15:50:40.000000000 +0000 @@ -1,6 +1,6 @@ * create an interactive configuration with the lxc-create command - line, like the 'make menuconfig' of the kernel. + line, like the 'make menuconfig' of the kernel. = lxc-create [-n foo] -m|--menuconfig diff -Nru lxc-0.8.0~rc1/aclocal.m4 lxc-1.0.0~alpha1/aclocal.m4 --- lxc-0.8.0~rc1/aclocal.m4 2012-03-01 23:04:42.000000000 +0000 +++ lxc-1.0.0~alpha1/aclocal.m4 2013-09-10 22:30:06.000000000 +0000 @@ -1,7 +1,7 @@ -# generated automatically by aclocal 1.11.1 -*- Autoconf -*- +# generated automatically by aclocal 1.13.3 -*- Autoconf -*- + +# Copyright (C) 1996-2013 Free Software Foundation, Inc. -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, -# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -11,15 +11,176 @@ # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. +m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl -m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.68],, -[m4_warning([this file was generated for autoconf 2.68. +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, +[m4_warning([this file was generated for autoconf 2.69. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. -To do so, use the procedure documented by the package, typically `autoreconf'.])]) +To do so, use the procedure documented by the package, typically 'autoreconf'.])]) + +# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- +# serial 1 (pkg-config-0.24) +# +# Copyright © 2004 Scott James Remnant . +# +# 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. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# PKG_PROG_PKG_CONFIG([MIN-VERSION]) +# ---------------------------------- +AC_DEFUN([PKG_PROG_PKG_CONFIG], +[m4_pattern_forbid([^_?PKG_[A-Z_]+$]) +m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) +m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$]) +AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) +AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) +AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=m4_default([$1], [0.9.0]) + AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + PKG_CONFIG="" + fi +fi[]dnl +])# PKG_PROG_PKG_CONFIG + +# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +# +# Check to see whether a particular set of modules exists. Similar +# to PKG_CHECK_MODULES(), but does not set variables or print errors. +# +# Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +# only at the first occurence in configure.ac, so if the first place +# it's called might be skipped (such as if it is within an "if", you +# have to call PKG_CHECK_EXISTS manually +# -------------------------------------------------------------- +AC_DEFUN([PKG_CHECK_EXISTS], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +if test -n "$PKG_CONFIG" && \ + AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then + m4_default([$2], [:]) +m4_ifvaln([$3], [else + $3])dnl +fi]) + +# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) +# --------------------------------------------- +m4_define([_PKG_CONFIG], +[if test -n "$$1"; then + pkg_cv_[]$1="$$1" + elif test -n "$PKG_CONFIG"; then + PKG_CHECK_EXISTS([$3], + [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes ], + [pkg_failed=yes]) + else + pkg_failed=untried +fi[]dnl +])# _PKG_CONFIG + +# _PKG_SHORT_ERRORS_SUPPORTED +# ----------------------------- +AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi[]dnl +])# _PKG_SHORT_ERRORS_SUPPORTED + + +# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +# [ACTION-IF-NOT-FOUND]) +# +# +# Note that if there is a possibility the first call to +# PKG_CHECK_MODULES might not happen, you should be sure to include an +# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac +# +# +# -------------------------------------------------------------- +AC_DEFUN([PKG_CHECK_MODULES], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl +AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl + +pkg_failed=no +AC_MSG_CHECKING([for $1]) + +_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) +_PKG_CONFIG([$1][_LIBS], [libs], [$2]) + +m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS +and $1[]_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details.]) -# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +if test $pkg_failed = yes; then + AC_MSG_RESULT([no]) + _PKG_SHORT_ERRORS_SUPPORTED + if test $_pkg_short_errors_supported = yes; then + $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` + else + $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD + + m4_default([$4], [AC_MSG_ERROR( +[Package requirements ($2) were not met: + +$$1_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +_PKG_TEXT])[]dnl + ]) +elif test $pkg_failed = untried; then + AC_MSG_RESULT([no]) + m4_default([$4], [AC_MSG_FAILURE( +[The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +_PKG_TEXT + +To get pkg-config, see .])[]dnl + ]) +else + $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS + $1[]_LIBS=$pkg_cv_[]$1[]_LIBS + AC_MSG_RESULT([yes]) + $3 +fi[]dnl +])# PKG_CHECK_MODULES + +# Copyright (C) 2002-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -31,10 +192,10 @@ # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], -[am__api_version='1.11' +[am__api_version='1.13' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.11.1], [], +m4_if([$1], [1.13.3], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) @@ -50,22 +211,22 @@ # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.11.1])dnl +[AM_AUTOMAKE_VERSION([1.13.3])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- -# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets -# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to -# `$srcdir', `$srcdir/..', or `$srcdir/../..'. +# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to +# '$srcdir', '$srcdir/..', or '$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and @@ -84,7 +245,7 @@ # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually -# harmless because $srcdir is `.', but things will broke when you +# harmless because $srcdir is '.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, @@ -108,24 +269,58 @@ am_aux_dir=`cd $ac_aux_dir && pwd` ]) -# AM_CONDITIONAL -*- Autoconf -*- +# AM_COND_IF -*- Autoconf -*- -# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008 -# Free Software Foundation, Inc. +# Copyright (C) 2008-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 9 +# _AM_COND_IF +# _AM_COND_ELSE +# _AM_COND_ENDIF +# -------------- +# These macros are only used for tracing. +m4_define([_AM_COND_IF]) +m4_define([_AM_COND_ELSE]) +m4_define([_AM_COND_ENDIF]) + +# AM_COND_IF(COND, [IF-TRUE], [IF-FALSE]) +# --------------------------------------- +# If the shell condition COND is true, execute IF-TRUE, otherwise execute +# IF-FALSE. Allow automake to learn about conditional instantiating macros +# (the AC_CONFIG_FOOS). +AC_DEFUN([AM_COND_IF], +[m4_ifndef([_AM_COND_VALUE_$1], + [m4_fatal([$0: no such condition "$1"])])dnl +_AM_COND_IF([$1])dnl +if test -z "$$1_TRUE"; then : + m4_n([$2])[]dnl +m4_ifval([$3], +[_AM_COND_ELSE([$1])dnl +else + $3 +])dnl +_AM_COND_ENDIF([$1])dnl +fi[]dnl +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], -[AC_PREREQ(2.52)dnl - ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], - [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +[AC_PREREQ([2.52])dnl + m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl @@ -144,16 +339,14 @@ Usually this means the macro was only invoked conditionally.]]) fi])]) -# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009 -# Free Software Foundation, Inc. +# Copyright (C) 1999-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 10 -# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be +# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing @@ -163,7 +356,7 @@ # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. -# NAME is "CC", "CXX", "GCJ", or "OBJC". +# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was @@ -176,12 +369,13 @@ AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl -ifelse([$1], CC, [depcc="$CC" am_compiler_list=], - [$1], CXX, [depcc="$CXX" am_compiler_list=], - [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], - [$1], UPC, [depcc="$UPC" am_compiler_list=], - [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], - [depcc="$$1" am_compiler_list=]) +m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], + [$1], [CXX], [depcc="$CXX" am_compiler_list=], + [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], + [$1], [UPC], [depcc="$UPC" am_compiler_list=], + [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], @@ -189,8 +383,9 @@ # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named `D' -- because `-MD' means `put the output - # in D'. + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. @@ -229,16 +424,16 @@ : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with - # Solaris 8's {/usr,}/bin/sh. - touch sub/conftst$i.h + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - # We check with `-c' and `-o' for the sake of the "dashmstdout" + # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly - # handle `-M -o', and we need to detect this. Also, some Intel - # versions had trouble with output in subdirs + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in @@ -247,16 +442,16 @@ test "$am__universal" = false || continue ;; nosideeffect) - # after this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; - msvisualcpp | msvcmsys) - # This compiler won't grok `-c -o', but also, the minuso test has + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} @@ -304,7 +499,7 @@ # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. -# This macro is AC_REQUIREd in _AM_DEPENDENCIES +# This macro is AC_REQUIREd in _AM_DEPENDENCIES. AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl @@ -314,34 +509,39 @@ # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], -[AC_ARG_ENABLE(dependency-tracking, -[ --disable-dependency-tracking speeds up one-time build - --enable-dependency-tracking do not reject slow dependency extractors]) +[AC_ARG_ENABLE([dependency-tracking], [dnl +AS_HELP_STRING( + [--enable-dependency-tracking], + [do not reject slow dependency extractors]) +AS_HELP_STRING( + [--disable-dependency-tracking], + [speeds up one-time build])]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' + am__nodep='_no' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +AC_SUBST([am__nodep])dnl +_AM_SUBST_NOTMAKE([am__nodep])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- -# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 -# Free Software Foundation, Inc. +# Copyright (C) 1999-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -#serial 5 # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ - # Autoconf 2.62 quotes --file arguments for eval, but not when files + # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in @@ -354,7 +554,7 @@ # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named `Makefile.in', but + # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. @@ -366,21 +566,19 @@ continue fi # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running `make'. + # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "am__include" && continue + test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # When using ansi2knr, U may be empty or an underscore; expand it - U=`sed -n 's/^U = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` @@ -398,7 +596,7 @@ # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking -# is enabled. FIXME. This creates each `.P' file that we will +# is enabled. FIXME. This creates each '.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], @@ -406,29 +604,14 @@ [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) -# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 -# Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 8 - -# AM_CONFIG_HEADER is obsolete. It has been replaced by AC_CONFIG_HEADERS. -AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)]) - # Do all the work for Automake. -*- Autoconf -*- -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, -# 2005, 2006, 2008, 2009 Free Software Foundation, Inc. +# Copyright (C) 1996-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 16 - # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. @@ -444,7 +627,7 @@ # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], -[AC_PREREQ([2.62])dnl +[AC_PREREQ([2.65])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl @@ -473,31 +656,40 @@ # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], -[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl +[AC_DIAGNOSE([obsolete], + [$0: two- and three-arguments forms are deprecated.]) +m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. -m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, +m4_if( + m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), + [ok:ok],, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, -[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) - AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl +[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) + AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl -AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) -AM_MISSING_PROG(AUTOCONF, autoconf) -AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) -AM_MISSING_PROG(AUTOHEADER, autoheader) -AM_MISSING_PROG(MAKEINFO, makeinfo) +AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) +AM_MISSING_PROG([AUTOCONF], [autoconf]) +AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) +AM_MISSING_PROG([AUTOHEADER], [autoheader]) +AM_MISSING_PROG([MAKEINFO], [makeinfo]) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl -AC_REQUIRE([AM_PROG_MKDIR_P])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# +# +AC_SUBST([mkdir_p], ['$(MKDIR_P)']) # We need awk for the "check" target. The system "awk" is bad on # some platforms. AC_REQUIRE([AC_PROG_AWK])dnl @@ -508,28 +700,32 @@ [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], - [_AM_DEPENDENCIES(CC)], - [define([AC_PROG_CC], - defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl + [_AM_DEPENDENCIES([CC])], + [m4_define([AC_PROG_CC], + m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], - [_AM_DEPENDENCIES(CXX)], - [define([AC_PROG_CXX], - defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl + [_AM_DEPENDENCIES([CXX])], + [m4_define([AC_PROG_CXX], + m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], - [_AM_DEPENDENCIES(OBJC)], - [define([AC_PROG_OBJC], - defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl -]) -_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl -dnl The `parallel-tests' driver may need to know about EXEEXT, so add the -dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro -dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. + [_AM_DEPENDENCIES([OBJC])], + [m4_define([AC_PROG_OBJC], + m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], + [_AM_DEPENDENCIES([OBJCXX])], + [m4_define([AC_PROG_OBJCXX], + m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl +]) +AC_REQUIRE([AM_SILENT_RULES])dnl +dnl The testsuite driver may need to know about EXEEXT, so add the +dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This +dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl ]) -dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], @@ -557,7 +753,7 @@ done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) -# Copyright (C) 2001, 2003, 2005, 2008 Free Software Foundation, Inc. +# Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -576,16 +772,14 @@ install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi -AC_SUBST(install_sh)]) +AC_SUBST([install_sh])]) -# Copyright (C) 2003, 2005 Free Software Foundation, Inc. +# Copyright (C) 2003-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 2 - # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], @@ -601,14 +795,12 @@ # Check to see how 'make' treats includes. -*- Autoconf -*- -# Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc. +# Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 4 - # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. @@ -626,7 +818,7 @@ _am_result=none # First try GNU make style include. echo "include confinc" > confmf -# Ignore all kinds of additional output from `make'. +# Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include @@ -651,15 +843,12 @@ rm -f confinc confmf ]) -# Copyright (C) 1999, 2000, 2001, 2003, 2004, 2005, 2008 -# Free Software Foundation, Inc. +# Copyright (C) 1999-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 6 - # AM_PROG_CC_C_O # -------------- # Like AC_PROG_CC_C_O, but changed for automake. @@ -688,15 +877,12 @@ # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- -# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008 -# Free Software Foundation, Inc. +# Copyright (C) 1997-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 6 - # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], @@ -704,11 +890,10 @@ $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) - # AM_MISSING_HAS_RUN # ------------------ -# Define MISSING if not defined so far and test if it supports --run. -# If it does, set am_missing_run to use it, otherwise, to nothing. +# Define MISSING if not defined so far and test if it is modern enough. +# If it is, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl @@ -721,63 +906,35 @@ esac fi # Use eval to expand $SHELL -if eval "$MISSING --run true"; then - am_missing_run="$MISSING --run " +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " else am_missing_run= - AC_MSG_WARN([`missing' script is too old or missing]) + AC_MSG_WARN(['missing' script is too old or missing]) fi ]) -# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_PROG_MKDIR_P -# --------------- -# Check for `mkdir -p'. -AC_DEFUN([AM_PROG_MKDIR_P], -[AC_PREREQ([2.60])dnl -AC_REQUIRE([AC_PROG_MKDIR_P])dnl -dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, -dnl while keeping a definition of mkdir_p for backward compatibility. -dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. -dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of -dnl Makefile.ins that do not define MKDIR_P, so we do our own -dnl adjustment using top_builddir (which is defined more often than -dnl MKDIR_P). -AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl -case $mkdir_p in - [[\\/$]]* | ?:[[\\/]]*) ;; - */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; -esac -]) - # Helper functions for option handling. -*- Autoconf -*- -# Copyright (C) 2001, 2002, 2003, 2005, 2008 Free Software Foundation, Inc. +# Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 4 - # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) -# ------------------------------ +# -------------------- # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], -[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) +[m4_define(_AM_MANGLE_OPTION([$1]), [1])]) # _AM_SET_OPTIONS(OPTIONS) -# ---------------------------------- +# ------------------------ # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) @@ -788,24 +945,270 @@ AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) -# Check to make sure that the build environment is sane. -*- Autoconf -*- +# Copyright (C) 1999-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. -# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008 -# Free Software Foundation, Inc. + +# AM_PATH_PYTHON([MINIMUM-VERSION], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +# --------------------------------------------------------------------------- +# Adds support for distributing Python modules and packages. To +# install modules, copy them to $(pythondir), using the python_PYTHON +# automake variable. To install a package with the same name as the +# automake package, install to $(pkgpythondir), or use the +# pkgpython_PYTHON automake variable. +# +# The variables $(pyexecdir) and $(pkgpyexecdir) are provided as +# locations to install python extension modules (shared libraries). +# Another macro is required to find the appropriate flags to compile +# extension modules. +# +# If your package is configured with a different prefix to python, +# users will have to add the install directory to the PYTHONPATH +# environment variable, or create a .pth file (see the python +# documentation for details). +# +# If the MINIMUM-VERSION argument is passed, AM_PATH_PYTHON will +# cause an error if the version of python installed on the system +# doesn't meet the requirement. MINIMUM-VERSION should consist of +# numbers and dots only. +AC_DEFUN([AM_PATH_PYTHON], + [ + dnl Find a Python interpreter. Python versions prior to 2.0 are not + dnl supported. (2.0 was released on October 16, 2000). + m4_define_default([_AM_PYTHON_INTERPRETER_LIST], +[python python2 python3 python3.3 python3.2 python3.1 python3.0 python2.7 dnl + python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0]) + + AC_ARG_VAR([PYTHON], [the Python interpreter]) + + m4_if([$1],[],[ + dnl No version check is needed. + # Find any Python interpreter. + if test -z "$PYTHON"; then + AC_PATH_PROGS([PYTHON], _AM_PYTHON_INTERPRETER_LIST, :) + fi + am_display_PYTHON=python + ], [ + dnl A version check is needed. + if test -n "$PYTHON"; then + # If the user set $PYTHON, use it and don't search something else. + AC_MSG_CHECKING([whether $PYTHON version is >= $1]) + AM_PYTHON_CHECK_VERSION([$PYTHON], [$1], + [AC_MSG_RESULT([yes])], + [AC_MSG_RESULT([no]) + AC_MSG_ERROR([Python interpreter is too old])]) + am_display_PYTHON=$PYTHON + else + # Otherwise, try each interpreter until we find one that satisfies + # VERSION. + AC_CACHE_CHECK([for a Python interpreter with version >= $1], + [am_cv_pathless_PYTHON],[ + for am_cv_pathless_PYTHON in _AM_PYTHON_INTERPRETER_LIST none; do + test "$am_cv_pathless_PYTHON" = none && break + AM_PYTHON_CHECK_VERSION([$am_cv_pathless_PYTHON], [$1], [break]) + done]) + # Set $PYTHON to the absolute path of $am_cv_pathless_PYTHON. + if test "$am_cv_pathless_PYTHON" = none; then + PYTHON=: + else + AC_PATH_PROG([PYTHON], [$am_cv_pathless_PYTHON]) + fi + am_display_PYTHON=$am_cv_pathless_PYTHON + fi + ]) + + if test "$PYTHON" = :; then + dnl Run any user-specified action, or abort. + m4_default([$3], [AC_MSG_ERROR([no suitable Python interpreter found])]) + else + + dnl Query Python for its version number. Getting [:3] seems to be + dnl the best way to do this; it's what "site.py" does in the standard + dnl library. + + AC_CACHE_CHECK([for $am_display_PYTHON version], [am_cv_python_version], + [am_cv_python_version=`$PYTHON -c "import sys; sys.stdout.write(sys.version[[:3]])"`]) + AC_SUBST([PYTHON_VERSION], [$am_cv_python_version]) + + dnl Use the values of $prefix and $exec_prefix for the corresponding + dnl values of PYTHON_PREFIX and PYTHON_EXEC_PREFIX. These are made + dnl distinct variables so they can be overridden if need be. However, + dnl general consensus is that you shouldn't need this ability. + + AC_SUBST([PYTHON_PREFIX], ['${prefix}']) + AC_SUBST([PYTHON_EXEC_PREFIX], ['${exec_prefix}']) + + dnl At times (like when building shared libraries) you may want + dnl to know which OS platform Python thinks this is. + + AC_CACHE_CHECK([for $am_display_PYTHON platform], [am_cv_python_platform], + [am_cv_python_platform=`$PYTHON -c "import sys; sys.stdout.write(sys.platform)"`]) + AC_SUBST([PYTHON_PLATFORM], [$am_cv_python_platform]) + + # Just factor out some code duplication. + am_python_setup_sysconfig="\ +import sys +# Prefer sysconfig over distutils.sysconfig, for better compatibility +# with python 3.x. See automake bug#10227. +try: + import sysconfig +except ImportError: + can_use_sysconfig = 0 +else: + can_use_sysconfig = 1 +# Can't use sysconfig in CPython 2.7, since it's broken in virtualenvs: +# +try: + from platform import python_implementation + if python_implementation() == 'CPython' and sys.version[[:3]] == '2.7': + can_use_sysconfig = 0 +except ImportError: + pass" + + dnl Set up 4 directories: + + dnl pythondir -- where to install python scripts. This is the + dnl site-packages directory, not the python standard library + dnl directory like in previous automake betas. This behavior + dnl is more consistent with lispdir.m4 for example. + dnl Query distutils for this directory. + AC_CACHE_CHECK([for $am_display_PYTHON script directory], + [am_cv_python_pythondir], + [if test "x$prefix" = xNONE + then + am_py_prefix=$ac_default_prefix + else + am_py_prefix=$prefix + fi + am_cv_python_pythondir=`$PYTHON -c " +$am_python_setup_sysconfig +if can_use_sysconfig: + sitedir = sysconfig.get_path('purelib', vars={'base':'$am_py_prefix'}) +else: + from distutils import sysconfig + sitedir = sysconfig.get_python_lib(0, 0, prefix='$am_py_prefix') +sys.stdout.write(sitedir)"` + case $am_cv_python_pythondir in + $am_py_prefix*) + am__strip_prefix=`echo "$am_py_prefix" | sed 's|.|.|g'` + am_cv_python_pythondir=`echo "$am_cv_python_pythondir" | sed "s,^$am__strip_prefix,$PYTHON_PREFIX,"` + ;; + *) + case $am_py_prefix in + /usr|/System*) ;; + *) + am_cv_python_pythondir=$PYTHON_PREFIX/lib/python$PYTHON_VERSION/site-packages + ;; + esac + ;; + esac + ]) + AC_SUBST([pythondir], [$am_cv_python_pythondir]) + + dnl pkgpythondir -- $PACKAGE directory under pythondir. Was + dnl PYTHON_SITE_PACKAGE in previous betas, but this naming is + dnl more consistent with the rest of automake. + + AC_SUBST([pkgpythondir], [\${pythondir}/$PACKAGE]) + + dnl pyexecdir -- directory for installing python extension modules + dnl (shared libraries) + dnl Query distutils for this directory. + AC_CACHE_CHECK([for $am_display_PYTHON extension module directory], + [am_cv_python_pyexecdir], + [if test "x$exec_prefix" = xNONE + then + am_py_exec_prefix=$am_py_prefix + else + am_py_exec_prefix=$exec_prefix + fi + am_cv_python_pyexecdir=`$PYTHON -c " +$am_python_setup_sysconfig +if can_use_sysconfig: + sitedir = sysconfig.get_path('platlib', vars={'platbase':'$am_py_prefix'}) +else: + from distutils import sysconfig + sitedir = sysconfig.get_python_lib(1, 0, prefix='$am_py_prefix') +sys.stdout.write(sitedir)"` + case $am_cv_python_pyexecdir in + $am_py_exec_prefix*) + am__strip_prefix=`echo "$am_py_exec_prefix" | sed 's|.|.|g'` + am_cv_python_pyexecdir=`echo "$am_cv_python_pyexecdir" | sed "s,^$am__strip_prefix,$PYTHON_EXEC_PREFIX,"` + ;; + *) + case $am_py_exec_prefix in + /usr|/System*) ;; + *) + am_cv_python_pyexecdir=$PYTHON_EXEC_PREFIX/lib/python$PYTHON_VERSION/site-packages + ;; + esac + ;; + esac + ]) + AC_SUBST([pyexecdir], [$am_cv_python_pyexecdir]) + + dnl pkgpyexecdir -- $(pyexecdir)/$(PACKAGE) + + AC_SUBST([pkgpyexecdir], [\${pyexecdir}/$PACKAGE]) + + dnl Run any user-specified action. + $2 + fi + +]) + + +# AM_PYTHON_CHECK_VERSION(PROG, VERSION, [ACTION-IF-TRUE], [ACTION-IF-FALSE]) +# --------------------------------------------------------------------------- +# Run ACTION-IF-TRUE if the Python interpreter PROG has version >= VERSION. +# Run ACTION-IF-FALSE otherwise. +# This test uses sys.hexversion instead of the string equivalent (first +# word of sys.version), in order to cope with versions such as 2.2c1. +# This supports Python 2.0 or higher. (2.0 was released on October 16, 2000). +AC_DEFUN([AM_PYTHON_CHECK_VERSION], + [prog="import sys +# split strings by '.' and convert to numeric. Append some zeros +# because we need at least 4 digits for the hex conversion. +# map returns an iterator in Python 3.0 and a list in 2.x +minver = list(map(int, '$2'.split('.'))) + [[0, 0, 0]] +minverhex = 0 +# xrange is not present in Python 3.0 and range returns an iterator +for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[[i]] +sys.exit(sys.hexversion < minverhex)" + AS_IF([AM_RUN_LOG([$1 -c "$prog"])], [$3], [$4])]) + +# Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 5 +# AM_RUN_LOG(COMMAND) +# ------------------- +# Run COMMAND, save the exit status in ac_status, and log it. +# (This has been adapted from Autoconf's _AC_RUN_LOG macro.) +AC_DEFUN([AM_RUN_LOG], +[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD + ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + (exit $ac_status); }]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) -# Just in case -sleep 1 -echo timestamp > conftest.file # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' @@ -816,32 +1219,40 @@ esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) - AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);; + AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; esac -# Do `set' in a subshell so we don't clobber the current shell's +# Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( - set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` - if test "$[*]" = "X"; then - # -L didn't work. - set X `ls -t "$srcdir/configure" conftest.file` - fi - rm -f conftest.file - if test "$[*]" != "X $srcdir/configure conftest.file" \ - && test "$[*]" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken -alias in your environment]) - fi - + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken + alias in your environment]) + fi + if test "$[2]" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done test "$[2]" = conftest.file ) then @@ -851,9 +1262,85 @@ AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi -AC_MSG_RESULT(yes)]) +AC_MSG_RESULT([yes]) +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi +AC_CONFIG_COMMANDS_PRE( + [AC_MSG_CHECKING([that generated files are newer than configure]) + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + AC_MSG_RESULT([done])]) +rm -f conftest.file +]) -# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# Copyright (C) 2009-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_SILENT_RULES([DEFAULT]) +# -------------------------- +# Enable less verbose build rules; with the default set to DEFAULT +# ("yes" being less verbose, "no" or empty being verbose). +AC_DEFUN([AM_SILENT_RULES], +[AC_ARG_ENABLE([silent-rules], [dnl +AS_HELP_STRING( + [--enable-silent-rules], + [less verbose build output (undo: "make V=1")]) +AS_HELP_STRING( + [--disable-silent-rules], + [verbose build output (undo: "make V=0")])dnl +]) +case $enable_silent_rules in @%:@ ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; +esac +dnl +dnl A few 'make' implementations (e.g., NonStop OS and NextStep) +dnl do not support nested variable expansions. +dnl See automake bug#9928 and bug#10237. +am_make=${MAKE-make} +AC_CACHE_CHECK([whether $am_make supports nested variables], + [am_cv_make_support_nested_variables], + [if AS_ECHO([['TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi]) +if test $am_cv_make_support_nested_variables = yes; then + dnl Using '$V' instead of '$(V)' breaks IRIX make. + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AC_SUBST([AM_V])dnl +AM_SUBST_NOTMAKE([AM_V])dnl +AC_SUBST([AM_DEFAULT_V])dnl +AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl +AC_SUBST([AM_DEFAULT_VERBOSITY])dnl +AM_BACKSLASH='\' +AC_SUBST([AM_BACKSLASH])dnl +_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl +]) + +# Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -861,34 +1348,32 @@ # AM_PROG_INSTALL_STRIP # --------------------- -# One issue with vendor `install' (even GNU) is that you can't +# One issue with vendor 'install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we -# always use install-sh in `make install-strip', and initialize +# always use install-sh in "make install-strip", and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl -# Installed binaries are usually stripped using `strip' when the user -# run `make install-strip'. However `strip' might not be the right +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake -# will honor the `STRIP' environment variable to overrule this program. -dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +# will honor the 'STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) -# Copyright (C) 2006, 2008 Free Software Foundation, Inc. +# Copyright (C) 2006-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 2 - # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. @@ -896,24 +1381,22 @@ AC_DEFUN([_AM_SUBST_NOTMAKE]) # AM_SUBST_NOTMAKE(VARIABLE) -# --------------------------- +# -------------------------- # Public sister of _AM_SUBST_NOTMAKE. AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- -# Copyright (C) 2004, 2005 Free Software Foundation, Inc. +# Copyright (C) 2004-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 2 - # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. -# FORMAT should be one of `v7', `ustar', or `pax'. +# FORMAT should be one of 'v7', 'ustar', or 'pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory @@ -923,78 +1406,116 @@ # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar +# AC_DEFUN([_AM_PROG_TAR], -[# Always define AMTAR for backward compatibility. -AM_MISSING_PROG([AMTAR], [tar]) -m4_if([$1], [v7], - [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], - [m4_case([$1], [ustar],, [pax],, - [m4_fatal([Unknown tar format])]) -AC_MSG_CHECKING([how to create a $1 tar archive]) -# Loop over all known methods to create a tar archive until one works. +[# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AC_SUBST([AMTAR], ['$${TAR-tar}']) + +# We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' -_am_tools=${am_cv_prog_tar_$1-$_am_tools} -# Do not fold the above two line into one, because Tru64 sh and -# Solaris sh will not grok spaces in the rhs of `-'. -for _am_tool in $_am_tools -do - case $_am_tool in - gnutar) - for _am_tar in tar gnutar gtar; - do - AM_RUN_LOG([$_am_tar --version]) && break - done - am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' - am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' - am__untar="$_am_tar -xf -" - ;; - plaintar) - # Must skip GNU tar: if it does not support --format= it doesn't create - # ustar tarball either. - (tar --version) >/dev/null 2>&1 && continue - am__tar='tar chf - "$$tardir"' - am__tar_='tar chf - "$tardir"' - am__untar='tar xf -' - ;; - pax) - am__tar='pax -L -x $1 -w "$$tardir"' - am__tar_='pax -L -x $1 -w "$tardir"' - am__untar='pax -r' - ;; - cpio) - am__tar='find "$$tardir" -print | cpio -o -H $1 -L' - am__tar_='find "$tardir" -print | cpio -o -H $1 -L' - am__untar='cpio -i -H $1 -d' - ;; - none) - am__tar=false - am__tar_=false - am__untar=false - ;; - esac - # If the value was cached, stop now. We just wanted to have am__tar - # and am__untar set. - test -n "${am_cv_prog_tar_$1}" && break +m4_if([$1], [v7], + [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], - # tar/untar a dummy directory, and stop if the command works - rm -rf conftest.dir - mkdir conftest.dir - echo GrepMe > conftest.dir/file - AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + [m4_case([$1], + [ustar], + [# The POSIX 1988 'ustar' format is defined with fixed-size fields. + # There is notably a 21 bits limit for the UID and the GID. In fact, + # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 + # and bug#13588). + am_max_uid=2097151 # 2^21 - 1 + am_max_gid=$am_max_uid + # The $UID and $GID variables are not portable, so we need to resort + # to the POSIX-mandated id(1) utility. Errors in the 'id' calls + # below are definitely unexpected, so allow the users to see them + # (that is, avoid stderr redirection). + am_uid=`id -u || echo unknown` + am_gid=`id -g || echo unknown` + AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) + if test $am_uid -le $am_max_uid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi + AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) + if test $am_gid -le $am_max_gid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi], + + [pax], + [], + + [m4_fatal([Unknown tar format])]) + + AC_MSG_CHECKING([how to create a $1 tar archive]) + + # Go ahead even if we have the value already cached. We do so because we + # need to set the values for the 'am__tar' and 'am__untar' variables. + _am_tools=${am_cv_prog_tar_$1-$_am_tools} + + for _am_tool in $_am_tools; do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works. + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi + done rm -rf conftest.dir - if test -s conftest.tar; then - AM_RUN_LOG([$am__untar /dev/null 2>&1 && break - fi -done -rm -rf conftest.dir -AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) -AC_MSG_RESULT([$am_cv_prog_tar_$1])]) + AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) + AC_MSG_RESULT([$am_cv_prog_tar_$1])]) + AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR m4_include([config/acinclude.m4]) -m4_include([config/linux.m4]) diff -Nru lxc-0.8.0~rc1/autogen.sh lxc-1.0.0~alpha1/autogen.sh --- lxc-0.8.0~rc1/autogen.sh 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/autogen.sh 2013-09-10 22:22:00.000000000 +0000 @@ -1,4 +1,25 @@ #!/bin/sh +# +# lxc: linux Container library +# +# (C) Copyright IBM Corp. 2007, 2008 +# +# Authors: +# Daniel Lezcano +# +# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA set -x diff -Nru lxc-0.8.0~rc1/config/Makefile.am lxc-1.0.0~alpha1/config/Makefile.am --- lxc-0.8.0~rc1/config/Makefile.am 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/config/Makefile.am 2013-09-10 22:22:00.000000000 +0000 @@ -1,2 +1,15 @@ -distclean: +configdir = $(sysconfdir)/lxc +config_DATA = default.conf +distroconf = @LXC_DISTRO_CONF@ + +EXTRA_DIST = default.conf.ubuntu default.conf.libvirt default.conf.unknown + +default.conf: + cp $(distroconf) $@ + +clean-local: + @$(RM) -f default.conf + +distclean-local: + @$(RM) -f default.conf @$(RM) -f compile config.guess config.sub depcomp install-sh ltmain.sh missing Makefile.in Makefile diff -Nru lxc-0.8.0~rc1/config/Makefile.in lxc-1.0.0~alpha1/config/Makefile.in --- lxc-0.8.0~rc1/config/Makefile.in 2012-03-01 23:04:43.000000000 +0000 +++ lxc-1.0.0~alpha1/config/Makefile.in 2013-09-10 22:30:08.000000000 +0000 @@ -1,9 +1,8 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. +# Makefile.in generated by automake 1.13.3 from Makefile.am. # @configure_input@ -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -14,7 +13,53 @@ # PARTICULAR PURPOSE. @SET_MAKE@ + VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -34,22 +79,71 @@ build_triplet = @build@ host_triplet = @host@ subdir = config -DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in compile \ - config.guess config.sub depcomp install-sh missing +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am compile \ + config.guess config.sub install-sh missing ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/config/acinclude.m4 \ - $(top_srcdir)/config/linux.m4 $(top_srcdir)/configure.ac + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/src/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = SOURCES = DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(configdir)" +DATA = $(config_DATA) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +APPARMOR_LIBS = @APPARMOR_LIBS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ @@ -80,19 +174,31 @@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBDIR = @LIBDIR@ +LIBEXECDIR = @LIBEXECDIR@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ -LINUX_DIR = @LINUX_DIR@ -LINUX_SRCARCH = @LINUX_SRCARCH@ LOCALSTATEDIR = @LOCALSTATEDIR@ +LOGPATH = @LOGPATH@ LTLIBOBJS = @LTLIBOBJS@ +LUA_CFLAGS = @LUA_CFLAGS@ +LUA_INSTALL_CMOD = @LUA_INSTALL_CMOD@ +LUA_INSTALL_LMOD = @LUA_INSTALL_LMOD@ +LUA_LIBS = @LUA_LIBS@ +LUA_VERSION = @LUA_VERSION@ +LXCHOOKDIR = @LXCHOOKDIR@ LXCINITDIR = @LXCINITDIR@ LXCPATH = @LXCPATH@ LXCROOTFSMOUNT = @LXCROOTFSMOUNT@ LXCTEMPLATEDIR = @LXCTEMPLATEDIR@ +LXC_DEFAULT_CONFIG = @LXC_DEFAULT_CONFIG@ +LXC_DISTRO_CONF = @LXC_DISTRO_CONF@ LXC_GENERATE_DATE = @LXC_GENERATE_DATE@ +LXC_GLOBAL_CONF = @LXC_GLOBAL_CONF@ +LXC_USERNIC_CONF = @LXC_USERNIC_CONF@ +LXC_USERNIC_DB = @LXC_USERNIC_DB@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +NEWUIDMAP = @NEWUIDMAP@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ @@ -102,8 +208,19 @@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PREFIX = @PREFIX@ -SETCAP = @SETCAP@ +PYTHON = @PYTHON@ +PYTHONDEV_CFLAGS = @PYTHONDEV_CFLAGS@ +PYTHONDEV_LIBS = @PYTHONDEV_LIBS@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +SECCOMP_LIBS = @SECCOMP_LIBS@ +SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ @@ -128,10 +245,11 @@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ +db2xman = @db2xman@ docdir = @docdir@ +docdtd = @docdtd@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ -have_docbook = @have_docbook@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ @@ -149,9 +267,13 @@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ @@ -160,6 +282,10 @@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ +configdir = $(sysconfdir)/lxc +config_DATA = default.conf +distroconf = @LXC_DISTRO_CONF@ +EXTRA_DIST = default.conf.ubuntu default.conf.libvirt default.conf.unknown all: all-am .SUFFIXES: @@ -193,11 +319,32 @@ $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): -tags: TAGS -TAGS: +install-configDATA: $(config_DATA) + @$(NORMAL_INSTALL) + @list='$(config_DATA)'; test -n "$(configdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(configdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(configdir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(configdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(configdir)" || exit $$?; \ + done + +uninstall-configDATA: + @$(NORMAL_UNINSTALL) + @list='$(config_DATA)'; test -n "$(configdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(configdir)'; $(am__uninstall_files_from_dir) +tags TAGS: + +ctags CTAGS: -ctags: CTAGS -CTAGS: +cscope cscopelist: distdir: $(DISTFILES) @@ -232,8 +379,11 @@ done check-am: all-am check: check-am -all-am: Makefile +all-am: Makefile $(DATA) installdirs: + for dir in "$(DESTDIR)$(configdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done install: install-am install-exec: install-exec-am install-data: install-data-am @@ -244,10 +394,15 @@ installcheck: installcheck-am install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi mostlyclean-generic: clean-generic: @@ -261,9 +416,11 @@ @echo "it deletes files that may require special tools to rebuild." clean: clean-am -clean-am: clean-generic mostlyclean-am +clean-am: clean-generic clean-local mostlyclean-am -distclean-am: clean-am distclean-generic +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-local dvi: dvi-am @@ -277,7 +434,7 @@ info-am: -install-data-am: +install-data-am: install-configDATA install-dvi: install-dvi-am @@ -321,21 +478,32 @@ ps-am: -uninstall-am: +uninstall-am: uninstall-configDATA .MAKE: install-am install-strip -.PHONY: all all-am check check-am clean clean-generic distclean \ - distclean-generic distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am +.PHONY: all all-am check check-am clean clean-generic clean-local \ + cscopelist-am ctags-am distclean distclean-generic \ + distclean-local distdir dvi dvi-am html html-am info info-am \ + install install-am install-configDATA install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ + pdf-am ps ps-am tags-am uninstall uninstall-am \ + uninstall-configDATA + + +default.conf: + cp $(distroconf) $@ + +clean-local: + @$(RM) -f default.conf -distclean: +distclean-local: + @$(RM) -f default.conf @$(RM) -f compile config.guess config.sub depcomp install-sh ltmain.sh missing Makefile.in Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. diff -Nru lxc-0.8.0~rc1/config/acinclude.m4 lxc-1.0.0~alpha1/config/acinclude.m4 --- lxc-0.8.0~rc1/config/acinclude.m4 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/config/acinclude.m4 2013-07-08 15:50:40.000000000 +0000 @@ -2,21 +2,21 @@ dnl autostars m4 macro for expanding directories using configure's prefix dnl thomas@apestaart.org dnl - + dnl AS_AC_EXPAND(VAR, CONFIGURE_VAR) dnl example dnl AS_AC_EXPAND(SYSCONFDIR, $sysconfdir) dnl will set SYSCONFDIR to /usr/local/etc if prefix=/usr/local - + AC_DEFUN([AS_AC_EXPAND], [ EXP_VAR=[$1] FROM_VAR=[$2] - + dnl first expand prefix and exec_prefix if necessary prefix_save=$prefix exec_prefix_save=$exec_prefix - + dnl if no prefix given, then use /usr/local, the default prefix if test "x$prefix" = "xNONE"; then prefix="$ac_default_prefix" @@ -25,7 +25,7 @@ if test "x$exec_prefix" = "xNONE"; then exec_prefix=$prefix fi - + full_var="$FROM_VAR" dnl loop until it doesn't change anymore while true; do @@ -33,11 +33,11 @@ if test "x$new_full_var" = "x$full_var"; then break; fi full_var=$new_full_var done - + dnl clean up full_var=$new_full_var AC_SUBST([$1], "$full_var") - + dnl restore prefix and exec_prefix prefix=$prefix_save exec_prefix=$exec_prefix_save @@ -94,7 +94,7 @@ # Determine the number of characters in A and B. ax_compare_version_len_A=`echo "$A" | awk '{print(length)}'` ax_compare_version_len_B=`echo "$B" | awk '{print(length)}'` - + # Set A to no more than B's length and B to no more than A's length. A=`echo "$A" | sed "s/\(.\{$ax_compare_version_len_B\}\).*/\1/"` B=`echo "$B" | sed "s/\(.\{$ax_compare_version_len_A\}\).*/\1/"` diff -Nru lxc-0.8.0~rc1/config/compile lxc-1.0.0~alpha1/config/compile --- lxc-0.8.0~rc1/config/compile 2012-03-01 21:47:20.000000000 +0000 +++ lxc-1.0.0~alpha1/config/compile 2013-09-10 22:30:08.000000000 +0000 @@ -1,10 +1,9 @@ #! /bin/sh -# Wrapper for compilers which do not understand `-c -o'. +# Wrapper for compilers which do not understand '-c -o'. -scriptversion=2009-10-06.20; # UTC +scriptversion=2012-10-14.11; # UTC -# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2009 Free Software -# Foundation, Inc. +# Copyright (C) 1999-2013 Free Software Foundation, Inc. # Written by Tom Tromey . # # This program is free software; you can redistribute it and/or modify @@ -29,21 +28,224 @@ # bugs to or send patches to # . +nl=' +' + +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent tools from complaining about whitespace usage. +IFS=" "" $nl" + +file_conv= + +# func_file_conv build_file lazy +# Convert a $build file to $host form and store it in $file +# Currently only supports Windows hosts. If the determined conversion +# type is listed in (the comma separated) LAZY, no conversion will +# take place. +func_file_conv () +{ + file=$1 + case $file in + / | /[!/]*) # absolute file, and not a UNC file + if test -z "$file_conv"; then + # lazily determine how to convert abs files + case `uname -s` in + MINGW*) + file_conv=mingw + ;; + CYGWIN*) + file_conv=cygwin + ;; + *) + file_conv=wine + ;; + esac + fi + case $file_conv/,$2, in + *,$file_conv,*) + ;; + mingw/*) + file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` + ;; + cygwin/*) + file=`cygpath -m "$file" || echo "$file"` + ;; + wine/*) + file=`winepath -w "$file" || echo "$file"` + ;; + esac + ;; + esac +} + +# func_cl_dashL linkdir +# Make cl look for libraries in LINKDIR +func_cl_dashL () +{ + func_file_conv "$1" + if test -z "$lib_path"; then + lib_path=$file + else + lib_path="$lib_path;$file" + fi + linker_opts="$linker_opts -LIBPATH:$file" +} + +# func_cl_dashl library +# Do a library search-path lookup for cl +func_cl_dashl () +{ + lib=$1 + found=no + save_IFS=$IFS + IFS=';' + for dir in $lib_path $LIB + do + IFS=$save_IFS + if $shared && test -f "$dir/$lib.dll.lib"; then + found=yes + lib=$dir/$lib.dll.lib + break + fi + if test -f "$dir/$lib.lib"; then + found=yes + lib=$dir/$lib.lib + break + fi + if test -f "$dir/lib$lib.a"; then + found=yes + lib=$dir/lib$lib.a + break + fi + done + IFS=$save_IFS + + if test "$found" != yes; then + lib=$lib.lib + fi +} + +# func_cl_wrapper cl arg... +# Adjust compile command to suit cl +func_cl_wrapper () +{ + # Assume a capable shell + lib_path= + shared=: + linker_opts= + for arg + do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + eat=1 + case $2 in + *.o | *.[oO][bB][jJ]) + func_file_conv "$2" + set x "$@" -Fo"$file" + shift + ;; + *) + func_file_conv "$2" + set x "$@" -Fe"$file" + shift + ;; + esac + ;; + -I) + eat=1 + func_file_conv "$2" mingw + set x "$@" -I"$file" + shift + ;; + -I*) + func_file_conv "${1#-I}" mingw + set x "$@" -I"$file" + shift + ;; + -l) + eat=1 + func_cl_dashl "$2" + set x "$@" "$lib" + shift + ;; + -l*) + func_cl_dashl "${1#-l}" + set x "$@" "$lib" + shift + ;; + -L) + eat=1 + func_cl_dashL "$2" + ;; + -L*) + func_cl_dashL "${1#-L}" + ;; + -static) + shared=false + ;; + -Wl,*) + arg=${1#-Wl,} + save_ifs="$IFS"; IFS=',' + for flag in $arg; do + IFS="$save_ifs" + linker_opts="$linker_opts $flag" + done + IFS="$save_ifs" + ;; + -Xlinker) + eat=1 + linker_opts="$linker_opts $2" + ;; + -*) + set x "$@" "$1" + shift + ;; + *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) + func_file_conv "$1" + set x "$@" -Tp"$file" + shift + ;; + *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) + func_file_conv "$1" mingw + set x "$@" "$file" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift + done + if test -n "$linker_opts"; then + linker_opts="-link$linker_opts" + fi + exec "$@" $linker_opts + exit 1 +} + +eat= + case $1 in '') - echo "$0: No command. Try \`$0 --help' for more information." 1>&2 + echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: compile [--help] [--version] PROGRAM [ARGS] -Wrapper for compilers which do not understand `-c -o'. -Remove `-o dest.o' from ARGS, run PROGRAM with the remaining +Wrapper for compilers which do not understand '-c -o'. +Remove '-o dest.o' from ARGS, run PROGRAM with the remaining arguments, and rename the output as expected. If you are trying to build a whole package this is not the -right script to run: please start by reading the file `INSTALL'. +right script to run: please start by reading the file 'INSTALL'. Report bugs to . EOF @@ -53,11 +255,13 @@ echo "compile $scriptversion" exit $? ;; + cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) + func_cl_wrapper "$@" # Doesn't return... + ;; esac ofile= cfile= -eat= for arg do @@ -66,8 +270,8 @@ else case $1 in -o) - # configure might choose to run compile as `compile cc -o foo foo.c'. - # So we strip `-o arg' only if arg is an object. + # configure might choose to run compile as 'compile cc -o foo foo.c'. + # So we strip '-o arg' only if arg is an object. eat=1 case $2 in *.o | *.obj) @@ -94,10 +298,10 @@ done if test -z "$ofile" || test -z "$cfile"; then - # If no `-o' option was seen then we might have been invoked from a + # If no '-o' option was seen then we might have been invoked from a # pattern rule where we don't need one. That is ok -- this is a # normal compilation that the losing compiler can handle. If no - # `.c' file was seen then we are probably linking. That is also + # '.c' file was seen then we are probably linking. That is also # ok. exec "$@" fi @@ -106,7 +310,7 @@ cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` # Create the lock directory. -# Note: use `[/\\:.-]' here to ensure that we don't use the same name +# Note: use '[/\\:.-]' here to ensure that we don't use the same name # that we are using for the .o file. Also, base the name on the expected # object file name, since that is what matters with a parallel build. lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d diff -Nru lxc-0.8.0~rc1/config/config.guess lxc-1.0.0~alpha1/config/config.guess --- lxc-0.8.0~rc1/config/config.guess 2012-03-01 21:47:20.000000000 +0000 +++ lxc-1.0.0~alpha1/config/config.guess 2013-09-10 22:30:08.000000000 +0000 @@ -1,14 +1,12 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, -# 2011 Free Software Foundation, Inc. +# Copyright 1992-2013 Free Software Foundation, Inc. -timestamp='2011-05-11' +timestamp='2013-06-10' # This file 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 +# the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but @@ -17,26 +15,22 @@ # 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., 51 Franklin Street - Fifth Floor, Boston, MA -# 02110-1301, USA. +# along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - - -# Originally written by Per Bothner. Please send patches (context -# diff format) to and include a ChangeLog -# entry. +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). # -# This script attempts to guess a canonical system name similar to -# config.sub. If it succeeds, it prints the system name on stdout, and -# exits with 0. Otherwise, it exits with 1. +# Originally written by Per Bothner. # # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD +# +# Please send patches with a ChangeLog entry to config-patches@gnu.org. + me=`echo "$0" | sed -e 's,.*/,,'` @@ -56,9 +50,7 @@ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, -2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free -Software Foundation, Inc. +Copyright 1992-2013 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -140,12 +132,33 @@ UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown +case "${UNAME_SYSTEM}" in +Linux|GNU|GNU/*) + # If the system lacks a compiler, then just pick glibc. + # We could probably try harder. + LIBC=gnu + + eval $set_cc_for_build + cat <<-EOF > $dummy.c + #include + #if defined(__UCLIBC__) + LIBC=uclibc + #elif defined(__dietlibc__) + LIBC=dietlibc + #else + LIBC=gnu + #endif + EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` + ;; +esac + # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or - # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward @@ -202,6 +215,10 @@ # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit ;; + *:Bitrig:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} + exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} @@ -304,7 +321,7 @@ arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; - arm:riscos:*:*|arm:RISCOS:*:*) + arm*:riscos:*:*|arm*:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) @@ -792,21 +809,26 @@ echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) - case ${UNAME_MACHINE} in - pc98) - echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + UNAME_PROCESSOR=`/usr/bin/uname -p` + case ${UNAME_PROCESSOR} in amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) - echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; + *:MINGW64*:*) + echo ${UNAME_MACHINE}-pc-mingw64 + exit ;; *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; + i*:MSYS*:*) + echo ${UNAME_MACHINE}-pc-msys + exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 @@ -852,15 +874,22 @@ exit ;; *:GNU:*:*) # the GNU system - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland - echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; + aarch64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; @@ -872,56 +901,54 @@ EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 - if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi - echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + if test "$?" = 0 ; then LIBC="gnulibc1" ; fi + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + arc:Linux:*:* | arceb:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; arm*:Linux:*:*) eval $set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then - echo ${UNAME_MACHINE}-unknown-linux-gnueabi + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi else - echo ${UNAME_MACHINE}-unknown-linux-gnueabihf + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf fi fi exit ;; avr32*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; cris:Linux:*:*) - echo cris-axis-linux-gnu + echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; crisv32:Linux:*:*) - echo crisv32-axis-linux-gnu + echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; frv:Linux:*:*) - echo frv-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + hexagon:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; i*86:Linux:*:*) - LIBC=gnu - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #ifdef __dietlibc__ - LIBC=dietlibc - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` - echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + echo ${UNAME_MACHINE}-pc-linux-${LIBC} exit ;; ia64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m32r*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; mips:Linux:*:* | mips64:Linux:*:*) eval $set_cc_for_build @@ -940,54 +967,63 @@ #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } ;; + or1k:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; or32:Linux:*:*) - echo or32-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; padre:Linux:*:*) - echo sparc-unknown-linux-gnu + echo sparc-unknown-linux-${LIBC} exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-gnu + echo hppa64-unknown-linux-${LIBC} exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-gnu ;; - PA8*) echo hppa2.0-unknown-linux-gnu ;; - *) echo hppa-unknown-linux-gnu ;; + PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; + PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; + *) echo hppa-unknown-linux-${LIBC} ;; esac exit ;; ppc64:Linux:*:*) - echo powerpc64-unknown-linux-gnu + echo powerpc64-unknown-linux-${LIBC} exit ;; ppc:Linux:*:*) - echo powerpc-unknown-linux-gnu + echo powerpc-unknown-linux-${LIBC} + exit ;; + ppc64le:Linux:*:*) + echo powerpc64le-unknown-linux-${LIBC} + exit ;; + ppcle:Linux:*:*) + echo powerpcle-unknown-linux-${LIBC} exit ;; s390:Linux:*:* | s390x:Linux:*:*) - echo ${UNAME_MACHINE}-ibm-linux + echo ${UNAME_MACHINE}-ibm-linux-${LIBC} exit ;; sh64*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sh*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; tile*:Linux:*:*) - echo ${UNAME_MACHINE}-tilera-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; vax:Linux:*:*) - echo ${UNAME_MACHINE}-dec-linux-gnu + echo ${UNAME_MACHINE}-dec-linux-${LIBC} exit ;; x86_64:Linux:*:*) - echo x86_64-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; xtensa*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. @@ -1191,6 +1227,9 @@ BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; + x86_64:Haiku:*:*) + echo x86_64-unknown-haiku + exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; @@ -1217,19 +1256,21 @@ exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - case $UNAME_PROCESSOR in - i386) - eval $set_cc_for_build - if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then - if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_64BIT_ARCH >/dev/null - then - UNAME_PROCESSOR="x86_64" - fi - fi ;; - unknown) UNAME_PROCESSOR=powerpc ;; - esac + eval $set_cc_for_build + if test "$UNAME_PROCESSOR" = unknown ; then + UNAME_PROCESSOR=powerpc + fi + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi + fi echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) @@ -1246,7 +1287,7 @@ NEO-?:NONSTOP_KERNEL:*:*) echo neo-tandem-nsk${UNAME_RELEASE} exit ;; - NSE-?:NONSTOP_KERNEL:*:*) + NSE-*:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; NSR-?:NONSTOP_KERNEL:*:*) @@ -1315,11 +1356,11 @@ i*86:AROS:*:*) echo ${UNAME_MACHINE}-pc-aros exit ;; + x86_64:VMkernel:*:*) + echo ${UNAME_MACHINE}-unknown-esx + exit ;; esac -#echo '(No uname command or uname output not recognized.)' 1>&2 -#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 - eval $set_cc_for_build cat >$dummy.c <. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). -# Please send patches to . Submit a context -# diff and a properly formatted GNU ChangeLog entry. +# Please send patches with a ChangeLog entry to config-patches@gnu.org. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. @@ -75,9 +68,7 @@ version="\ GNU config.sub ($timestamp) -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, -2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free -Software Foundation, Inc. +Copyright 1992-2013 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -125,13 +116,17 @@ maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ - linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ + linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ knetbsd*-gnu* | netbsd*-gnu* | \ kopensolaris*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; + android-linux) + os=-linux-android + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown + ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] @@ -154,7 +149,7 @@ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ - -apple | -axis | -knuth | -cray | -microblaze) + -apple | -axis | -knuth | -cray | -microblaze*) os= basic_machine=$1 ;; @@ -223,6 +218,12 @@ -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; + -lynx*178) + os=-lynxos178 + ;; + -lynx*5) + os=-lynxos5 + ;; -lynx*) os=-lynxos ;; @@ -247,20 +248,27 @@ # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ + | aarch64 | aarch64_be \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ - | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ + | arc | arceb \ + | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ + | avr | avr32 \ + | be32 | be64 \ | bfin \ - | c4x | clipper \ + | c4x | c8051 | clipper \ | d10v | d30v | dlx | dsp16xx \ + | epiphany \ | fido | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ + | le32 | le64 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ - | maxq | mb | microblaze | mcore | mep | metag \ + | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ @@ -278,20 +286,21 @@ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ + | mipsr5900 | mipsr5900el \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nds32 | nds32le | nds32be \ - | nios | nios2 \ + | nios | nios2 | nios2eb | nios2el \ | ns16k | ns32k \ | open8 \ - | or32 \ + | or1k | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pyramid \ - | rx \ + | rl78 | rx \ | score \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ @@ -300,7 +309,7 @@ | spu \ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | ubicom32 \ - | v850 | v850e \ + | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | we32k \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) @@ -315,8 +324,7 @@ c6x) basic_machine=tic6x-unknown ;; - m6811 | m68hc11 | m6812 | m68hc12 | picochip) - # Motorola 68HC11/12. + m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) basic_machine=$basic_machine-unknown os=-none ;; @@ -329,7 +337,10 @@ strongarm | thumb | xscale) basic_machine=arm-unknown ;; - + xgate) + basic_machine=$basic_machine-unknown + os=-none + ;; xscaleeb) basic_machine=armeb-unknown ;; @@ -352,25 +363,30 @@ # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ + | aarch64-* | aarch64_be-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ - | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ + | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ - | clipper-* | craynv-* | cydra-* \ + | c8051-* | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | hexagon-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ + | le32-* | le64-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ - | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ + | microblaze-* | microblazeel-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ @@ -388,19 +404,20 @@ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipsr5900-* | mipsr5900el-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nds32-* | nds32le-* | nds32be-* \ - | nios-* | nios2-* \ + | nios-* | nios2-* | nios2eb-* | nios2el-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | open8-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | pyramid-* \ - | romp-* | rs6000-* | rx-* \ + | rl78-* | romp-* | rs6000-* | rx-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ @@ -408,10 +425,11 @@ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ | tahoe-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ - | tile-* | tilegx-* \ + | tile*-* \ | tron-* \ | ubicom32-* \ - | v850-* | v850e-* | vax-* \ + | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ + | vax-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ @@ -711,7 +729,6 @@ i370-ibm* | ibm*) basic_machine=i370-ibm ;; -# I'm not sure what "Sysv32" means. Should this be sysv3.2? i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 @@ -769,11 +786,15 @@ basic_machine=ns32k-utek os=-sysv ;; - microblaze) + microblaze*) basic_machine=microblaze-xilinx ;; + mingw64) + basic_machine=x86_64-pc + os=-mingw64 + ;; mingw32) - basic_machine=i386-pc + basic_machine=i686-pc os=-mingw32 ;; mingw32ce) @@ -808,10 +829,18 @@ ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; + msys) + basic_machine=i686-pc + os=-msys + ;; mvs) basic_machine=i370-ibm os=-mvs ;; + nacl) + basic_machine=le32-unknown + os=-nacl + ;; ncr3000) basic_machine=i486-ncr os=-sysv4 @@ -992,7 +1021,11 @@ basic_machine=i586-unknown os=-pw32 ;; - rdos) + rdos | rdos64) + basic_machine=x86_64-pc + os=-rdos + ;; + rdos32) basic_machine=i386-pc os=-rdos ;; @@ -1120,13 +1153,8 @@ basic_machine=t90-cray os=-unicos ;; - # This must be matched before tile*. - tilegx*) - basic_machine=tilegx-unknown - os=-linux-gnu - ;; tile*) - basic_machine=tile-unknown + basic_machine=$basic_machine-unknown os=-linux-gnu ;; tx39) @@ -1324,21 +1352,21 @@ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ - | -sym* | -kopensolaris* \ + | -sym* | -kopensolaris* | -plan9* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* | -aros* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ - | -openbsd* | -solidbsd* \ + | -bitrig* | -openbsd* | -solidbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* \ - | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -linux-gnu* | -linux-android* \ - | -linux-newlib* | -linux-uclibc* \ + | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ + | -linux-newlib* | -linux-musl* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ @@ -1470,9 +1498,6 @@ -aros*) os=-aros ;; - -kaos*) - os=-kaos - ;; -zvmoe) os=-zvmoe ;; @@ -1521,6 +1546,12 @@ c4x-* | tic4x-*) os=-coff ;; + c8051-*) + os=-elf + ;; + hexagon-*) + os=-elf + ;; tic54x-*) os=-coff ;; @@ -1548,9 +1579,6 @@ ;; m68000-sun) os=-sunos3 - # This also exists in the configure program, but was not the - # default. - # os=-sunos4 ;; m68*-cisco) os=-aout @@ -1564,6 +1592,9 @@ mips*-*) os=-elf ;; + or1k-*) + os=-elf + ;; or32-*) os=-coff ;; diff -Nru lxc-0.8.0~rc1/config/default.conf.libvirt lxc-1.0.0~alpha1/config/default.conf.libvirt --- lxc-0.8.0~rc1/config/default.conf.libvirt 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/config/default.conf.libvirt 2013-07-08 15:50:40.000000000 +0000 @@ -0,0 +1,3 @@ +lxc.network.type = veth +lxc.network.link = virbr0 +lxc.network.flags = up diff -Nru lxc-0.8.0~rc1/config/default.conf.ubuntu lxc-1.0.0~alpha1/config/default.conf.ubuntu --- lxc-0.8.0~rc1/config/default.conf.ubuntu 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/config/default.conf.ubuntu 2013-07-08 15:50:40.000000000 +0000 @@ -0,0 +1,3 @@ +lxc.network.type = veth +lxc.network.link = lxcbr0 +lxc.network.flags = up diff -Nru lxc-0.8.0~rc1/config/default.conf.unknown lxc-1.0.0~alpha1/config/default.conf.unknown --- lxc-0.8.0~rc1/config/default.conf.unknown 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/config/default.conf.unknown 2013-07-08 15:50:40.000000000 +0000 @@ -0,0 +1 @@ +lxc.network.type = empty diff -Nru lxc-0.8.0~rc1/config/depcomp lxc-1.0.0~alpha1/config/depcomp --- lxc-0.8.0~rc1/config/depcomp 2012-03-01 21:47:20.000000000 +0000 +++ lxc-1.0.0~alpha1/config/depcomp 2013-09-10 22:30:09.000000000 +0000 @@ -1,10 +1,9 @@ #! /bin/sh # depcomp - compile a program generating dependencies as side-effects -scriptversion=2009-04-28.21; # UTC +scriptversion=2013-05-30.07; # UTC -# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009 Free -# Software Foundation, Inc. +# Copyright (C) 1999-2013 Free Software Foundation, Inc. # 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 @@ -28,9 +27,9 @@ case $1 in '') - echo "$0: No command. Try \`$0 --help' for more information." 1>&2 - exit 1; - ;; + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; -h | --h*) cat <<\EOF Usage: depcomp [--help] [--version] PROGRAM [ARGS] @@ -40,11 +39,11 @@ Environment variables: depmode Dependency tracking mode. - source Source file read by `PROGRAMS ARGS'. - object Object file output by `PROGRAMS ARGS'. + source Source file read by 'PROGRAMS ARGS'. + object Object file output by 'PROGRAMS ARGS'. DEPDIR directory where to store dependencies. depfile Dependency file to output. - tmpdepfile Temporary file to use when outputing dependencies. + tmpdepfile Temporary file to use when outputting dependencies. libtool Whether libtool is used (yes/no). Report bugs to . @@ -57,6 +56,66 @@ ;; esac +# Get the directory component of the given path, and save it in the +# global variables '$dir'. Note that this directory component will +# be either empty or ending with a '/' character. This is deliberate. +set_dir_from () +{ + case $1 in + */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; + *) dir=;; + esac +} + +# Get the suffix-stripped basename of the given path, and save it the +# global variable '$base'. +set_base_from () +{ + base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` +} + +# If no dependency file was actually created by the compiler invocation, +# we still have to create a dummy depfile, to avoid errors with the +# Makefile "include basename.Plo" scheme. +make_dummy_depfile () +{ + echo "#dummy" > "$depfile" +} + +# Factor out some common post-processing of the generated depfile. +# Requires the auxiliary global variable '$tmpdepfile' to be set. +aix_post_process_depfile () +{ + # If the compiler actually managed to produce a dependency file, + # post-process it. + if test -f "$tmpdepfile"; then + # Each line is of the form 'foo.o: dependency.h'. + # Do two passes, one to just change these to + # $object: dependency.h + # and one to simply output + # dependency.h: + # which is needed to avoid the deleted-header problem. + { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" + sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" + } > "$depfile" + rm -f "$tmpdepfile" + else + make_dummy_depfile + fi +} + +# A tabulation character. +tab=' ' +# A newline character. +nl=' +' +# Character ranges might be problematic outside the C locale. +# These definitions help. +upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ +lower=abcdefghijklmnopqrstuvwxyz +digits=0123456789 +alpha=${upper}${lower} + if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 @@ -69,6 +128,9 @@ rm -f "$tmpdepfile" +# Avoid interferences from the environment. +gccflag= dashmflag= + # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case @@ -80,18 +142,32 @@ fi if test "$depmode" = dashXmstdout; then - # This is just like dashmstdout with a different argument. - dashmflag=-xM - depmode=dashmstdout + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout fi cygpath_u="cygpath -u -f -" if test "$depmode" = msvcmsys; then - # This is just like msvisualcpp but w/o cygpath translation. - # Just convert the backslash-escaped backslashes to single forward - # slashes to satisfy depend.m4 - cygpath_u="sed s,\\\\\\\\,/,g" - depmode=msvisualcpp + # This is just like msvisualcpp but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvisualcpp +fi + +if test "$depmode" = msvc7msys; then + # This is just like msvc7 but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvc7 +fi + +if test "$depmode" = xlc; then + # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. + gccflag=-qmakedep=gcc,-MF + depmode=gcc fi case "$depmode" in @@ -114,8 +190,7 @@ done "$@" stat=$? - if test $stat -eq 0; then : - else + if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi @@ -123,13 +198,17 @@ ;; gcc) +## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. +## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. +## (see the conditional assignment to $gccflag above). ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like -## -MM, not -M (despite what the docs say). +## -MM, not -M (despite what the docs say). Also, it might not be +## supported by the other compilers which use the 'gcc' depmode. ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then @@ -137,31 +216,31 @@ fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? - if test $stat -eq 0; then : - else + if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" - alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz -## The second -e expression handles DOS-style file names with drive letters. + # The second -e expression handles DOS-style file names with drive + # letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" -## This next piece of magic avoids the `deleted header file' problem. +## This next piece of magic avoids the "deleted header file" problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. - tr ' ' ' -' < "$tmpdepfile" | -## Some versions of gcc put a space before the `:'. On the theory +## Some versions of gcc put a space before the ':'. On the theory ## that the space means something, we add a space to the output as -## well. +## well. hp depmode also adds that space, but also prefixes the VPATH +## to the object. Take care to not repeat it in the output. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. - sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; @@ -179,8 +258,7 @@ "$@" -MDupdate "$tmpdepfile" fi stat=$? - if test $stat -eq 0; then : - else + if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi @@ -188,43 +266,41 @@ if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" - # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; - # the IRIX cc adds comments like `#:fec' to the end of the + # the IRIX cc adds comments like '#:fec' to the end of the # dependency line. - tr ' ' ' -' < "$tmpdepfile" \ - | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ - tr ' -' ' ' >> "$depfile" + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ + | tr "$nl" ' ' >> "$depfile" echo >> "$depfile" - # The second pass generates a dummy entry for each header file. - tr ' ' ' -' < "$tmpdepfile" \ - | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ - >> "$depfile" + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> "$depfile" else - # The sourcefile does not contain any dependencies, so just - # store a dummy comment line, to avoid errors with the Makefile - # "include basename.Plo" scheme. - echo "#dummy" > "$depfile" + make_dummy_depfile fi rm -f "$tmpdepfile" ;; +xlc) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. In older versions, this file always lives in the - # current directory. Also, the AIX compiler puts `$object:' at the + # current directory. Also, the AIX compiler puts '$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. - dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` - test "x$dir" = "x$object" && dir= - base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + set_dir_from "$object" + set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.u tmpdepfile2=$base.u @@ -237,9 +313,7 @@ "$@" -M fi stat=$? - - if test $stat -eq 0; then : - else + if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi @@ -248,44 +322,100 @@ do test -f "$tmpdepfile" && break done - if test -f "$tmpdepfile"; then - # Each line is of the form `foo.o: dependent.h'. - # Do two passes, one to just change these to - # `$object: dependent.h' and one to simply `dependent.h:'. - sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" - # That's a tab and a space in the []. - sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" - else - # The sourcefile does not contain any dependencies, so just - # store a dummy comment line, to avoid errors with the Makefile - # "include basename.Plo" scheme. - echo "#dummy" > "$depfile" + aix_post_process_depfile + ;; + +tcc) + # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 + # FIXME: That version still under development at the moment of writing. + # Make that this statement remains true also for stable, released + # versions. + # It will wrap lines (doesn't matter whether long or short) with a + # trailing '\', as in: + # + # foo.o : \ + # foo.c \ + # foo.h \ + # + # It will put a trailing '\' even on the last line, and will use leading + # spaces rather than leading tabs (at least since its commit 0394caf7 + # "Emit spaces for -MD"). + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat fi + rm -f "$depfile" + # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. + # We have to change lines of the first kind to '$object: \'. + sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" + # And for each line of the second kind, we have to emit a 'dep.h:' + # dummy dependency, to avoid the deleted-header problem. + sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" rm -f "$tmpdepfile" ;; -icc) - # Intel's C compiler understands `-MD -MF file'. However on - # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c - # ICC 7.0 will fill foo.d with something like - # foo.o: sub/foo.c - # foo.o: sub/foo.h - # which is wrong. We want: - # sub/foo.o: sub/foo.c - # sub/foo.o: sub/foo.h - # sub/foo.c: - # sub/foo.h: - # ICC 7.1 will output +## The order of this option in the case statement is important, since the +## shell code in configure will try each of these formats in the order +## listed in this file. A plain '-MD' option would be understood by many +## compilers, so we must ensure this comes after the gcc and icc options. +pgcc) + # Portland's C compiler understands '-MD'. + # Will always output deps to 'file.d' where file is the root name of the + # source file under compilation, even if file resides in a subdirectory. + # The object file name does not affect the name of the '.d' file. + # pgcc 10.2 will output # foo.o: sub/foo.c sub/foo.h - # and will wrap long lines using \ : + # and will wrap long lines using '\' : # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... + set_dir_from "$object" + # Use the source, not the object, to determine the base name, since + # that's sadly what pgcc will do too. + set_base_from "$source" + tmpdepfile=$base.d + + # For projects that build the same source file twice into different object + # files, the pgcc approach of using the *source* file root name can cause + # problems in parallel builds. Use a locking strategy to avoid stomping on + # the same $tmpdepfile. + lockdir=$base.d-lock + trap " + echo '$0: caught signal, cleaning up...' >&2 + rmdir '$lockdir' + exit 1 + " 1 2 13 15 + numtries=100 + i=$numtries + while test $i -gt 0; do + # mkdir is a portable test-and-set. + if mkdir "$lockdir" 2>/dev/null; then + # This process acquired the lock. + "$@" -MD + stat=$? + # Release the lock. + rmdir "$lockdir" + break + else + # If the lock is being held by a different process, wait + # until the winning process is done or we timeout. + while test -d "$lockdir" && test $i -gt 0; do + sleep 1 + i=`expr $i - 1` + done + fi + i=`expr $i - 1` + done + trap - 1 2 13 15 + if test $i -le 0; then + echo "$0: failed to acquire lock after $numtries attempts" >&2 + echo "$0: check lockdir '$lockdir'" >&2 + exit 1 + fi - "$@" -MD -MF "$tmpdepfile" - stat=$? - if test $stat -eq 0; then : - else + if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi @@ -297,8 +427,8 @@ sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this invocation # correctly. Breaking it into two sed invocations is a workaround. - sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | - sed -e 's/$/ :/' >> "$depfile" + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ + | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; @@ -309,9 +439,8 @@ # 'foo.d', which lands next to the object file, wherever that # happens to be. # Much of this is similar to the tru64 case; see comments there. - dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` - test "x$dir" = "x$object" && dir= - base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + set_dir_from "$object" + set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.d tmpdepfile2=$dir.libs/$base.d @@ -322,8 +451,7 @@ "$@" +Maked fi stat=$? - if test $stat -eq 0; then : - else + if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi @@ -333,77 +461,107 @@ test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then - sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" - # Add `dependent.h:' lines. + sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" + # Add 'dependent.h:' lines. sed -ne '2,${ - s/^ *// - s/ \\*$// - s/$/:/ - p - }' "$tmpdepfile" >> "$depfile" + s/^ *// + s/ \\*$// + s/$/:/ + p + }' "$tmpdepfile" >> "$depfile" else - echo "#dummy" > "$depfile" + make_dummy_depfile fi rm -f "$tmpdepfile" "$tmpdepfile2" ;; tru64) - # The Tru64 compiler uses -MD to generate dependencies as a side - # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. - # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put - # dependencies in `foo.d' instead, so we check for that too. - # Subdirectories are respected. - dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` - test "x$dir" = "x$object" && dir= - base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` - - if test "$libtool" = yes; then - # With Tru64 cc, shared objects can also be used to make a - # static library. This mechanism is used in libtool 1.4 series to - # handle both shared and static libraries in a single compilation. - # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. - # - # With libtool 1.5 this exception was removed, and libtool now - # generates 2 separate objects for the 2 libraries. These two - # compilations output dependencies in $dir.libs/$base.o.d and - # in $dir$base.o.d. We have to check for both files, because - # one of the two compilations can be disabled. We should prefer - # $dir$base.o.d over $dir.libs/$base.o.d because the latter is - # automatically cleaned when .libs/ is deleted, while ignoring - # the former would cause a distcleancheck panic. - tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 - tmpdepfile2=$dir$base.o.d # libtool 1.5 - tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 - tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 - "$@" -Wc,-MD - else - tmpdepfile1=$dir$base.o.d - tmpdepfile2=$dir$base.d - tmpdepfile3=$dir$base.d - tmpdepfile4=$dir$base.d - "$@" -MD - fi + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in 'foo.d' instead, so we check for that too. + # Subdirectories are respected. + set_dir_from "$object" + set_base_from "$object" + + if test "$libtool" = yes; then + # Libtool generates 2 separate objects for the 2 libraries. These + # two compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir$base.o.d # libtool 1.5 + tmpdepfile2=$dir.libs/$base.o.d # Likewise. + tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" - exit $stat - fi - - for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" - do - test -f "$tmpdepfile" && break - done - if test -f "$tmpdepfile"; then - sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" - # That's a tab and a space in the []. - sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" - else - echo "#dummy" > "$depfile" - fi - rm -f "$tmpdepfile" - ;; + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + # Same post-processing that is required for AIX mode. + aix_post_process_depfile + ;; + +msvc7) + if test "$libtool" = yes; then + showIncludes=-Wc,-showIncludes + else + showIncludes=-showIncludes + fi + "$@" $showIncludes > "$tmpdepfile" + stat=$? + grep -v '^Note: including file: ' "$tmpdepfile" + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The first sed program below extracts the file names and escapes + # backslashes for cygpath. The second sed program outputs the file + # name when reading, but also accumulates all include files in the + # hold buffer in order to output them again at the end. This only + # works with sed implementations that can handle large buffers. + sed < "$tmpdepfile" -n ' +/^Note: including file: *\(.*\)/ { + s//\1/ + s/\\/\\\\/g + p +}' | $cygpath_u | sort -u | sed -n ' +s/ /\\ /g +s/\(.*\)/'"$tab"'\1 \\/p +s/.\(.*\) \\/\1:/ +H +$ { + s/.*/'"$tab"'/ + G + p +}' >> "$depfile" + echo >> "$depfile" # make sure the fragment doesn't end with a backslash + rm -f "$tmpdepfile" + ;; + +msvc7msys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; #nosideeffect) # This comment above is used by automake to tell side-effect @@ -422,7 +580,7 @@ shift fi - # Remove `-o $object'. + # Remove '-o $object'. IFS=" " for arg do @@ -442,18 +600,18 @@ done test -z "$dashmflag" && dashmflag=-M - # Require at least two characters before searching for `:' + # Require at least two characters before searching for ':' # in the target name. This is to cope with DOS-style filenames: - # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. + # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. "$@" $dashmflag | - sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" + sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" - tr ' ' ' -' < "$tmpdepfile" | \ -## Some versions of the HPUX 10.20 sed can't process this invocation -## correctly. Breaking it into two sed invocations is a workaround. - sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + # Some versions of the HPUX 10.20 sed can't process this sed invocation + # correctly. Breaking it into two sed invocations is a workaround. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; @@ -503,12 +661,15 @@ touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" - cat < "$tmpdepfile" > "$depfile" - sed '1,2d' "$tmpdepfile" | tr ' ' ' -' | \ -## Some versions of the HPUX 10.20 sed can't process this invocation -## correctly. Breaking it into two sed invocations is a workaround. - sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + # makedepend may prepend the VPATH from the source file name to the object. + # No need to regex-escape $object, excess matching of '.' is harmless. + sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process the last invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed '1,2d' "$tmpdepfile" \ + | tr ' ' "$nl" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; @@ -525,7 +686,7 @@ shift fi - # Remove `-o $object'. + # Remove '-o $object'. IFS=" " for arg do @@ -544,10 +705,10 @@ esac done - "$@" -E | - sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ - -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | - sed '$ s: \\$::' > "$tmpdepfile" + "$@" -E \ + | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" @@ -579,23 +740,23 @@ shift ;; "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") - set fnord "$@" - shift - shift - ;; + set fnord "$@" + shift + shift + ;; *) - set fnord "$@" "$arg" - shift - shift - ;; + set fnord "$@" "$arg" + shift + shift + ;; esac done "$@" -E 2>/dev/null | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" - sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" - echo " " >> "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" + echo "$tab" >> "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; diff -Nru lxc-0.8.0~rc1/config/install-sh lxc-1.0.0~alpha1/config/install-sh --- lxc-0.8.0~rc1/config/install-sh 2012-03-01 21:47:20.000000000 +0000 +++ lxc-1.0.0~alpha1/config/install-sh 2013-09-10 22:30:08.000000000 +0000 @@ -1,7 +1,7 @@ #!/bin/sh # install - install a program, script, or datafile -scriptversion=2009-04-28.21; # UTC +scriptversion=2011-11-20.07; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the @@ -35,7 +35,7 @@ # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent -# `make' implicit rules from creating a file called install from it +# 'make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written @@ -156,6 +156,10 @@ -s) stripcmd=$stripprog;; -t) dst_arg=$2 + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac shift;; -T) no_target_directory=true;; @@ -186,6 +190,10 @@ fi shift # arg dst_arg=$arg + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac done fi @@ -194,13 +202,17 @@ echo "$0: no input file specified." >&2 exit 1 fi - # It's OK to call `install-sh -d' without argument. + # It's OK to call 'install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then - trap '(exit $?); exit' 1 2 13 15 + do_exit='(exit $ret); exit $ret' + trap "ret=129; $do_exit" 1 + trap "ret=130; $do_exit" 2 + trap "ret=141; $do_exit" 13 + trap "ret=143; $do_exit" 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. @@ -228,9 +240,9 @@ for src do - # Protect names starting with `-'. + # Protect names problematic for 'test' and other utilities. case $src in - -*) src=./$src;; + -* | [=\(\)!]) src=./$src;; esac if test -n "$dir_arg"; then @@ -252,12 +264,7 @@ echo "$0: no destination specified." >&2 exit 1 fi - dst=$dst_arg - # Protect names starting with `-'. - case $dst in - -*) dst=./$dst;; - esac # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. @@ -347,7 +354,7 @@ if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or - # other-writeable bit of parent directory when it shouldn't. + # other-writable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. ls_ld_tmpdir=`ls -ld "$tmpdir"` case $ls_ld_tmpdir in @@ -385,7 +392,7 @@ case $dstdir in /*) prefix='/';; - -*) prefix='./';; + [-=\(\)!]*) prefix='./';; *) prefix='';; esac @@ -403,7 +410,7 @@ for d do - test -z "$d" && continue + test X"$d" = X && continue prefix=$prefix$d if test -d "$prefix"; then diff -Nru lxc-0.8.0~rc1/config/linux.m4 lxc-1.0.0~alpha1/config/linux.m4 --- lxc-0.8.0~rc1/config/linux.m4 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/config/linux.m4 1970-01-01 00:00:00.000000000 +0000 @@ -1,76 +0,0 @@ -AC_DEFUN([AC_LINUX], -[ - AC_LINUX_DIR() - AC_LINUX_SRCARCH() -]) - -AC_DEFUN([AS_TRY_LINUX_DIR], - [AC_MSG_CHECKING(for Linux in $1) - - if test -f "$1/Makefile" ; then - result=yes - $2 - else - result="not found" - $3 - fi - - AC_MSG_RESULT($result) -]) - -AC_DEFUN([AC_LINUX_DIR], -[ - AC_ARG_WITH([linuxdir], - [AC_HELP_STRING([--with-linuxdir=DIR], - [specify path to Linux source directory])], - [LINUX_DIR="${withval}"], - [LINUX_DIR=default]) - - dnl if specified, use the specified one - if test "${LINUX_DIR}" != "default" ; then - AS_TRY_LINUX_DIR([${LINUX_DIR}], , AC_MSG_ERROR([Linux dir not found]) ) - fi - - dnl if not specified, first try with previously set LINUX_KERNEL_RELEASE - if test "${LINUX_DIR}" = "default" ; then - dir="/lib/modules/$LINUX_KERNEL_RELEASE/build"; - AS_TRY_LINUX_DIR([${dir}], [LINUX_DIR=${dir}], ) - fi - - dnl next try using the kernel source dir - if test "${LINUX_DIR}" = "default" ; then - dir="/usr/src/linux-$LINUX_KERNEL_RELEASE"; - AS_TRY_LINUX_DIR([${dir}], [LINUX_DIR=${dir}], ) - fi - - dnl then try a common default of /usr/src/linux - if test "${LINUX_DIR}" = "default" ; then - dir="/usr/src/linux"; - AS_TRY_LINUX_DIR([${dir}], [LINUX_DIR=${dir}], ) - fi - - dnl if still nothing found, fail - if test "${LINUX_DIR}" = "default" ; then - AC_MSG_WARN([Linux source directory not found]) - fi - - AC_SUBST(LINUX_DIR) -]) - -AC_DEFUN([AC_LINUX_SRCARCH],[ - AC_MSG_CHECKING(for linux SRCARCH) - - case "${host}" in - i[[3456]]86-*) LINUX_SRCARCH=x86;; - x86_64-*) LINUX_SRCARCH=x86;; - powerpc*-*) LINUX_SRCARCH=powerpc;; - s390*-*) LINUX_SRCARCH=s390;; - arm*-*) LINUX_SRCARCH=arm;; - mips*-*) LINUX_SRCARCH=mips;; - sparc*-*) LINUX_SRCARCH=sparc;; - *) AC_MSG_ERROR([architecture ${host} not supported]);; - esac - - AC_MSG_RESULT(${LINUX_SRCARCH}) - AC_SUBST(LINUX_SRCARCH) -]) diff -Nru lxc-0.8.0~rc1/config/missing lxc-1.0.0~alpha1/config/missing --- lxc-0.8.0~rc1/config/missing 2012-03-01 21:47:20.000000000 +0000 +++ lxc-1.0.0~alpha1/config/missing 2013-09-10 22:30:08.000000000 +0000 @@ -1,11 +1,10 @@ #! /bin/sh -# Common stub for a few missing GNU programs while installing. +# Common wrapper for a few potentially missing GNU programs. -scriptversion=2009-04-28.21; # UTC +scriptversion=2012-06-26.16; # UTC -# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006, -# 2008, 2009 Free Software Foundation, Inc. -# Originally by Fran,cois Pinard , 1996. +# Copyright (C) 1996-2013 Free Software Foundation, Inc. +# Originally written by Fran,cois Pinard , 1996. # 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 @@ -26,69 +25,40 @@ # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then - echo 1>&2 "Try \`$0 --help' for more information" + echo 1>&2 "Try '$0 --help' for more information" exit 1 fi -run=: -sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' -sed_minuso='s/.* -o \([^ ]*\).*/\1/p' - -# In the cases where this matters, `missing' is being run in the -# srcdir already. -if test -f configure.ac; then - configure_ac=configure.ac -else - configure_ac=configure.in -fi +case $1 in -msg="missing on your system" + --is-lightweight) + # Used by our autoconf macros to check whether the available missing + # script is modern enough. + exit 0 + ;; -case $1 in ---run) - # Try to run requested program, and just exit if it succeeds. - run= - shift - "$@" && exit 0 - # Exit code 63 means version mismatch. This often happens - # when the user try to use an ancient version of a tool on - # a file that requires a minimum version. In this case we - # we should proceed has if the program had been absent, or - # if --run hadn't been passed. - if test $? = 63; then - run=: - msg="probably too old" - fi - ;; + --run) + # Back-compat with the calling convention used by older automake. + shift + ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... -Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an -error status if there is no known handling for PROGRAM. +Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due +to PROGRAM being missing or too old. Options: -h, --help display this help and exit -v, --version output version information and exit - --run try to run the given command, and emulate it if it fails Supported PROGRAM values: - aclocal touch file \`aclocal.m4' - autoconf touch file \`configure' - autoheader touch file \`config.h.in' - autom4te touch the output file, or create a stub one - automake touch all \`Makefile.in' files - bison create \`y.tab.[ch]', if possible, from existing .[ch] - flex create \`lex.yy.c', if possible, from existing .c - help2man touch the output file - lex create \`lex.yy.c', if possible, from existing .c - makeinfo touch the output file - tar try tar, gnutar, gtar, then tar without non-portable flags - yacc create \`y.tab.[ch]', if possible, from existing .[ch] + aclocal autoconf autoheader autom4te automake makeinfo + bison yacc flex lex help2man -Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and -\`g' are ignored when checking the name. +Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and +'g' are ignored when checking the name. Send bug reports to ." exit $? @@ -100,272 +70,141 @@ ;; -*) - echo 1>&2 "$0: Unknown \`$1' option" - echo 1>&2 "Try \`$0 --help' for more information" + echo 1>&2 "$0: unknown '$1' option" + echo 1>&2 "Try '$0 --help' for more information" exit 1 ;; esac -# normalize program name to check for. -program=`echo "$1" | sed ' - s/^gnu-//; t - s/^gnu//; t - s/^g//; t'` - -# Now exit if we have it, but it failed. Also exit now if we -# don't have it and --version was passed (most likely to detect -# the program). This is about non-GNU programs, so use $1 not -# $program. -case $1 in - lex*|yacc*) - # Not GNU programs, they don't have --version. - ;; - - tar*) - if test -n "$run"; then - echo 1>&2 "ERROR: \`tar' requires --run" - exit 1 - elif test "x$2" = "x--version" || test "x$2" = "x--help"; then - exit 1 - fi - ;; +# Run the given program, remember its exit status. +"$@"; st=$? - *) - if test -z "$run" && ($1 --version) > /dev/null 2>&1; then - # We have it, but it failed. - exit 1 - elif test "x$2" = "x--version" || test "x$2" = "x--help"; then - # Could not run --version or --help. This is probably someone - # running `$TOOL --version' or `$TOOL --help' to check whether - # $TOOL exists and not knowing $TOOL uses missing. - exit 1 - fi - ;; -esac - -# If it does not exist, or fails to run (possibly an outdated version), -# try to emulate it. -case $program in - aclocal*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`acinclude.m4' or \`${configure_ac}'. You might want - to install the \`Automake' and \`Perl' packages. Grab them from - any GNU archive site." - touch aclocal.m4 - ;; - - autoconf*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`${configure_ac}'. You might want to install the - \`Autoconf' and \`GNU m4' packages. Grab them from any GNU - archive site." - touch configure - ;; - - autoheader*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`acconfig.h' or \`${configure_ac}'. You might want - to install the \`Autoconf' and \`GNU m4' packages. Grab them - from any GNU archive site." - files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` - test -z "$files" && files="config.h" - touch_files= - for f in $files; do - case $f in - *:*) touch_files="$touch_files "`echo "$f" | - sed -e 's/^[^:]*://' -e 's/:.*//'`;; - *) touch_files="$touch_files $f.in";; - esac - done - touch $touch_files - ;; - - automake*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. - You might want to install the \`Automake' and \`Perl' packages. - Grab them from any GNU archive site." - find . -type f -name Makefile.am -print | - sed 's/\.am$/.in/' | - while read f; do touch "$f"; done - ;; +# If it succeeded, we are done. +test $st -eq 0 && exit 0 - autom4te*) - echo 1>&2 "\ -WARNING: \`$1' is needed, but is $msg. - You might have modified some files without having the - proper tools for further handling them. - You can get \`$1' as part of \`Autoconf' from any GNU - archive site." - - file=`echo "$*" | sed -n "$sed_output"` - test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` - if test -f "$file"; then - touch $file - else - test -z "$file" || exec >$file - echo "#! /bin/sh" - echo "# Created by GNU Automake missing as a replacement of" - echo "# $ $@" - echo "exit 0" - chmod +x $file - exit 1 - fi - ;; - - bison*|yacc*) - echo 1>&2 "\ -WARNING: \`$1' $msg. You should only need it if - you modified a \`.y' file. You may need the \`Bison' package - in order for those modifications to take effect. You can get - \`Bison' from any GNU archive site." - rm -f y.tab.c y.tab.h - if test $# -ne 1; then - eval LASTARG="\${$#}" - case $LASTARG in - *.y) - SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` - if test -f "$SRCFILE"; then - cp "$SRCFILE" y.tab.c - fi - SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` - if test -f "$SRCFILE"; then - cp "$SRCFILE" y.tab.h - fi - ;; - esac - fi - if test ! -f y.tab.h; then - echo >y.tab.h - fi - if test ! -f y.tab.c; then - echo 'main() { return 0; }' >y.tab.c - fi - ;; - - lex*|flex*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified a \`.l' file. You may need the \`Flex' package - in order for those modifications to take effect. You can get - \`Flex' from any GNU archive site." - rm -f lex.yy.c - if test $# -ne 1; then - eval LASTARG="\${$#}" - case $LASTARG in - *.l) - SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` - if test -f "$SRCFILE"; then - cp "$SRCFILE" lex.yy.c - fi - ;; - esac - fi - if test ! -f lex.yy.c; then - echo 'main() { return 0; }' >lex.yy.c - fi - ;; - - help2man*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified a dependency of a manual page. You may need the - \`Help2man' package in order for those modifications to take - effect. You can get \`Help2man' from any GNU archive site." - - file=`echo "$*" | sed -n "$sed_output"` - test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` - if test -f "$file"; then - touch $file - else - test -z "$file" || exec >$file - echo ".ab help2man is required to generate this page" - exit $? - fi - ;; - - makeinfo*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified a \`.texi' or \`.texinfo' file, or any other file - indirectly affecting the aspect of the manual. The spurious - call might also be the consequence of using a buggy \`make' (AIX, - DU, IRIX). You might want to install the \`Texinfo' package or - the \`GNU make' package. Grab either from any GNU archive site." - # The file to touch is that specified with -o ... - file=`echo "$*" | sed -n "$sed_output"` - test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` - if test -z "$file"; then - # ... or it is the one specified with @setfilename ... - infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` - file=`sed -n ' - /^@setfilename/{ - s/.* \([^ ]*\) *$/\1/ - p - q - }' $infile` - # ... or it is derived from the source name (dir/f.texi becomes f.info) - test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info - fi - # If the file does not exist, the user really needs makeinfo; - # let's fail without touching anything. - test -f $file || exit 1 - touch $file - ;; - - tar*) - shift - - # We have already tried tar in the generic part. - # Look for gnutar/gtar before invocation to avoid ugly error - # messages. - if (gnutar --version > /dev/null 2>&1); then - gnutar "$@" && exit 0 - fi - if (gtar --version > /dev/null 2>&1); then - gtar "$@" && exit 0 - fi - firstarg="$1" - if shift; then - case $firstarg in - *o*) - firstarg=`echo "$firstarg" | sed s/o//` - tar "$firstarg" "$@" && exit 0 - ;; - esac - case $firstarg in - *h*) - firstarg=`echo "$firstarg" | sed s/h//` - tar "$firstarg" "$@" && exit 0 - ;; - esac - fi - - echo 1>&2 "\ -WARNING: I can't seem to be able to run \`tar' with the given arguments. - You may want to install GNU tar or Free paxutils, or check the - command line arguments." - exit 1 - ;; - - *) - echo 1>&2 "\ -WARNING: \`$1' is needed, and is $msg. - You might have modified some files without having the - proper tools for further handling them. Check the \`README' file, - it often tells you about the needed prerequisites for installing - this package. You may also peek at any GNU archive site, in case - some other package would contain this missing \`$1' program." - exit 1 - ;; -esac +# Also exit now if we it failed (or wasn't found), and '--version' was +# passed; such an option is passed most likely to detect whether the +# program is present and works. +case $2 in --version|--help) exit $st;; esac + +# Exit code 63 means version mismatch. This often happens when the user +# tries to use an ancient version of a tool on a file that requires a +# minimum version. +if test $st -eq 63; then + msg="probably too old" +elif test $st -eq 127; then + # Program was missing. + msg="missing on your system" +else + # Program was found and executed, but failed. Give up. + exit $st +fi -exit 0 +perl_URL=http://www.perl.org/ +flex_URL=http://flex.sourceforge.net/ +gnu_software_URL=http://www.gnu.org/software + +program_details () +{ + case $1 in + aclocal|automake) + echo "The '$1' program is part of the GNU Automake package:" + echo "<$gnu_software_URL/automake>" + echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/autoconf>" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + autoconf|autom4te|autoheader) + echo "The '$1' program is part of the GNU Autoconf package:" + echo "<$gnu_software_URL/autoconf/>" + echo "It also requires GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + esac +} + +give_advice () +{ + # Normalize program name to check for. + normalized_program=`echo "$1" | sed ' + s/^gnu-//; t + s/^gnu//; t + s/^g//; t'` + + printf '%s\n' "'$1' is $msg." + + configure_deps="'configure.ac' or m4 files included by 'configure.ac'" + case $normalized_program in + autoconf*) + echo "You should only need it if you modified 'configure.ac'," + echo "or m4 files included by it." + program_details 'autoconf' + ;; + autoheader*) + echo "You should only need it if you modified 'acconfig.h' or" + echo "$configure_deps." + program_details 'autoheader' + ;; + automake*) + echo "You should only need it if you modified 'Makefile.am' or" + echo "$configure_deps." + program_details 'automake' + ;; + aclocal*) + echo "You should only need it if you modified 'acinclude.m4' or" + echo "$configure_deps." + program_details 'aclocal' + ;; + autom4te*) + echo "You might have modified some maintainer files that require" + echo "the 'automa4te' program to be rebuilt." + program_details 'autom4te' + ;; + bison*|yacc*) + echo "You should only need it if you modified a '.y' file." + echo "You may want to install the GNU Bison package:" + echo "<$gnu_software_URL/bison/>" + ;; + lex*|flex*) + echo "You should only need it if you modified a '.l' file." + echo "You may want to install the Fast Lexical Analyzer package:" + echo "<$flex_URL>" + ;; + help2man*) + echo "You should only need it if you modified a dependency" \ + "of a man page." + echo "You may want to install the GNU Help2man package:" + echo "<$gnu_software_URL/help2man/>" + ;; + makeinfo*) + echo "You should only need it if you modified a '.texi' file, or" + echo "any other file indirectly affecting the aspect of the manual." + echo "You might want to install the Texinfo package:" + echo "<$gnu_software_URL/texinfo/>" + echo "The spurious makeinfo call might also be the consequence of" + echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" + echo "want to install GNU make:" + echo "<$gnu_software_URL/make/>" + ;; + *) + echo "You might have modified some files without having the proper" + echo "tools for further handling them. Check the 'README' file, it" + echo "often tells you about the needed prerequisites for installing" + echo "this package. You may also peek at any GNU archive site, in" + echo "case some other package contains this missing '$1' program." + ;; + esac +} + +give_advice "$1" | sed -e '1s/^/WARNING: /' \ + -e '2,$s/^/ /' >&2 + +# Propagate the correct exit status (expected to be 127 for a program +# not found, 63 for a program that failed due to version mismatch). +exit $st # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) diff -Nru lxc-0.8.0~rc1/configure lxc-1.0.0~alpha1/configure --- lxc-0.8.0~rc1/configure 2012-03-01 23:04:44.000000000 +0000 +++ lxc-1.0.0~alpha1/configure 2013-09-10 22:30:07.000000000 +0000 @@ -1,11 +1,9 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for lxc 0.8.0-rc1. +# Generated by GNU Autoconf 2.69 for lxc 1.0.0.alpha1. # # -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, -# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software -# Foundation, Inc. +# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation @@ -134,6 +132,31 @@ # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +as_fn_exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh @@ -167,7 +190,8 @@ else exitcode=1; echo positional parameters were not saved. fi -test x\$exitcode = x0 || exit 1" +test x\$exitcode = x0 || exit 1 +test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && @@ -212,21 +236,25 @@ if test "x$CONFIG_SHELL" != x; then : - # We cannot yet assume a decent shell, so we have to provide a - # neutralization value for shells without unset; and this also - # works around shells that cannot unset nonexistent variables. - # Preserve -v and -x to the replacement shell. - BASH_ENV=/dev/null - ENV=/dev/null - (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV - export CONFIG_SHELL - case $- in # (((( - *v*x* | *x*v* ) as_opts=-vx ;; - *v* ) as_opts=-v ;; - *x* ) as_opts=-x ;; - * ) as_opts= ;; - esac - exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"} + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 fi if test x$as_have_required = xno; then : @@ -328,6 +356,14 @@ } # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take @@ -449,6 +485,10 @@ chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). @@ -483,16 +523,16 @@ # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -p'. + # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -p' + as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else - as_ln_s='cp -p' + as_ln_s='cp -pR' fi else - as_ln_s='cp -p' + as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null @@ -504,28 +544,8 @@ as_mkdir_p=false fi -if test -x / >/dev/null 2>&1; then - as_test_x='test -x' -else - if ls -dL / >/dev/null 2>&1; then - as_ls_L_option=L - else - as_ls_L_option= - fi - as_test_x=' - eval sh -c '\'' - if test -d "$1"; then - test -d "$1/."; - else - case $1 in #( - -*)set "./$1";; - esac; - case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( - ???[sx]*):;;*)false;;esac;fi - '\'' sh - ' -fi -as_executable_p=$as_test_x +as_test_x='test -x' +as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" @@ -557,8 +577,8 @@ # Identity of this package. PACKAGE_NAME='lxc' PACKAGE_TARNAME='lxc' -PACKAGE_VERSION='0.8.0-rc1' -PACKAGE_STRING='lxc 0.8.0-rc1' +PACKAGE_VERSION='1.0.0.alpha1' +PACKAGE_STRING='lxc 1.0.0.alpha1' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -603,36 +623,88 @@ am__EXEEXT_TRUE LTLIBOBJS LIBOBJS -LINUX_SRCARCH -LINUX_DIR +SED +HAVE_FGETLN_FALSE +HAVE_FGETLN_TRUE +HAVE_GETLINE_FALSE +HAVE_GETLINE_TRUE +IS_BIONIC_FALSE +IS_BIONIC_TRUE CAP_LIBS -LXCTEMPLATEDIR +LOGPATH LXCINITDIR +LXCHOOKDIR +LXCTEMPLATEDIR LXCROOTFSMOUNT +LXC_USERNIC_DB +LXC_USERNIC_CONF +LXC_GLOBAL_CONF LXCPATH LXC_GENERATE_DATE +LXC_DISTRO_CONF DOCDIR LOCALSTATEDIR DATADIR +LXC_DEFAULT_CONFIG SYSCONFDIR INCLUDEDIR +LIBEXECDIR BINDIR LIBDIR PREFIX +USE_CONFIGPATH_LOGS_FALSE +USE_CONFIGPATH_LOGS_TRUE +ENABLE_TESTS_FALSE +ENABLE_TESTS_TRUE +LUA_INSTALL_LMOD +LUA_INSTALL_CMOD +LUA_VERSION +ENABLE_LUA_FALSE +ENABLE_LUA_TRUE +LUA_LIBS +LUA_CFLAGS +PYTHONDEV_LIBS +PYTHONDEV_CFLAGS +PKG_CONFIG_LIBDIR +PKG_CONFIG_PATH +PKG_CONFIG +pkgpyexecdir +pyexecdir +pkgpythondir +pythondir +PYTHON_PLATFORM +PYTHON_EXEC_PREFIX +PYTHON_PREFIX +PYTHON_VERSION +PYTHON +ENABLE_PYTHON_FALSE +ENABLE_PYTHON_TRUE ENABLE_EXAMPLES_FALSE ENABLE_EXAMPLES_TRUE +SECCOMP_LIBS +ENABLE_SECCOMP_FALSE +ENABLE_SECCOMP_TRUE +APPARMOR_LIBS +ENABLE_APPARMOR_FALSE +ENABLE_APPARMOR_TRUE +docdtd ENABLE_DOCBOOK_FALSE ENABLE_DOCBOOK_TRUE -have_docbook +db2xman ENABLE_RPATH_FALSE ENABLE_RPATH_TRUE -SETCAP +HAVE_NEWUIDMAP_FALSE +HAVE_NEWUIDMAP_TRUE +NEWUIDMAP +HAVE_DEBIAN_FALSE +HAVE_DEBIAN_TRUE EGREP GREP CPP am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE +am__nodep AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE @@ -654,6 +726,10 @@ build_vendor build_cpu build +AM_BACKSLASH +AM_DEFAULT_VERBOSITY +AM_DEFAULT_V +AM_V am__untar am__tar AMTAR @@ -718,13 +794,26 @@ ac_subst_files='' ac_user_opts=' enable_option_checking +enable_silent_rules enable_dependency_tracking +with_distro enable_rpath enable_doc +enable_apparmor +enable_seccomp enable_examples +enable_python +enable_lua +with_lua_pc +enable_tests with_config_path +with_global_conf +with_usernic_conf +with_usernic_db with_rootfs_path -with_linuxdir +enable_configpath_log +with_log_path +enable_capabilities ' ac_precious_vars='build_alias host_alias @@ -734,7 +823,18 @@ LDFLAGS LIBS CPPFLAGS -CPP' +CPP +PYTHON +PKG_CONFIG +PKG_CONFIG_PATH +PKG_CONFIG_LIBDIR +PYTHONDEV_CFLAGS +PYTHONDEV_LIBS +LUA_CFLAGS +LUA_LIBS +LUA_VERSION +LUA_INSTALL_CMOD +LUA_INSTALL_LMOD' # Initialize some variables set by options. @@ -1190,8 +1290,6 @@ if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe - $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host. - If a cross compiler is detected then cross compile mode will be used" >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi @@ -1277,7 +1375,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures lxc 0.8.0-rc1 to adapt to many kinds of systems. +\`configure' configures lxc 1.0.0.alpha1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1347,7 +1445,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of lxc 0.8.0-rc1:";; + short | recursive ) echo "Configuration of lxc 1.0.0.alpha1:";; esac cat <<\_ACEOF @@ -1355,19 +1453,37 @@ --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --disable-dependency-tracking speeds up one-time build - --enable-dependency-tracking do not reject slow dependency extractors + --enable-silent-rules less verbose build output (undo: "make V=1") + --disable-silent-rules verbose build output (undo: "make V=0") + --enable-dependency-tracking + do not reject slow dependency extractors + --disable-dependency-tracking + speeds up one-time build --disable-rpath do not set rpath in executables - --enable-doc make mans (require docbook2man installed) - [default=auto] + --enable-doc make mans (requires docbook2man or docbook2x-man to + be installed) [default=auto] + --enable-apparmor enable apparmor + --enable-seccomp enable seccomp --disable-examples do not install configuration examples + --enable-python enable python binding + --enable-lua enable lua binding + --enable-tests build test/example binaries + --enable-configpath-log use logfiles in config path + --disable-capabilities disable kernel capabilities Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-distro=DISTRO Specify the Linux distribution to target: One of + redhat, oracle, fedora, suse, gentoo, debian, arch, + slackware, paldo, mandriva or pardus. + --with-lua-pc=PKG Specify pkg-config package name for lua --with-config-path=dir lxc configuration repository path + --with-global-conf=dir global lxc configuration file + --with-usernic-conf user network interface configuration file + --with-usernic-db lxc user nic database --with-rootfs-path=dir lxc rootfs mount point - --with-linuxdir=DIR specify path to Linux source directory + --with-log-path=dir per container log path Some influential environment variables: CC C compiler command @@ -1378,6 +1494,23 @@ CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor + PYTHON the Python interpreter + PKG_CONFIG path to pkg-config utility + PKG_CONFIG_PATH + directories to add to pkg-config's search path + PKG_CONFIG_LIBDIR + path overriding pkg-config's built-in search path + PYTHONDEV_CFLAGS + C compiler flags for PYTHONDEV, overriding pkg-config + PYTHONDEV_LIBS + linker flags for PYTHONDEV, overriding pkg-config + LUA_CFLAGS C compiler flags for LUA, overriding pkg-config + LUA_LIBS linker flags for LUA, overriding pkg-config + LUA_VERSION value of V for $LUAPKGCONFIG, overriding pkg-config + LUA_INSTALL_CMOD + value of INSTALL_CMOD for $LUAPKGCONFIG, overriding pkg-config + LUA_INSTALL_LMOD + value of INSTALL_LMOD for $LUAPKGCONFIG, overriding pkg-config Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. @@ -1445,10 +1578,10 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -lxc configure 0.8.0-rc1 -generated by GNU Autoconf 2.68 +lxc configure 1.0.0.alpha1 +generated by GNU Autoconf 2.69 -Copyright (C) 2010 Free Software Foundation, Inc. +Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF @@ -1721,7 +1854,7 @@ test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || - $as_test_x conftest$ac_exeext + test -x conftest$ac_exeext }; then : ac_retval=0 else @@ -1740,6 +1873,60 @@ } # ac_fn_c_try_link +# ac_fn_c_check_type LINENO TYPE VAR INCLUDES +# ------------------------------------------- +# Tests whether TYPE exists after having included INCLUDES, setting cache +# variable VAR accordingly. +ac_fn_c_check_type () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof ($2)) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof (($2))) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + eval "$3=yes" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_type + # ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES # --------------------------------------------- # Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR @@ -1785,12 +1972,79 @@ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_decl + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case declares $2. + For example, HP-UX 11i declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_func cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by lxc $as_me 0.8.0-rc1, which was -generated by GNU Autoconf 2.68. Invocation command line was +It was created by lxc $as_me 1.0.0.alpha1, which was +generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2170,7 +2424,7 @@ ac_config_headers="$ac_config_headers src/config.h" -am__api_version='1.11' +am__api_version='1.13' # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or @@ -2209,7 +2463,7 @@ # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. @@ -2267,9 +2521,6 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } -# Just in case -sleep 1 -echo timestamp > conftest.file # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' @@ -2280,32 +2531,40 @@ esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) - as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;; + as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; esac -# Do `set' in a subshell so we don't clobber the current shell's +# Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( - set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` - if test "$*" = "X"; then - # -L didn't work. - set X `ls -t "$srcdir/configure" conftest.file` - fi - rm -f conftest.file - if test "$*" != "X $srcdir/configure conftest.file" \ - && test "$*" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - as_fn_error $? "ls -t appears to fail. Make sure there is not a broken -alias in your environment" "$LINENO" 5 - fi + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken + alias in your environment" "$LINENO" 5 + fi + if test "$2" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done test "$2" = conftest.file ) then @@ -2317,6 +2576,16 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi + +rm -f conftest.file + test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. @@ -2339,12 +2608,12 @@ esac fi # Use eval to expand $SHELL -if eval "$MISSING --run true"; then - am_missing_run="$MISSING --run " +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " else am_missing_run= - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5 -$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} fi if test x"${install_sh}" != xset; then @@ -2356,10 +2625,10 @@ esac fi -# Installed binaries are usually stripped using `strip' when the user -# run `make install-strip'. However `strip' might not be the right +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake -# will honor the `STRIP' environment variable to overrule this program. +# will honor the 'STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. @@ -2378,7 +2647,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -2418,7 +2687,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -2469,7 +2738,7 @@ test -z "$as_dir" && as_dir=. for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do - { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue + as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir (GNU coreutils) '* | \ 'mkdir (coreutils) '* | \ @@ -2498,12 +2767,6 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } -mkdir_p="$MKDIR_P" -case $mkdir_p in - [\\/$]* | ?:[\\/]*) ;; - */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; -esac - for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. @@ -2522,7 +2785,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -2586,6 +2849,45 @@ fi rmdir .tst 2>/dev/null +# Check whether --enable-silent-rules was given. +if test "${enable_silent_rules+set}" = set; then : + enableval=$enable_silent_rules; +fi + +case $enable_silent_rules in # ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=1;; +esac +am_make=${MAKE-make} +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 +$as_echo_n "checking whether $am_make supports nested variables... " >&6; } +if ${am_cv_make_support_nested_variables+:} false; then : + $as_echo_n "(cached) " >&6 +else + if $as_echo 'TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 +$as_echo "$am_cv_make_support_nested_variables" >&6; } +if test $am_cv_make_support_nested_variables = yes; then + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AM_BACKSLASH='\' + if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." @@ -2608,7 +2910,7 @@ # Define the identity of the package. PACKAGE='lxc' - VERSION='0.8.0-rc1' + VERSION='1.0.0.alpha1' cat >>confdefs.h <<_ACEOF @@ -2636,13 +2938,24 @@ MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# +# +mkdir_p='$(MKDIR_P)' + # We need awk for the "check" target. The system "awk" is bad on # some platforms. -# Always define AMTAR for backward compatibility. +# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AMTAR='$${TAR-tar}' -AMTAR=${AMTAR-"${am_missing_run}tar"} -am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar pax cpio none' + +am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' + @@ -2738,7 +3051,7 @@ _am_result=none # First try GNU make style include. echo "include confinc" > confmf -# Ignore all kinds of additional output from `make'. +# Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include @@ -2771,6 +3084,7 @@ if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' + am__nodep='_no' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= @@ -2803,7 +3117,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -2843,7 +3157,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -2896,7 +3210,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -2937,7 +3251,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue @@ -2995,7 +3309,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -3039,7 +3353,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -3485,8 +3799,7 @@ /* end confdefs.h. */ #include #include -#include -#include +struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); @@ -3582,8 +3895,9 @@ # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named `D' -- because `-MD' means `put the output - # in D'. + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. @@ -3617,16 +3931,16 @@ : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with - # Solaris 8's {/usr,}/bin/sh. - touch sub/conftst$i.h + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - # We check with `-c' and `-o' for the sake of the "dashmstdout" + # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly - # handle `-M -o', and we need to detect this. Also, some Intel - # versions had trouble with output in subdirs + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in @@ -3635,16 +3949,16 @@ test "$am__universal" = false || continue ;; nosideeffect) - # after this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; - msvisualcpp | msvcmsys) - # This compiler won't grok `-c -o', but also, the minuso test has + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} @@ -3979,7 +4293,7 @@ for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue + as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in @@ -4045,7 +4359,7 @@ for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue + as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in @@ -4252,8 +4566,8 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -# define __EXTENSIONS__ 1 - $ac_includes_default +# define __EXTENSIONS__ 1 + $ac_includes_default int main () { @@ -4284,24 +4598,296 @@ -# Extract the first word of "setcap", so it can be a program name with args. -set dummy setcap; ac_word=$2 + +# Detect the distribution. This is used for the default configuration and +# for some distro-specific build options. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host distribution" >&5 +$as_echo_n "checking host distribution... " >&6; } + +# Check whether --with-distro was given. +if test "${with_distro+set}" = set; then : + withval=$with_distro; +fi + +if test "z$with_distro" = "z"; then + with_distro=`lsb_release -is` +fi +if test "z$with_distro" = "z"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for /etc/redhat-release" >&5 +$as_echo_n "checking for /etc/redhat-release... " >&6; } +if ${ac_cv_file__etc_redhat_release+:} false; then : + $as_echo_n "(cached) " >&6 +else + test "$cross_compiling" = yes && + as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 +if test -r "/etc/redhat-release"; then + ac_cv_file__etc_redhat_release=yes +else + ac_cv_file__etc_redhat_release=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_file__etc_redhat_release" >&5 +$as_echo "$ac_cv_file__etc_redhat_release" >&6; } +if test "x$ac_cv_file__etc_redhat_release" = xyes; then : + with_distro="redhat" +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for /etc/oracle-release" >&5 +$as_echo_n "checking for /etc/oracle-release... " >&6; } +if ${ac_cv_file__etc_oracle_release+:} false; then : + $as_echo_n "(cached) " >&6 +else + test "$cross_compiling" = yes && + as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 +if test -r "/etc/oracle-release"; then + ac_cv_file__etc_oracle_release=yes +else + ac_cv_file__etc_oracle_release=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_file__etc_oracle_release" >&5 +$as_echo "$ac_cv_file__etc_oracle_release" >&6; } +if test "x$ac_cv_file__etc_oracle_release" = xyes; then : + with_distro="oracle" +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for /etc/fedora-release" >&5 +$as_echo_n "checking for /etc/fedora-release... " >&6; } +if ${ac_cv_file__etc_fedora_release+:} false; then : + $as_echo_n "(cached) " >&6 +else + test "$cross_compiling" = yes && + as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 +if test -r "/etc/fedora-release"; then + ac_cv_file__etc_fedora_release=yes +else + ac_cv_file__etc_fedora_release=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_file__etc_fedora_release" >&5 +$as_echo "$ac_cv_file__etc_fedora_release" >&6; } +if test "x$ac_cv_file__etc_fedora_release" = xyes; then : + with_distro="fedora" +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for /etc/SuSE-release" >&5 +$as_echo_n "checking for /etc/SuSE-release... " >&6; } +if ${ac_cv_file__etc_SuSE_release+:} false; then : + $as_echo_n "(cached) " >&6 +else + test "$cross_compiling" = yes && + as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 +if test -r "/etc/SuSE-release"; then + ac_cv_file__etc_SuSE_release=yes +else + ac_cv_file__etc_SuSE_release=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_file__etc_SuSE_release" >&5 +$as_echo "$ac_cv_file__etc_SuSE_release" >&6; } +if test "x$ac_cv_file__etc_SuSE_release" = xyes; then : + with_distro="suse" +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for /etc/gentoo-release" >&5 +$as_echo_n "checking for /etc/gentoo-release... " >&6; } +if ${ac_cv_file__etc_gentoo_release+:} false; then : + $as_echo_n "(cached) " >&6 +else + test "$cross_compiling" = yes && + as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 +if test -r "/etc/gentoo-release"; then + ac_cv_file__etc_gentoo_release=yes +else + ac_cv_file__etc_gentoo_release=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_file__etc_gentoo_release" >&5 +$as_echo "$ac_cv_file__etc_gentoo_release" >&6; } +if test "x$ac_cv_file__etc_gentoo_release" = xyes; then : + with_distro="gentoo" +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for /etc/debian_version" >&5 +$as_echo_n "checking for /etc/debian_version... " >&6; } +if ${ac_cv_file__etc_debian_version+:} false; then : + $as_echo_n "(cached) " >&6 +else + test "$cross_compiling" = yes && + as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 +if test -r "/etc/debian_version"; then + ac_cv_file__etc_debian_version=yes +else + ac_cv_file__etc_debian_version=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_file__etc_debian_version" >&5 +$as_echo "$ac_cv_file__etc_debian_version" >&6; } +if test "x$ac_cv_file__etc_debian_version" = xyes; then : + with_distro="debian" +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for /etc/arch-release" >&5 +$as_echo_n "checking for /etc/arch-release... " >&6; } +if ${ac_cv_file__etc_arch_release+:} false; then : + $as_echo_n "(cached) " >&6 +else + test "$cross_compiling" = yes && + as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 +if test -r "/etc/arch-release"; then + ac_cv_file__etc_arch_release=yes +else + ac_cv_file__etc_arch_release=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_file__etc_arch_release" >&5 +$as_echo "$ac_cv_file__etc_arch_release" >&6; } +if test "x$ac_cv_file__etc_arch_release" = xyes; then : + with_distro="arch" +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for /etc/slackware-version" >&5 +$as_echo_n "checking for /etc/slackware-version... " >&6; } +if ${ac_cv_file__etc_slackware_version+:} false; then : + $as_echo_n "(cached) " >&6 +else + test "$cross_compiling" = yes && + as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 +if test -r "/etc/slackware-version"; then + ac_cv_file__etc_slackware_version=yes +else + ac_cv_file__etc_slackware_version=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_file__etc_slackware_version" >&5 +$as_echo "$ac_cv_file__etc_slackware_version" >&6; } +if test "x$ac_cv_file__etc_slackware_version" = xyes; then : + with_distro="slackware" +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for /etc/frugalware-release" >&5 +$as_echo_n "checking for /etc/frugalware-release... " >&6; } +if ${ac_cv_file__etc_frugalware_release+:} false; then : + $as_echo_n "(cached) " >&6 +else + test "$cross_compiling" = yes && + as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 +if test -r "/etc/frugalware-release"; then + ac_cv_file__etc_frugalware_release=yes +else + ac_cv_file__etc_frugalware_release=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_file__etc_frugalware_release" >&5 +$as_echo "$ac_cv_file__etc_frugalware_release" >&6; } +if test "x$ac_cv_file__etc_frugalware_release" = xyes; then : + with_distro="frugalware" +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for /etc/mandrakelinux-release" >&5 +$as_echo_n "checking for /etc/mandrakelinux-release... " >&6; } +if ${ac_cv_file__etc_mandrakelinux_release+:} false; then : + $as_echo_n "(cached) " >&6 +else + test "$cross_compiling" = yes && + as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 +if test -r "/etc/mandrakelinux-release"; then + ac_cv_file__etc_mandrakelinux_release=yes +else + ac_cv_file__etc_mandrakelinux_release=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_file__etc_mandrakelinux_release" >&5 +$as_echo "$ac_cv_file__etc_mandrakelinux_release" >&6; } +if test "x$ac_cv_file__etc_mandrakelinux_release" = xyes; then : + with_distro="mandriva" +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for /etc/mandriva-release" >&5 +$as_echo_n "checking for /etc/mandriva-release... " >&6; } +if ${ac_cv_file__etc_mandriva_release+:} false; then : + $as_echo_n "(cached) " >&6 +else + test "$cross_compiling" = yes && + as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 +if test -r "/etc/mandriva-release"; then + ac_cv_file__etc_mandriva_release=yes +else + ac_cv_file__etc_mandriva_release=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_file__etc_mandriva_release" >&5 +$as_echo "$ac_cv_file__etc_mandriva_release" >&6; } +if test "x$ac_cv_file__etc_mandriva_release" = xyes; then : + with_distro="mandriva" +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for /etc/pardus-release" >&5 +$as_echo_n "checking for /etc/pardus-release... " >&6; } +if ${ac_cv_file__etc_pardus_release+:} false; then : + $as_echo_n "(cached) " >&6 +else + test "$cross_compiling" = yes && + as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 +if test -r "/etc/pardus-release"; then + ac_cv_file__etc_pardus_release=yes +else + ac_cv_file__etc_pardus_release=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_file__etc_pardus_release" >&5 +$as_echo "$ac_cv_file__etc_pardus_release" >&6; } +if test "x$ac_cv_file__etc_pardus_release" = xyes; then : + with_distro="pardus" +fi + +fi +with_distro=`echo ${with_distro} | tr '[:upper:]' '[:lower:]'` + +if test "z$with_distro" = "z"; then + with_distro="unknown" +fi +case $with_distro in + ubuntu) + distroconf=default.conf.ubuntu + ;; + redhat|fedora|oracle|oracleserver) + distroconf=default.conf.libvirt + ;; + *) + echo -n "Linux distribution network config unknown, defaulting to lxc.network.type = empty" + distroconf=default.conf.unknown + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_distro" >&5 +$as_echo "$with_distro" >&6; } + if test x"$with_distro" = "xdebian" -o x"$with_distro" = "xubuntu"; then + HAVE_DEBIAN_TRUE= + HAVE_DEBIAN_FALSE='#' +else + HAVE_DEBIAN_TRUE='#' + HAVE_DEBIAN_FALSE= +fi + + +# Extract the first word of "newuidmap", so it can be a program name with args. +set dummy newuidmap; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_SETCAP+:} false; then : +if ${ac_cv_prog_NEWUIDMAP+:} false; then : $as_echo_n "(cached) " >&6 else - if test -n "$SETCAP"; then - ac_cv_prog_SETCAP="$SETCAP" # Let the user override the test. + if test -n "$NEWUIDMAP"; then + ac_cv_prog_NEWUIDMAP="$NEWUIDMAP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/sbin +for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_SETCAP="yes" + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_NEWUIDMAP="newuidmap" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi @@ -4309,20 +4895,28 @@ done IFS=$as_save_IFS - test -z "$ac_cv_prog_SETCAP" && ac_cv_prog_SETCAP="no" fi fi -SETCAP=$ac_cv_prog_SETCAP -if test -n "$SETCAP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SETCAP" >&5 -$as_echo "$SETCAP" >&6; } +NEWUIDMAP=$ac_cv_prog_NEWUIDMAP +if test -n "$NEWUIDMAP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NEWUIDMAP" >&5 +$as_echo "$NEWUIDMAP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi + if test -n "$NEWUIDMAP"; then + HAVE_NEWUIDMAP_TRUE= + HAVE_NEWUIDMAP_FALSE='#' +else + HAVE_NEWUIDMAP_TRUE='#' + HAVE_NEWUIDMAP_FALSE= +fi + +# Allow disabling rpath # Check whether --enable-rpath was given. if test "${enable_rpath+set}" = set; then : enableval=$enable_rpath; @@ -4330,7 +4924,6 @@ enable_rpath=yes fi - if test "x$enable_rpath" = "xyes"; then ENABLE_RPATH_TRUE= ENABLE_RPATH_FALSE='#' @@ -4340,6 +4933,7 @@ fi +# Documentation (manpages) # Check whether --enable-doc was given. if test "${enable_doc+set}" = set; then : enableval=$enable_doc; @@ -4349,50 +4943,32 @@ if test "x$enable_doc" = "xyes" -o "x$enable_doc" = "xauto"; then - # Extract the first word of "docbook2man", so it can be a program name with args. -set dummy docbook2man; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_have_docbook+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$have_docbook"; then - ac_cv_prog_have_docbook="$have_docbook" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_have_docbook="yes" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS + db2xman="" + dbparsers="docbook2x-man db2x_docbook2man docbook2man" - test -z "$ac_cv_prog_have_docbook" && ac_cv_prog_have_docbook="no" -fi -fi -have_docbook=$ac_cv_prog_have_docbook -if test -n "$have_docbook"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_docbook" >&5 -$as_echo "$have_docbook" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for docbook2x-man" >&5 +$as_echo_n "checking for docbook2x-man... " >&6; } + for name in ${dbparsers}; do + if "$name" --help >/dev/null 2>&1; then + db2xman="$name" + break; + fi + done + + if test -n "${db2xman}"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${db2xman}" >&5 +$as_echo "${db2xman}" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } -fi - + if test "x$enable_doc" = "xyes"; then + as_fn_error $? "docbook2x-man required by man request, but not found" "$LINENO" 5 + fi + fi - test "x$have_docbook" = "xno" -a "x$enable_doc" = "xyes" && \ - as_fn_error $? "docbook2man required by man request, but not found" "$LINENO" 5 fi - - if test "x$have_docbook" = "xyes"; then + if test "x$db2xman" != "x"; then ENABLE_DOCBOOK_TRUE= ENABLE_DOCBOOK_FALSE='#' else @@ -4401,26 +4977,2008 @@ fi -# Check whether --enable-examples was given. +if test "x$db2xman" = "xdocbook2man"; then + docdtd="\"-//Davenport//DTD DocBook V3.0//EN\"" +else + docdtd="\"-//OASIS//DTD DocBook XML\" \"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd\"" +fi + + +# Apparmor +# Check whether --enable-apparmor was given. +if test "${enable_apparmor+set}" = set; then : + enableval=$enable_apparmor; +else + enable_apparmor=check +fi + + +if test "$enable_apparmor" = "check" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for aa_change_profile in -lapparmor" >&5 +$as_echo_n "checking for aa_change_profile in -lapparmor... " >&6; } +if ${ac_cv_lib_apparmor_aa_change_profile+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lapparmor $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char aa_change_profile (); +int +main () +{ +return aa_change_profile (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_apparmor_aa_change_profile=yes +else + ac_cv_lib_apparmor_aa_change_profile=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_apparmor_aa_change_profile" >&5 +$as_echo "$ac_cv_lib_apparmor_aa_change_profile" >&6; } +if test "x$ac_cv_lib_apparmor_aa_change_profile" = xyes; then : + enable_apparmor=yes +else + enable_apparmor=no +fi + +fi + if test "x$enable_apparmor" = "xyes"; then + ENABLE_APPARMOR_TRUE= + ENABLE_APPARMOR_FALSE='#' +else + ENABLE_APPARMOR_TRUE='#' + ENABLE_APPARMOR_FALSE= +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for gnutls_hash_fast in -lgnutls" >&5 +$as_echo_n "checking for gnutls_hash_fast in -lgnutls... " >&6; } +if ${ac_cv_lib_gnutls_gnutls_hash_fast+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lgnutls $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char gnutls_hash_fast (); +int +main () +{ +return gnutls_hash_fast (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_gnutls_gnutls_hash_fast=yes +else + ac_cv_lib_gnutls_gnutls_hash_fast=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gnutls_gnutls_hash_fast" >&5 +$as_echo "$ac_cv_lib_gnutls_gnutls_hash_fast" >&6; } +if test "x$ac_cv_lib_gnutls_gnutls_hash_fast" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBGNUTLS 1 +_ACEOF + + LIBS="-lgnutls $LIBS" + +fi + + +if test -z "$ENABLE_APPARMOR_TRUE"; then : + ac_fn_c_check_header_mongrel "$LINENO" "sys/apparmor.h" "ac_cv_header_sys_apparmor_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_apparmor_h" = xyes; then : + +else + as_fn_error $? "You must install the AppArmor development package in order to compile lxc" "$LINENO" 5 +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for aa_change_profile in -lapparmor" >&5 +$as_echo_n "checking for aa_change_profile in -lapparmor... " >&6; } +if ${ac_cv_lib_apparmor_aa_change_profile+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lapparmor $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char aa_change_profile (); +int +main () +{ +return aa_change_profile (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_apparmor_aa_change_profile=yes +else + ac_cv_lib_apparmor_aa_change_profile=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_apparmor_aa_change_profile" >&5 +$as_echo "$ac_cv_lib_apparmor_aa_change_profile" >&6; } +if test "x$ac_cv_lib_apparmor_aa_change_profile" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBAPPARMOR 1 +_ACEOF + + LIBS="-lapparmor $LIBS" + +else + as_fn_error $? "You must install the AppArmor development package in order to compile lxc" "$LINENO" 5 +fi + + APPARMOR_LIBS=-lapparmor + +fi + +# Seccomp syscall filter +# Check whether --enable-seccomp was given. +if test "${enable_seccomp+set}" = set; then : + enableval=$enable_seccomp; +else + enable_seccomp=check +fi + + +if test "$enable_seccomp" = "check" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for seccomp_init in -lseccomp" >&5 +$as_echo_n "checking for seccomp_init in -lseccomp... " >&6; } +if ${ac_cv_lib_seccomp_seccomp_init+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lseccomp $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char seccomp_init (); +int +main () +{ +return seccomp_init (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_seccomp_seccomp_init=yes +else + ac_cv_lib_seccomp_seccomp_init=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_seccomp_seccomp_init" >&5 +$as_echo "$ac_cv_lib_seccomp_seccomp_init" >&6; } +if test "x$ac_cv_lib_seccomp_seccomp_init" = xyes; then : + enable_seccomp=yes +else + enable_seccomp=no +fi + +fi + if test "x$enable_seccomp" = "xyes"; then + ENABLE_SECCOMP_TRUE= + ENABLE_SECCOMP_FALSE='#' +else + ENABLE_SECCOMP_TRUE='#' + ENABLE_SECCOMP_FALSE= +fi + + +if test -z "$ENABLE_SECCOMP_TRUE"; then : + ac_fn_c_check_header_mongrel "$LINENO" "seccomp.h" "ac_cv_header_seccomp_h" "$ac_includes_default" +if test "x$ac_cv_header_seccomp_h" = xyes; then : + +else + as_fn_error $? "You must install the seccomp development package in order to compile lxc" "$LINENO" 5 +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for seccomp_init in -lseccomp" >&5 +$as_echo_n "checking for seccomp_init in -lseccomp... " >&6; } +if ${ac_cv_lib_seccomp_seccomp_init+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lseccomp $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char seccomp_init (); +int +main () +{ +return seccomp_init (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_seccomp_seccomp_init=yes +else + ac_cv_lib_seccomp_seccomp_init=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_seccomp_seccomp_init" >&5 +$as_echo "$ac_cv_lib_seccomp_seccomp_init" >&6; } +if test "x$ac_cv_lib_seccomp_seccomp_init" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBSECCOMP 1 +_ACEOF + + LIBS="-lseccomp $LIBS" + +else + as_fn_error $? "You must install the seccomp development package in order to compile lxc" "$LINENO" 5 +fi + + SECCOMP_LIBS=-lseccomp + +fi + +# HAVE_SCMP_FILTER_CTX=1 will tell us we have libseccomp api >= 1.0.0 +ac_fn_c_check_type "$LINENO" "scmp_filter_ctx" "ac_cv_type_scmp_filter_ctx" "#include +" +if test "x$ac_cv_type_scmp_filter_ctx" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_SCMP_FILTER_CTX 1 +_ACEOF + + +fi + + +# Configuration examples +# Check whether --enable-examples was given. if test "${enable_examples+set}" = set; then : enableval=$enable_examples; else enable_examples=yes fi + if test "x$enable_examples" = "xyes"; then + ENABLE_EXAMPLES_TRUE= + ENABLE_EXAMPLES_FALSE='#' +else + ENABLE_EXAMPLES_TRUE='#' + ENABLE_EXAMPLES_FALSE= +fi + + +# Python3 module and scripts +# Check whether --enable-python was given. +if test "${enable_python+set}" = set; then : + enableval=$enable_python; enable_python=yes +else + enable_python=no +fi + + if test "x$enable_python" = "xyes"; then + ENABLE_PYTHON_TRUE= + ENABLE_PYTHON_FALSE='#' +else + ENABLE_PYTHON_TRUE='#' + ENABLE_PYTHON_FALSE= +fi + + + + + + + + + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. +set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +PKG_CONFIG=$ac_cv_path_PKG_CONFIG +if test -n "$PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 +$as_echo "$PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_PKG_CONFIG"; then + ac_pt_PKG_CONFIG=$PKG_CONFIG + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $ac_pt_PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG +if test -n "$ac_pt_PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 +$as_echo "$ac_pt_PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_pt_PKG_CONFIG" = x; then + PKG_CONFIG="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + PKG_CONFIG=$ac_pt_PKG_CONFIG + fi +else + PKG_CONFIG="$ac_cv_path_PKG_CONFIG" +fi + +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=0.9.0 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 +$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + PKG_CONFIG="" + fi +fi +if test -z "$ENABLE_PYTHON_TRUE"; then : + + + + + + + if test -n "$PYTHON"; then + # If the user set $PYTHON, use it and don't search something else. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $PYTHON version is >= 3.2" >&5 +$as_echo_n "checking whether $PYTHON version is >= 3.2... " >&6; } + prog="import sys +# split strings by '.' and convert to numeric. Append some zeros +# because we need at least 4 digits for the hex conversion. +# map returns an iterator in Python 3.0 and a list in 2.x +minver = list(map(int, '3.2'.split('.'))) + [0, 0, 0] +minverhex = 0 +# xrange is not present in Python 3.0 and range returns an iterator +for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[i] +sys.exit(sys.hexversion < minverhex)" + if { echo "$as_me:$LINENO: $PYTHON -c "$prog"" >&5 + ($PYTHON -c "$prog") >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + as_fn_error $? "Python interpreter is too old" "$LINENO" 5 +fi + am_display_PYTHON=$PYTHON + else + # Otherwise, try each interpreter until we find one that satisfies + # VERSION. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a Python interpreter with version >= 3.2" >&5 +$as_echo_n "checking for a Python interpreter with version >= 3.2... " >&6; } +if ${am_cv_pathless_PYTHON+:} false; then : + $as_echo_n "(cached) " >&6 +else + + for am_cv_pathless_PYTHON in python python2 python3 python3.3 python3.2 python3.1 python3.0 python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0 none; do + test "$am_cv_pathless_PYTHON" = none && break + prog="import sys +# split strings by '.' and convert to numeric. Append some zeros +# because we need at least 4 digits for the hex conversion. +# map returns an iterator in Python 3.0 and a list in 2.x +minver = list(map(int, '3.2'.split('.'))) + [0, 0, 0] +minverhex = 0 +# xrange is not present in Python 3.0 and range returns an iterator +for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[i] +sys.exit(sys.hexversion < minverhex)" + if { echo "$as_me:$LINENO: $am_cv_pathless_PYTHON -c "$prog"" >&5 + ($am_cv_pathless_PYTHON -c "$prog") >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then : + break +fi + done +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_pathless_PYTHON" >&5 +$as_echo "$am_cv_pathless_PYTHON" >&6; } + # Set $PYTHON to the absolute path of $am_cv_pathless_PYTHON. + if test "$am_cv_pathless_PYTHON" = none; then + PYTHON=: + else + # Extract the first word of "$am_cv_pathless_PYTHON", so it can be a program name with args. +set dummy $am_cv_pathless_PYTHON; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_PYTHON+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $PYTHON in + [\\/]* | ?:[\\/]*) + ac_cv_path_PYTHON="$PYTHON" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_PYTHON="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +PYTHON=$ac_cv_path_PYTHON +if test -n "$PYTHON"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON" >&5 +$as_echo "$PYTHON" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi + am_display_PYTHON=$am_cv_pathless_PYTHON + fi + + + if test "$PYTHON" = :; then + as_fn_error $? "You must install python3" "$LINENO" 5 + else + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON version" >&5 +$as_echo_n "checking for $am_display_PYTHON version... " >&6; } +if ${am_cv_python_version+:} false; then : + $as_echo_n "(cached) " >&6 +else + am_cv_python_version=`$PYTHON -c "import sys; sys.stdout.write(sys.version[:3])"` +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_version" >&5 +$as_echo "$am_cv_python_version" >&6; } + PYTHON_VERSION=$am_cv_python_version + + + + PYTHON_PREFIX='${prefix}' + + PYTHON_EXEC_PREFIX='${exec_prefix}' + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON platform" >&5 +$as_echo_n "checking for $am_display_PYTHON platform... " >&6; } +if ${am_cv_python_platform+:} false; then : + $as_echo_n "(cached) " >&6 +else + am_cv_python_platform=`$PYTHON -c "import sys; sys.stdout.write(sys.platform)"` +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_platform" >&5 +$as_echo "$am_cv_python_platform" >&6; } + PYTHON_PLATFORM=$am_cv_python_platform + + + # Just factor out some code duplication. + am_python_setup_sysconfig="\ +import sys +# Prefer sysconfig over distutils.sysconfig, for better compatibility +# with python 3.x. See automake bug#10227. +try: + import sysconfig +except ImportError: + can_use_sysconfig = 0 +else: + can_use_sysconfig = 1 +# Can't use sysconfig in CPython 2.7, since it's broken in virtualenvs: +# +try: + from platform import python_implementation + if python_implementation() == 'CPython' and sys.version[:3] == '2.7': + can_use_sysconfig = 0 +except ImportError: + pass" + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON script directory" >&5 +$as_echo_n "checking for $am_display_PYTHON script directory... " >&6; } +if ${am_cv_python_pythondir+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$prefix" = xNONE + then + am_py_prefix=$ac_default_prefix + else + am_py_prefix=$prefix + fi + am_cv_python_pythondir=`$PYTHON -c " +$am_python_setup_sysconfig +if can_use_sysconfig: + sitedir = sysconfig.get_path('purelib', vars={'base':'$am_py_prefix'}) +else: + from distutils import sysconfig + sitedir = sysconfig.get_python_lib(0, 0, prefix='$am_py_prefix') +sys.stdout.write(sitedir)"` + case $am_cv_python_pythondir in + $am_py_prefix*) + am__strip_prefix=`echo "$am_py_prefix" | sed 's|.|.|g'` + am_cv_python_pythondir=`echo "$am_cv_python_pythondir" | sed "s,^$am__strip_prefix,$PYTHON_PREFIX,"` + ;; + *) + case $am_py_prefix in + /usr|/System*) ;; + *) + am_cv_python_pythondir=$PYTHON_PREFIX/lib/python$PYTHON_VERSION/site-packages + ;; + esac + ;; + esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_pythondir" >&5 +$as_echo "$am_cv_python_pythondir" >&6; } + pythondir=$am_cv_python_pythondir + + + + pkgpythondir=\${pythondir}/$PACKAGE + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON extension module directory" >&5 +$as_echo_n "checking for $am_display_PYTHON extension module directory... " >&6; } +if ${am_cv_python_pyexecdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$exec_prefix" = xNONE + then + am_py_exec_prefix=$am_py_prefix + else + am_py_exec_prefix=$exec_prefix + fi + am_cv_python_pyexecdir=`$PYTHON -c " +$am_python_setup_sysconfig +if can_use_sysconfig: + sitedir = sysconfig.get_path('platlib', vars={'platbase':'$am_py_prefix'}) +else: + from distutils import sysconfig + sitedir = sysconfig.get_python_lib(1, 0, prefix='$am_py_prefix') +sys.stdout.write(sitedir)"` + case $am_cv_python_pyexecdir in + $am_py_exec_prefix*) + am__strip_prefix=`echo "$am_py_exec_prefix" | sed 's|.|.|g'` + am_cv_python_pyexecdir=`echo "$am_cv_python_pyexecdir" | sed "s,^$am__strip_prefix,$PYTHON_EXEC_PREFIX,"` + ;; + *) + case $am_py_exec_prefix in + /usr|/System*) ;; + *) + am_cv_python_pyexecdir=$PYTHON_EXEC_PREFIX/lib/python$PYTHON_VERSION/site-packages + ;; + esac + ;; + esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_pyexecdir" >&5 +$as_echo "$am_cv_python_pyexecdir" >&6; } + pyexecdir=$am_cv_python_pyexecdir + + + + pkgpyexecdir=\${pyexecdir}/$PACKAGE + + + + fi + + + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for PYTHONDEV" >&5 +$as_echo_n "checking for PYTHONDEV... " >&6; } + +if test -n "$PYTHONDEV_CFLAGS"; then + pkg_cv_PYTHONDEV_CFLAGS="$PYTHONDEV_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"python3 >= 3.2\""; } >&5 + ($PKG_CONFIG --exists --print-errors "python3 >= 3.2") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_PYTHONDEV_CFLAGS=`$PKG_CONFIG --cflags "python3 >= 3.2" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$PYTHONDEV_LIBS"; then + pkg_cv_PYTHONDEV_LIBS="$PYTHONDEV_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"python3 >= 3.2\""; } >&5 + ($PKG_CONFIG --exists --print-errors "python3 >= 3.2") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_PYTHONDEV_LIBS=`$PKG_CONFIG --libs "python3 >= 3.2" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + PYTHONDEV_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "python3 >= 3.2" 2>&1` + else + PYTHONDEV_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "python3 >= 3.2" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$PYTHONDEV_PKG_ERRORS" >&5 + + as_fn_error $? "You must install python3-dev" "$LINENO" 5 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + as_fn_error $? "You must install python3-dev" "$LINENO" 5 +else + PYTHONDEV_CFLAGS=$pkg_cv_PYTHONDEV_CFLAGS + PYTHONDEV_LIBS=$pkg_cv_PYTHONDEV_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi + +cat >>confdefs.h <<_ACEOF +#define ENABLE_PYTHON 1 +_ACEOF + +fi + +# Not in older autoconf versions +# AS_VAR_COPY(DEST, SOURCE) +# ------------------------- +# Set the polymorphic shell variable DEST to the contents of the polymorphic +# shell variable SOURCE. + + +# PKG_CHECK_VAR + + +# Lua module and scripts +# Check whether --enable-lua was given. +if test "${enable_lua+set}" = set; then : + enableval=$enable_lua; +else + enable_lua=check +fi + + + +# Check whether --with-lua-pc was given. +if test "${with_lua_pc+set}" = set; then : + withval=$with_lua_pc; +else + with_lua_pc=no +fi + + +if test "x$enable_lua" = "xyes" -a "x$with_lua_pc" != "xno"; then + # exit with error if not found + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LUA" >&5 +$as_echo_n "checking for LUA... " >&6; } + +if test -n "$LUA_CFLAGS"; then + pkg_cv_LUA_CFLAGS="$LUA_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$with_lua_pc\""; } >&5 + ($PKG_CONFIG --exists --print-errors "$with_lua_pc") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LUA_CFLAGS=`$PKG_CONFIG --cflags "$with_lua_pc" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LUA_LIBS"; then + pkg_cv_LUA_LIBS="$LUA_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$with_lua_pc\""; } >&5 + ($PKG_CONFIG --exists --print-errors "$with_lua_pc") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LUA_LIBS=`$PKG_CONFIG --libs "$with_lua_pc" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LUA_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$with_lua_pc" 2>&1` + else + LUA_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$with_lua_pc" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LUA_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements ($with_lua_pc) were not met: + +$LUA_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables LUA_CFLAGS +and LUA_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables LUA_CFLAGS +and LUA_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see . +See \`config.log' for more details" "$LINENO" 5; } +else + LUA_CFLAGS=$pkg_cv_LUA_CFLAGS + LUA_LIBS=$pkg_cv_LUA_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + LUAPKGCONFIG=$with_lua_pc +fi +fi + +if test "x$enable_lua" = "xcheck" -a "x$with_lua_pc" != "xno"; then + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LUA" >&5 +$as_echo_n "checking for LUA... " >&6; } + +if test -n "$LUA_CFLAGS"; then + pkg_cv_LUA_CFLAGS="$LUA_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$with_lua_pc\""; } >&5 + ($PKG_CONFIG --exists --print-errors "$with_lua_pc") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LUA_CFLAGS=`$PKG_CONFIG --cflags "$with_lua_pc" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LUA_LIBS"; then + pkg_cv_LUA_LIBS="$LUA_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$with_lua_pc\""; } >&5 + ($PKG_CONFIG --exists --print-errors "$with_lua_pc") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LUA_LIBS=`$PKG_CONFIG --libs "$with_lua_pc" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LUA_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$with_lua_pc" 2>&1` + else + LUA_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$with_lua_pc" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LUA_PKG_ERRORS" >&5 + + enable_lua=no +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + enable_lua=no +else + LUA_CFLAGS=$pkg_cv_LUA_CFLAGS + LUA_LIBS=$pkg_cv_LUA_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + LUAPKGCONFIG=$with_lua_pc + enable_lua=yes +fi +fi + +if test "x$enable_lua" != "xno"; then + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LUA" >&5 +$as_echo_n "checking for LUA... " >&6; } + +if test -n "$LUA_CFLAGS"; then + pkg_cv_LUA_CFLAGS="$LUA_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"lua\""; } >&5 + ($PKG_CONFIG --exists --print-errors "lua") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LUA_CFLAGS=`$PKG_CONFIG --cflags "lua" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LUA_LIBS"; then + pkg_cv_LUA_LIBS="$LUA_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"lua\""; } >&5 + ($PKG_CONFIG --exists --print-errors "lua") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LUA_LIBS=`$PKG_CONFIG --libs "lua" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LUA_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "lua" 2>&1` + else + LUA_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "lua" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LUA_PKG_ERRORS" >&5 + + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LUA" >&5 +$as_echo_n "checking for LUA... " >&6; } + +if test -n "$LUA_CFLAGS"; then + pkg_cv_LUA_CFLAGS="$LUA_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"lua5.2\""; } >&5 + ($PKG_CONFIG --exists --print-errors "lua5.2") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LUA_CFLAGS=`$PKG_CONFIG --cflags "lua5.2" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LUA_LIBS"; then + pkg_cv_LUA_LIBS="$LUA_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"lua5.2\""; } >&5 + ($PKG_CONFIG --exists --print-errors "lua5.2") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LUA_LIBS=`$PKG_CONFIG --libs "lua5.2" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LUA_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "lua5.2" 2>&1` + else + LUA_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "lua5.2" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LUA_PKG_ERRORS" >&5 + + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LUA" >&5 +$as_echo_n "checking for LUA... " >&6; } + +if test -n "$LUA_CFLAGS"; then + pkg_cv_LUA_CFLAGS="$LUA_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"lua5.1\""; } >&5 + ($PKG_CONFIG --exists --print-errors "lua5.1") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LUA_CFLAGS=`$PKG_CONFIG --cflags "lua5.1" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LUA_LIBS"; then + pkg_cv_LUA_LIBS="$LUA_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"lua5.1\""; } >&5 + ($PKG_CONFIG --exists --print-errors "lua5.1") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LUA_LIBS=`$PKG_CONFIG --libs "lua5.1" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LUA_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "lua5.1" 2>&1` + else + LUA_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "lua5.1" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LUA_PKG_ERRORS" >&5 + + if test "x$enable_lua" = "xyes"; then : + as_fn_error $? "Lua not found. Please use --with-lua-pc=PKG" "$LINENO" 5 +else + enable_lua=no +fi + +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + if test "x$enable_lua" = "xyes"; then : + as_fn_error $? "Lua not found. Please use --with-lua-pc=PKG" "$LINENO" 5 +else + enable_lua=no +fi + +else + LUA_CFLAGS=$pkg_cv_LUA_CFLAGS + LUA_LIBS=$pkg_cv_LUA_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + LUAPKGCONFIG=lua5.1 +fi + +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LUA" >&5 +$as_echo_n "checking for LUA... " >&6; } + +if test -n "$LUA_CFLAGS"; then + pkg_cv_LUA_CFLAGS="$LUA_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"lua5.1\""; } >&5 + ($PKG_CONFIG --exists --print-errors "lua5.1") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LUA_CFLAGS=`$PKG_CONFIG --cflags "lua5.1" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LUA_LIBS"; then + pkg_cv_LUA_LIBS="$LUA_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"lua5.1\""; } >&5 + ($PKG_CONFIG --exists --print-errors "lua5.1") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LUA_LIBS=`$PKG_CONFIG --libs "lua5.1" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LUA_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "lua5.1" 2>&1` + else + LUA_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "lua5.1" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LUA_PKG_ERRORS" >&5 + + if test "x$enable_lua" = "xyes"; then : + as_fn_error $? "Lua not found. Please use --with-lua-pc=PKG" "$LINENO" 5 +else + enable_lua=no +fi + +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + if test "x$enable_lua" = "xyes"; then : + as_fn_error $? "Lua not found. Please use --with-lua-pc=PKG" "$LINENO" 5 +else + enable_lua=no +fi + +else + LUA_CFLAGS=$pkg_cv_LUA_CFLAGS + LUA_LIBS=$pkg_cv_LUA_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + LUAPKGCONFIG=lua5.1 +fi + +else + LUA_CFLAGS=$pkg_cv_LUA_CFLAGS + LUA_LIBS=$pkg_cv_LUA_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + LUAPKGCONFIG=lua5.2 +fi +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LUA" >&5 +$as_echo_n "checking for LUA... " >&6; } + +if test -n "$LUA_CFLAGS"; then + pkg_cv_LUA_CFLAGS="$LUA_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"lua5.2\""; } >&5 + ($PKG_CONFIG --exists --print-errors "lua5.2") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LUA_CFLAGS=`$PKG_CONFIG --cflags "lua5.2" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LUA_LIBS"; then + pkg_cv_LUA_LIBS="$LUA_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"lua5.2\""; } >&5 + ($PKG_CONFIG --exists --print-errors "lua5.2") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LUA_LIBS=`$PKG_CONFIG --libs "lua5.2" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LUA_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "lua5.2" 2>&1` + else + LUA_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "lua5.2" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LUA_PKG_ERRORS" >&5 + + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LUA" >&5 +$as_echo_n "checking for LUA... " >&6; } + +if test -n "$LUA_CFLAGS"; then + pkg_cv_LUA_CFLAGS="$LUA_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"lua5.1\""; } >&5 + ($PKG_CONFIG --exists --print-errors "lua5.1") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LUA_CFLAGS=`$PKG_CONFIG --cflags "lua5.1" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LUA_LIBS"; then + pkg_cv_LUA_LIBS="$LUA_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"lua5.1\""; } >&5 + ($PKG_CONFIG --exists --print-errors "lua5.1") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LUA_LIBS=`$PKG_CONFIG --libs "lua5.1" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LUA_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "lua5.1" 2>&1` + else + LUA_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "lua5.1" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LUA_PKG_ERRORS" >&5 + + if test "x$enable_lua" = "xyes"; then : + as_fn_error $? "Lua not found. Please use --with-lua-pc=PKG" "$LINENO" 5 +else + enable_lua=no +fi + +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + if test "x$enable_lua" = "xyes"; then : + as_fn_error $? "Lua not found. Please use --with-lua-pc=PKG" "$LINENO" 5 +else + enable_lua=no +fi + +else + LUA_CFLAGS=$pkg_cv_LUA_CFLAGS + LUA_LIBS=$pkg_cv_LUA_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + LUAPKGCONFIG=lua5.1 +fi + +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LUA" >&5 +$as_echo_n "checking for LUA... " >&6; } + +if test -n "$LUA_CFLAGS"; then + pkg_cv_LUA_CFLAGS="$LUA_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"lua5.1\""; } >&5 + ($PKG_CONFIG --exists --print-errors "lua5.1") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LUA_CFLAGS=`$PKG_CONFIG --cflags "lua5.1" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LUA_LIBS"; then + pkg_cv_LUA_LIBS="$LUA_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"lua5.1\""; } >&5 + ($PKG_CONFIG --exists --print-errors "lua5.1") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LUA_LIBS=`$PKG_CONFIG --libs "lua5.1" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LUA_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "lua5.1" 2>&1` + else + LUA_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "lua5.1" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LUA_PKG_ERRORS" >&5 + + if test "x$enable_lua" = "xyes"; then : + as_fn_error $? "Lua not found. Please use --with-lua-pc=PKG" "$LINENO" 5 +else + enable_lua=no +fi + +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + if test "x$enable_lua" = "xyes"; then : + as_fn_error $? "Lua not found. Please use --with-lua-pc=PKG" "$LINENO" 5 +else + enable_lua=no +fi + +else + LUA_CFLAGS=$pkg_cv_LUA_CFLAGS + LUA_LIBS=$pkg_cv_LUA_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + LUAPKGCONFIG=lua5.1 +fi + +else + LUA_CFLAGS=$pkg_cv_LUA_CFLAGS + LUA_LIBS=$pkg_cv_LUA_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + LUAPKGCONFIG=lua5.2 +fi +else + LUA_CFLAGS=$pkg_cv_LUA_CFLAGS + LUA_LIBS=$pkg_cv_LUA_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + LUAPKGCONFIG=lua +fi + if test "x$LUAPKGCONFIG" != "x"; then : + enable_lua=yes +fi +fi + + if test "x$enable_lua" = "xyes"; then + ENABLE_LUA_TRUE= + ENABLE_LUA_FALSE='#' +else + ENABLE_LUA_TRUE='#' + ENABLE_LUA_FALSE= +fi + + +if test -z "$ENABLE_LUA_TRUE"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking Lua version" >&5 +$as_echo_n "checking Lua version... " >&6; } + if test -n "$LUA_VERSION"; then + pkg_cv_LUA_VERSION="$LUA_VERSION" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$LUAPKGCONFIG\""; } >&5 + ($PKG_CONFIG --exists --print-errors "$LUAPKGCONFIG") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LUA_VERSION=`$PKG_CONFIG --variable="V" "$LUAPKGCONFIG" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + LUA_VERSION=$pkg_cv_LUA_VERSION + if test "x$LUA_VERSION" = x""; then : + if test -n "$LUA_VERSION"; then + pkg_cv_LUA_VERSION="$LUA_VERSION" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$LUAPKGCONFIG\""; } >&5 + ($PKG_CONFIG --exists --print-errors "$LUAPKGCONFIG") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LUA_VERSION=`$PKG_CONFIG --variable="major_version" "$LUAPKGCONFIG" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + LUA_VERSION=$pkg_cv_LUA_VERSION + if test "x$LUA_VERSION" = x""; then : + +fi +fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LUA_VERSION" >&5 +$as_echo "$LUA_VERSION" >&6; } + if test -n "$LUA_INSTALL_CMOD"; then + pkg_cv_LUA_INSTALL_CMOD="$LUA_INSTALL_CMOD" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$LUAPKGCONFIG\""; } >&5 + ($PKG_CONFIG --exists --print-errors "$LUAPKGCONFIG") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LUA_INSTALL_CMOD=`$PKG_CONFIG --variable="INSTALL_CMOD" "$LUAPKGCONFIG" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + LUA_INSTALL_CMOD=$pkg_cv_LUA_INSTALL_CMOD + if test "x$LUA_INSTALL_CMOD" = x""; then : + LUA_INSTALL_CMOD=$libdir/lua/$LUA_VERSION +fi + if test -n "$LUA_INSTALL_LMOD"; then + pkg_cv_LUA_INSTALL_LMOD="$LUA_INSTALL_LMOD" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$LUAPKGCONFIG\""; } >&5 + ($PKG_CONFIG --exists --print-errors "$LUAPKGCONFIG") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LUA_INSTALL_LMOD=`$PKG_CONFIG --variable="INSTALL_LMOD" "$LUAPKGCONFIG" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + LUA_INSTALL_LMOD=$pkg_cv_LUA_INSTALL_LMOD + if test "x$LUA_INSTALL_LMOD" = x""; then : + LUA_INSTALL_LMOD=$datadir/lua/$LUA_VERSION +fi + +fi + +# Optional test binaries +# Check whether --enable-tests was given. +if test "${enable_tests+set}" = set; then : + enableval=$enable_tests; enable_tests=yes +else + enable_tests=no +fi + + if test "x$enable_tests" = "xyes"; then + ENABLE_TESTS_TRUE= + ENABLE_TESTS_FALSE='#' +else + ENABLE_TESTS_TRUE='#' + ENABLE_TESTS_FALSE= +fi + + +# LXC container path, where the containers are actually stored +# This is overridden by an entry in the file called LXCCONF +# (i.e. /etc/lxc/lxc.conf) + +# Check whether --with-config-path was given. +if test "${with_config_path+set}" = set; then : + withval=$with_config_path; +else + with_config_path='${localstatedir}/lib/lxc' +fi + + +# The path of the global lxc configuration file. + +# Check whether --with-global-conf was given. +if test "${with_global_conf+set}" = set; then : + withval=$with_global_conf; +else + with_global_conf='${sysconfdir}/lxc/lxc.conf' +fi + + + +# Check whether --with-usernic-conf was given. +if test "${with_usernic_conf+set}" = set; then : + withval=$with_usernic_conf; +else + with_usernic_conf='${sysconfdir}/lxc/lxc-usernet' +fi + + + +# Check whether --with-usernic-db was given. +if test "${with_usernic_db+set}" = set; then : + withval=$with_usernic_db; +else + with_usernic_db='/run/lxc/nics' +fi + + +# Rootfs path, where the container mount structure is assembled + +# Check whether --with-rootfs-path was given. +if test "${with_rootfs_path+set}" = set; then : + withval=$with_rootfs_path; +else + with_rootfs_path='${libdir}/lxc/rootfs' +fi + + +# Container log path. By default, use $lxcpath. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking Whether to place logfiles in container config path" >&5 +$as_echo_n "checking Whether to place logfiles in container config path... " >&6; } +# Check whether --enable-configpath-log was given. +if test "${enable_configpath_log+set}" = set; then : + enableval=$enable_configpath_log; use_configpath_logs=yes +else + use_configpath_logs=no +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $use_configpath_logs" >&5 +$as_echo "$use_configpath_logs" >&6; } + if test "$use_configpath_logs" = "yes"; then + USE_CONFIGPATH_LOGS_TRUE= + USE_CONFIGPATH_LOGS_FALSE='#' +else + USE_CONFIGPATH_LOGS_TRUE='#' + USE_CONFIGPATH_LOGS_FALSE= +fi + + +if test "$use_configpath_logs" = "yes"; then + default_log_path="${with_config_path}" +else + default_log_path="${localstatedir}/log/lxc" +fi + + +# Check whether --with-log-path was given. +if test "${with_log_path+set}" = set; then : + withval=$with_log_path; +else + with_log_path='${default_log_path}' +fi + + +# Expand some useful variables + + EXP_VAR=PREFIX + FROM_VAR="$prefix" + + prefix_save=$prefix + exec_prefix_save=$exec_prefix + + if test "x$prefix" = "xNONE"; then + prefix="$ac_default_prefix" + fi + if test "x$exec_prefix" = "xNONE"; then + exec_prefix=$prefix + fi + + full_var="$FROM_VAR" + while true; do + new_full_var="`eval echo $full_var`" + if test "x$new_full_var" = "x$full_var"; then break; fi + full_var=$new_full_var + done + + full_var=$new_full_var + PREFIX="$full_var" + + + prefix=$prefix_save + exec_prefix=$exec_prefix_save + + + EXP_VAR=LIBDIR + FROM_VAR="$libdir" + + prefix_save=$prefix + exec_prefix_save=$exec_prefix + + if test "x$prefix" = "xNONE"; then + prefix="$ac_default_prefix" + fi + if test "x$exec_prefix" = "xNONE"; then + exec_prefix=$prefix + fi + + full_var="$FROM_VAR" + while true; do + new_full_var="`eval echo $full_var`" + if test "x$new_full_var" = "x$full_var"; then break; fi + full_var=$new_full_var + done + + full_var=$new_full_var + LIBDIR="$full_var" + + + prefix=$prefix_save + exec_prefix=$exec_prefix_save + + + EXP_VAR=BINDIR + FROM_VAR="$bindir" + + prefix_save=$prefix + exec_prefix_save=$exec_prefix + + if test "x$prefix" = "xNONE"; then + prefix="$ac_default_prefix" + fi + if test "x$exec_prefix" = "xNONE"; then + exec_prefix=$prefix + fi + + full_var="$FROM_VAR" + while true; do + new_full_var="`eval echo $full_var`" + if test "x$new_full_var" = "x$full_var"; then break; fi + full_var=$new_full_var + done + + full_var=$new_full_var + BINDIR="$full_var" + + + prefix=$prefix_save + exec_prefix=$exec_prefix_save + + + EXP_VAR=LIBEXECDIR + FROM_VAR="$libexecdir" + + prefix_save=$prefix + exec_prefix_save=$exec_prefix + + if test "x$prefix" = "xNONE"; then + prefix="$ac_default_prefix" + fi + if test "x$exec_prefix" = "xNONE"; then + exec_prefix=$prefix + fi + + full_var="$FROM_VAR" + while true; do + new_full_var="`eval echo $full_var`" + if test "x$new_full_var" = "x$full_var"; then break; fi + full_var=$new_full_var + done + + full_var=$new_full_var + LIBEXECDIR="$full_var" + + + prefix=$prefix_save + exec_prefix=$exec_prefix_save + + + EXP_VAR=INCLUDEDIR + FROM_VAR="$includedir" + + prefix_save=$prefix + exec_prefix_save=$exec_prefix + + if test "x$prefix" = "xNONE"; then + prefix="$ac_default_prefix" + fi + if test "x$exec_prefix" = "xNONE"; then + exec_prefix=$prefix + fi + + full_var="$FROM_VAR" + while true; do + new_full_var="`eval echo $full_var`" + if test "x$new_full_var" = "x$full_var"; then break; fi + full_var=$new_full_var + done + + full_var=$new_full_var + INCLUDEDIR="$full_var" + + + prefix=$prefix_save + exec_prefix=$exec_prefix_save + + + EXP_VAR=SYSCONFDIR + FROM_VAR="$sysconfdir" + + prefix_save=$prefix + exec_prefix_save=$exec_prefix + + if test "x$prefix" = "xNONE"; then + prefix="$ac_default_prefix" + fi + if test "x$exec_prefix" = "xNONE"; then + exec_prefix=$prefix + fi + + full_var="$FROM_VAR" + while true; do + new_full_var="`eval echo $full_var`" + if test "x$new_full_var" = "x$full_var"; then break; fi + full_var=$new_full_var + done + + full_var=$new_full_var + SYSCONFDIR="$full_var" + + + prefix=$prefix_save + exec_prefix=$exec_prefix_save + + + EXP_VAR=LXC_DEFAULT_CONFIG + FROM_VAR="$sysconfdir/lxc/default.conf" + + prefix_save=$prefix + exec_prefix_save=$exec_prefix + + if test "x$prefix" = "xNONE"; then + prefix="$ac_default_prefix" + fi + if test "x$exec_prefix" = "xNONE"; then + exec_prefix=$prefix + fi + + full_var="$FROM_VAR" + while true; do + new_full_var="`eval echo $full_var`" + if test "x$new_full_var" = "x$full_var"; then break; fi + full_var=$new_full_var + done + + full_var=$new_full_var + LXC_DEFAULT_CONFIG="$full_var" + + + prefix=$prefix_save + exec_prefix=$exec_prefix_save + + + EXP_VAR=DATADIR + FROM_VAR="$datadir" + + prefix_save=$prefix + exec_prefix_save=$exec_prefix + + if test "x$prefix" = "xNONE"; then + prefix="$ac_default_prefix" + fi + if test "x$exec_prefix" = "xNONE"; then + exec_prefix=$prefix + fi + + full_var="$FROM_VAR" + while true; do + new_full_var="`eval echo $full_var`" + if test "x$new_full_var" = "x$full_var"; then break; fi + full_var=$new_full_var + done + + full_var=$new_full_var + DATADIR="$full_var" + + + prefix=$prefix_save + exec_prefix=$exec_prefix_save + + + EXP_VAR=LOCALSTATEDIR + FROM_VAR="$localstatedir" + + prefix_save=$prefix + exec_prefix_save=$exec_prefix + + if test "x$prefix" = "xNONE"; then + prefix="$ac_default_prefix" + fi + if test "x$exec_prefix" = "xNONE"; then + exec_prefix=$prefix + fi + + full_var="$FROM_VAR" + while true; do + new_full_var="`eval echo $full_var`" + if test "x$new_full_var" = "x$full_var"; then break; fi + full_var=$new_full_var + done + + full_var=$new_full_var + LOCALSTATEDIR="$full_var" - if test "x$enable_examples" = "xyes"; then - ENABLE_EXAMPLES_TRUE= - ENABLE_EXAMPLES_FALSE='#' -else - ENABLE_EXAMPLES_TRUE='#' - ENABLE_EXAMPLES_FALSE= -fi + prefix=$prefix_save + exec_prefix=$exec_prefix_save - EXP_VAR=PREFIX - FROM_VAR=$prefix + EXP_VAR=DOCDIR + FROM_VAR="$docdir" prefix_save=$prefix exec_prefix_save=$exec_prefix @@ -4440,15 +6998,15 @@ done full_var=$new_full_var - PREFIX="$full_var" + DOCDIR="$full_var" prefix=$prefix_save exec_prefix=$exec_prefix_save - EXP_VAR=LIBDIR - FROM_VAR=$libdir + EXP_VAR=LXC_DISTRO_CONF + FROM_VAR="$distroconf" prefix_save=$prefix exec_prefix_save=$exec_prefix @@ -4468,15 +7026,15 @@ done full_var=$new_full_var - LIBDIR="$full_var" + LXC_DISTRO_CONF="$full_var" prefix=$prefix_save exec_prefix=$exec_prefix_save - EXP_VAR=BINDIR - FROM_VAR=$bindir + EXP_VAR=LXC_GENERATE_DATE + FROM_VAR="$(date)" prefix_save=$prefix exec_prefix_save=$exec_prefix @@ -4496,15 +7054,15 @@ done full_var=$new_full_var - BINDIR="$full_var" + LXC_GENERATE_DATE="$full_var" prefix=$prefix_save exec_prefix=$exec_prefix_save - EXP_VAR=INCLUDEDIR - FROM_VAR=$includedir + EXP_VAR=LXCPATH + FROM_VAR="$with_config_path" prefix_save=$prefix exec_prefix_save=$exec_prefix @@ -4524,15 +7082,15 @@ done full_var=$new_full_var - INCLUDEDIR="$full_var" + LXCPATH="$full_var" prefix=$prefix_save exec_prefix=$exec_prefix_save - EXP_VAR=SYSCONFDIR - FROM_VAR=$sysconfdir + EXP_VAR=LXC_GLOBAL_CONF + FROM_VAR="$with_global_conf" prefix_save=$prefix exec_prefix_save=$exec_prefix @@ -4552,15 +7110,15 @@ done full_var=$new_full_var - SYSCONFDIR="$full_var" + LXC_GLOBAL_CONF="$full_var" prefix=$prefix_save exec_prefix=$exec_prefix_save - EXP_VAR=DATADIR - FROM_VAR=$datadir + EXP_VAR=LXC_USERNIC_CONF + FROM_VAR="$with_usernic_conf" prefix_save=$prefix exec_prefix_save=$exec_prefix @@ -4580,15 +7138,15 @@ done full_var=$new_full_var - DATADIR="$full_var" + LXC_USERNIC_CONF="$full_var" prefix=$prefix_save exec_prefix=$exec_prefix_save - EXP_VAR=LOCALSTATEDIR - FROM_VAR=$localstatedir + EXP_VAR=LXC_USERNIC_DB + FROM_VAR="$with_usernic_db" prefix_save=$prefix exec_prefix_save=$exec_prefix @@ -4608,15 +7166,15 @@ done full_var=$new_full_var - LOCALSTATEDIR="$full_var" + LXC_USERNIC_DB="$full_var" prefix=$prefix_save exec_prefix=$exec_prefix_save - EXP_VAR=DOCDIR - FROM_VAR=$docdir + EXP_VAR=LXCROOTFSMOUNT + FROM_VAR="$with_rootfs_path" prefix_save=$prefix exec_prefix_save=$exec_prefix @@ -4636,34 +7194,43 @@ done full_var=$new_full_var - DOCDIR="$full_var" + LXCROOTFSMOUNT="$full_var" prefix=$prefix_save exec_prefix=$exec_prefix_save + EXP_VAR=LXCTEMPLATEDIR + FROM_VAR="$datadir/lxc/templates" -# Check whether --with-config-path was given. -if test "${with_config_path+set}" = set; then : - withval=$with_config_path; -else - with_config_path='${localstatedir}/lib/lxc' -fi + prefix_save=$prefix + exec_prefix_save=$exec_prefix + if test "x$prefix" = "xNONE"; then + prefix="$ac_default_prefix" + fi + if test "x$exec_prefix" = "xNONE"; then + exec_prefix=$prefix + fi + + full_var="$FROM_VAR" + while true; do + new_full_var="`eval echo $full_var`" + if test "x$new_full_var" = "x$full_var"; then break; fi + full_var=$new_full_var + done + full_var=$new_full_var + LXCTEMPLATEDIR="$full_var" -# Check whether --with-rootfs-path was given. -if test "${with_rootfs_path+set}" = set; then : - withval=$with_rootfs_path; -else - with_rootfs_path='${libdir}/lxc/rootfs' -fi + prefix=$prefix_save + exec_prefix=$exec_prefix_save - EXP_VAR=LXC_GENERATE_DATE - FROM_VAR="$(date)" + EXP_VAR=LXCHOOKDIR + FROM_VAR="$datadir/lxc/hooks" prefix_save=$prefix exec_prefix_save=$exec_prefix @@ -4683,63 +7250,366 @@ done full_var=$new_full_var - LXC_GENERATE_DATE="$full_var" + LXCHOOKDIR="$full_var" + + + prefix=$prefix_save + exec_prefix=$exec_prefix_save + + + EXP_VAR=LXCINITDIR + FROM_VAR="$libexecdir" + + prefix_save=$prefix + exec_prefix_save=$exec_prefix + + if test "x$prefix" = "xNONE"; then + prefix="$ac_default_prefix" + fi + if test "x$exec_prefix" = "xNONE"; then + exec_prefix=$prefix + fi + + full_var="$FROM_VAR" + while true; do + new_full_var="`eval echo $full_var`" + if test "x$new_full_var" = "x$full_var"; then break; fi + full_var=$new_full_var + done + + full_var=$new_full_var + LXCINITDIR="$full_var" + + + prefix=$prefix_save + exec_prefix=$exec_prefix_save + + + EXP_VAR=LOGPATH + FROM_VAR="$with_log_path" + + prefix_save=$prefix + exec_prefix_save=$exec_prefix + + if test "x$prefix" = "xNONE"; then + prefix="$ac_default_prefix" + fi + if test "x$exec_prefix" = "xNONE"; then + exec_prefix=$prefix + fi + + full_var="$FROM_VAR" + while true; do + new_full_var="`eval echo $full_var`" + if test "x$new_full_var" = "x$full_var"; then break; fi + full_var=$new_full_var + done + + full_var=$new_full_var + LOGPATH="$full_var" prefix=$prefix_save exec_prefix=$exec_prefix_save -LXCPATH="${with_config_path}" +# Check for some standard kernel headers +for ac_header in linux/unistd.h linux/netlink.h linux/genetlink.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "#include +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +else + as_fn_error $? "Please install the Linux kernel headers." "$LINENO" 5 +fi + +done + + +# Allow disabling libcap support +# Check whether --enable-capabilities was given. +if test "${enable_capabilities+set}" = set; then : + enableval=$enable_capabilities; +else + enable_capabilities=yes +fi + + +# Check for libcap support +if test "x$enable_capabilities" = "xyes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cap_set_proc in -lcap" >&5 +$as_echo_n "checking for cap_set_proc in -lcap... " >&6; } +if ${ac_cv_lib_cap_cap_set_proc+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lcap $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char cap_set_proc (); +int +main () +{ +return cap_set_proc (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_cap_cap_set_proc=yes +else + ac_cv_lib_cap_cap_set_proc=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_cap_cap_set_proc" >&5 +$as_echo "$ac_cv_lib_cap_cap_set_proc" >&6; } +if test "x$ac_cv_lib_cap_cap_set_proc" = xyes; then : + caplib=yes +else + caplib=no +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking linux capabilities" >&5 +$as_echo_n "checking linux capabilities... " >&6; } + if test "x$caplib" = "xyes" ; then + CAP_LIBS="-lcap" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CAP_LIBS" >&5 +$as_echo "$CAP_LIBS" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + as_fn_error $? "You are missing libcap support. If you really want to build without kernel capabilities, use --disable-capabilities" "$LINENO" 5 + fi +else + CAP_LIBS="" +fi + + +# Check for alternate C libraries +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for bionic libc" >&5 +$as_echo_n "checking for bionic libc... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifndef __ANDROID__ +error: Not bionic! +#endif +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + is_bionic=yes +else + is_bionic=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +if test "x$is_bionic" = "xyes"; then + +$as_echo "#define IS_BIONIC 1" >>confdefs.h + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + if test "x$is_bionic" = "xyes"; then + IS_BIONIC_TRUE= + IS_BIONIC_FALSE='#' +else + IS_BIONIC_TRUE='#' + IS_BIONIC_FALSE= +fi + + +# Some systems lack PR_CAPBSET_DROP definition => HAVE_DECL_PR_CAPBSET_DROP +ac_fn_c_check_decl "$LINENO" "PR_CAPBSET_DROP" "ac_cv_have_decl_PR_CAPBSET_DROP" "#include +" +if test "x$ac_cv_have_decl_PR_CAPBSET_DROP" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_PR_CAPBSET_DROP $ac_have_decl +_ACEOF + + +# Check for some headers +for ac_header in sys/signalfd.h pty.h ifaddrs.h sys/capability.h sys/personality.h utmpx.h sys/timerfd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +# Check for some syscalls functions +for ac_func in setns pivot_root sethostname unshare rand_r confstr +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +# Check for some functions +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for openpty in -lutil" >&5 +$as_echo_n "checking for openpty in -lutil... " >&6; } +if ${ac_cv_lib_util_openpty+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lutil $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char openpty (); +int +main () +{ +return openpty (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_util_openpty=yes +else + ac_cv_lib_util_openpty=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_util_openpty" >&5 +$as_echo "$ac_cv_lib_util_openpty" >&6; } +if test "x$ac_cv_lib_util_openpty" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBUTIL 1 +_ACEOF -LXCROOTFSMOUNT="${with_rootfs_path}" + LIBS="-lutil $LIBS" -LXCINITDIR='${libexecdir}/lxc' +fi -LXCTEMPLATEDIR='${libdir}/lxc/templates' +for ac_func in openpty hasmntopt setmntent endmntent +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF +fi +done -for ac_header in linux/netlink.h linux/genetlink.h +for ac_func in getline do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "#include - -" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + ac_fn_c_check_func "$LINENO" "getline" "ac_cv_func_getline" +if test "x$ac_cv_func_getline" = xyes; then : cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +#define HAVE_GETLINE 1 _ACEOF + if true; then + HAVE_GETLINE_TRUE= + HAVE_GETLINE_FALSE='#' +else + HAVE_GETLINE_TRUE='#' + HAVE_GETLINE_FALSE= +fi + +$as_echo "#define HAVE_GETLINE 1" >>confdefs.h + +else + if false; then + HAVE_GETLINE_TRUE= + HAVE_GETLINE_FALSE='#' else - as_fn_error $? "netlink headers not found. Please install the linux kernel headers." "$LINENO" 5 + HAVE_GETLINE_TRUE='#' + HAVE_GETLINE_FALSE= fi +fi done - -for ac_header in sys/capability.h +for ac_func in fgetln do : - ac_fn_c_check_header_compile "$LINENO" "sys/capability.h" "ac_cv_header_sys_capability_h" "#include -#include -" -if test "x$ac_cv_header_sys_capability_h" = xyes; then : + ac_fn_c_check_func "$LINENO" "fgetln" "ac_cv_func_fgetln" +if test "x$ac_cv_func_fgetln" = xyes; then : cat >>confdefs.h <<_ACEOF -#define HAVE_SYS_CAPABILITY_H 1 +#define HAVE_FGETLN 1 _ACEOF + if true; then + HAVE_FGETLN_TRUE= + HAVE_FGETLN_FALSE='#' +else + HAVE_FGETLN_TRUE='#' + HAVE_FGETLN_FALSE= +fi + +$as_echo "#define HAVE_FGETLN 1" >>confdefs.h + +else + if false; then + HAVE_FGETLN_TRUE= + HAVE_FGETLN_FALSE='#' else - as_fn_error $? "please install libcap-devel." "$LINENO" 5 + HAVE_FGETLN_TRUE='#' + HAVE_FGETLN_FALSE= fi +fi done -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for cap_set_proc in -lcap" >&5 -$as_echo_n "checking for cap_set_proc in -lcap... " >&6; } -if ${ac_cv_lib_cap_cap_set_proc+:} false; then : + +# Check for some libraries +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing sem_open" >&5 +$as_echo_n "checking for library containing sem_open... " >&6; } +if ${ac_cv_search_sem_open+:} false; then : $as_echo_n "(cached) " >&6 else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lcap $LIBS" + ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -4749,70 +7619,105 @@ #ifdef __cplusplus extern "C" #endif -char cap_set_proc (); +char sem_open (); int main () { -return cap_set_proc (); +return sem_open (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_cap_cap_set_proc=yes -else - ac_cv_lib_cap_cap_set_proc=no +for ac_lib in '' rt pthread; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_sem_open=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_cap_cap_set_proc" >&5 -$as_echo "$ac_cv_lib_cap_cap_set_proc" >&6; } -if test "x$ac_cv_lib_cap_cap_set_proc" = xyes; then : - caplib=yes -else - caplib=no + conftest$ac_exeext + if ${ac_cv_search_sem_open+:} false; then : + break fi +done +if ${ac_cv_search_sem_open+:} false; then : -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking linux capabilities" >&5 -$as_echo_n "checking linux capabilities... " >&6; } -if test "x$caplib" = "xyes" ; then - CAP_LIBS="-lcap" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CAP_LIBS" >&5 -$as_echo "$CAP_LIBS" >&6; } else - as_fn_error $? "not found" "$LINENO" 5 + ac_cv_search_sem_open=no fi - - -# Some systems lack PR_CAPBSET_DROP definition => HAVE_DECL_PR_CAPBSET_DROP -ac_fn_c_check_decl "$LINENO" "PR_CAPBSET_DROP" "ac_cv_have_decl_PR_CAPBSET_DROP" "#include -" -if test "x$ac_cv_have_decl_PR_CAPBSET_DROP" = xyes; then : - ac_have_decl=1 -else - ac_have_decl=0 +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_sem_open" >&5 +$as_echo "$ac_cv_search_sem_open" >&6; } +ac_res=$ac_cv_search_sem_open +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" -cat >>confdefs.h <<_ACEOF -#define HAVE_DECL_PR_CAPBSET_DROP $ac_have_decl -_ACEOF +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing clock_gettime" >&5 +$as_echo_n "checking for library containing clock_gettime... " >&6; } +if ${ac_cv_search_clock_gettime+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ -for ac_header in sys/signalfd.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "sys/signalfd.h" "ac_cv_header_sys_signalfd_h" "$ac_includes_default" -if test "x$ac_cv_header_sys_signalfd_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_SYS_SIGNALFD_H 1 +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char clock_gettime (); +int +main () +{ +return clock_gettime (); + ; + return 0; +} _ACEOF +for ac_lib in '' rt; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_clock_gettime=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_clock_gettime+:} false; then : + break +fi +done +if ${ac_cv_search_clock_gettime+:} false; then : +else + ac_cv_search_clock_gettime=no fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_clock_gettime" >&5 +$as_echo "$ac_cv_search_clock_gettime" >&6; } +ac_res=$ac_cv_search_clock_gettime +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" -done +fi +# Check for some standard binaries if test $ac_cv_c_compiler_gnu = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC needs -traditional" >&5 $as_echo_n "checking whether $CC needs -traditional... " >&6; } @@ -4855,122 +7760,82 @@ fi fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +$as_echo_n "checking for a sed that does not truncate output... " >&6; } +if ${ac_cv_path_SED+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + { ac_script=; unset ac_script;} + if test -z "$SED"; then + ac_path_SED_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_SED" || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac - - - -# Check whether --with-linuxdir was given. -if test "${with_linuxdir+set}" = set; then : - withval=$with_linuxdir; LINUX_DIR="${withval}" + $ac_path_SED_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_SED"; then + as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 + fi else - LINUX_DIR=default + ac_cv_path_SED=$SED fi - - if test "${LINUX_DIR}" != "default" ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Linux in ${LINUX_DIR}" >&5 -$as_echo_n "checking for Linux in ${LINUX_DIR}... " >&6; } - - if test -f "${LINUX_DIR}/Makefile" ; then - result=yes - - else - result="not found" - as_fn_error $? "Linux dir not found" "$LINENO" 5 - fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $result" >&5 -$as_echo "$result" >&6; } - - fi - - if test "${LINUX_DIR}" = "default" ; then - dir="/lib/modules/$LINUX_KERNEL_RELEASE/build"; - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Linux in ${dir}" >&5 -$as_echo_n "checking for Linux in ${dir}... " >&6; } - - if test -f "${dir}/Makefile" ; then - result=yes - LINUX_DIR=${dir} - else - result="not found" - - fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $result" >&5 -$as_echo "$result" >&6; } - - fi - - if test "${LINUX_DIR}" = "default" ; then - dir="/usr/src/linux-$LINUX_KERNEL_RELEASE"; - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Linux in ${dir}" >&5 -$as_echo_n "checking for Linux in ${dir}... " >&6; } - - if test -f "${dir}/Makefile" ; then - result=yes - LINUX_DIR=${dir} - else - result="not found" - - fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $result" >&5 -$as_echo "$result" >&6; } - - fi - - if test "${LINUX_DIR}" = "default" ; then - dir="/usr/src/linux"; - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Linux in ${dir}" >&5 -$as_echo_n "checking for Linux in ${dir}... " >&6; } - - if test -f "${dir}/Makefile" ; then - result=yes - LINUX_DIR=${dir} - else - result="not found" - - fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $result" >&5 -$as_echo "$result" >&6; } - - fi - - if test "${LINUX_DIR}" = "default" ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Linux source directory not found" >&5 -$as_echo "$as_me: WARNING: Linux source directory not found" >&2;} - fi - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for linux SRCARCH" >&5 -$as_echo_n "checking for linux SRCARCH... " >&6; } - - case "${host}" in - i[3456]86-*) LINUX_SRCARCH=x86;; - x86_64-*) LINUX_SRCARCH=x86;; - powerpc*-*) LINUX_SRCARCH=powerpc;; - s390*-*) LINUX_SRCARCH=s390;; - arm*-*) LINUX_SRCARCH=arm;; - mips*-*) LINUX_SRCARCH=mips;; - sparc*-*) LINUX_SRCARCH=sparc;; - *) as_fn_error $? "architecture ${host} not supported" "$LINENO" 5;; - esac - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${LINUX_SRCARCH}" >&5 -$as_echo "${LINUX_SRCARCH}" >&6; } - - +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +$as_echo "$ac_cv_path_SED" >&6; } + SED="$ac_cv_path_SED" + rm -f conftest.sed if test "x$GCC" = "xyes"; then - CFLAGS="$CFLAGS -Wall" + CFLAGS="$CFLAGS -Wall -Werror" fi -ac_config_files="$ac_config_files Makefile lxc.pc lxc.spec config/Makefile doc/Makefile doc/lxc-create.sgml doc/lxc-destroy.sgml doc/lxc-execute.sgml doc/lxc-start.sgml doc/lxc-checkpoint.sgml doc/lxc-restart.sgml doc/lxc-stop.sgml doc/lxc-console.sgml doc/lxc-freeze.sgml doc/lxc-unfreeze.sgml doc/lxc-monitor.sgml doc/lxc-wait.sgml doc/lxc-ls.sgml doc/lxc-ps.sgml doc/lxc-cgroup.sgml doc/lxc-kill.sgml doc/lxc-attach.sgml doc/lxc.conf.sgml doc/lxc.sgml doc/common_options.sgml doc/see_also.sgml doc/rootfs/Makefile doc/examples/Makefile doc/examples/lxc-macvlan.conf doc/examples/lxc-vlan.conf doc/examples/lxc-no-netns.conf doc/examples/lxc-empty-netns.conf doc/examples/lxc-phys.conf doc/examples/lxc-veth.conf doc/examples/lxc-complex.conf templates/Makefile templates/lxc-lenny templates/lxc-debian templates/lxc-ubuntu templates/lxc-ubuntu-cloud templates/lxc-opensuse templates/lxc-busybox templates/lxc-fedora templates/lxc-altlinux templates/lxc-sshd templates/lxc-archlinux src/Makefile src/lxc/Makefile src/lxc/lxc-ps src/lxc/lxc-ls src/lxc/lxc-netstat src/lxc/lxc-checkconfig src/lxc/lxc-setcap src/lxc/lxc-setuid src/lxc/lxc-version src/lxc/lxc-create src/lxc/lxc-clone src/lxc/lxc-destroy" +# Files requiring some variable expansion +ac_config_files="$ac_config_files Makefile lxc.pc lxc.spec config/Makefile doc/Makefile doc/legacy/lxc-ls.sgml doc/lxc-attach.sgml doc/lxc-cgroup.sgml doc/lxc-checkconfig.sgml doc/lxc-checkpoint.sgml doc/lxc-clone.sgml doc/lxc-console.sgml doc/lxc-create.sgml doc/lxc-destroy.sgml doc/lxc-device.sgml doc/lxc-execute.sgml doc/lxc-freeze.sgml doc/lxc-info.sgml doc/lxc-kill.sgml doc/lxc-ls.sgml doc/lxc-monitor.sgml doc/lxc-netstat.sgml doc/lxc-ps.sgml doc/lxc-restart.sgml doc/lxc-start-ephemeral.sgml doc/lxc-start.sgml doc/lxc-stop.sgml doc/lxc-top.sgml doc/lxc-unfreeze.sgml doc/lxc-unshare.sgml doc/lxc-version.sgml doc/lxc-wait.sgml doc/lxc.conf.sgml doc/lxc.sgml doc/common_options.sgml doc/see_also.sgml doc/rootfs/Makefile doc/examples/Makefile doc/examples/lxc-macvlan.conf doc/examples/lxc-vlan.conf doc/examples/lxc-no-netns.conf doc/examples/lxc-empty-netns.conf doc/examples/lxc-phys.conf doc/examples/lxc-veth.conf doc/examples/lxc-complex.conf hooks/Makefile templates/Makefile templates/lxc-cirros templates/lxc-debian templates/lxc-ubuntu templates/lxc-ubuntu-cloud templates/lxc-opensuse templates/lxc-busybox templates/lxc-fedora templates/lxc-oracle templates/lxc-altlinux templates/lxc-sshd templates/lxc-archlinux templates/lxc-alpine src/Makefile src/lxc/Makefile src/lxc/lxc-ps src/lxc/lxc-netstat src/lxc/lxc-checkconfig src/lxc/lxc-version src/lxc/lxc-start-ephemeral src/lxc/legacy/lxc-ls src/lxc/lxc.functions src/python-lxc/Makefile src/lua-lxc/Makefile src/tests/Makefile" ac_config_commands="$ac_config_commands default" @@ -5083,6 +7948,14 @@ LTLIBOBJS=$ac_ltlibobjs +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 +$as_echo_n "checking that generated files are newer than configure... " >&6; } + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 +$as_echo "done" >&6; } if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' @@ -5099,6 +7972,14 @@ as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${HAVE_DEBIAN_TRUE}" && test -z "${HAVE_DEBIAN_FALSE}"; then + as_fn_error $? "conditional \"HAVE_DEBIAN\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_NEWUIDMAP_TRUE}" && test -z "${HAVE_NEWUIDMAP_FALSE}"; then + as_fn_error $? "conditional \"HAVE_NEWUIDMAP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${ENABLE_RPATH_TRUE}" && test -z "${ENABLE_RPATH_FALSE}"; then as_fn_error $? "conditional \"ENABLE_RPATH\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -5107,10 +7988,54 @@ as_fn_error $? "conditional \"ENABLE_DOCBOOK\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${ENABLE_APPARMOR_TRUE}" && test -z "${ENABLE_APPARMOR_FALSE}"; then + as_fn_error $? "conditional \"ENABLE_APPARMOR\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${ENABLE_SECCOMP_TRUE}" && test -z "${ENABLE_SECCOMP_FALSE}"; then + as_fn_error $? "conditional \"ENABLE_SECCOMP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${ENABLE_EXAMPLES_TRUE}" && test -z "${ENABLE_EXAMPLES_FALSE}"; then as_fn_error $? "conditional \"ENABLE_EXAMPLES\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${ENABLE_PYTHON_TRUE}" && test -z "${ENABLE_PYTHON_FALSE}"; then + as_fn_error $? "conditional \"ENABLE_PYTHON\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${ENABLE_LUA_TRUE}" && test -z "${ENABLE_LUA_FALSE}"; then + as_fn_error $? "conditional \"ENABLE_LUA\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${ENABLE_TESTS_TRUE}" && test -z "${ENABLE_TESTS_FALSE}"; then + as_fn_error $? "conditional \"ENABLE_TESTS\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${USE_CONFIGPATH_LOGS_TRUE}" && test -z "${USE_CONFIGPATH_LOGS_FALSE}"; then + as_fn_error $? "conditional \"USE_CONFIGPATH_LOGS\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${IS_BIONIC_TRUE}" && test -z "${IS_BIONIC_FALSE}"; then + as_fn_error $? "conditional \"IS_BIONIC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_GETLINE_TRUE}" && test -z "${HAVE_GETLINE_FALSE}"; then + as_fn_error $? "conditional \"HAVE_GETLINE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_GETLINE_TRUE}" && test -z "${HAVE_GETLINE_FALSE}"; then + as_fn_error $? "conditional \"HAVE_GETLINE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_FGETLN_TRUE}" && test -z "${HAVE_FGETLN_FALSE}"; then + as_fn_error $? "conditional \"HAVE_FGETLN\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_FGETLN_TRUE}" && test -z "${HAVE_FGETLN_FALSE}"; then + as_fn_error $? "conditional \"HAVE_FGETLN\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 @@ -5409,16 +8334,16 @@ # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -p'. + # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -p' + as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else - as_ln_s='cp -p' + as_ln_s='cp -pR' fi else - as_ln_s='cp -p' + as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null @@ -5478,28 +8403,16 @@ as_mkdir_p=false fi -if test -x / >/dev/null 2>&1; then - as_test_x='test -x' -else - if ls -dL / >/dev/null 2>&1; then - as_ls_L_option=L - else - as_ls_L_option= - fi - as_test_x=' - eval sh -c '\'' - if test -d "$1"; then - test -d "$1/."; - else - case $1 in #( - -*)set "./$1";; - esac; - case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( - ???[sx]*):;;*)false;;esac;fi - '\'' sh - ' -fi -as_executable_p=$as_test_x + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" @@ -5520,8 +8433,8 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by lxc $as_me 0.8.0-rc1, which was -generated by GNU Autoconf 2.68. Invocation command line was +This file was extended by lxc $as_me 1.0.0.alpha1, which was +generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS @@ -5586,11 +8499,11 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -lxc config.status 0.8.0-rc1 -configured by $0, generated by GNU Autoconf 2.68, +lxc config.status 1.0.0.alpha1 +configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" -Copyright (C) 2010 Free Software Foundation, Inc. +Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." @@ -5681,7 +8594,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then - set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' @@ -5723,23 +8636,33 @@ "lxc.spec") CONFIG_FILES="$CONFIG_FILES lxc.spec" ;; "config/Makefile") CONFIG_FILES="$CONFIG_FILES config/Makefile" ;; "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; + "doc/legacy/lxc-ls.sgml") CONFIG_FILES="$CONFIG_FILES doc/legacy/lxc-ls.sgml" ;; + "doc/lxc-attach.sgml") CONFIG_FILES="$CONFIG_FILES doc/lxc-attach.sgml" ;; + "doc/lxc-cgroup.sgml") CONFIG_FILES="$CONFIG_FILES doc/lxc-cgroup.sgml" ;; + "doc/lxc-checkconfig.sgml") CONFIG_FILES="$CONFIG_FILES doc/lxc-checkconfig.sgml" ;; + "doc/lxc-checkpoint.sgml") CONFIG_FILES="$CONFIG_FILES doc/lxc-checkpoint.sgml" ;; + "doc/lxc-clone.sgml") CONFIG_FILES="$CONFIG_FILES doc/lxc-clone.sgml" ;; + "doc/lxc-console.sgml") CONFIG_FILES="$CONFIG_FILES doc/lxc-console.sgml" ;; "doc/lxc-create.sgml") CONFIG_FILES="$CONFIG_FILES doc/lxc-create.sgml" ;; "doc/lxc-destroy.sgml") CONFIG_FILES="$CONFIG_FILES doc/lxc-destroy.sgml" ;; + "doc/lxc-device.sgml") CONFIG_FILES="$CONFIG_FILES doc/lxc-device.sgml" ;; "doc/lxc-execute.sgml") CONFIG_FILES="$CONFIG_FILES doc/lxc-execute.sgml" ;; - "doc/lxc-start.sgml") CONFIG_FILES="$CONFIG_FILES doc/lxc-start.sgml" ;; - "doc/lxc-checkpoint.sgml") CONFIG_FILES="$CONFIG_FILES doc/lxc-checkpoint.sgml" ;; + "doc/lxc-freeze.sgml") CONFIG_FILES="$CONFIG_FILES doc/lxc-freeze.sgml" ;; + "doc/lxc-info.sgml") CONFIG_FILES="$CONFIG_FILES doc/lxc-info.sgml" ;; + "doc/lxc-kill.sgml") CONFIG_FILES="$CONFIG_FILES doc/lxc-kill.sgml" ;; + "doc/lxc-ls.sgml") CONFIG_FILES="$CONFIG_FILES doc/lxc-ls.sgml" ;; + "doc/lxc-monitor.sgml") CONFIG_FILES="$CONFIG_FILES doc/lxc-monitor.sgml" ;; + "doc/lxc-netstat.sgml") CONFIG_FILES="$CONFIG_FILES doc/lxc-netstat.sgml" ;; + "doc/lxc-ps.sgml") CONFIG_FILES="$CONFIG_FILES doc/lxc-ps.sgml" ;; "doc/lxc-restart.sgml") CONFIG_FILES="$CONFIG_FILES doc/lxc-restart.sgml" ;; + "doc/lxc-start-ephemeral.sgml") CONFIG_FILES="$CONFIG_FILES doc/lxc-start-ephemeral.sgml" ;; + "doc/lxc-start.sgml") CONFIG_FILES="$CONFIG_FILES doc/lxc-start.sgml" ;; "doc/lxc-stop.sgml") CONFIG_FILES="$CONFIG_FILES doc/lxc-stop.sgml" ;; - "doc/lxc-console.sgml") CONFIG_FILES="$CONFIG_FILES doc/lxc-console.sgml" ;; - "doc/lxc-freeze.sgml") CONFIG_FILES="$CONFIG_FILES doc/lxc-freeze.sgml" ;; + "doc/lxc-top.sgml") CONFIG_FILES="$CONFIG_FILES doc/lxc-top.sgml" ;; "doc/lxc-unfreeze.sgml") CONFIG_FILES="$CONFIG_FILES doc/lxc-unfreeze.sgml" ;; - "doc/lxc-monitor.sgml") CONFIG_FILES="$CONFIG_FILES doc/lxc-monitor.sgml" ;; + "doc/lxc-unshare.sgml") CONFIG_FILES="$CONFIG_FILES doc/lxc-unshare.sgml" ;; + "doc/lxc-version.sgml") CONFIG_FILES="$CONFIG_FILES doc/lxc-version.sgml" ;; "doc/lxc-wait.sgml") CONFIG_FILES="$CONFIG_FILES doc/lxc-wait.sgml" ;; - "doc/lxc-ls.sgml") CONFIG_FILES="$CONFIG_FILES doc/lxc-ls.sgml" ;; - "doc/lxc-ps.sgml") CONFIG_FILES="$CONFIG_FILES doc/lxc-ps.sgml" ;; - "doc/lxc-cgroup.sgml") CONFIG_FILES="$CONFIG_FILES doc/lxc-cgroup.sgml" ;; - "doc/lxc-kill.sgml") CONFIG_FILES="$CONFIG_FILES doc/lxc-kill.sgml" ;; - "doc/lxc-attach.sgml") CONFIG_FILES="$CONFIG_FILES doc/lxc-attach.sgml" ;; "doc/lxc.conf.sgml") CONFIG_FILES="$CONFIG_FILES doc/lxc.conf.sgml" ;; "doc/lxc.sgml") CONFIG_FILES="$CONFIG_FILES doc/lxc.sgml" ;; "doc/common_options.sgml") CONFIG_FILES="$CONFIG_FILES doc/common_options.sgml" ;; @@ -5753,29 +8676,32 @@ "doc/examples/lxc-phys.conf") CONFIG_FILES="$CONFIG_FILES doc/examples/lxc-phys.conf" ;; "doc/examples/lxc-veth.conf") CONFIG_FILES="$CONFIG_FILES doc/examples/lxc-veth.conf" ;; "doc/examples/lxc-complex.conf") CONFIG_FILES="$CONFIG_FILES doc/examples/lxc-complex.conf" ;; + "hooks/Makefile") CONFIG_FILES="$CONFIG_FILES hooks/Makefile" ;; "templates/Makefile") CONFIG_FILES="$CONFIG_FILES templates/Makefile" ;; - "templates/lxc-lenny") CONFIG_FILES="$CONFIG_FILES templates/lxc-lenny" ;; + "templates/lxc-cirros") CONFIG_FILES="$CONFIG_FILES templates/lxc-cirros" ;; "templates/lxc-debian") CONFIG_FILES="$CONFIG_FILES templates/lxc-debian" ;; "templates/lxc-ubuntu") CONFIG_FILES="$CONFIG_FILES templates/lxc-ubuntu" ;; "templates/lxc-ubuntu-cloud") CONFIG_FILES="$CONFIG_FILES templates/lxc-ubuntu-cloud" ;; "templates/lxc-opensuse") CONFIG_FILES="$CONFIG_FILES templates/lxc-opensuse" ;; "templates/lxc-busybox") CONFIG_FILES="$CONFIG_FILES templates/lxc-busybox" ;; "templates/lxc-fedora") CONFIG_FILES="$CONFIG_FILES templates/lxc-fedora" ;; + "templates/lxc-oracle") CONFIG_FILES="$CONFIG_FILES templates/lxc-oracle" ;; "templates/lxc-altlinux") CONFIG_FILES="$CONFIG_FILES templates/lxc-altlinux" ;; "templates/lxc-sshd") CONFIG_FILES="$CONFIG_FILES templates/lxc-sshd" ;; "templates/lxc-archlinux") CONFIG_FILES="$CONFIG_FILES templates/lxc-archlinux" ;; + "templates/lxc-alpine") CONFIG_FILES="$CONFIG_FILES templates/lxc-alpine" ;; "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; "src/lxc/Makefile") CONFIG_FILES="$CONFIG_FILES src/lxc/Makefile" ;; "src/lxc/lxc-ps") CONFIG_FILES="$CONFIG_FILES src/lxc/lxc-ps" ;; - "src/lxc/lxc-ls") CONFIG_FILES="$CONFIG_FILES src/lxc/lxc-ls" ;; "src/lxc/lxc-netstat") CONFIG_FILES="$CONFIG_FILES src/lxc/lxc-netstat" ;; "src/lxc/lxc-checkconfig") CONFIG_FILES="$CONFIG_FILES src/lxc/lxc-checkconfig" ;; - "src/lxc/lxc-setcap") CONFIG_FILES="$CONFIG_FILES src/lxc/lxc-setcap" ;; - "src/lxc/lxc-setuid") CONFIG_FILES="$CONFIG_FILES src/lxc/lxc-setuid" ;; "src/lxc/lxc-version") CONFIG_FILES="$CONFIG_FILES src/lxc/lxc-version" ;; - "src/lxc/lxc-create") CONFIG_FILES="$CONFIG_FILES src/lxc/lxc-create" ;; - "src/lxc/lxc-clone") CONFIG_FILES="$CONFIG_FILES src/lxc/lxc-clone" ;; - "src/lxc/lxc-destroy") CONFIG_FILES="$CONFIG_FILES src/lxc/lxc-destroy" ;; + "src/lxc/lxc-start-ephemeral") CONFIG_FILES="$CONFIG_FILES src/lxc/lxc-start-ephemeral" ;; + "src/lxc/legacy/lxc-ls") CONFIG_FILES="$CONFIG_FILES src/lxc/legacy/lxc-ls" ;; + "src/lxc/lxc.functions") CONFIG_FILES="$CONFIG_FILES src/lxc/lxc.functions" ;; + "src/python-lxc/Makefile") CONFIG_FILES="$CONFIG_FILES src/python-lxc/Makefile" ;; + "src/lua-lxc/Makefile") CONFIG_FILES="$CONFIG_FILES src/lua-lxc/Makefile" ;; + "src/tests/Makefile") CONFIG_FILES="$CONFIG_FILES src/tests/Makefile" ;; "default") CONFIG_COMMANDS="$CONFIG_COMMANDS default" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; @@ -6373,7 +9299,7 @@ case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || { - # Autoconf 2.62 quotes --file arguments for eval, but not when files + # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in @@ -6386,7 +9312,7 @@ # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named `Makefile.in', but + # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. @@ -6420,21 +9346,19 @@ continue fi # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running `make'. + # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "am__include" && continue + test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # When using ansi2knr, U may be empty or an underscore; expand it - U=`sed -n 's/^U = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`$as_dirname -- "$file" || @@ -6506,50 +9430,3 @@ $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi - -if test "x$SETCAP" = "xno"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: - -Warning: --------- - -The setcap binary was not found. This means the tools to set the -privilege for the lxc commands are not available, that's ok, but you -will need to run these commands as root or install libcap-2. - -" >&5 -$as_echo "$as_me: - -Warning: --------- - -The setcap binary was not found. This means the tools to set the -privilege for the lxc commands are not available, that's ok, but you -will need to run these commands as root or install libcap-2. - -" >&6;} - -else - - { $as_echo "$as_me:${as_lineno-$LINENO}: - -Advice: -------- - -If you wish to have a non root user to use the lxc tools, -you can add the needed capabilities to the tools by invoking -the 'lxc-setcap' script. To remove the capabilities, use -'lxc-setcap -d'. -" >&5 -$as_echo "$as_me: - -Advice: -------- - -If you wish to have a non root user to use the lxc tools, -you can add the needed capabilities to the tools by invoking -the 'lxc-setcap' script. To remove the capabilities, use -'lxc-setcap -d'. -" >&6;} - -fi diff -Nru lxc-0.8.0~rc1/configure.ac lxc-1.0.0~alpha1/configure.ac --- lxc-0.8.0~rc1/configure.ac 2012-03-01 23:03:10.000000000 +0000 +++ lxc-1.0.0~alpha1/configure.ac 2013-09-10 22:22:00.000000000 +0000 @@ -1,102 +1,386 @@ # -*- Autoconf -*- # Process this file with autoconf to produce a configure script. -AC_INIT([lxc], [0.8.0-rc1]) +AC_INIT([lxc], [1.0.0.alpha1]) AC_CONFIG_SRCDIR([configure.ac]) AC_CONFIG_AUX_DIR([config]) -AM_CONFIG_HEADER([src/config.h]) -AM_INIT_AUTOMAKE([-Wno-portability]) +AC_CONFIG_HEADERS([src/config.h]) +AM_INIT_AUTOMAKE([-Wall -Werror -Wno-portability subdir-objects]) AC_CANONICAL_HOST AM_PROG_CC_C_O AC_GNU_SOURCE -AC_CHECK_PROG(SETCAP, setcap, yes, no, $PATH$PATH_SEPARATOR/sbin) +# Detect the distribution. This is used for the default configuration and +# for some distro-specific build options. +AC_MSG_CHECKING([host distribution]) +AC_ARG_WITH(distro, AS_HELP_STRING([--with-distro=DISTRO], [Specify the Linux distribution to target: One of redhat, oracle, fedora, suse, gentoo, debian, arch, slackware, paldo, mandriva or pardus.])) +if test "z$with_distro" = "z"; then + with_distro=`lsb_release -is` +fi +if test "z$with_distro" = "z"; then + AC_CHECK_FILE(/etc/redhat-release,with_distro="redhat") + AC_CHECK_FILE(/etc/oracle-release,with_distro="oracle") + AC_CHECK_FILE(/etc/fedora-release,with_distro="fedora") + AC_CHECK_FILE(/etc/SuSE-release,with_distro="suse") + AC_CHECK_FILE(/etc/gentoo-release,with_distro="gentoo") + AC_CHECK_FILE(/etc/debian_version,with_distro="debian") + AC_CHECK_FILE(/etc/arch-release,with_distro="arch") + AC_CHECK_FILE(/etc/slackware-version,with_distro="slackware") + AC_CHECK_FILE(/etc/frugalware-release,with_distro="frugalware") + AC_CHECK_FILE(/etc/mandrakelinux-release, with_distro="mandriva") + AC_CHECK_FILE(/etc/mandriva-release,with_distro="mandriva") + AC_CHECK_FILE(/etc/pardus-release,with_distro="pardus") +fi +with_distro=`echo ${with_distro} | tr '[[:upper:]]' '[[:lower:]]'` + +if test "z$with_distro" = "z"; then + with_distro="unknown" +fi +case $with_distro in + ubuntu) + distroconf=default.conf.ubuntu + ;; + redhat|fedora|oracle|oracleserver) + distroconf=default.conf.libvirt + ;; + *) + echo -n "Linux distribution network config unknown, defaulting to lxc.network.type = empty" + distroconf=default.conf.unknown + ;; +esac +AC_MSG_RESULT([$with_distro]) +AM_CONDITIONAL([HAVE_DEBIAN], [test x"$with_distro" = "xdebian" -o x"$with_distro" = "xubuntu"]) + +AC_CHECK_PROG([NEWUIDMAP], [newuidmap], [newuidmap]) +AM_CONDITIONAL([HAVE_NEWUIDMAP], [test -n "$NEWUIDMAP"]) + +# Allow disabling rpath AC_ARG_ENABLE([rpath], [AC_HELP_STRING([--disable-rpath], [do not set rpath in executables])], [], [enable_rpath=yes]) - AM_CONDITIONAL([ENABLE_RPATH], [test "x$enable_rpath" = "xyes"]) +# Documentation (manpages) AC_ARG_ENABLE([doc], - [AC_HELP_STRING([--enable-doc], [make mans (require docbook2man installed) [default=auto]])], + [AC_HELP_STRING([--enable-doc], [make mans (requires docbook2man or docbook2x-man to be installed) [default=auto]])], [], [enable_doc=auto]) if test "x$enable_doc" = "xyes" -o "x$enable_doc" = "xauto"; then - AC_CHECK_PROG(have_docbook, [docbook2man], [yes], [no]) + db2xman="" + dbparsers="docbook2x-man db2x_docbook2man docbook2man" + + AC_MSG_CHECKING(for docbook2x-man) + for name in ${dbparsers}; do + if "$name" --help >/dev/null 2>&1; then + db2xman="$name" + break; + fi + done + + if test -n "${db2xman}"; then + AC_MSG_RESULT([${db2xman}]) + else + AC_MSG_RESULT([no]) + if test "x$enable_doc" = "xyes"; then + AC_MSG_ERROR([docbook2x-man required by man request, but not found]) + fi + fi + + AC_SUBST(db2xman) +fi +AM_CONDITIONAL([ENABLE_DOCBOOK], [test "x$db2xman" != "x"]) + +if test "x$db2xman" = "xdocbook2man"; then + docdtd="\"-//Davenport//DTD DocBook V3.0//EN\"" +else + docdtd="\"-//OASIS//DTD DocBook XML\" \"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd\"" +fi +AC_SUBST(docdtd) + +# Apparmor +AC_ARG_ENABLE([apparmor], + [AC_HELP_STRING([--enable-apparmor], [enable apparmor])], + [], [enable_apparmor=check]) - test "x$have_docbook" = "xno" -a "x$enable_doc" = "xyes" && \ - AC_MSG_ERROR([docbook2man required by man request, but not found]) +if test "$enable_apparmor" = "check" ; then + AC_CHECK_LIB([apparmor],[aa_change_profile],[enable_apparmor=yes], [enable_apparmor=no]) fi +AM_CONDITIONAL([ENABLE_APPARMOR], [test "x$enable_apparmor" = "xyes"]) -AM_CONDITIONAL([ENABLE_DOCBOOK], [test "x$have_docbook" = "xyes"]) +AC_CHECK_LIB([gnutls], [gnutls_hash_fast]) + +AM_COND_IF([ENABLE_APPARMOR], + [AC_CHECK_HEADER([sys/apparmor.h],[],[AC_MSG_ERROR([You must install the AppArmor development package in order to compile lxc])]) + AC_CHECK_LIB([apparmor], [aa_change_profile],[],[AC_MSG_ERROR([You must install the AppArmor development package in order to compile lxc])]) + AC_SUBST([APPARMOR_LIBS], [-lapparmor])]) + +# Seccomp syscall filter +AC_ARG_ENABLE([seccomp], + [AC_HELP_STRING([--enable-seccomp], [enable seccomp])], + [], [enable_seccomp=check]) + +if test "$enable_seccomp" = "check" ; then + AC_CHECK_LIB([seccomp],[seccomp_init],[enable_seccomp=yes],[enable_seccomp=no]) +fi +AM_CONDITIONAL([ENABLE_SECCOMP], [test "x$enable_seccomp" = "xyes"]) +AM_COND_IF([ENABLE_SECCOMP], + [AC_CHECK_HEADER([seccomp.h],[],[AC_MSG_ERROR([You must install the seccomp development package in order to compile lxc])]) + AC_CHECK_LIB([seccomp], [seccomp_init],[],[AC_MSG_ERROR([You must install the seccomp development package in order to compile lxc])]) + AC_SUBST([SECCOMP_LIBS], [-lseccomp])]) + +# HAVE_SCMP_FILTER_CTX=1 will tell us we have libseccomp api >= 1.0.0 +AC_CHECK_TYPES([scmp_filter_ctx], [], [], [#include ]) + +# Configuration examples AC_ARG_ENABLE([examples], [AC_HELP_STRING([--disable-examples], [do not install configuration examples])], [], [enable_examples=yes]) - AM_CONDITIONAL([ENABLE_EXAMPLES], [test "x$enable_examples" = "xyes"]) -AS_AC_EXPAND(PREFIX, $prefix) -AS_AC_EXPAND(LIBDIR, $libdir) -AS_AC_EXPAND(BINDIR, $bindir) -AS_AC_EXPAND(INCLUDEDIR, $includedir) -AS_AC_EXPAND(SYSCONFDIR, $sysconfdir) -AS_AC_EXPAND(DATADIR, $datadir) -AS_AC_EXPAND(LOCALSTATEDIR, $localstatedir) -AS_AC_EXPAND(DOCDIR, $docdir) +# Python3 module and scripts +AC_ARG_ENABLE([python], + [AC_HELP_STRING([--enable-python], [enable python binding])], + [enable_python=yes], [enable_python=no]) +AM_CONDITIONAL([ENABLE_PYTHON], [test "x$enable_python" = "xyes"]) + +AM_COND_IF([ENABLE_PYTHON], + [AM_PATH_PYTHON([3.2], [], [AC_MSG_ERROR([You must install python3])]) + PKG_CHECK_MODULES([PYTHONDEV], [python3 >= 3.2],[],[AC_MSG_ERROR([You must install python3-dev])]) + AC_DEFINE_UNQUOTED([ENABLE_PYTHON], 1, [Python3 is available])]) + +# Not in older autoconf versions +# AS_VAR_COPY(DEST, SOURCE) +# ------------------------- +# Set the polymorphic shell variable DEST to the contents of the polymorphic +# shell variable SOURCE. +m4_ifdef([AS_VAR_COPY], [], +[AC_DEFUN([AS_VAR_COPY], + [AS_LITERAL_IF([$1[]$2], [$1=$$2], [eval $1=\$$2])]) +]) +dnl PKG_CHECK_VAR was introduced with pkg-config 0.28 +m4_ifdef([PKG_CHECK_VAR], [], +[AC_DEFUN([PKG_CHECK_VAR], + [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl + AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl + _PKG_CONFIG([$1], [variable="][$3]["], [$2]) + AS_VAR_COPY([$1], [pkg_cv_][$1]) + AS_VAR_IF([$1], [""], [$5], [$4])dnl + ])# PKG_CHECK_VAR +]) + +# Lua module and scripts +AC_ARG_ENABLE([lua], + [AC_HELP_STRING([--enable-lua], [enable lua binding])], + [], [enable_lua=check]) + +AC_ARG_WITH([lua-pc], + [AS_HELP_STRING( + [--with-lua-pc=PKG], + [Specify pkg-config package name for lua] + )], [], [with_lua_pc=no]) + +if test "x$enable_lua" = "xyes" -a "x$with_lua_pc" != "xno"; then + # exit with error if not found + PKG_CHECK_MODULES([LUA], [$with_lua_pc], [LUAPKGCONFIG=$with_lua_pc]) +fi + +if test "x$enable_lua" = "xcheck" -a "x$with_lua_pc" != "xno"; then + PKG_CHECK_MODULES([LUA], [$with_lua_pc], + [LUAPKGCONFIG=$with_lua_pc + enable_lua=yes], + [enable_lua=no]) +fi + +if test "x$enable_lua" != "xno"; then + PKG_CHECK_MODULES([LUA], [lua], [LUAPKGCONFIG=lua], + [PKG_CHECK_MODULES([LUA], [lua5.2], [LUAPKGCONFIG=lua5.2], + [PKG_CHECK_MODULES([LUA], [lua5.1], [LUAPKGCONFIG=lua5.1], + [AS_IF([test "x$enable_lua" = "xyes"], + [AC_MSG_ERROR([Lua not found. Please use --with-lua-pc=PKG])], + [enable_lua=no])] + )] + )]) + AS_IF([test "x$LUAPKGCONFIG" != "x"], [enable_lua=yes]) +fi + +AM_CONDITIONAL([ENABLE_LUA], + [test "x$enable_lua" = "xyes"]) + +AM_COND_IF([ENABLE_LUA], + [AC_MSG_CHECKING([Lua version]) + PKG_CHECK_VAR([LUA_VERSION], [$LUAPKGCONFIG], [V],, + [PKG_CHECK_VAR([LUA_VERSION], [$LUAPKGCONFIG], [major_version])]) + AC_MSG_RESULT([$LUA_VERSION]) + PKG_CHECK_VAR([LUA_INSTALL_CMOD], [$LUAPKGCONFIG], [INSTALL_CMOD],, + [LUA_INSTALL_CMOD=$libdir/lua/$LUA_VERSION]) + PKG_CHECK_VAR([LUA_INSTALL_LMOD], [$LUAPKGCONFIG], [INSTALL_LMOD],, + [LUA_INSTALL_LMOD=$datadir/lua/$LUA_VERSION]) + ]) + +# Optional test binaries +AC_ARG_ENABLE([tests], + [AC_HELP_STRING([--enable-tests], [build test/example binaries])], + [enable_tests=yes], [enable_tests=no]) +AM_CONDITIONAL([ENABLE_TESTS], [test "x$enable_tests" = "xyes"]) + +# LXC container path, where the containers are actually stored +# This is overridden by an entry in the file called LXCCONF +# (i.e. /etc/lxc/lxc.conf) AC_ARG_WITH([config-path], [AC_HELP_STRING( [--with-config-path=dir], [lxc configuration repository path] )], [], [with_config_path=['${localstatedir}/lib/lxc']]) +# The path of the global lxc configuration file. +AC_ARG_WITH([global-conf], + [AC_HELP_STRING( + [--with-global-conf=dir], + [global lxc configuration file] + )], [], [with_global_conf=['${sysconfdir}/lxc/lxc.conf']]) + +AC_ARG_WITH([usernic-conf], + [AC_HELP_STRING( + [--with-usernic-conf], + [user network interface configuration file] + )], [], [with_usernic_conf=['${sysconfdir}/lxc/lxc-usernet']]) + +AC_ARG_WITH([usernic-db], + [AC_HELP_STRING( + [--with-usernic-db], + [lxc user nic database] + )], [], [with_usernic_db=['/run/lxc/nics']]) + +# Rootfs path, where the container mount structure is assembled AC_ARG_WITH([rootfs-path], [AC_HELP_STRING( [--with-rootfs-path=dir], [lxc rootfs mount point] )], [], [with_rootfs_path=['${libdir}/lxc/rootfs']]) -AS_AC_EXPAND(LXC_GENERATE_DATE, "$(date)") +# Container log path. By default, use $lxcpath. +AC_MSG_CHECKING([Whether to place logfiles in container config path]) +AC_ARG_ENABLE([configpath-log], + [AC_HELP_STRING([--enable-configpath-log], [use logfiles in config path])], + [use_configpath_logs=yes], [use_configpath_logs=no]) +AC_MSG_RESULT([$use_configpath_logs]) +AM_CONDITIONAL([USE_CONFIGPATH_LOGS], [test "$use_configpath_logs" = "yes"]) + +if test "$use_configpath_logs" = "yes"; then + default_log_path="${with_config_path}" +else + default_log_path="${localstatedir}/log/lxc" +fi -AC_SUBST(LXCPATH, "${with_config_path}") -AC_SUBST(LXCROOTFSMOUNT, "${with_rootfs_path}") -AC_SUBST(LXCINITDIR, ['${libexecdir}/lxc']) -AC_SUBST(LXCTEMPLATEDIR, ['${libdir}/lxc/templates']) - -AC_CHECK_HEADERS([linux/netlink.h linux/genetlink.h], - [], - AC_MSG_ERROR([netlink headers not found. Please install the linux kernel headers.]), - [#include - ]) - -AC_CHECK_HEADERS([sys/capability.h], [], AC_MSG_ERROR([please install libcap-devel.]), -[#include -#include ]) -AC_CHECK_LIB(cap,cap_set_proc,caplib=yes,caplib=no) -AC_MSG_CHECKING([linux capabilities]) -if test "x$caplib" = "xyes" ; then - CAP_LIBS="-lcap" - AC_MSG_RESULT([$CAP_LIBS]) +AC_ARG_WITH([log-path], + [AC_HELP_STRING( + [--with-log-path=dir], + [per container log path] + )], [], [with_log_path=['${default_log_path}']]) + +# Expand some useful variables +AS_AC_EXPAND(PREFIX, "$prefix") +AS_AC_EXPAND(LIBDIR, "$libdir") +AS_AC_EXPAND(BINDIR, "$bindir") +AS_AC_EXPAND(LIBEXECDIR, "$libexecdir") +AS_AC_EXPAND(INCLUDEDIR, "$includedir") +AS_AC_EXPAND(SYSCONFDIR, "$sysconfdir") +AS_AC_EXPAND(LXC_DEFAULT_CONFIG, "$sysconfdir/lxc/default.conf") +AS_AC_EXPAND(DATADIR, "$datadir") +AS_AC_EXPAND(LOCALSTATEDIR, "$localstatedir") +AS_AC_EXPAND(DOCDIR, "$docdir") +AS_AC_EXPAND(LXC_DISTRO_CONF, "$distroconf") +AS_AC_EXPAND(LXC_GENERATE_DATE, "$(date)") +AS_AC_EXPAND(LXCPATH, "$with_config_path") +AS_AC_EXPAND(LXC_GLOBAL_CONF, "$with_global_conf") +AS_AC_EXPAND(LXC_USERNIC_CONF, "$with_usernic_conf") +AS_AC_EXPAND(LXC_USERNIC_DB, "$with_usernic_db") +AS_AC_EXPAND(LXCROOTFSMOUNT, "$with_rootfs_path") +AS_AC_EXPAND(LXCTEMPLATEDIR, "$datadir/lxc/templates") +AS_AC_EXPAND(LXCHOOKDIR, "$datadir/lxc/hooks") +AS_AC_EXPAND(LXCINITDIR, "$libexecdir") +AS_AC_EXPAND(LOGPATH, "$with_log_path") + +# Check for some standard kernel headers +AC_CHECK_HEADERS([linux/unistd.h linux/netlink.h linux/genetlink.h], + [], + AC_MSG_ERROR([Please install the Linux kernel headers.]), + [#include ]) + +# Allow disabling libcap support +AC_ARG_ENABLE([capabilities], + [AC_HELP_STRING([--disable-capabilities], [disable kernel capabilities])], + [], [enable_capabilities=yes]) + +# Check for libcap support +if test "x$enable_capabilities" = "xyes"; then + AC_CHECK_LIB(cap,cap_set_proc,caplib=yes,caplib=no) + AC_MSG_CHECKING([linux capabilities]) + if test "x$caplib" = "xyes" ; then + CAP_LIBS="-lcap" + AC_MSG_RESULT([$CAP_LIBS]) + else + AC_MSG_RESULT([no]) + AC_MSG_ERROR([You are missing libcap support. If you really want to build without kernel capabilities, use --disable-capabilities]) + fi else - AC_MSG_ERROR([not found]) + CAP_LIBS="" fi AC_SUBST([CAP_LIBS]) +# Check for alternate C libraries +AC_MSG_CHECKING(for bionic libc) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM( + [[#ifndef __ANDROID__ +error: Not bionic! +#endif]])], + [is_bionic=yes], + [is_bionic=no]) +if test "x$is_bionic" = "xyes"; then + AC_DEFINE([IS_BIONIC], 1, [bionic libc]) + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) +fi +AM_CONDITIONAL([IS_BIONIC], [test "x$is_bionic" = "xyes"]) + # Some systems lack PR_CAPBSET_DROP definition => HAVE_DECL_PR_CAPBSET_DROP AC_CHECK_DECLS([PR_CAPBSET_DROP], [], [], [#include ]) -AC_CHECK_HEADERS([sys/signalfd.h]) +# Check for some headers +AC_CHECK_HEADERS([sys/signalfd.h pty.h ifaddrs.h sys/capability.h sys/personality.h utmpx.h sys/timerfd.h]) -AC_PROG_GCC_TRADITIONAL +# Check for some syscalls functions +AC_CHECK_FUNCS([setns pivot_root sethostname unshare rand_r confstr]) -AC_LINUX +# Check for some functions +AC_CHECK_LIB(util, openpty) +AC_CHECK_FUNCS([openpty hasmntopt setmntent endmntent]) +AC_CHECK_FUNCS([getline], + AM_CONDITIONAL(HAVE_GETLINE, true) + AC_DEFINE(HAVE_GETLINE,1,[Have getline]), + AM_CONDITIONAL(HAVE_GETLINE, false)) +AC_CHECK_FUNCS([fgetln], + AM_CONDITIONAL(HAVE_FGETLN, true) + AC_DEFINE(HAVE_FGETLN,1,[Have fgetln]), + AM_CONDITIONAL(HAVE_FGETLN, false)) + +# Check for some libraries +AC_SEARCH_LIBS(sem_open, [rt pthread]) +AC_SEARCH_LIBS(clock_gettime, [rt]) + +# Check for some standard binaries +AC_PROG_GCC_TRADITIONAL +AC_PROG_SED if test "x$GCC" = "xyes"; then - CFLAGS="$CFLAGS -Wall" + CFLAGS="$CFLAGS -Wall -Werror" fi +# Files requiring some variable expansion AC_CONFIG_FILES([ Makefile lxc.pc @@ -104,23 +388,34 @@ config/Makefile doc/Makefile + doc/legacy/lxc-ls.sgml + doc/lxc-attach.sgml + doc/lxc-cgroup.sgml + doc/lxc-checkconfig.sgml + doc/lxc-checkpoint.sgml + doc/lxc-clone.sgml + doc/lxc-console.sgml doc/lxc-create.sgml doc/lxc-destroy.sgml + doc/lxc-device.sgml doc/lxc-execute.sgml - doc/lxc-start.sgml - doc/lxc-checkpoint.sgml + doc/lxc-freeze.sgml + doc/lxc-info.sgml + doc/lxc-kill.sgml + doc/lxc-ls.sgml + doc/lxc-monitor.sgml + doc/lxc-netstat.sgml + doc/lxc-ps.sgml doc/lxc-restart.sgml + doc/lxc-start-ephemeral.sgml + doc/lxc-start.sgml doc/lxc-stop.sgml - doc/lxc-console.sgml - doc/lxc-freeze.sgml + doc/lxc-top.sgml doc/lxc-unfreeze.sgml - doc/lxc-monitor.sgml + doc/lxc-unshare.sgml + doc/lxc-version.sgml doc/lxc-wait.sgml - doc/lxc-ls.sgml - doc/lxc-ps.sgml - doc/lxc-cgroup.sgml - doc/lxc-kill.sgml - doc/lxc-attach.sgml + doc/lxc.conf.sgml doc/lxc.sgml doc/common_options.sgml @@ -137,58 +432,37 @@ doc/examples/lxc-veth.conf doc/examples/lxc-complex.conf + hooks/Makefile + templates/Makefile - templates/lxc-lenny + templates/lxc-cirros templates/lxc-debian templates/lxc-ubuntu templates/lxc-ubuntu-cloud templates/lxc-opensuse templates/lxc-busybox templates/lxc-fedora + templates/lxc-oracle templates/lxc-altlinux templates/lxc-sshd templates/lxc-archlinux + templates/lxc-alpine src/Makefile src/lxc/Makefile src/lxc/lxc-ps - src/lxc/lxc-ls src/lxc/lxc-netstat src/lxc/lxc-checkconfig - src/lxc/lxc-setcap - src/lxc/lxc-setuid src/lxc/lxc-version - src/lxc/lxc-create - src/lxc/lxc-clone - src/lxc/lxc-destroy - -]) -AC_CONFIG_COMMANDS([default],[[]],[[]]) -AC_OUTPUT - -if test "x$SETCAP" = "xno"; then - AC_MSG_NOTICE([ + src/lxc/lxc-start-ephemeral + src/lxc/legacy/lxc-ls + src/lxc/lxc.functions -Warning: --------- + src/python-lxc/Makefile -The setcap binary was not found. This means the tools to set the -privilege for the lxc commands are not available, that's ok, but you -will need to run these commands as root or install libcap-2. + src/lua-lxc/Makefile + src/tests/Makefile ]) - -else - - AC_MSG_NOTICE([ - -Advice: -------- - -If you wish to have a non root user to use the lxc tools, -you can add the needed capabilities to the tools by invoking -the 'lxc-setcap' script. To remove the capabilities, use -'lxc-setcap -d'. -]) - -fi +AC_CONFIG_COMMANDS([default],[[]],[[]]) +AC_OUTPUT diff -Nru lxc-0.8.0~rc1/debian/apparmor/abstractions-lxc-container-base lxc-1.0.0~alpha1/debian/apparmor/abstractions-lxc-container-base --- lxc-0.8.0~rc1/debian/apparmor/abstractions-lxc-container-base 2013-02-07 19:27:22.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/apparmor/abstractions-lxc-container-base 2013-10-10 16:57:54.000000000 +0000 @@ -46,3 +46,4 @@ deny /sys/fs/c[^g]*/** wklx, deny /sys/fs/cg[^r]*/** wklx, deny /sys/firmware/efi/efivars/** rwklx, + deny /sys/kernel/security/** rwklx, diff -Nru lxc-0.8.0~rc1/debian/apparmor/abstractions-lxc-start-container lxc-1.0.0~alpha1/debian/apparmor/abstractions-lxc-start-container --- lxc-0.8.0~rc1/debian/apparmor/abstractions-lxc-start-container 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/apparmor/abstractions-lxc-start-container 2013-10-07 21:32:53.000000000 +0000 @@ -4,6 +4,7 @@ # currently blocked by apparmor bug mount -> /usr/lib/*/lxc/{**,}, + mount -> /usr/lib/lxc/{**,}, mount fstype=devpts -> /dev/pts/, mount options=bind /dev/pts/ptmx/ -> /dev/ptmx/, mount fstype=debugfs, @@ -22,6 +23,7 @@ #umount /mnt/{**,}, pivot_root /usr/lib/*/lxc/, + pivot_root /usr/lib/lxc/root/, change_profile -> lxc-*, change_profile -> unconfined, diff -Nru lxc-0.8.0~rc1/debian/apparmor/lxc-default-with-nesting lxc-1.0.0~alpha1/debian/apparmor/lxc-default-with-nesting --- lxc-0.8.0~rc1/debian/apparmor/lxc-default-with-nesting 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/apparmor/lxc-default-with-nesting 2013-10-07 21:32:53.000000000 +0000 @@ -9,4 +9,5 @@ mount fstype=proc -> /var/cache/lxc/**, mount fstype=sysfs -> /var/cache/lxc/**, + mount options=(rw,bind) /var/cache/lxc/**/dev/shm/ -> /var/cache/lxc/**/run/shm/, } diff -Nru lxc-0.8.0~rc1/debian/changelog lxc-1.0.0~alpha1/debian/changelog --- lxc-0.8.0~rc1/debian/changelog 2013-02-28 15:12:53.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/changelog 2013-11-12 17:46:36.000000000 +0000 @@ -1,38 +1,652 @@ -lxc (0.8.0~rc1-4ubuntu39.12.10.2~ubuntu12.04.1) precise-backports; urgency=low +lxc (1.0.0~alpha1-0ubuntu13~ubuntu12.04.1) precise-backports; urgency=low - * No-change backport to precise + * No-change backport to precise (LP: #1250510) - -- Scott Kitterman Thu, 28 Feb 2013 10:12:53 -0500 + -- Iain Lane Tue, 12 Nov 2013 17:46:36 +0000 -lxc (0.8.0~rc1-4ubuntu39.12.10.2) quantal-proposed; urgency=low +lxc (1.0.0~alpha1-0ubuntu13) saucy-proposed; urgency=low + + * debian/rules and debian/lxc.postinst: set /var/lib/lxc and /var/cache/lxc + to be perms 700. That prevents unprivileged users from running setuid-root + applications. Install that way by default, and for any previous versions, + update the permissions. After this version, respect the user's choice. + (LP: #1244635) + + -- Serge Hallyn Mon, 04 Nov 2013 08:12:35 -0600 + +lxc (1.0.0~alpha1-0ubuntu12) saucy-proposed; urgency=low + + * 0012-ubuntu-Improper-pty-permissions.patch: fix pty permissions + (LP: #1242913) + * 0013-get-rid-of-lxcpath_anon-idea.patch: make containers started with + a custom config easier to manage. (LP: #1244301) + + -- Serge Hallyn Fri, 25 Oct 2013 15:42:27 -0500 + +lxc (1.0.0~alpha1-0ubuntu11) saucy; urgency=low + + * Deny any kind of access to /sys/kernel/security/** as the containers + have no reason to read that and it's been causing dbus-daemon to think + it can integrate with apparmor. + + -- Stéphane Graber Thu, 10 Oct 2013 12:58:54 -0400 + +lxc (1.0.0~alpha1-0ubuntu10) saucy; urgency=low + + [ Serge Hallyn ] + * Cherrypicking bugfix from upstream + - 0011-ubuntu-cloud-prep-hook-fix-debug-helper-to-not-inapp.patch + + [ Stéphane Graber ] + * On saucy and higher, add "dbus," to the container-base profile. + (done that way as LXC is backported down to 12.04) + + -- Stéphane Graber Wed, 09 Oct 2013 14:04:23 -0400 + +lxc (1.0.0~alpha1-0ubuntu9) saucy; urgency=low + + * Update patch with current upstream version (LP: #1236726) + - 0009-lxc-ubuntu-cloud-pass-numeric-owner-and-p-to-untar.patch + * Cherrypicking bugfix from upstream + - 0010-lxc-ubuntu-cloud-Cope-with-spaces-in-paths.patch + + -- Stéphane Graber Tue, 08 Oct 2013 11:11:33 -0400 + +lxc (1.0.0~alpha1-0ubuntu8) saucy; urgency=low + + * Add a recommends on uuid-runtime to lxc-templates as the + ubuntu-cloud template uses uuidgen. + + -- Stéphane Graber Mon, 07 Oct 2013 17:35:56 -0400 + +lxc (1.0.0~alpha1-0ubuntu7) saucy; urgency=low + + * Cherrypicking bugfix from upstream (LP: #1236577) + - 0009-lxc-ubuntu-cloud-pass-numeric-owner-and-p-to-untar.patch + + -- Serge Hallyn Mon, 07 Oct 2013 16:17:27 -0500 + +lxc (1.0.0~alpha1-0ubuntu6) saucy; urgency=low + + * Cherrypicking bugfix from upstream + - 0008-Fix-crasher-in-get_ips.patch + (Fixes lxc-list on Ubuntu Touch amongst other cases) + + -- Stéphane Graber Sun, 29 Sep 2013 20:52:53 -0400 + +lxc (1.0.0~alpha1-0ubuntu5) saucy; urgency=low + + * Cherrypicking bugfix from upstream (LP: #1227313) + - 0007-apparmor.c-drop-newline-when-reading-current-profile.patch + + -- Serge Hallyn Fri, 27 Sep 2013 15:14:24 -0500 + +lxc (1.0.0~alpha1-0ubuntu4) saucy; urgency=low + + * modify 0006-add-pstore-to-container-fstab.patch: make pstore mount + optional. + + -- Serge Hallyn Mon, 16 Sep 2013 11:50:05 -0500 + +lxc (1.0.0~alpha1-0ubuntu3) saucy; urgency=low + + * Cherrypick bugfix from upstream + (pre-mount pstore to avoid mountall hanging at boot time): + - 0006-add-pstore-to-container-fstab.patch + + -- Stéphane Graber Fri, 13 Sep 2013 16:57:29 -0400 + +lxc (1.0.0~alpha1-0ubuntu2) saucy; urgency=low + + * Add allow-stderr to autopkgtst restrictions as the Ubuntu template + uses policy-rc.d to disable some daemons and that causes a message to + be printed on stderr when the service tries to start. + + -- Stéphane Graber Thu, 12 Sep 2013 13:57:17 -0400 + +lxc (1.0.0~alpha1-0ubuntu1) saucy; urgency=low + + * New upstream release (LP: #1218426) + - A very long list of bugfixes, including: + (LP: #1081786, LP: #1029777, LP: #987770, LP: #1212290, LP: #1199146, + LP: #1124526, LP: #1014916, LP: #1212414, LP: #1168526, LP: #1135871) + * Removed patches: + - transition/00-redirect-lxc-halt.patch + - 0001-fix-race-with-fast-init + - 0002-lxc-functions-safe-in-dash + - 0003-python-module-fixes + - 0004-lxc-ps-handle-cgroup-collisions.patch + - 0005-cgroup-prevent-DOS-when-a-hierachy-is-mounted-multip.patch + - 0006-lxc-clone-fix-lvm-blockdev-usage + - 0007-lxc.conf.doc + - 0008-ignore-rootfs-pin-fail.patch + - 0009-conf.c-if-we-don-t-specify-a-rootfs-we-still-need-pr.patch + - conf.c-always-strdup-rootfs.mount + - 0011-cgroup-hook-handle-stricter-kernel + - 0012-add-kernel-filesystems-to-fstab + - 0013-ubuntu-cloud-fix-hostid + - 0014-lxc-apparmor-null-terminate-buffer + - 0015-fix-ipv6-pton + * Refreshed patches: + - transition/00-redirect-lxc-list.patch + - 0000-add-autostart.patch + - 0001-debian-template-set-hwaddr + * New patches (fix regression when /var/lib/lxc is read-only): + - 0002-pin_rootfs-be-quiet-and-don-t-fail-container-start.patch + - 0003-move-monitor-fifo-and-monitor-sock-to-run.patch + - 0004-hash-lxcname-for-use-in-monitor-unix-socket-sun_path.patch + - 0005-ignore-ability-to-init-lxc-monitord.log.patch + * Updated debian/copyright to reflect reality. + * Fix lxc-template's short description. + * Replace the cloud-utils recommends by cloud-image-utils | cloud-utils + to use the new saucy package and still allow for easy backports. + (LP: #1224545) + + -- Stéphane Graber Thu, 12 Sep 2013 12:45:05 -0400 + +lxc (0.9.0-0ubuntu23) saucy; urgency=low + + * 0014-lxc-apparmor-null-terminate-buffer: make sure a value we fread is + null-terminated (LP: #1215386) + * 0015-fix-ipv6-pton: call inet_pton on the value without the netmask. + (LP: #1215391) + + -- Serge Hallyn Fri, 23 Aug 2013 11:39:55 -0500 + +lxc (0.9.0-0ubuntu22) saucy; urgency=low + + * ubuntu-cloud: fix typo keeping --hostid from working (LP: #1197357) + + -- Serge Hallyn Thu, 15 Aug 2013 14:40:58 -0500 + +lxc (0.9.0-0ubuntu21) saucy; urgency=low + + * Fix autopkgtest failure by unsetting TMPDIR in the test. + + -- Stéphane Graber Fri, 09 Aug 2013 16:30:47 +0200 + +lxc (0.9.0-0ubuntu20) saucy; urgency=low + + * Build-depend on hardening-wrapper to meet MIR security requirements. + This is done instead of using the new dpkg-buildflags as those are a pain + to get to work when building both binaries and libraries when using -PIE. + + -- Stéphane Graber Fri, 09 Aug 2013 14:33:59 +0200 + +lxc (0.9.0-0ubuntu19) saucy; urgency=low + + * Add variable in /etc/default/lxc-net to optionally resolve .lxc on + lxcbr0. + + -- Serge Hallyn Tue, 06 Aug 2013 09:03:59 -0500 + +lxc (0.9.0-0ubuntu18) saucy; urgency=low + + * 0012-add-kernel-filesystems-to-fstab: saucy containers will fail to start + unless security, debug, and connections are pre-mounted. + + -- Serge Hallyn Thu, 25 Jul 2013 22:01:02 -0500 + +lxc (0.9.0-0ubuntu17) saucy; urgency=low + + * 0011-cgroup-hook-handle-stricter-kernel: fix the mountcgroups hook in the + face of new restrictions imposed by the kernel on devices cgroups. + (LP: #1196518) + + -- Serge Hallyn Fri, 05 Jul 2013 20:44:57 +0200 + +lxc (0.9.0-0ubuntu16) saucy; urgency=low + + * conf.c-always-strdup-rootfs.mount: prevent segfault when using + lxc.rootfs.mount. + + -- Serge Hallyn Mon, 01 Jul 2013 15:29:17 -0500 + +lxc (0.9.0-0ubuntu15) saucy; urgency=low + + * lxc-net: support an optional dnsmasq configuration file. + * 0010-debian-template-set-hwaddr: set persistent macaddr when creating a + debian container (LP: #1080681) + * lxc.apport: add /etc/lxc/{dnsmasq,default,lxc}.conf and + /etc/default/lxc{,-net}.conf + + -- Serge Hallyn Tue, 11 Jun 2013 07:47:32 -0500 + +lxc (0.9.0-0ubuntu14) saucy; urgency=low + + * 0009-conf.c-if-we-don-t-specify-a-rootfs-we-still-need-pr.patch: if + apparmor is enabled and no rootfs was specified, then re-mount /proc + so that we can write the requested apparmor profile under /proc/1. + (LP: #1188501) + + -- Serge Hallyn Mon, 10 Jun 2013 09:27:32 -0500 + +lxc (0.9.0-0ubuntu13) saucy; urgency=low + + * 0008-ignore-rootfs-pin-fail.patch: don't refuse to start a container + on readonly fs. + + -- Serge Hallyn Wed, 05 Jun 2013 21:35:40 +0200 + +lxc (0.9.0-0ubuntu12) saucy; urgency=low + + * 0007-lxc.conf.doc: Fill in missing sections in lxc.conf(5) manual + page (LP: 1182085) + + -- Serge Hallyn Tue, 28 May 2013 13:23:57 -0500 + +lxc (0.9.0-0ubuntu11) saucy; urgency=low + + * lxc-net: deal with the fact that some kernels may not have the needed + network bridge support. + + -- Stéphane Graber Tue, 28 May 2013 10:52:22 -0400 + +lxc (0.9.0-0ubuntu10) saucy; urgency=low + + * Rebuild-only upload (LP: #1183807) + + -- Serge Hallyn Fri, 24 May 2013 10:51:44 -0500 + +lxc (0.9.0-0ubuntu9) saucy; urgency=low + + * 0006-lxc-clone-fix-lvm-blockdev-usage: fix use of wrong pathnames for both + block devices and mount targets in the LVM case. (LP: #1183354) + + -- Serge Hallyn Thu, 23 May 2013 14:22:38 -0500 + +lxc (0.9.0-0ubuntu8) saucy; urgency=low + + [ James Hunt ] + * Add basic DEP-8 tests to ensure a container can be created, started, + stopped and cloned. + + -- James Hunt Tue, 21 May 2013 14:44:12 +0100 + +lxc (0.9.0-0ubuntu7) saucy; urgency=low + + * 0005-cgroup-prevent-DOS-when-a-hierachy-is-mounted-multip.patch: prevent + DOS when a cgroup hierarchy is mounted multiple times (LP: #1176287) + + -- Serge Hallyn Wed, 15 May 2013 22:19:59 +0000 + +lxc (0.9.0-0ubuntu6) saucy; urgency=low + + * debian/lxc.default, debian/lxc.preinst: calculate an open 10.0.x.0 network + for lxcbr0 to use at package install time. This allows easier package + installion when nested. + + -- Serge Hallyn Tue, 14 May 2013 14:34:51 -0500 + +lxc (0.9.0-0ubuntu5) saucy; urgency=low + + * push 0004-lxc-ps-handle-cgroup-collisions.patch from upstream to handle + the case where $container's cgroup is + /sys/fs/cgroup/$cgroup/lxc/$container-1. + + -- Serge Hallyn Wed, 08 May 2013 16:02:44 -0500 + +lxc (0.9.0-0ubuntu4) saucy; urgency=low + + * Fix lxc-list crashing when passed --nesting with nested containers. + (LP: #1177408) + * Fix lxc-ls to show nested containers when using alternate lxcpath. + (LP: #1177412) + * Fix python3 API bug leading to parameter corruption in create and start. + (LP: #1177400) + + -- Stéphane Graber Tue, 07 May 2013 10:48:40 -0400 + +lxc (0.9.0-0ubuntu3) raring; urgency=low + + * 0003-python-module-fixes: Cherry pick python module bugfixes from upstream. + * Update deprecation warning for lxc-halt and lxc-list, moving the + deprecation from 0.9 to 1.0. + + -- Stéphane Graber Thu, 18 Apr 2013 22:29:39 +0200 + +lxc (0.9.0-0ubuntu2) raring; urgency=low + + * 0002-lxc-functions-safe-in-dash: stop lxc-clone from silently failing. + (LP: #1166870) + + -- Serge Hallyn Tue, 09 Apr 2013 12:38:02 -0500 + +lxc (0.9.0-0ubuntu1) raring; urgency=low + + * New upstream release (0.9.0) (LP: #1166286) + - New features + (fixing a regression for 0.8/0.9alpha who relied on --keep-env) + + lxc-attach: Add --clear-env and --keep-env to lxc-attach + + lxc-clone: Support 'permanent ephemeral' containers + + lxc-start-ephemeral: Implement -n to match manpage + - Bugfix + + automake: Fix 'make clean' + + automake: Fix missing files with "make dist" + + core: API shouldn't be calling create for already defined containers or + destroy for non defined ones + + core: Build fixes for ia64 + + core: Make lxc.functions return the default lxcpath if + /etc/lxc/lxc.conf doesn't provide one + + core: Properly cleanup network devices if pinning root filesystem + din't work + + core: rcfile shouldn't be recorded in lxc_conf if the attempt to load a + config file fails + + core: Set all mounts to MS_SLAVE when starting a container without + a rootfs + + core: Use $localstatedir/log/lxc for default log path + + git: Updated gitignore (for lxc-ls) + + lxc-attach: Set container=lxc in the environment + + lxc-create: require absolute path for non-standard templates + + lxc-shutdown Make all processes exit before timeout if shutdown works + + lxc-shutdown: Properly handle timeout case + + manpage: Fixed typo in the main LXC manpage + + python: Fix runtime failure on armhf + + ubuntu template: Tweak architecture support (to match what's supported) + * Removed 0002-fix-armhf-python-failure, merged upstream. + + -- Stéphane Graber Mon, 08 Apr 2013 12:19:32 -0400 + +lxc (0.9.0~rc1-0ubuntu3) raring; urgency=low + + * Add code to postinst to fix any double-migration of /etc/dnsmasq. + (LP: #1157332) + + -- Stéphane Graber Wed, 27 Mar 2013 16:51:11 -0400 + +lxc (0.9.0~rc1-0ubuntu2) raring; urgency=low + + * Fix python3-lxc on armhf (LP: #1159817). + + -- Stéphane Graber Tue, 26 Mar 2013 11:21:46 -0400 + +lxc (0.9.0~rc1-0ubuntu1) raring; urgency=low + + * New upstream release (0.9.0~rc1) + - New features + * alpine: template now supports bridges auto-detect and setting hwaddr + * archlinux: update template to use lxc.stopsignal and lxc.kmsg + * core: Add example hooks from Ubuntu package + * core: Add --lxcpath (-P) option to all the tools + * core: attach: now also changes the apparmor profile + * core: attach: try to detect the user shell when attaching + * core: config: add lxc.kmsg (defaults to old enabled behaviour) + * core: config: add lxc.stopsignal (defaults to old SIGKILL behaviour) + * core: lxc-ls: Implement support for nested containers + * core: New exported API function, get_version + * lenny: Remove deprecated template + * lxc-ps: New '--host' option + * opensuse: update template to support 12.2 and 12.3 + - Bugfixes + * core: Add missing config.h includes. + * core: af_unix: make sure to keep useful errno + * core: attach: fixed lxc-attach to deal with user namespaces + * core: attach: free result before potentially strduping a second time. + * core: c api -> createl: correctly handle 0 template args + * core: commands.c: sanity check to not write too-long cgroup path name + * core: ensure clock_gettime symbol is found + * core: Fix typos identified by lintian + * core: fix writing multiple uidmap ranges + * core: give a hint if old cgroup can't be moved + * core: improved README + * core: lxc_id_mapping: don't try to write mappings if there are none + * core: make [ug]id map ordering consistent with /proc//[ug]id_map + * core: only INFO rcfile if asprintf successfully allocates it + * core: Remove redundant clearenv call + * core: Replace deprecated AM_CONFIG_HEADER + * core: rootfs pin: fix two bugs + * core: try to set clone_children when setting up cgroups + * core: Use AC_SEARCH_LIBS instead of hardcoded lists + * core: userns: handle delayed write errors at fclose + * legacy: only output appropriate directories/containers in lxc-ls + * lxc-ubuntu{-cloud}: Config layout tweaking + * opensuse: fix template to better work with lxc-clone, support shutdown, + * oracle: template fixes for older releases + * python: Drop use of hardcoded @LXCPATH@ + * rpm: include hook files and tests in make dist + various code improvements + * Remove example hooks from packaging as they have now been upstreamed. + * Update apparmor profile to allow for lxc-create to work for nested + precise containers. + + -- Stéphane Graber Tue, 19 Mar 2013 11:32:44 -0400 + +lxc (0.9.0~alpha3-0ubuntu3) raring; urgency=low + + * 0001-fix-race-with-fast-init: Before starting lxc_mainloop, check whether + lxc-init has already exited. If it has, return immediately to reap it. + (LP: #1134923) (LP: #1144873) + + -- Serge Hallyn Mon, 11 Mar 2013 10:14:39 -0500 + +lxc (0.9.0~alpha3-0ubuntu2) raring; urgency=low + + * Remove hardcoded --enable-seccomp from debian/rules as seccomp isn't + present on armhf and powerpc, leading to FTBFS on those two architectures. + + -- Stéphane Graber Mon, 18 Feb 2013 19:01:38 -0500 + +lxc (0.9.0~alpha3-0ubuntu1) raring; urgency=low + + * New upstream release (0.9.0~alpha3) + * NOTE: We took the opportunity of this new upstream release bringing + its lot of significant changes to reduce the amount of custom code that's + shipped in the packages and hasn't been submitted upstream. + If you strongly feel about any of those, please submit a cleaned up version + to upstream LXC for inclusion. + + The following tools/templates have been dropped: + - lxc-debconf (upstream ships lxc-debian and lxc-lenny) + - lxc (use the lxc-* commands directly) + - lxc-backup (was just a wrapper on rsync using hardcoded paths) + - lxc-restore (was just a wrapper on rsync using hardcoded paths) + + And the following are provided through compatibility symlinks and will be + dropped in final 0.9: + - lxc-list (equivalent of lxc-ls --fancy) + - lxc-halt (replaced by lxc-shutdown) + + This release also deprecates the following tools as they were considered + mostly broken and the user namespace support makes them mostly useless: + - lxc-setcap + - lxc-setuid + + * The following patches were included upstream: + - 0013-lxc-create-use-default-config.patch + - 0030-ubuntu-template-fail.patch + - 0031-ubuntu-template-resolvconf.patch + - 0044-lxc-destroy-rm-autos + - 0045-fix-other-templates + - 0046-lxc-clone-change-hwaddr + - 0047-bindhome-check-shell + - 0049-ubuntu-template-sudo-and-cleanup + - 0050-clone-lvm-sizes + - 0052-ubuntu-bind-user-conflict + - 0053-lxc-start-pin-rootfs + - 0054-ubuntu-debug + - 0055-ubuntu-handle-badgrp + - 0056-dont-watch-utmp + - 0057-update-manpages + - 0058-fixup-ubuntu-cloud + - 0059-reenable-daily-cloudimg + - 0060-lxc-shutdown + - 0061-lxc-start-apparmor + - 0062-templates-relative-paths + - 0063-check-apparmor-enabled + - 0064-apparmor-mount-proc + - 0065-fix-bindhome-relpath + - 0066-confile-typo + - 0067-templates-lxc-profile + - 0068-fix-lxc-config-layout + - 0069-ubuntu-cloud-fix + - 0070-templates-rmdir-dev-shm + - 0071-ubuntu-cloud-fix-image-extraction + - 0072-lxc-shutdown-help + - 0073-lxc-destroy-waits-before-destroy + - 0074-lxc-execute-find-init + - 0075-lxc-ls-bash + - 0076-fix-sprintfs + - 0077-execute-without-rootfs + - 0078-lxc-clone-quote-line + - 0079-quantal-support + - 0080-drop-maverick + - 0081-fix-multiarch-install + - 0082-umount-old-proc + - 0083-ubuntu-simplify-template + - 0084-lxc-ubuntu-drop-duplicate-code.patch + - 0085-pivot-dir + - 0086-lxc-unshare-zero-args + - 0087-lxc-ls-dash + - 0088-ubuntu-template-flock + - 0089-lxc-netstat-exec + - 0090-lxc-ubuntu-use-dpkg-add-architecture + - 0091-introduce-container-hooks.patch + - 0092-clone-no-dhclient.conf-update-when-not-hardcoded + - 0093-lxc-clone-copy-fstab + - 0094-fix-dev-shm-check + - 0095-lxc-clone-change-uuid-on-xfs.patch + - 0096-lxc-wait-add-timeout.patch + - 0097-seccomp + - 0098-config-file-includes + - 0099-cleanup-after-template-help + - 0100-template-cleanup-cache + - 0101-template-empty-apt-cache + - 0102-lxc-start-d-check-privs + - 0103-make-rootfs-location-optional + - 0104-add-option-to-lxc-attach-to-select-ns + - 0105-lxc-attach-add-R-option + - 01-lxc-directories.patch + - 0200-liblxc + - 0201-fix-mkdir-race + - 0202-make-api-start-reliable + - 0203-python-lxc + - 0204-ubuntu-cloud-userdata-path + - 0205-lxc-ls-manpage-document-two-lines + - 0206-lxc-wait-initialize-timeout + - 0207-ubuntu-cloud-fixes.patch + - 0208-fix-getitem-utsname-segv + - 0209-reload-conf-after-create + - 0210-fix-debian-templates + - 0211-add-hooks-to-manpage + - 0213-add-premount-hook.patch + - 0214-give-pclose-errno + - 0215-lxc-clone-name-arg + - 0216-hook-kmsg-to-console + - 0217-lxc-clone-fix-fstab + - 0218-api-shutdown-fix-doublestop + - 0219-python-module-improvements + - 0220-getitem-per-hook-type + - 0221-make-nonflush-upgrades-robust + - 0222-debian-dhcp3-package + - 0223-ubuntu-template-user-msg + - 0225-ubuntu-cloud-numeric-owner + - 0226-add-lxc-autodev + - 0227-ubuntu-cloud-parsing + - 0228-ignore-kmsg-setup-failure + - 0229-lxc-clone-mount-fix + - 0230-autodev-makedev-console + - 02-lxc-distclean.patch + - 03-lxc-configuration-path.patch + - 04-lxc-create-template-name.patch + - 05-doc-ip-address.patch + - 06-bash.patch + - 07-lxc-netstat.patch + - 08-lxc-debconf.patch + - 09-lxc-create-trap-name.patch + - 10-lxc-clone-trap-name.patch + - 11-lxc-console-escape.patch + - 12-lxc-create-rootfs.patch + - compilecleanups/0001-replace-HOOK-define-with-proper-code.patch + - compilecleanups/0002-add-prototype-for-clone-2-as-per-manpage.patch + - compilecleanups/0003-check-chdir-return-value.patch + - compilecleanups/0004-Fix-passing-non-const-char-in-for-const-char.patch + - compilecleanups/0005-return-nonvoid + - compilecleanups/0006-unused-var + - compilecleanups/0007-tests-check-return-values + - seccompapi/0001-seccomp-free-conf-seccomp-filename-char.patch + - seccompapi/0002-README-fix-typo-in-example-script.patch + - seccompapi/0003-support-new-libseccomp-api.patch + + * New patches: + - transition/00-redirect-lxc-halt.patch: Show warning when lxc-halt is + called as lxc-shutdown now replaces it. + - transition/01-redirect-lxc-list.patch: Show warning when lxc-list is + called as lxc-ls now replaces it. Default to --fancy in this mode. + - 0000-add-autostart.patch: Add autostart support to lxc-destroy and + lxc-ls. + + * Disable the test binaries, those are only useful in the dailies. + * Drop lxc.manpages, all the needed manpages are now upstream. + * Transition /etc/lxc/lxc.conf to /etc/lxc/default.conf. + * Drop debian/*.in as they didn't contain any variable anymore. + * Drop outdated sysvinit script. We use upstart and don't intend to maintain + the sysvinit script in Ubuntu. + * Drop lxc.config and po/*. We've never used debconf for lxc in Ubuntu. + * Fix some bugs in the ecryptfs hook. + + -- Stéphane Graber Mon, 18 Feb 2013 18:25:18 -0500 + +lxc (0.8.0~rc1-4ubuntu50) raring; urgency=low + + * Create /etc/dnsmasq.d when missing. + + -- Stéphane Graber Fri, 08 Feb 2013 16:25:44 -0500 + +lxc (0.8.0~rc1-4ubuntu49) raring; urgency=low * Don't directly write/remove /etc/dnsmasq.d/lxc as that's causing problems when removing and reinstalling lxc. Instead have dnsmasq ship /etc/dnsmasq.d-available/lxc and create/remove a symlink in /etc/dnsmasq.d/. (LP: #1113821) - * Allow the container to mount efivars on /sys/firmware/efi/efivars. - efivars is automatically mounted by mountall on UEFI systems, failure to - do so leads to a complete boot failure. (LP: #1117589) - -- Stéphane Graber Thu, 07 Feb 2013 14:26:22 -0500 + -- Stéphane Graber Wed, 06 Feb 2013 16:13:18 -0500 -lxc (0.8.0~rc1-4ubuntu39.12.10.1) quantal-proposed; urgency=low +lxc (0.8.0~rc1-4ubuntu48) raring; urgency=low - * 0228-ignore-kmsg-setup-failure: ignore failure to set up kmsg, since that - is not critical. (LP: #1097312) + * debian/patches/seccompapi/: update the seccomp usage to handle the + >= 1.0.0 libseccomp api. - -- Serge Hallyn Tue, 08 Jan 2013 10:25:43 -0600 + -- Serge Hallyn Tue, 11 Dec 2012 12:46:08 -0600 -lxc (0.8.0~rc1-4ubuntu39) quantal-proposed; urgency=low +lxc (0.8.0~rc1-4ubuntu47) raring; urgency=low + + * 0230-autodev-makedev-console: Run MAKEDEV(console) before creating + consoles in the container. This is to make up for the fact that + userspace (i.e. mountall) won't be doing so, since it otherwise + would overwrite the consoles set up by lxc. (LP: #1075717) + + -- Serge Hallyn Wed, 28 Nov 2012 16:08:37 -0600 + +lxc (0.8.0~rc1-4ubuntu46) raring; urgency=low - * 0227-ubuntu-cloud-parsing: fix some option parsing bugs in ubuntu-cloud - template (LP: #1076031) * 0229-lxc-clone-mount-fix: fix wrong handling of lxc.mount entries in lxc-clone. (LP: #1084089) + * debian/apparmor/abstractions-lxc-container-base: deny read/write under + /sys/firmware/efi/efivars. - -- Serge Hallyn Thu, 29 Nov 2012 12:45:19 -0600 + -- Serge Hallyn Wed, 28 Nov 2012 11:04:17 -0600 -lxc (0.8.0~rc1-4ubuntu38) quantal-proposed; urgency=low +lxc (0.8.0~rc1-4ubuntu45) raring; urgency=low + + [ Stéphane Graber ] + * Allow the container to mount efivars on /sys/firmware/efi/efivars. + efivars is automatically mounted by mountall on UEFI systems, failure to + do so leads to a complete boot failured. + * Allow mounts and pivot_roots under /usr/lib/lxc/root/ for compatibility + with nested precise lxc hosts (quantal -> precise -> containers). + + [ Serge Hallyn ] + * update 0227-ubuntu-cloud-parsing to catch a doc typo stgraber had found + in the upstream review. + * 0228-ignore-kmsg-setup-failure: ignore failure to set up kmsg, since that + is not critical. + + [ Christian Kampka ] + * Have upstart run lxc instances (LP: #1049908) + + -- Serge Hallyn Tue, 27 Nov 2012 22:52:10 -0600 + +lxc (0.8.0~rc1-4ubuntu44) raring; urgency=low [ Scott Moser ] * 0225-ubuntu-cloud-numeric-owner: use --numeric-owner when extracting root @@ -40,8 +654,45 @@ [ Serge Hallyn ] * Remove 0224-ubuntu-templates-devtmpfs (LP: #1070914) + * 0226-add-lxc-autodev: implement automatic mount and populate of /dev. + * 0227-ubuntu-cloud-parsing: fix some option parsing bugs in ubuntu-cloud + template (LP: #1076031) + + -- Serge Hallyn Mon, 26 Nov 2012 10:11:00 -0600 + +lxc (0.8.0~rc1-4ubuntu43) raring; urgency=low + + * Fix debian/lxc.install.in to drop /var/lib/lxc/{cache|packages|templates} + as they've been moved to the new lxc-templates package. + * Bump Breaks/Replaces/Depends/Recommends versions to ubuntu43. + + -- Stéphane Graber Tue, 13 Nov 2012 12:09:30 -0500 + +lxc (0.8.0~rc1-4ubuntu42) raring; urgency=low + + * Add --dhcp-authoritative and --dhcp-leasefile options to lxc-net's dnsmasq. + This should help LXC keep IPs consistent accross reboots. + * Wrap-and-sort debian/control and debian/lxc.install + * Split templates out of the lxc binary package into a new lxc-templates + package. Have python3-lxc and lxc recommend the new package and have it + depend on lxc as a few templates use the command line tools. + * Move template related Depends/Recommends/Suggests to the new lxc-templates + package. + + -- Stéphane Graber Mon, 12 Nov 2012 17:28:12 -0500 + +lxc (0.8.0~rc1-4ubuntu41) raring; urgency=low + + * Rebuild to drop python3.2 extension. + + -- Matthias Klose Thu, 08 Nov 2012 11:15:42 +0000 + +lxc (0.8.0~rc1-4ubuntu40) raring; urgency=low + + * Add the multiarch include path for python3.3. + * Use dpkg-buildflags. - -- Serge Hallyn Wed, 24 Oct 2012 11:12:42 -0500 + -- Matthias Klose Thu, 25 Oct 2012 19:34:54 +0200 lxc (0.8.0~rc1-4ubuntu37) quantal; urgency=low diff -Nru lxc-0.8.0~rc1/debian/control lxc-1.0.0~alpha1/debian/control --- lxc-0.8.0~rc1/debian/control 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/control 2013-10-07 21:33:27.000000000 +0000 @@ -2,22 +2,42 @@ Section: admin Priority: optional Maintainer: Ubuntu Developers -XSBC-Original-Maintainer: Daniel Baumann -Uploaders: Jonas Genannt -Build-Depends: - debhelper (>= 9), autotools-dev, dh-apparmor, docbook-utils, libcap-dev, - linux-libc-dev, libapparmor-dev, libseccomp-dev [i386 amd64], dh-autoreconf, - python3-dev (>= 3.2.3) -Standards-Version: 3.9.3 +Build-Depends: autotools-dev, + debhelper (>= 9), + dh-apparmor, + dh-autoreconf, + docbook2x, + hardening-wrapper, + libapparmor-dev, + libcap-dev, + libseccomp-dev [i386 amd64], + linux-libc-dev, + pkg-config, + python3-dev (>= 3.2.3) +Standards-Version: 3.9.4 Homepage: http://lxc.sourceforge.net/ X-Python3-Version: >= 3.2 +XS-Testsuite: autopkgtest Package: lxc Architecture: linux-any -Pre-Depends: ${multiarch:Pre-Depends}, dpkg (>= 1.15.7.2) -Depends: ${misc:Depends}, ${shlibs:Depends}, liblxc0 (= ${binary:Version}), apparmor, bridge-utils, dnsmasq-base, iptables, rsync, adduser -Recommends: debootstrap | cdebootstrap, cloud-utils, libcap2-bin, cgroup-lite | cgroup-bin, openssl -Suggests: lxctl, btrfs-tools, lvm2, qemu-user-static +Pre-Depends: ${misc:Pre-Depends} +Depends: adduser, + apparmor, + bridge-utils, + dnsmasq-base, + iptables, + liblxc0 (= ${binary:Version}), + python3, + python3-lxc, + rsync, + ${misc:Depends}, + ${shlibs:Depends} +Recommends: cgroup-lite | cgroup-bin, + libcap2-bin, + lxc-templates (>= 0.8.0~rc1-4ubuntu43), + openssl +Suggests: btrfs-tools, lvm2, lxctl Description: Linux Containers userspace tools Containers are insulated areas inside a system, which have their own namespace for filesystem, network, PID, IPC, CPU and memory allocation and which can be @@ -32,8 +52,9 @@ Section: debug Priority: extra Architecture: linux-any -Depends: - ${misc:Depends}, lxc (= ${binary:Version}), lxc-dev (= ${binary:Version}) +Depends: lxc (= ${binary:Version}), + lxc-dev (= ${binary:Version}), + ${misc:Depends} Description: Linux Containers userspace tools (debug) Containers are insulated areas inside a system, which have their own namespace for filesystem, network, PID, IPC, CPU and memory allocation and which can be @@ -45,7 +66,7 @@ Package: lxc-dev Section: libdevel Architecture: linux-any -Depends: ${misc:Depends}, lxc (= ${binary:Version}) +Depends: lxc (= ${binary:Version}), ${misc:Depends} Description: Linux Containers userspace tools (development) Containers are insulated areas inside a system, which have their own namespace for filesystem, network, PID, IPC, CPU and memory allocation and which can be @@ -54,10 +75,31 @@ . This package contains the development files. +Package: lxc-templates +Architecture: all +Depends: lxc (>= 0.8.0~rc1-4ubuntu43), ${misc:Depends} +Recommends: cloud-image-utils | cloud-utils, + debootstrap | cdebootstrap, + openssl, + rsync, + uuid-runtime +Suggests: qemu-user-static +Replaces: lxc (<< 0.8.0~rc1-4ubuntu43) +Breaks: lxc (<< 0.8.0~rc1-4ubuntu43) +Description: Linux Containers userspace tools (templates) + Containers are insulated areas inside a system, which have their own namespace + for filesystem, network, PID, IPC, CPU and memory allocation and which can be + created using the Control Group and Namespace features included in the Linux + kernel. + . + This package contains the templates. + Package: liblxc0 Architecture: any -Pre-Depends: ${multiarch:Pre-Depends} -Depends: ${shlibs:Depends}, ${misc:Depends} +Pre-Depends: ${misc:Pre-Depends} +Depends: ${misc:Depends}, ${shlibs:Depends} +Replaces: lxc (<< 0.9.0~alpha3-0ubuntu1~) +Breaks: lxc (<< 0.9.0~alpha3-0ubuntu1~) Description: Linux Containers userspace tools (library) Containers are insulated areas inside a system, which have their own namespace for filesystem, network, PID, IPC, CPU and memory allocation and which can be @@ -69,8 +111,11 @@ Package: python3-lxc Architecture: any Section: python -Provides: ${python3:Provides} -Depends: liblxc0 (=${binary:Version}), python3, ${python3:Depends}, ${misc:Depends}, ${shlibs:Depends} +Depends: liblxc0 (=${binary:Version}), + python3, + ${misc:Depends}, + ${shlibs:Depends} +Recommends: lxc-templates (>= 0.8.0~rc1-4ubuntu43) Description: Linux Containers userspace tools (Python 3.x bindings) Containers are insulated areas inside a system, which have their own namespace for filesystem, network, PID, IPC, CPU and memory allocation and which can be diff -Nru lxc-0.8.0~rc1/debian/copyright lxc-1.0.0~alpha1/debian/copyright --- lxc-0.8.0~rc1/debian/copyright 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/copyright 2013-10-07 21:33:27.000000000 +0000 @@ -4,27 +4,78 @@ Source: http://lxc.sourceforge.net/download/lxc/ Files: * -Copyright: 2007-2012 IBM Corporation -License: GPL-2+ +Copyright: 2007-2013 various LXC contributors (see headers for details) +License: LGPL-2.1+ -Files: * -Copyright: 2011-2012 Daniel Baumann -License: GPL-2+ +Files: src/lxc/lxc_clone.c src/lxc/lxc_create.c src/lxc/lxc_destroy.c src/lxc/lxc_snapshot.c src/lxc/lxc_user_nic.c src/tests/cgpath.c src/tests/clonetest.c src/tests/console.c src/tests/containertests.c src/tests/createtest.c src/tests/destroytest.c src/tests/get_item.c src/tests/getkeys.c src/tests/locktests.c src/tests/lxcpath.c src/tests/saveconfig.c src/tests/shutdowntest.c src/tests/snapshot.c src/tests/startone.c +Copyright: 2007-2013 various LXC contributors (see headers for details) +License: GPL-2 + +Files: src/include/getline.c src/include/getline.h +Copyright: 2006 SPARTA, Inc. +License: BSD-2-clause + +Files: src/include/ifaddrs.c src/include/ifaddrs.h +Copyright: 2013 Kenneth MacKay +License: BSD-2-clause -License: GPL-2+ - 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. +Files: src/include/lxcmntent.c src/include/lxcmntent.h src/include/openpty.c src/include/openpty.h +Copyright: 1995-2013 Free Software Foundation, Inc. +License: LGPL-2.1+ + +License: LGPL-2.1+ + 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + . + On Debian systems, the full text of the GNU Lesser General Public + License version 2.1 can be found in the file + `/usr/share/common-licenses/LGPL-2.1'. + +License: GPL-2 + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2, as + published by the Free Software Foundation. . 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 + 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + . + On Debian systems, the full text of the GNU General Public + License version 2 can be found in the file + `/usr/share/common-licenses/GPL-2'. + +License: BSD-2-clause + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. . - The complete text of the GNU General Public License - can be found in /usr/share/common-licenses/GPL-2 file. + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff -Nru lxc-0.8.0~rc1/debian/hooks/mountcgroups lxc-1.0.0~alpha1/debian/hooks/mountcgroups --- lxc-0.8.0~rc1/debian/hooks/mountcgroups 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/hooks/mountcgroups 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ -#!/bin/bash - -# (C) Copyright Canonical 2011,2012 - -# 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 - -# -# This is an example hook to mount all mounted cgroups in the -# container. Only the container's own cgroup (not parents) will be -# accessible to the container. You can enable this by adding -# lxc.hook.mount = /usr/share/lxc/hooks/mountcgroups -# to your container's configuration file. - -set -e - -c=$1 -d=/sys/fs/cgroup -d2=/usr/lib/x86_64-linux-gnu/lxc/${d} -if [ ! -d "$d" ]; then - exit 0 -fi - -mount -n -t tmpfs tmpfs ${d2} - -for dir in `/bin/ls $d`; do - mkdir -p "${d}/${dir}/lxc/${c}/${c}.real" - echo 1 > "${d}/${dir}/lxc/${c}/${c}.real/tasks" - mkdir -p ${d2}/${dir} - mount -n --bind "${d}/${dir}/lxc/${c}/${c}.real" "${d2}/${dir}" -done diff -Nru lxc-0.8.0~rc1/debian/hooks/mountecryptfsroot lxc-1.0.0~alpha1/debian/hooks/mountecryptfsroot --- lxc-0.8.0~rc1/debian/hooks/mountecryptfsroot 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/hooks/mountecryptfsroot 1970-01-01 00:00:00.000000000 +0000 @@ -1,50 +0,0 @@ -#!/bin/bash - -# (C) Copyright Canonical 2011,2012 - -# 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 - -# This hook can be used to mount an ecryptfs filesystem as a container's -# rootfs. -# To use this hook, assuming your container is called q1, -# 1. add 'lxc.hook.pre-mount = /var/lib/lxc/q1/ecryptfs-root' to -# the container's configuration file -# 2. change the rootfs to /var/lib/lxc/q1/ecryptfs-root in the configuration -# file by setting 'lxc.rootfs = /var/lib/lxc/ecryptfs-root' -# 3. Create /var/lib/lxc/q1/ecryptfs-root -# a. mkdir /var/lib/lxc/q1/ecryptfs-root -# 4. convert your container's root filesystem to be ecryptfs-backed. Assuming -# your container is called 'q1', do -# a. c=q1 -# b. mv /var/lib/lxc/$x/rootfs /var/lib/lxc/$c/rootfs.plain -# c. mkdir /var/lib/lxc/$c/rootfs{,.crypt} -# d. sig=`echo none | ecryptfs-add-passphrase | grep -v Passphrase | cut -d[ -f 2 | cut -d] -f 1` -# e. echo $sig > /var/lib/lxc/$c/sig -# f. mount -t ecryptfs -o ecryptfs_cipher=aes,ecryptfs_key_bytes=16,ecryptfs_passthrough=n,ecryptfs_enable_filename_crypto=n,ecryptfs_sig=${sig},sig=${sig},verbosity=0 rootfs.crypt rootfs -# g. rsync -va /var/lib/lxc/$c/rootfs.plain/ /var/lib/lxc/$c/rootfs/ -# h. umount /var/lib/lxc/$c/rootfs -# i. rm -rf /var/lib/lxc/$c/rootfs.plain -# 5. Now you can start your container by adding the passphrase to your -# in-kernel keyring using 'ecryptfs-add-passphrase', then starting your -# container as normal. -# a. echo none | ecryptfs-add-passphrase -# b. lxc-start -n q1 -# Note that you may well want to use a wrapped passhrase (see the ecryptfs-wrap-passphrase(1) manual page). - -set -e -container=$1 -sig=`cat /var/lib/lxc/${container}/sig` -mount -t ecryptfs -o ecryptfs_cipher=aes,ecryptfs_key_bytes=16,ecryptfs_passthrough=n,ecryptfs_enable_filename_crypto=n,ecryptfs_sig=${sig},sig=${sig},verbosity=0 /var/lib/lxc/${container}/rootfs.crypt /var/lib/lxc/${container}/ecryptfs-root -exit 0 diff -Nru lxc-0.8.0~rc1/debian/liblxc0.install lxc-1.0.0~alpha1/debian/liblxc0.install --- lxc-0.8.0~rc1/debian/liblxc0.install 2013-02-08 21:28:52.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/liblxc0.install 2013-10-07 21:33:27.000000000 +0000 @@ -1 +1,2 @@ usr/lib/*/*.so.* +usr/lib/*/lxc/README diff -Nru lxc-0.8.0~rc1/debian/liblxc0.install.in lxc-1.0.0~alpha1/debian/liblxc0.install.in --- lxc-0.8.0~rc1/debian/liblxc0.install.in 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/liblxc0.install.in 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -usr/lib/*/*.so.* diff -Nru lxc-0.8.0~rc1/debian/local/examples/lxc-debian.cfg lxc-1.0.0~alpha1/debian/local/examples/lxc-debian.cfg --- lxc-0.8.0~rc1/debian/local/examples/lxc-debian.cfg 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/local/examples/lxc-debian.cfg 1970-01-01 00:00:00.000000000 +0000 @@ -1,56 +0,0 @@ -## LXC - -# lxc-debconf -linux-container linux-container/debconf-frontend select noninteractive -linux-container linux-container/debconf-priority select critical - -linux-container linux-container/distribution string squeeze -linux-container linux-container/architecture select -linux-container linux-container/packages string - -linux-container linux-container/mirror string http://ftp.ch.debian.org/debian/ -linux-container linux-container/mirror-security string http://ftp.ch.debian.org/debian-security/ -linux-container linux-container/mirror-backports string http://ftp.ch.debian.org/debian-backports/ - -linux-container linux-container/archives multiselect squeeze-security, squeeze-updates, squeeze-backports -linux-container linux-container/archive-areas multiselect main - -linux-container linux-container/auto boolean false -linux-container linux-container/capabilities string mac_admin mac_override sys_admin sys_module -#linux-container linux-container/mount0/comment string -#linux-container linux-container/mount0/entry string -linux-container linux-container/late-command string -linux-container linux-container/late-host-command string - -# linux-container -linux-container linux-container/enable boolean true -linux-container linux-container/consoles string 6 -linux-container linux-container/hostname string debian - -linux-container linux-container/eth0/comment string The primary network interface -linux-container linux-container/eth0/dhcp boolean true -linux-container linux-container/eth0/mac string 00:FF:00:00:00:02 -linux-container linux-container/eth0/bridge string br0 -linux-container linux-container/eth0/veth string veth-debian - -## System - -# tzdata -tzdata tzdata/Areas select Europe -tzdata tzdata/Zones/Etc select UTC -tzdata tzdata/Zones/Europe select Zurich - -# user-setup -user-setup passwd/make-user boolean true -user-setup passwd/user-fullname string System Administration -user-setup passwd/username string sysadmin -user-setup passwd/user-password password debian -user-setup passwd/user-password-again password debian -user-setup passwd/user-uid string 1000 -user-setup passwd/user-default-groups string audio cdrom dip floppy video plugdev netdev powerdev scanner bluetooth -# wheezy -#user-setup passwd/user-default-groups string audio cdrom dip floppy video plugdev netdev powerdev scanner bluetooth debian-tor -user-setup passwd/root-login boolean true -user-setup passwd/root-password password debian -user-setup passwd/root-password-again password debian -user-setup passwd/shadow boolean true diff -Nru lxc-0.8.0~rc1/debian/local/examples/lxc-progress.cfg lxc-1.0.0~alpha1/debian/local/examples/lxc-progress.cfg --- lxc-0.8.0~rc1/debian/local/examples/lxc-progress.cfg 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/local/examples/lxc-progress.cfg 1970-01-01 00:00:00.000000000 +0000 @@ -1,95 +0,0 @@ -## LXC - -# lxc-debconf -linux-container linux-container/debconf-frontend select noninteractive -linux-container linux-container/debconf-priority select critical - -linux-container linux-container/distribution string artax-backports -linux-container linux-container/architecture select -linux-container linux-container/packages string bash-completion cron less logrotate postfix psmisc rsync rsyslog screen sudo user-setup vim git git-stuff inetutils-ping - -linux-container linux-container/mirror string http://eu.archive.progress-linux.org/progress/ -linux-container linux-container/parent-mirror string http://ftp.ch.debian.org/debian/ -linux-container linux-container/parent-mirror-security string http://ftp.ch.debian.org/debian-security/ -linux-container linux-container/parent-mirror-backports string http://ftp.ch.debian.org/debian-backports/ - -linux-container linux-container/archives multiselect artax-security, artax-updates, artax-backports -linux-container linux-container/parent-archives multiselect squeeze-security, squeeze-updates -linux-container linux-container/archive-areas multiselect main, contrib, non-free -linux-container linux-container/parent-archive-areas multiselect main, contrib, non-free - -linux-container linux-container/local0/comment string Third-Party Software -linux-container linux-container/local0/list string 3rd-party -linux-container linux-container/local0/repository string http://archive.progress-technologies.net/progress/ artax main contrib non-free restricted -linux-container linux-container/local0/key string http://archive.progress-technologies.net/progress/project/keys/archive-key-1.0-artax-automatic.asc -linux-container linux-container/local0/source boolean false - -linux-container linux-container/auto boolean true -linux-container linux-container/capabilities string mac_admin mac_override sys_admin sys_module -#linux-container linux-container/mount0/comment string -#linux-container linux-container/mount0/entry string -linux-container linux-container/late-command string -linux-container linux-container/late-host-command string - -# linux-container -linux-container linux-container/enable boolean true -linux-container linux-container/consoles string 1 -linux-container linux-container/hostname string progress - -linux-container linux-container/eth0/comment string private -linux-container linux-container/eth0/dhcp boolean false -linux-container linux-container/eth0/address string 10.0.2.200 -linux-container linux-container/eth0/broadcast string 10.0.2.255 -linux-container linux-container/eth0/gateway string 10.0.2.1 -linux-container linux-container/eth0/mtu string 1500 -linux-container linux-container/eth0/netmask string 255.255.255.0 -linux-container linux-container/eth0/network string 10.0.2.0 -linux-container linux-container/eth0/post-up string route add -net 10.0.0.0 netmask 255.255.0.0 gw 10.0.2.1 dev eth0 -linux-container linux-container/eth0/mac string 00:FF:10:00:02:00 -linux-container linux-container/eth0/bridge string br0 -linux-container linux-container/eth0/veth string veth-private200 - -linux-container linux-container/eth1/comment string public -linux-container linux-container/eth1/dhcp boolean false -linux-container linux-container/eth1/address string 123.45.678.200 -linux-container linux-container/eth1/broadcast string 123.45.678.255 -linux-container linux-container/eth1/mtu string 1500 -linux-container linux-container/eth1/netmask string 255.255.255.0 -linux-container linux-container/eth1/network string 123.45.678.128 -linux-container linux-container/eth1/mac string 00:FF:12:00:02:00 -linux-container linux-container/eth1/bridge string br1 -linux-container linux-container/eth1/veth string veth-public200 - -linux-container linux-container/nameservers string 8.8.8.8 8.8.4.4 - -## System - -# debconf -debconf debconf/frontend select dialog -debconf debconf/priority select low - -# git-stuff -git-stuff git-stuff/bash-profile boolean true - -# postfix -postfix postfix/main_mailer_type select Internet Site -postfix postfix/mailname string progress - -# tzdata -tzdata tzdata/Areas select Europe -tzdata tzdata/Zones/Etc select UTC -tzdata tzdata/Zones/Europe select Zurich - -# user-setup -user-setup passwd/make-user boolean true -user-setup passwd/user-fullname string System Administration -user-setup passwd/username string sysadmin -user-setup passwd/user-password password progress -user-setup passwd/user-password-again password progress -user-setup passwd/user-uid string 1000 -user-setup passwd/user-default-groups string audio cdrom dip floppy video plugdev netdev powerdev scanner bluetooth sudo -# baureo -#user-setup passwd/user-default-groups string audio cdrom dip floppy video plugdev netdev powerdev scanner bluetooth debian-tor sudo -user-setup passwd/root-login boolean true -user-setup passwd/root-password-crypted string * -user-setup passwd/shadow boolean true diff -Nru lxc-0.8.0~rc1/debian/local/lxc lxc-1.0.0~alpha1/debian/local/lxc --- lxc-0.8.0~rc1/debian/local/lxc 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/local/lxc 1970-01-01 00:00:00.000000000 +0000 @@ -1,46 +0,0 @@ -#!/bin/sh - -set -e - -_PROGRAM="${1}" - -if [ -n "${_PROGRAM}" ] -then - shift -else - echo "Usage: ${0} PROGRAM CONTAINER" - exit 1 -fi - -if [ ! -x "$(which lxc-${_PROGRAM} 2>/dev/null)" ] -then - echo "E: lxc-${_PROGRAM} - no such program" >&2 - exit 1 -fi - -_CONTAINER="${1}" - -if [ -n "${_CONTAINER}" ] -then - shift - - if ! lxc-ls | grep -qs ^${_CONTAINER}$ - then - echo "E: ${_CONTAINER} - no such container" >&2 - exit 1 - fi - - _OPTIONS="--name ${_CONTAINER}" -else - case "${_PROGRAM}" in - backup|list|restore) - ;; - - *) - echo "Usage: ${0} PROGRAM CONTAINER" - exit 1 - ;; - esac -fi - -lxc-${_PROGRAM} ${_OPTIONS} ${@} diff -Nru lxc-0.8.0~rc1/debian/local/lxc-aa-custom-profile lxc-1.0.0~alpha1/debian/local/lxc-aa-custom-profile --- lxc-0.8.0~rc1/debian/local/lxc-aa-custom-profile 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/local/lxc-aa-custom-profile 2013-10-07 21:32:53.000000000 +0000 @@ -16,6 +16,8 @@ # License along with this library; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +. /usr/share/lxc/lxc.functions + set -e _OPTIONS="$(getopt -o n: -l name: -- "${@}")" @@ -60,8 +62,8 @@ exit 1 fi -if [ ! -f /var/lib/lxc/${_CONTAINER}/config ]; then - echo "E: $(basename ${0}): /var/lib/lxc/${_CONTAINER}/config - no such file" +if [ ! -f $lxc_path/${_CONTAINER}/config ]; then + echo "E: $(basename ${0}): $lxc_path/${_CONTAINER}/config - no such file" exit 1 fi @@ -79,8 +81,8 @@ cp -f /etc/apparmor.d/lxc/lxc-default /etc/apparmor.d/lxc/${profile} sed -i "s/profile lxc-container-default/profile ${profile}/" /etc/apparmor.d/lxc/${profile} -sed -i '/lxc.aa_profile/d' /var/lib/lxc/${_CONTAINER}/config -echo "lxc.aa_profile = ${profile}" >> /var/lib/lxc/${_CONTAINER}/config +sed -i '/lxc.aa_profile/d' $lxc_path/${_CONTAINER}/config +echo "lxc.aa_profile = ${profile}" >> $lxc_path/${_CONTAINER}/config /lib/init/apparmor-profile-load lxc-containers diff -Nru lxc-0.8.0~rc1/debian/local/lxc-backup lxc-1.0.0~alpha1/debian/local/lxc-backup --- lxc-0.8.0~rc1/debian/local/lxc-backup 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/local/lxc-backup 1970-01-01 00:00:00.000000000 +0000 @@ -1,53 +0,0 @@ -#!/bin/sh - -set -e - -_CONTAINER="${1}" - -if [ -n "${_CONTAINER}" ] -then - shift -else -# echo "Usage: ${0} CONTAINER [BACKUP_NUMBER]" - echo "Usage: ${0} CONTAINER" - exit 1 -fi - -if [ ! -x "$(which rsync 2>/dev/null)" ] -then - echo "E: rsync - no such file" >&2 - exit 1 -fi - -if [ ! -x "$(which lxc-info 2>/dev/null)" ] -then - echo "E: lxc-info - no such file" >&2 - exit 1 -fi - -if ! lxc-info -n ${_CONTAINER} 2>&1 | grep -qs "STOPPED" -then - echo "E: ${_CONTAINER} - not stopped" >&2 - exit 1 -fi - -# FIXME: Assumption of /var/lib/lxc -if [ -e /var/lib/lxc/${_CONTAINER}/rootfs ] -then -# if [ -n "${2}" ] -# then -# _BACKUP="${2}" -# else -# _BACKUP="1" -# -# while [ -e "/var/lib/lxc/${_CONTAINER}/rootfs.backup${_BACKUP}" ] -# do -# _BACKUP="$((${_BACKUP} + 1))" -# done -# fi - - rsync -aPHv --delete --progress /var/lib/lxc/${_CONTAINER}/rootfs/ /var/lib/lxc/${_CONTAINER}/rootfs.backup${_BACKUP} -else - echo "E: /var/lib/lxc/${_CONTAINER}/rootfs - no such directory" >&2 - exit 1 -fi diff -Nru lxc-0.8.0~rc1/debian/local/lxc-debconf lxc-1.0.0~alpha1/debian/local/lxc-debconf --- lxc-0.8.0~rc1/debian/local/lxc-debconf 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/local/lxc-debconf 1970-01-01 00:00:00.000000000 +0000 @@ -1,915 +0,0 @@ -#!/bin/bash - -Chroot () -{ - _CHROOT="${1}" - shift - - chroot "${_CHROOT}" /usr/bin/env -i \ - LC_ALL="C" PATH="/usr/sbin:/usr/bin:/sbin:/bin" TERM="${TERM}" \ - DEBIAN_FRONTEND="${_DEBCONF_FRONTEND}" DEBIAN_PRIORITY="${_DEBCONF_PRIORITY}" \ - ftp_proxy="${ftp_proxy}" http_proxy="${http_proxy}" \ - ${@} -} - -Upgrade_system () -{ - _ROOT="${1}" - - # Mount pseudo-filesystems - mount -o bind /dev/pts "${_ROOT}/dev/pts" - mount -o bind /proc "${_ROOT}/proc" - mount -o bind /sys "${_ROOT}/sys" - - # Bind mount systems apt cache - mount -o bind /var/cache/apt/archives "${_ROOT}/var/cache/apt/archives" - - # Disable dpkg syncing - -cat > "${_ROOT}/etc/dpkg/dpkg.cfg.d/lxc-debconf" << EOF -force-unsafe-io -EOF - - # Create policy-rc.d file - -cat > "${_ROOT}/usr/sbin/policy-rc.d" << EOF -#!/bin/sh -echo "All runlevel operations denied by policy" >&2 -exit 101 -EOF - - chmod 0755 "${_ROOT}/usr/sbin/policy-rc.d" - - # Upgrade system - Chroot "${_ROOT}" "apt-get update" - Chroot "${_ROOT}" "apt-get --yes upgrade" - Chroot "${_ROOT}" "apt-get --yes dist-upgrade" - - # Unmount systems apt cache - umount "${_ROOT}/var/cache/apt/archives" - - Chroot "${_ROOT}" "apt-get clean" -} - -Cleanup_system () -{ - _ROOT="${1}" - - Chroot "${_ROOT}" "apt-get --yes autoremove" - Chroot "${_ROOT}" "apt-get clean" - - # Cleanup - rm -f "${_ROOT}/etc/dpkg/dpkg.cfg.d/lxc-debconf" - rm -f "${_ROOT}/usr/sbin/policy-rc.d" - - # Unmount pseudo-filesystems - umount "${_ROOT}/dev/pts" - umount "${_ROOT}/proc" - umount "${_ROOT}/sys" -} - -Configure_system () -{ - _ROOTFS="${1}" - - # Configure apt - rm -f "${_ROOTFS}/etc/apt/sources.list" - - _PARENT_AREA="$(echo ${_PARENT_ARCHIVE_AREAS} | sed -e 's|,| |g')" - _PARENT_DIST="$(echo ${_PARENT_DISTRIBUTION} | sed -e 's|-backports||')" - - echo "deb ${_PARENT_MIRROR} ${_PARENT_DIST} ${_PARENT_AREA}" > "${_ROOTFS}/etc/apt/sources.list.d/debian.list" - - for _PARENT_REPO in ${_PARENT_ARCHIVES} - do - case "${_PARENT_REPO}" in - ${_PARENT_DIST}-security) - echo "deb ${_PARENT_MIRROR_SECURITY} ${_PARENT_DIST}/updates ${_PARENT_AREA}" >> "${_ROOTFS}/etc/apt/sources.list.d/debian.list" - ;; - - ${_PARENT_DIST}-updates) - echo "deb ${_PARENT_MIRROR} ${_PARENT_DIST}-updates ${_PARENT_AREA}" >> "${_ROOTFS}/etc/apt/sources.list.d/debian.list" - ;; - - ${_PARENT_DIST}-backports) - echo "deb ${_PARENT_MIRROR_BACKPORTS} ${_PARENT_DIST}-backports ${_PARENT_AREA}" >> "${_ROOTFS}/etc/apt/sources.list.d/debian.list" - ;; - - ${_PARENT_DIST}-proposed-updates) - echo "deb ${_PARENT_MIRROR} ${_PARENT_DIST}-proposed-updates ${_PARENT_AREA}" >> "${_ROOTFS}/etc/apt/sources.list.d/debian.list" - esac - done - - case "${_MODE}" in - progress) - _AREA="$(echo ${_ARCHIVE_AREAS} | sed -e 's|,| |g')" - _DIST="$(echo ${_DISTRIBUTION} | sed -e 's|-backports||')" - - echo "deb ${_MIRROR} ${_DIST} ${_AREA}" > "${_ROOTFS}/etc/apt/sources.list.d/progress.list" - - for _REPO in ${_ARCHIVES} - do - case "${_REPO}" in - ${_DIST}-staging) - echo "deb ${_MIRROR} ${_DIST}-staging ${_AREA}" >> "${_ROOTFS}/etc/apt/sources.list.d/progress.list" - ;; - - ${_DIST}-security) - echo "deb ${_MIRROR_SECURITY} ${_DIST}-security ${_AREA}" >> "${_ROOTFS}/etc/apt/sources.list.d/progress.list" - ;; - - ${_DIST}-security-staging) - echo "deb ${_MIRROR_SECURITY} ${_DIST}-security-staging ${_AREA}" >> "${_ROOTFS}/etc/apt/sources.list.d/progress.list" - ;; - - ${_DIST}-updates) - echo "deb ${_MIRROR} ${_DIST}-updates ${_AREA}" >> "${_ROOTFS}/etc/apt/sources.list.d/progress.list" - ;; - - ${_DIST}-updates-staging) - echo "deb ${_MIRROR} ${_DIST}-updates-staging ${_AREA}" >> "${_ROOTFS}/etc/apt/sources.list.d/progress.list" - ;; - - ${_DIST}-backports) - echo "deb ${_MIRROR_BACKPORTS} ${_DIST}-backports ${_AREA}" >> "${_ROOTFS}/etc/apt/sources.list.d/progress.list" - ;; - - ${_DIST}-backports-staging) - echo "deb ${_MIRROR_BACKPORTS} ${_DIST}-backports-staging ${_AREA}" >> "${_ROOTFS}/etc/apt/sources.list.d/progress.list" - ;; - esac - done - ;; - - *) - if [ "${_APT_RECOMMENDS}" = "false" ] - then - -cat > "${_ROOTFS}/etc/apt/apt.conf.d/recommends.conf" << EOF -APT::Install-Recommends "false"; -EOF - - fi - ;; - esac - - # Configure fstab - -cat > "${_ROOTFS}/etc/fstab" << EOF -# /etc/fstab: static file system information. -# -# Use 'blkid' to print the universally unique identifier for a -# device; this may be used with UUID= as a more robust way to name devices -# that works even if disks are added and removed. See fstab(5). -# -# - -EOF - - Upgrade_system "${_ROOTFS}" - - # Temporary hack for base-files (FIXME) - for _FILE in motd profile - do - rm -f "${_ROOTFS}/etc/${_FILE}" - cp "${_ROOTFS}/usr/share/base-files/${_FILE}" "${_ROOTFS}/etc" - done - - # Removing hostname - rm -f "${_ROOTFS}"/etc/hostname - - # Removing openssh-server host keys - rm -f "${_ROOTFS}"/etc/ssh/ssh_host_*_key - rm -f "${_ROOTFS}"/etc/ssh/ssh_host_*_key.pub - - # Preseed system - if [ -e "${_PRESEED_FILE}" ] - then - cat "${_PRESEED_FILE}" > "${_ROOTFS}/preseed.cfg" - - Chroot "${_ROOTFS}" "debconf-set-selections preseed.cfg" - - rm -f "${_ROOTFS}/preseed.cfg" - fi - - # Reconfigure tzdata - if grep -qs tzdata "${_PRESEED_FILE}" - then - Chroot "${_ROOTFS}" "DEBIAN_FRONTEND=noninteractive DEBIAN_PRIORITY=criticial dpkg-reconfigure tzdata" - fi - - # Install additional packages - if [ -n "${_PACKAGES}" ] - then - Chroot "${_ROOTFS}" "apt-get --yes install ${_PACKAGES}" - fi - - # Configure linux-container - -cat > "${_ROOTFS}/preseed.cfg" << EOF -linux-container linux-container/enable boolean true -EOF - - Chroot "${_ROOTFS}" "debconf-set-selections preseed.cfg" - - rm -f "${_ROOTFS}/preseed.cfg" - - if ls /usr/share/lxc/packages/linux-container*deb > /dev/null 2>&1 - then - # Install local linux-container package - cp -L /usr/share/lxc/packages/linux-container_*.deb "${_ROOTFS}" - - Chroot "${_ROOTFS}" "dpkg -i $(basename ${_ROOTFS}/linux-container_*.deb)" - rm -f "${_ROOTFS}"/linux-container_*.deb - else - # Install remote linux-container package - Chroot "${_ROOTFS}" "apt-get install --yes linux-container" - fi - - # Configure user-setup - -cat > "${_ROOTFS}/preseed.cfg" << EOF -user-setup passwd/root-password string ${_ROOT_PASSWORD} -user-setup passwd/root-password-again string ${_ROOT_PASSWORD} -EOF - - Chroot "${_ROOTFS}" "debconf-set-selections preseed.cfg" - Chroot "${_ROOTFS}" "/usr/lib/user-setup/user-setup-apply" - - rm -f "${_ROOTFS}/preseed.cfg" - - case "${_ROOT_RANDOM_PASSWORD}" in - true) - echo "P: Setting root password to ${_ROOT_PASSWORD}" - ;; - esac - - if [ -n "${_LATE_COMMAND}" ] - then - Chroot "${_ROOTFS}" "${_LATE_COMMAND}" - fi - - if [ -n "${_LATE_HOST_COMMAND}" ] - then - ${_LATE_HOST_COMMAND} - fi - - Cleanup_system "${_ROOTFS}" - - return 0 -} - -Download_system () -{ - _CACHE="${1}" - _ARCHITECTURE="${2}" - - case "${_MODE}" in - debian) - _INCLUDE="ifupdown,locales,libui-dialog-perl,dialog,isc-dhcp-client,netbase,net-tools,iproute,user-setup,openssh-server" - ;; - - progress) - _INCLUDE="apt-utils,ifupdown,locales-all,libui-dialog-perl,dialog,isc-dhcp-client,netbase,net-tools,iproute,user-setup" - ;; - esac - - # check the minimal system was not already downloaded - mkdir -p "${_CACHE}/${_DISTRIBUTION}_${_ARCHITECTURE}.partial" - - if [ "${?}" -ne 0 ] - then - echo "Failed to create '${_CACHE}/${_DISTRIBUTION}_${_ARCHITECTURE}.partial' directory" - return 1 - fi - - # download a minimal system into a cache - echo "Downloading minimal system..." - - if [ -x "$(which cdebootstrap 2>/dev/null)" ] - then - cdebootstrap --arch=${_ARCHITECTURE} \ - --flavour=minimal --include=${_INCLUDE} \ - ${_PARENT_DISTRIBUTION} "${_CACHE}/${_DISTRIBUTION}_${_ARCHITECTURE}.partial" ${_PARENT_MIRROR} - - Chroot "${_CACHE}/${_DISTRIBUTION}_${_ARCHITECTURE}.partial" "dpkg --purge cdebootstrap-helper-rc.d" - elif [ -x "$(which debootstrap 2>/dev/null)" ] - then - debootstrap --verbose --arch=${_ARCHITECTURE} --components=${_PARENT_ARCHIVE_AREAS} \ - --variant=minbase --include=${_INCLUDE} \ - ${_PARENT_DISTRIBUTION} "${_CACHE}/${_DISTRIBUTION}_${_ARCHITECTURE}.partial" ${_PARENT_MIRROR} - fi - - if [ "${?}" -ne 0 ] - then - echo "Failed to download the rootfs, aborting." - return 1 - fi - - # Configure apt - rm -f "${_CACHE}/${_DISTRIBUTION}_${_ARCHITECTURE}.partial/etc/apt/sources.list" - - _PARENT_AREA="$(echo ${_PARENT_ARCHIVE_AREAS} | sed -e 's|,| |g')" - _PARENT_DIST="$(echo ${_PARENT_DISTRIBUTION} | sed -e 's|-backports||')" - - echo "deb ${_PARENT_MIRROR} ${_PARENT_DIST} ${_PARENT_AREA}" > "${_CACHE}/${_DISTRIBUTION}_${_ARCHITECTURE}.partial/etc/apt/sources.list.d/debian.list" - - case "${_MODE}" in - progress) - _AREA="$(echo ${_ARCHIVE_AREAS} | sed -e 's|,| |g')" - _DIST="$(echo ${_DISTRIBUTION} | sed -e 's|-backports||')" - - echo "deb ${_MIRROR} ${_DIST} ${_AREA}" > "${_CACHE}/${_DISTRIBUTION}_${_ARCHITECTURE}.partial/etc/apt/sources.list.d/progress.list" - - for _REPO in ${_ARCHIVES} - do - case "${_REPO}" in - ${_DIST}-staging) - echo "deb ${_MIRROR} ${_DIST}-staging ${_AREA}" >> "${_CACHE}/${_DISTRIBUTION}_${_ARCHITECTURE}.partial/etc/apt/sources.list.d/progress.list" - ;; - esac - done - - case "${_DISTRIBUTION}" in - *-backports) - for _REPO in ${_ARCHIVES} - do - case "${_REPO}" in - ${_DIST}-backports) - echo "deb ${_MIRROR_BACKPORTS} ${_DIST}-backports ${_AREA}" >> "${_CACHE}/${_DISTRIBUTION}_${_ARCHITECTURE}.partial/etc/apt/sources.list.d/progress.list" - ;; - - ${_DIST}-backports-staging) - echo "deb ${_MIRROR_BACKPORTS} ${_DIST}-backports-staging ${_AREA}" >> "${_CACHE}/${_DISTRIBUTION}_${_ARCHITECTURE}.partial/etc/apt/sources.list.d/progress.list" - ;; - esac - done - ;; - esac - -cat > "${_CACHE}/${_DISTRIBUTION}_${_ARCHITECTURE}.partial/etc/apt/apt.conf.d/progress.conf" << EOF -Acquire::PDiffs "false"; -// Acquire::Language "none"; -APT::Clean-Installed "true"; -APT::Get:AutomaticRemove "true"; -APT::Get::HideAutoRemove "false"; -APT::Get:Show-Upgraded "true"; -APT::Install-Recommends "false"; -EOF - -cat > "${_CACHE}/${_DISTRIBUTION}_${_ARCHITECTURE}.partial/etc/apt/preferences.d/progress.pref" << EOF -Package: * -Pin: release n=${_DIST} -Pin-Priority: 999 - -Package: * -Pin: release n=${_DIST}-security -Pin-Priority: 999 - -Package: * -Pin: release n=${_DIST}-updates -Pin-Priority: 999 -EOF - case "${_DISTRIBUTION}" in - *-backports) - -cat >> "${_CACHE}/${_DISTRIBUTION}_${_ARCHITECTURE}.partial/etc/apt/preferences.d/progress.pref" << EOF - -Package: * -Pin: release n=${_DIST}-backports -Pin-Priority: 999 -EOF - - ;; - - *) - -cat >> "${_CACHE}/${_DISTRIBUTION}_${_ARCHITECTURE}.partial/etc/apt/preferences.d/progress.pref" << EOF - -#Package: * -#Pin: release n=${_DIST}-backports -#Pin-Priority: 999 -EOF - - ;; - esac - - # Import archive keys - for _KEY in 1.0-artax-automatic 1.0-artax-stable - do - wget "${_MIRROR}/project/keys/archive-key-${_KEY}.asc" -O "${_CACHE}/${_DISTRIBUTION}_${_ARCHITECTURE}.partial/key.asc" - Chroot "${_CACHE}/${_DISTRIBUTION}_${_ARCHITECTURE}.partial" "apt-key add key.asc" - rm -f "${_CACHE}/${_DISTRIBUTION}_${_ARCHITECTURE}.partial/key.asc" - done - ;; - esac - - mv "${_CACHE}/${_DISTRIBUTION}_${_ARCHITECTURE}.partial" "${_CACHE}/${_DISTRIBUTION}_${_ARCHITECTURE}" - echo "Download complete." - - return 0 -} - -Copy_system () -{ - _CACHE="${1}" - _ARCHITECTURE="${2}" - _ROOTFS="${3}" - - if [ -e "/usr/share/lxc/cache/${_MODE}/${_DISTRIBUTION}_${_ARCHITECTURE}" ] - then - # system cache in the form of a directory - echo -n "Copying system cache to ${_ROOTFS}..." - cp -a "/usr/share/lxc/cache/${_MODE}/${_DISTRIBUTION}_${_ARCHITECTURE}" "${_ROOTFS}" || return 1 - elif ls "/usr/share/lxc/cache/${_MODE}/${_DISTRIBUTION}_${_ARCHITECTURE}".* > /dev/null 2>&1 - then - # system cache in the form of a tarball - for _FORMAT in tar.lz tar.xz tar.lzma tar.bz2 tar.gz tar - do - if [ -e "/usr/share/lxc/cache/${_MODE}/${_DISTRIBUTION}_${_ARCHITECTURE}.${_FORMAT}" ] - then - echo -n "Extracting system cache to ${_ROOTFS}..." - - mkdir -p "${_ROOTFS}" - tar xf "/usr/share/lxc/cache/${_MODE}/${_DISTRIBUTION}_${_ARCHITECTURE}.${_FORMAT}" -C "${_ROOTFS}" || return 1 - break - fi - done - else - # local cache from bootstrap - - # Upgrade cache before copying it - Upgrade_system "${_CACHE}/${_DISTRIBUTION}_${_ARCHITECTURE}" - Cleanup_system "${_CACHE}/${_DISTRIBUTION}_${_ARCHITECTURE}" - - # make a local copy of the minimal system - echo -n "Copying local cache to ${_ROOTFS}..." - cp -a "${_CACHE}/${_DISTRIBUTION}_${_ARCHITECTURE}" "${_ROOTFS}" || return 1 - fi - - # Add local repositories configured from preseed file - if ls "${_TMPDIR}/sources.list.d"/*.list > /dev/null 2>&1 - then - cp "${_TMPDIR}/sources.list.d"/*.list "${_ROOTFS}/etc/apt/sources.list.d" - - if ls "${_TMPDIR}/sources.list.d"/*.key > /dev/null 2>&1 - then - for _KEY in "${_TMPDIR}/sources.list.d"/*.key - do - cp "${_KEY}" "${_ROOTFS}" - Chroot "${_ROOTFS}" "apt-key add $(basename ${_KEY})" - rm -f "${_ROOTFS}/$(basename ${_KEY})" - done - fi - - Upgrade_system "${_ROOTFS}" - Cleanup_system "${_ROOTFS}" - fi - - return 0 -} - -Install_system () -{ - _CACHE="/var/cache/lxc/${_MODE}" - _ROOTFS="${1}" - - mkdir -p /var/lock/subsys/ - ( - flock -n -x 200 - - if [ "${?}" -ne 0 ] - then - echo "Cache repository is busy." - return 1 - fi - - _ARCHITECTURE="${_ARCHITECTURE:-$(dpkg --print-architecture)}" - - if ! ls "/usr/share/lxc/cache/${_MODE}/${_DISTRIBUTION}_${_ARCHITECTURE}"* > /dev/null 2>&1 && \ - [ ! -e "${_CACHE}/${_DISTRIBUTION}_${_ARCHITECTURE}" ] - then - Download_system "${_CACHE}" "${_ARCHITECTURE}" - - if [ "${?}" -ne 0 ] - then - echo "Failed to download base system" - return 1 - fi - fi - - Copy_system "${_CACHE}" "${_ARCHITECTURE}" "${_ROOTFS}" - - if [ "${?}" -ne 0 ] - then - echo "Failed to copy rootfs" - return 1 - fi - - return 0 - ) 200>/var/lock/subsys/lxc - - return "${?}" -} - -Copy_configuration() -{ - _PATH="${1}" - _ROOTFS="${2}" - _NAME="${3}" - -cat >> "${_PATH}/config" << EOF -# ${_PATH}/config - -## Container -lxc.utsname = ${_NAME} -lxc.rootfs = ${_ROOTFS} -EOF - - case "${_ARCHITECTURE}" in - amd64) - echo "lxc.arch = x86_64" >> "${_PATH}/config" - ;; - - i386) - echo "lxc.arch = x86" >> "${_PATH}/config" - ;; - esac - -cat >> "${_PATH}/config" << EOF -#lxc.console = /var/log/lxc/${_NAME}.console -lxc.tty = 6 -lxc.pts = 1024 - -## Capabilities -EOF - - _CAPABILITIES="${_CAPABILITIES:-mac_admin mac_override sys_admin sys_module}" - - for _CAPABILITY in ${_CAPABILITIES} - do - echo "lxc.cap.drop = ${_CAPABILITY}" >> "${_PATH}/config" - done - -cat >> "${_PATH}/config" << EOF -## Devices -# Allow all devices -#lxc.cgroup.devices.allow = a -# Deny all devices -lxc.cgroup.devices.deny = a -# Allow to mknod all devices (but not using them) -lxc.cgroup.devices.allow = c *:* m -lxc.cgroup.devices.allow = b *:* m - -# /dev/console -lxc.cgroup.devices.allow = c 5:1 rwm -# /dev/fuse -lxc.cgroup.devices.allow = c 10:229 rwm -# /dev/null -lxc.cgroup.devices.allow = c 1:3 rwm -# /dev/ptmx -lxc.cgroup.devices.allow = c 5:2 rwm -# /dev/pts/* -lxc.cgroup.devices.allow = c 136:* rwm -# /dev/random -lxc.cgroup.devices.allow = c 1:8 rwm -# /dev/rtc -lxc.cgroup.devices.allow = c 254:0 rwm -# /dev/tty -lxc.cgroup.devices.allow = c 5:0 rwm -# /dev/urandom -lxc.cgroup.devices.allow = c 1:9 rwm -# /dev/zero -lxc.cgroup.devices.allow = c 1:5 rwm - -## Limits -#lxc.cgroup.cpu.shares = 1024 -#lxc.cgroup.cpuset.cpus = 0 -#lxc.cgroup.memory.limit_in_bytes = 256M -#lxc.cgroup.memory.memsw.limit_in_bytes = 1G - -## Filesystem -lxc.mount.entry = proc ${_ROOTFS}/proc proc nodev,noexec,nosuid 0 0 -lxc.mount.entry = sysfs ${_ROOTFS}/sys sysfs defaults,ro 0 0 -EOF - - # Adding preseeded mount entries - for _NUMBER in $(seq 0 ${LINUX_CONTAINER_MOUNT_NUMBER}) - do - eval _COMMENT="$`echo LINUX_CONTAINER_MOUNT${_NUMBER}_COMMENT`" - eval _ENTRY="$`echo LINUX_CONTAINER_MOUNT${_NUMBER}_ENTRY`" - - if [ -n "${_COMMENT}" ] - then - echo "# ${_COMMENT}" >> "${_PATH}/config" - fi - - if [ -n "${_ENTRY}" ] - then - echo "lxc.mount.entry = ${_ENTRY}" >> "${_PATH}/config" - - # Create directories - _DIRECTORIES="$(echo ${_ENTRY} | awk '{ print $1, $2 }')" - mkdir -p ${_DIRECTORIES} - fi - done - - if [ -z "${_ENTRY}" ] - then - # Adding shared data directory if existing - if [ -d "/srv/share/${_NAME}" ] - then - echo "lxc.mount.entry = /srv/share/${_NAME} ${_ROOTFS}/srv/${_NAME} none defaults,bind 0 0" >> "${_PATH}/config" - elif [ -d "/srv/${_NAME}" ] - then - echo "lxc.mount.entry = /srv/${_NAME} ${_ROOTFS}/srv/${_NAME} none defaults,bind 0 0" >> "${_PATH}/config" - elif [ -d "/srv/share" ] - then - echo "#lxc.mount.entry = /srv/share/${_NAME} ${_ROOTFS}/srv/${_NAME} none defaults,bind 0 0" >> "${_PATH}/config" - else - echo "#lxc.mount.entry = /srv/${_NAME} ${_ROOTFS}/srv/${_NAME} none defaults,bind 0 0" >> "${_PATH}/config" - fi - fi - - # Adding network configuration - for _NUMBER in $(seq 0 ${LINUX_CONTAINER_ETH_NUMBER}) - do - eval _COMMENT="$`echo LINUX_CONTAINER_ETH${_NUMBER}_COMMENT`" - eval _BRIDGE="$`echo LINUX_CONTAINER_ETH${_NUMBER}_BRIDGE`" - eval _MAC="$`echo LINUX_CONTAINER_ETH${_NUMBER}_MAC`" - eval _MTU="$`echo LINUX_CONTAINER_ETH${_NUMBER}_MTU`" - eval _VETH="$`echo LINUX_CONTAINER_ETH${_NUMBER}_VETH`" - - if [ -n "${_COMMENT}" ] - then - -cat >> "${_PATH}/config" << EOF - -## Network: ${_COMMENT} -EOF - - else - -cat >> "${_PATH}/config" << EOF - -## Network -EOF - - fi - -cat >> "${_PATH}/config" << EOF -lxc.network.type = veth -lxc.network.flags = up -lxc.network.hwaddr = ${_MAC} -lxc.network.link = ${_BRIDGE} -EOF - - if [ -n "${_MTU}" ] - then - echo "lxc.network.mtu = ${_MTU}" >> "${_PATH}/config" - fi - - echo "lxc.network.name = eth${_NUMBER}" >> "${_PATH}/config" - - if [ -n "${_VETH}" ] - then - echo "lxc.network.veth.pair = ${_VETH}" >> "${_PATH}/config" - fi - - _NUMBER="$((${_NUMBER} + 1))" - done - - # Remove configuration symlinks - rm -f /etc/lxc/auto/${_NAME} /etc/lxc/auto/${_NAME}.conf - - case "${_AUTO}" in - true) - ln -s ${_PATH}/config /etc/lxc/auto/${_NAME} - ;; - esac - - if [ "${?}" -ne 0 ] - then - echo "Failed to add configuration" - return 1 - fi - - return 0 -} - -Clean () -{ - _CACHE="/var/cache/lxc/${_MODE}" - - if [ ! -e "${_CACHE}" ] - then - exit 0 - fi - - # lock, so we won't purge while someone is creating a repository - ( - flock -n -x 200 - - if [ "${?}" != 0 ] - then - echo "Cache repository is busy." - exit 1 - fi - - echo -n "Purging the download cache..." - rm --preserve-root --one-file-system -rf $cache && echo "done." || exit 1 - - exit 0 - ) 200>/var/lock/subsys/lxc -} - -Usage () -{ - echo "Usage: $(basename ${0}) --apt-recommends=|--debconf-frontend=|--debconf-priority=|--preseed-file=|-h|--help -p|--path= --clean" - - return 0 -} - -_OPTIONS="$(getopt -o d:hp:n:c -l apt-recommends:,debconf-frontend:,debconf-priority:,distribution:,preseed-file:,help,path:,name:,clean -- "$@")" - -if [ "${?}" -ne 0 ] -then - Usage - exit 1 -fi - -eval set -- "${_OPTIONS}" - -while true -do - case "${1}" in - --apt-recommends) - _APT_RECOMMENDS="${2}" - export _APT_RECOMMENDS - shift 2 - ;; - - --debconf-frontend) - _DEBCONF_FRONTEND="${2}" - export _DEBCONF_FRONTEND - shift 2 - ;; - - --debconf-priority) - _DEBCONF_PRIORITY="${2}" - export _DEBCONF_PRIORITY - shift 2 - ;; - - --preseed-file) - _PRESEED_FILE="${2}" - export _PRESEED_FILE - shift 2 - ;; - - -h|--help) - Usage - exit 0 - ;; - - -p|--path) - _PATH="${2}" - shift 2 - ;; - - -n|--name) - _NAME="${2}" - shift 2 - ;; - - -c|--clean) - _CLEAN="${2}" - shift 2 - ;; - - --) - shift 1 - break - ;; - - *) - break - ;; - esac -done - -if [ -n "${_CLEAN}" ] && [ -z "${_PATH}" ] -then - Clean || exit 1 - exit 0 -fi - -if ! type debootstrap > /dev/null 2>&1 \ -&& ! type cdebootstrap > /dev/null 2>&1 -then - echo "E: neither debootstrap nor cdebootstrap found." >&2 - exit 1 -fi - -if [ -z "${_PATH}" ] -then - echo "'path' parameter is required" - exit 1 -fi - -if [ "$(id -u)" != "0" ] -then - echo "$(basename ${0}) should be run as 'root'" - exit 1 -fi - -_ROOTFS="${_PATH}/rootfs" - -# Get distributor from template filename -_MODE="$(basename ${0} | sed -e 's|^lxc-||' -e 's|debconf||')" -export _MODE - -# Configure local debconf -_TMPDIR="$(mktemp -d -t $(basename ${0}).XXXXXXXX)" -export _TMPDIR - -# FIXME: check umask, nobody should be able to read these files -mkdir -p "${_TMPDIR}/debconf" - -cat > "${_TMPDIR}/debconf.systemrc" << EOF -Config: configdb -Templates: templatedb - -Name: config -Driver: File -Mode: 644 -Reject-Type: password -Filename: ${_TMPDIR}/debconf/config.dat - -Name: passwords -Driver: File -Mode: 600 -Backup: false -Required: false -Accept-Type: password -Filename: ${_TMPDIR}/debconf/passwords.dat - -Name: configdb -Driver: Stack -Stack: config, passwords - -Name: templatedb -Driver: File -Mode: 644 -Filename: ${_TMPDIR}/debconf/templates.dat -EOF - -DEBCONF_SYSTEMRC="${_TMPDIR}/debconf.systemrc" -export DEBCONF_SYSTEMRC - -# Run debconf parts -for _SCRIPT in /usr/share/lxc/templates/lxc-debconf.d/* -do - if [ -x "${_SCRIPT}" ] - then - # FIXME - #debconf -olxc-debconf "${_SCRIPT}" - "${_SCRIPT}" - fi -done - -# Read-in configuration from debconf -. "${_TMPDIR}/debconf.default" - -Install_system "${_ROOTFS}" - -if [ "${?}" -ne 0 ] -then - echo "failed to install system" - exit 1 -fi - -Configure_system "${_ROOTFS}" "${_NAME}" - -if [ "${?}" -ne 0 ] -then - echo "failed to configure system for a container" - exit 1 -fi - -Copy_configuration "${_PATH}" "${_ROOTFS}" "${_NAME}" - -if [ "${?}" -ne 0 ] -then - echo "failed write configuration file" - exit 1 -fi - -# remove debconf temporary files -rm --preserve-root --one-file-system -rf "${_TMPDIR}" - -if [ -n "${_CLEAN}" ] -then - Clean || exit 1 - exit 0 -fi diff -Nru lxc-0.8.0~rc1/debian/local/lxc-debconf.d/01-preseed-file lxc-1.0.0~alpha1/debian/local/lxc-debconf.d/01-preseed-file --- lxc-0.8.0~rc1/debian/local/lxc-debconf.d/01-preseed-file 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/local/lxc-debconf.d/01-preseed-file 1970-01-01 00:00:00.000000000 +0000 @@ -1,47 +0,0 @@ -#!/bin/sh - -set -e - -. /usr/share/debconf/confmodule - -if [ -e "${_PRESEED_FILE}" ] -then - # user specified preseed file through commandline option - db_set linux-container/preseed-file "${_PRESEED_FILE}" - db_fset linux-container/preseed-file seen true -elif ls /etc/lxc/debconf/* > /dev/null 2>&1 -then - _PRESEED_FILES="$(for _FILE in $(ls /etc/lxc/debconf/*); do echo -n "$(basename ${_FILE}), "; done)" - - if [ -n "${_PRESEED_FILES}" ] - then - db_subst linux-container/preseed-files CHOICES "${_PRESEED_FILES}custom" - - db_settitle linux-container/title - db_input high linux-container/preseed-files || true - db_go - - db_get linux-container/preseed-files - _PRESEED_FILE="${RET}" # select - - if [ "${_PRESEED_FILE}" != "custom" ] - then - # user specified preseed file through debconf select - db_set linux-container/preseed-file "/etc/lxc/debconf/${_PRESEED_FILE}" - db_fset linux-container/preseed-file seen true - fi - fi -fi - -# ask user for a preseed file -db_settitle linux-container/title -db_input high linux-container/preseed-file || true -db_go - -db_get linux-container/preseed-file -_PRESEED_FILE="${RET}" # string (w/ empty) - -echo "_PRESEED_FILE=\"${_PRESEED_FILE}\"" >> "${_TMPDIR}/debconf.default" -export _PRESEED_FILE - -db_stop diff -Nru lxc-0.8.0~rc1/debian/local/lxc-debconf.d/01-preseed-file.templates lxc-1.0.0~alpha1/debian/local/lxc-debconf.d/01-preseed-file.templates --- lxc-0.8.0~rc1/debian/local/lxc-debconf.d/01-preseed-file.templates 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/local/lxc-debconf.d/01-preseed-file.templates 1970-01-01 00:00:00.000000000 +0000 @@ -1,15 +0,0 @@ -Template: linux-container/title -Type: title -Description: Linux Container (LXC) - -Template: linux-container/preseed-file -Type: string -Default: -Description: Enter (optional) preseed file to use: - Preseed file anyone? - -Template: linux-container/preseed-files -Type: select -Default: custom -Choices: ${CHOICES} -Description: Choose an existing preseed config diff -Nru lxc-0.8.0~rc1/debian/local/lxc-debconf.d/02-preseed-debconf lxc-1.0.0~alpha1/debian/local/lxc-debconf.d/02-preseed-debconf --- lxc-0.8.0~rc1/debian/local/lxc-debconf.d/02-preseed-debconf 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/local/lxc-debconf.d/02-preseed-debconf 1970-01-01 00:00:00.000000000 +0000 @@ -1,14 +0,0 @@ -#!/bin/sh - -set -e - -if [ -e "${_TMPDIR}/debconf.default" ] -then - . "${_TMPDIR}/debconf.default" -fi - -if [ -e "${_PRESEED_FILE}" ] -then - # Apply user specified preseed file - debconf-set-selections "${_PRESEED_FILE}" -fi diff -Nru lxc-0.8.0~rc1/debian/local/lxc-debconf.d/03-debconf lxc-1.0.0~alpha1/debian/local/lxc-debconf.d/03-debconf --- lxc-0.8.0~rc1/debian/local/lxc-debconf.d/03-debconf 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/local/lxc-debconf.d/03-debconf 1970-01-01 00:00:00.000000000 +0000 @@ -1,904 +0,0 @@ -#!/bin/sh - -set -e - -# FIXME: this whole mess should be simplified at some point - -. /usr/share/debconf/confmodule - -Distribution () -{ - db_get linux-container/distribution - _DISTRIBUTION="${RET}" # select - - if [ -z "${_DISTRIBUTION}" ] - then - case "${_MODE}" in - debian) - db_subst linux-container/distribution CHOICES "Debian GNU/Linux 6.0 \"squeeze\", Debian GNU/Linux 7.0 \"wheezy\", Debian GNU/Linux unstable/sid" - db_subst linux-container/distribution CHOICES_C "squeeze, wheezy, sid" - - db_set linux-container/distribution squeeze - db_fset linux-container/distribution seen false - ;; - - progress) - db_subst linux-container/distribution CHOICES "Progress Linux 1.0 (artax), Progress Linux 1.9 (artax-backports), Progress Linux 2.0 (baureo)" - db_subst linux-container/distribution CHOICES_C "artax, artax-backports, baureo" - - db_set linux-container/distribution artax - db_fset linux-container/distribution seen false - ;; - esac - - db_settitle linux-container/title - db_input high linux-container/distribution || true - db_go - - db_get linux-container/distribution - _DISTRIBUTION="${RET}" # select - fi - - echo "_DISTRIBUTION=\"${_DISTRIBUTION}\"" >> "${_TMPDIR}/debconf.default" - export _DISTRIBUTION -} - -Parent_distribution () -{ - db_get linux-container/parent-distribution - _PARENT_DISTRIBUTION="${RET}" - - if [ -z "${_PARENT_DISTRIBUTION}" ] - then - case "${_MODE}" in - progress) - case "${_DISTRIBUTION}" in - artax*) - _PARENT_DISTRIBUTION="squeeze" - ;; - - baureo*) - _PARENT_DISTRIBUTION="sid" - ;; - esac - ;; - - *) - _PARENT_DISTRIBUTION="${_DISTRIBUTION}" - ;; - esac - fi - - echo "_PARENT_DISTRIBUTION=\"${_PARENT_DISTRIBUTION}\"" >> "${_TMPDIR}/debconf.default" - export _PARENT_DISTRIBUTION -} - -Architecture () -{ - _CHOICES="${1}" - _CHOICES_C="${2}" - _DEFAULT="${3}" - - db_get linux-container/architecture - _ARCHITECTURE="${RET}" # select - - if [ -z "${_ARCHITECTURE}" ] - then - db_subst linux-container/architecture CHOICES ${_CHOICES} - db_subst linux-container/architecture CHOICES_C ${_CHOICES_C} - - db_set linux-container/architecture ${_DEFAULT} - db_fset linux-container/distribution seen false - - db_settitle linux-container/title - db_input high linux-container/architecture || true - db_go - - db_get linux-container/architecture - _ARCHITECTURE="${RET}" # select - fi - - echo "_ARCHITECTURE=\"${_ARCHITECTURE}\"" >> "${_TMPDIR}/debconf.default" - export _ARCHITECTURE -} - -Archives () -{ - db_get linux-container/archives - _ARCHIVES="${RET}" # multiselect - - if [ -z "${_ARCHIVES}" ] - then - case "${_MODE}" in - debian) - db_subst linux-container/archives CHOICES "Debian Security, Debian Updates, Debian Backports, Debian Proposed Updates" - db_subst linux-container/archives CHOICES_C "${_DISTRIBUTION}-security, ${_DISTRIBUTION}-updates, ${_DISTRIBUTION}-backports, ${_DISTRIBUTION}-proposed-updates" - - db_set linux-container/archives "${_DISTRIBUTION}-security, ${_DISTRIBUTION}-updates, ${_DISTRIBUTION}-backports" - db_fset linux-container/archives seen false - ;; - - progress) - db_subst linux-container/archives CHOICES "Progress (staging), Progress Security, Progress Security (staging), Progress Updates, Progress Updates (staging), Progress Backports, Progress Backports (staging)" - db_subst linux-container/archives CHOICES_C "${_DISTRIBUTION}-staging, ${_DISTRIBUTION}-security, ${_DISTRIBUTION}-security-staging, ${_DISTRIBUTION}-updates, ${_DISTRIBUTION}-updates-staging, ${_DISTRIBUTION}-backports, ${_DISTRIBUTION}-backports-staging" - - db_set linux-container/archives "${_DISTRIBUTION}-security, ${_DISTRIBUTION}-updates, ${_DISTRIBUTION}-backports" - db_fset linux-container/archives seen false - ;; - esac - - db_settitle linux-container/title - db_input high linux-container/archives || true - db_go - - db_get linux-container/archives - _ARCHIVES="${RET}" # multiselect - fi - - _ARCHIVES="$(echo ${_ARCHIVES} | sed -e 's|, | |g')" - - echo "_ARCHIVES=\"${_ARCHIVES}\"" >> "${_TMPDIR}/debconf.default" - export _ARCHIVES -} - -Parent_archives () -{ - db_get linux-container/parent-archives - _PARENT_ARCHIVES="${RET}" # multiselect (w/o empty) - - if [ -z "${_PARENT_ARCHIVES}" ] - then - case "${_MODE}" in - progress) - db_subst linux-container/parent-archives CHOICES "Debian Security, Debian Updates , Debian Backports, Debian Proposed Updates" - db_subst linux-container/parent-archives CHOICES_C "${_DISTRIBUTION}-security, ${_DISTRIBUTION}-updates, ${_DISTRIBUTION}-backports, ${_DISTRIBUTION}-proposed-updates" - - db_set linux-container/parent-archives "${_DISTRIBUTION}-security, ${_DISTRIBUTION}-updates, ${_DISTRIBUTION}-backports" - db_fset linux-container/parent-archives seen false - - db_settitle linux-container/title - db_input high linux-container/parent-archives || true - db_go - ;; - - *) - db_subst linux-container/parent-archives CHOICES "Debian Security, Debian Updates , Debian Backports, Debian Proposed Updates" - db_subst linux-container/parent-archives CHOICES_C "${_ARCHIVES}" - - db_set linux-container/parent-archives "${_ARCHIVES}" - db_fset linux-container/parent-archives seen true - ;; - esac - - db_get linux-container/parent-archives - _PARENT_ARCHIVES="${RET}" # multiselect (w/o empty) - - if [ -z "${_PARENT_ARCHIVES}" ] - then - case "${_MODE}" in - progress) - _PARENT_ARCHIVES="${_DISTRIBUTION}-security, ${_DISTRIBUTION}-updates, ${_DISTRIBUTION}-backports" - ;; - - *) - _PARENT_ARCHIVES="${_ARCHIVES}" - ;; - esac - fi - fi - - _PARENT_ARCHIVES="$(echo ${_PARENT_ARCHIVES} | sed -e 's|, | |g')" - - echo "_PARENT_ARCHIVES=\"${_PARENT_ARCHIVES}\"" >> "${_TMPDIR}/debconf.default" - export _PARENT_ARCHIVES -} - -Mirror () -{ - db_get linux-container/mirror - _MIRROR="${RET}" - - if [ -z "${_MIRROR}" ] - then - case "${_MODE}" in - debian) - db_set linux-container/mirror http://ftp.debian.org/debian/ - db_fset linux-container/mirror seen false - ;; - - progress) - db_set linux-container/mirror http://cdn.archive.progress-linux.org/progress/ - db_fset linux-container/mirror seen false - ;; - esac - - db_settitle linux-container/title - db_input high linux-container/mirror || true - db_go - - db_get linux-container/mirror - _MIRROR="${RET}" # string (w/o empty) - - if [ -z "${_MIRROR}" ] - then - case "${_MODE}" in - debian) - _MIRROR="http://ftp.debian.org/debian/" - ;; - - progress) - _MIRROR="http://cdn.archive.progress-linux.org/progress/" - ;; - esac - fi - fi - - echo "_MIRROR=\"${_MIRROR}\"" >> "${_TMPDIR}/debconf.default" - export _MIRROR -} - -Mirror_security () -{ - db_get linux-container/mirror-security - _MIRROR_SECURITY="${RET}" # string (w/o empty) - - if [ -z "${_MIRROR_SECURITY}" ] - then - case "${_MODE}" in - debian) - db_set linux-container/mirror-security http://security.debian.org/ - db_fset linux-container/mirror-security seen false - ;; - - *) - db_set linux-container/mirror-security ${_MIRROR} - db_fset linux-container/mirror-security seen true - ;; - esac - - db_settitle linux-container/title - db_input high linux-container/mirror-security || true - db_go - - db_get linux-container/mirror-security - _MIRROR_SECURITY="${RET}" # string (w/o empty) - - if [ -z "${_MIRROR_SECURITY}" ] - then - case "${_MODE}" in - debian) - _MIRROR_SECURITY="http://security.debian.org/" - ;; - - *) - _MIRROR_SECURITY="${_MIRROR}" - ;; - esac - fi - fi - - echo "_MIRROR_SECURITY=\"${_MIRROR_SECURITY}\"" >> "${_TMPDIR}/debconf.default" - export _MIRROR_SECURITY -} - -Mirror_backports () -{ - db_get linux-container/mirror-backports - _MIRROR_BACKPORTS="${RET}" # string (w/o empty) - - if [ -z "${_MIRROR_BACKPORTS}" ] - then - case "${_MODE}" in - debian) - db_set linux-container/mirror-backports http://backports.debian.org/debian-backports/ - db_fset linux-container/mirror-backports seen false - ;; - - *) - db_set linux-container/mirror-backports ${_MIRROR} - db_fset linux-container/mirror-backports seen true - ;; - esac - - db_settitle linux-container/title - db_input high linux-container/mirror-backports || true - db_go - - db_get linux-container/mirror-backports - _MIRROR_BACKPORTS="${RET}" # string (w/o empty) - - if [ -z "${_MIRROR_BACKPORTS}" ] - then - case "${_MODE}" in - debian) - _MIRROR_BACKPORTS="http://backports.debian.org/debian-backports/" - ;; - - *) - _MIRROR_BACKPORTS="${_MIRROR}" - ;; - esac - fi - fi - - echo "_MIRROR_BACKPORTS=\"${_MIRROR_BACKPORTS}\"" >> "${_TMPDIR}/debconf.default" - export _MIRROR_BACKPORTS -} - -Parent_mirror () -{ - db_get linux-container/parent-mirror - _PARENT_MIRROR="${RET}" # string (w/o empty) - - if [ -z "${_PARENT_MIRROR}" ] - then - case "${_MODE}" in - progress) - db_set linux-container/parent-mirror http://ftp.debian.org/debian/ - db_fset linux-container/parent-mirror seen false - - db_settitle linux-container/title - db_input high linux-container/parent-mirror || true - db_go - ;; - - *) - db_set linux-container/parent-mirror ${_MIRROR} - db_fset linux-container/parent-mirror seen true - ;; - esac - - db_get linux-container/parent-mirror - _PARENT_MIRROR="${RET}" # string (w/o empty) - - if [ -z "${_PARENT_MIRROR}" ] - then - case "${_MODE}" in - progress) - _PARENT_MIRROR="http://ftp.debian.org/debian/" - ;; - - *) - _PARENT_MIRROR="${_MIRROR}" - ;; - esac - fi - fi - - echo "_PARENT_MIRROR=\"${_PARENT_MIRROR}\"" >> "${_TMPDIR}/debconf.default" - export _PARENT_MIRROR -} - -Parent_mirror_security () -{ - db_get linux-container/parent-mirror-security - _PARENT_MIRROR_SECURITY="${RET}" # string (w/o empty) - - if [ -z "${_PARENT_MIRROR_SECURITY}" ] - then - case "${_MODE}" in - progress) - db_set linux-container/parent-mirror-security http://security.debian.org/ - db_fset linux-container/parent-mirror-security seen false - - db_settitle linux-container/title - db_input high linux-container/parent-mirror-security || true - db_go - ;; - - *) - db_set linux-container/parent-mirror-security ${_MIRROR_SECURITY} - db_fset linux-container/parent-mirror-security seen true - ;; - esac - - db_get linux-container/parent-mirror-security - _PARENT_MIRROR_SECURITY="${RET}" # string (w/o empty) - - if [ -z "${_PARENT_MIRROR_SECURITY}" ] - then - case "${_MODE}" in - progress) - _PARENT_MIRROR_SECURITY="http://security.debian.org/" - ;; - - *) - _PARENT_MIRROR_SECURITY="${_MIRROR_SECURITY}" - ;; - esac - fi - fi - - echo "_PARENT_MIRROR_SECURITY=\"${_PARENT_MIRROR_SECURITY}\"" >> "${_TMPDIR}/debconf.default" - export _PARENT_MIRROR_SECURITY -} - -Parent_mirror_backports () -{ - db_get linux-container/parent-mirror-backports - _PARENT_MIRROR_BACKPORTS="${RET}" # string (w/o empty) - - if [ -z "${_PARENT_MIRROR_BACKPORTS}" ] - then - case "${_MODE}" in - progress) - db_set linux-container/parent-mirror-backports http://backports.debian.org/debian-backports/ - db_fset linux-container/parent-mirror-backports seen false - - db_settitle linux-container/title - db_input high linux-container/parent-mirror-backports || true - db_go - ;; - - *) - db_set linux-container/parent-mirror-backports ${_MIRROR_BACKPORTS} - db_fset linux-container/parent-mirror-backports seen true - ;; - esac - - db_get linux-container/parent-mirror-backports - _PARENT_MIRROR_BACKPORTS="${RET}" # string (w/o empty) - - if [ -z "${_PARENT_MIRROR_BACKPORTS}" ] - then - case "${_MODE}" in - progress) - _PARENT_MIRROR_BACKPORTS="http://backports.debian.org/debian-backports/" - ;; - - *) - _PARENT_MIRROR_BACKPORTS="${_MIRROR_BACKPORTS}" - ;; - esac - fi - fi - - echo "_PARENT_MIRROR_BACKPORTS=\"${_PARENT_MIRROR_BACKPORTS}\"" >> "${_TMPDIR}/debconf.default" - export _PARENT_MIRROR_BACKPORTS -} - -Archive_areas () -{ - db_get linux-container/archive-areas - _ARCHIVE_AREAS="${RET}" - - if [ -z "${_ARCHIVE_AREAS}" ] - then - case "${_MODE}" in - progress) - db_subst linux-container/archive-areas CHOICES "main, contrib, non-free" - - db_set linux-container/archive-areas "main, contrib, non-free" - db_fset linux-container/archive-areas seen false - ;; - - *) - db_subst linux-container/archive-areas CHOICES "main, contrib, non-free" - - db_set linux-container/archive-areas "main" - db_fset linux-container/archive-areas seen false - ;; - esac - - db_settitle linux-container/title - db_input high linux-container/archive-areas || true - db_go - - db_get linux-container/archive-areas - _ARCHIVE_AREAS="${RET}" # multiselect (w/o empty) - - if [ -z "${_ARCHIVE_AREAS}" ] - then - case "${_MODE}" in - debian) - _ARCHIVE_AREAS="main" - ;; - - progress) - _ARCHIVE_AREAS="main, contrib, non-free" - ;; - esac - fi - fi - - _ARCHIVE_AREAS="$(echo ${_ARCHIVE_AREAS} | sed -e 's| ||g')" - - echo "_ARCHIVE_AREAS=\"${_ARCHIVE_AREAS}\"" >> "${_TMPDIR}/debconf.default" - export _ARCHIVE_AREAS -} - -Parent_archive_areas () -{ - db_get linux-container/parent-archive-areas - _PARENT_ARCHIVE_AREAS="${RET}" # multiselect (w/o empty) - - if [ -z "${_PARENT_ARCHIVE_AREAS}" ] - then - case "${_MODE}" in - progress) - db_subst linux-container/parent-archive-areas CHOICES "main, contrib, non-free" - - db_set linux-container/parent-archive-areas "main, contrib, non-free" - db_fset linux-container/parent-archive-areas seen false - - db_settitle linux-container/title - db_input high linux-container/parent-archive-areas || true - db_go - ;; - - *) - db_subst linux-container/parent-archive-areas CHOICES "${_ARCHIVE_AREAS}" - - db_set linux-container/parent-archive-areas "${_ARCHIVE_AREAS}" - db_fset linux-container/parent-archive-areas seen true - ;; - esac - - db_get linux-container/parent-archive-areas - _PARENT_ARCHIVE_AREAS="${RET}" # multiselect (w/o empty) - - if [ -z "${_PARENT_ARCHIVE_AREAS}" ] - then - case "${_MODE}" in - progress) - _PARENT_ARCHIVE_AREAS="main, contrib, non-free" - ;; - - *) - _PARENT_ARCHIVE_AREAS="${_ARCHIVE_AREAS}" - ;; - esac - fi - fi - - _PARENT_ARCHIVE_AREAS="$(echo ${_PARENT_ARCHIVE_AREAS} | sed -e 's| ||g')" - - echo "_PARENT_ARCHIVE_AREAS=\"${_PARENT_ARCHIVE_AREAS}\"" >> "${_TMPDIR}/debconf.default" - export _PARENT_ARCHIVE_AREAS -} - -Packages () -{ - db_get linux-container/packages - _PACKAGES="${RET}" # string (w/ empty) - - if [ -z "${_PACKAGES}" ] - then - db_settitle linux-container/title - db_input high linux-container/packages || true - db_go - - db_get linux-container/packages - _PACKAGES="${RET}" # string (w/ empty) - fi - - echo "_PACKAGES=\"${_PACKAGES}\"" >> "${_TMPDIR}/debconf.default" - export _PACKAGES -} - -Local_repositories () -{ - _NUMBER="0" - - while db_get linux-container/local${_NUMBER}/repository && [ "${RET}" ] - do - mkdir -p "${_TMPDIR}/sources.list.d" - - _REPOSITORY="${RET#deb }" - - _LIST="local${_NUMBER}.list" - if db_get linux-container/local${_NUMBER}/list - then - _LIST="$(basename ${RET} .list).list" - fi - - _COMMENT="" - if db_get linux-container/local${_NUMBER}/comment - then - _COMMENT="${RET}" - - echo "# ${_COMMENT}" > "${_TMPDIR}/sources.list.d/${_LIST}" - fi - - echo "deb ${_REPOSITORY}" >> "${_TMPDIR}/sources.list.d/${_LIST}" - - if db_get linux-container/local${_NUMBER}/source && [ "$RET" = true ] - then - echo "deb-src ${_REPOSITORY}" >> "${_TMPDIR}/sources.list.d/${_LIST}" - fi - - _KEY="" - if db_get linux-container/local${_NUMBER}/key - then - _KEY="${RET}" - - wget -q "${_KEY}" -O "${_TMPDIR}/sources.list.d/$(basename ${_LIST} .list).key" - fi - - _NUMBER="$((${_NUMBER} + 1))" - done -} - -Root_password () -{ - if db_get passwd/root-password - then - _ROOT_PASSWORD="${RET}" # string (w/o empty) - fi - - if [ -z "${_ROOT_PASSWORD}" ] - then - # Create a random password as suggestion for the user - _RANDOM_PASSWORD="$(dd if=/dev/urandom bs=6 count=1 2> /dev/null | base64)" - - db_set passwd/root-password ${_RANDOM_PASSWORD} - db_fset passwd/root-password seen false - - db_settitle linux-container/title - db_input high passwd/root-password || true - db_go - - db_get passwd/root-password - _ROOT_PASSWORD="${RET}" - - if [ -z "${_ROOT_PASSWORD}" ] - then - # User did set not set a password, falling back to random password - _ROOT_PASSWORD="${_RANDOM_PASSWORD}" - - echo "_ROOT_RANDOM_PASSWORD=\"true\"" >> "${_TMPDIR}/debconf.default" - fi - fi - - echo "_ROOT_PASSWORD=\"${_ROOT_PASSWORD}\"" >> "${_TMPDIR}/debconf.default" -} - -Network () -{ - _NUMBER="0" - - while db_get linux-container/eth${_NUMBER}/dhcp && [ "${RET}" ] - do - if db_get linux-container/eth${_NUMBER}/comment - then - eval LINUX_CONTAINER_ETH${_NUMBER}_COMMENT="\"${RET}\"" # string (w/) - fi - - if db_get linux-container/eth${_NUMBER}/bridge - then - eval LINUX_CONTAINER_ETH${_NUMBER}_BRIDGE="\"${RET}\"" # string (w/o empty) - fi - - if db_get linux-container/eth${_NUMBER}/mac - then - eval LINUX_CONTAINER_ETH${_NUMBER}_MAC="\"${RET}\"" # string (w/o empty) - fi - - if db_get linux-container/eth${_NUMBER}/mtu - then - eval LINUX_CONTAINER_ETH${_NUMBER}_MTU="\"${RET}\"" # string (w/ empty) - fi - - if db_get linux-container/eth${_NUMBER}/veth - then - eval LINUX_CONTAINER_ETH${_NUMBER}_VETH="\"${RET}\"" # string (w/ empty) - fi - - _NUMBER="$((${_NUMBER} + 1))" - done - - # FIXME: this is ugly - if [ "${_NUMBER}" -gt 0 ] - then - LINUX_CONTAINER_ETH_NUMBER="$((${_NUMBER} - 1))" - else - LINUX_CONTAINER_ETH_NUMBER="${_NUMBER}" - fi - - if [ -z ${LINUX_CONTAINER_ETH0_BRIDGE} ] - then - # FIXME: do guess the default bridge device - db_set linux-container/eth0/bridge br0 - db_fset linux-container/eth0/bridge seen false - - db_settitle linux-container/title - db_input high linux-container/eth0/bridge || true - db_go - - db_get linux-container/eth0/bridge - LINUX_CONTAINER_ETH0_BRIDGE="${RET:-br0}" - fi - - if [ -z "${LINUX_CONTAINER_ETH0_MAC}" ] - then - # FIXME: do guess the default mac address - db_set linux-container/eth0/mac 00:FF:00:00:00:01 - db_fset linux-container/eth0/mac seen false - - db_settitle linux-container/title - db_input high linux-container/eth0/mac || true - db_go - - db_get linux-container/eth0/mac - LINUX_CONTAINER_ETH0_MAC="${RET:-00:FF:00:00:00:01}" - fi - - echo "LINUX_CONTAINER_ETH_NUMBER=\"${LINUX_CONTAINER_ETH_NUMBER}\"" >> "${_TMPDIR}/debconf.default" - - for _NUMBER in $(seq 0 ${LINUX_CONTAINER_ETH_NUMBER}) - do - eval _COMMENT="$`echo LINUX_CONTAINER_ETH${_NUMBER}_COMMENT`" - echo "LINUX_CONTAINER_ETH${_NUMBER}_COMMENT=\"${_COMMENT}\"" >> "${_TMPDIR}/debconf.default" - - eval _BRIDGE="$`echo LINUX_CONTAINER_ETH${_NUMBER}_BRIDGE`" - echo "LINUX_CONTAINER_ETH${_NUMBER}_BRIDGE=\"${_BRIDGE}\"" >> "${_TMPDIR}/debconf.default" - - eval _MAC="$`echo LINUX_CONTAINER_ETH${_NUMBER}_MAC`" - echo "LINUX_CONTAINER_ETH${_NUMBER}_MAC=\"${_MAC}\"" >> "${_TMPDIR}/debconf.default" - - eval _MTU="$`echo LINUX_CONTAINER_ETH${_NUMBER}_MTU`" - echo "LINUX_CONTAINER_ETH${_NUMBER}_MTU=\"${_MTU}\"" >> "${_TMPDIR}/debconf.default" - - eval _VETH="$`echo LINUX_CONTAINER_ETH${_NUMBER}_VETH`" - echo "LINUX_CONTAINER_ETH${_NUMBER}_VETH=\"${_VETH}\"" >> "${_TMPDIR}/debconf.default" - done -} - -Auto () -{ - db_get linux-container/auto - _AUTO="${RET}" # boolean - - if [ -z "${_AUTO}" ] - then - db_set linux-container/auto false - db_fset linux-container/auto seen false - - db_settitle linux-container/title - db_input high linux-container/auto || true - db_go - - db_get linux-container/auto - _AUTO="${RET}" - fi - - echo "_AUTO=\"${_AUTO}\"" >> "${_TMPDIR}/debconf.default" - export _AUTO -} - -Internal_options () -{ - if db_get linux-container/apt-recommends - then - _APT_RECOMMENDS="${RET}" # boolean (w/ empty) - fi - - echo "_APT_RECOMMENDS=\"${_APT_RECOMMENDS}\"" >> "${_TMPDIR}/debconf.default" - - if db_get linux-container/debconf-frontend - then - _DEBCONF_FRONTEND="${RET}" # select - fi - - _DEBCONF_FRONTEND="${_DEBCONF_FRONTEND:-dialog}" - echo "_DEBCONF_FRONTEND=\"${_DEBCONF_FRONTEND}\"" >> "${_TMPDIR}/debconf.default" - - if db_get linux-container/debconf-priority - then - _DEBCONF_PRIORITY="${RET}" # select - fi - - _DEBCONF_PRIORITY="${_DEBCONF_PRIORITY:-high}" - echo "_DEBCONF_PRIORITY=\"${_DEBCONF_PRIORITY}\"" >> "${_TMPDIR}/debconf.default" - - if db_get linux-container/late-command - then - _LATE_COMMAND="${RET}" # string (w/ empty) - fi - - echo "_LATE_COMMAND=\"${_LATE_COMMAND}\"" >> "${_TMPDIR}/debconf.default" - - if db_get linux-container/late-host-command - then - _LATE_HOST_COMMAND="${RET}" # string (w/ empty) - fi - - echo "_LATE_HOST_COMMAND=\"${_LATE_HOST_COMMAND}\"" >> "${_TMPDIR}/debconf.default" - - if db_get linux-container/capabilities - then - _CAPABILITIES="${RET}" # string (w/ empty) - fi - - echo "_CAPABILITIES=\"${_CAPABILITIES}\"" >> "${_TMPDIR}/debconf.default" - - _NUMBER="0" - - while db_get linux-container/mount${_NUMBER}/entry && [ "${RET}" ] - do - eval LINUX_CONTAINER_MOUNT${_NUMBER}_ENTRY="\"${RET}\"" # string (w/o empty) - - if db_get linux-container/mount${_NUMBER}/comment - then - eval LINUX_CONTAINER_MOUNT${_NUMBER}_COMMENT="\"${RET}\"" # string (w/ empty) - fi - - _NUMBER="$((${_NUMBER} + 1))" - done - - # FIXME: this is ugly - if [ "${_NUMBER}" -gt 0 ] - then - LINUX_CONTAINER_MOUNT_NUMBER="$((${_NUMBER} - 1))" - else - LINUX_CONTAINER_MOUNT_NUMBER="${_NUMBER}" - fi - - echo "LINUX_CONTAINER_MOUNT_NUMBER=\"${LINUX_CONTAINER_MOUNT_NUMBER}\"" >> "${_TMPDIR}/debconf.default" - - for _NUMBER in $(seq 0 ${LINUX_CONTAINER_MOUNT_NUMBER}) - do - eval _COMMENT="$`echo LINUX_CONTAINER_MOUNT${_NUMBER}_COMMENT`" - echo "LINUX_CONTAINER_MOUNT${_NUMBER}_COMMENT=\"${_COMMENT}\"" >> "${_TMPDIR}/debconf.default" - - eval _ENTRY="$`echo LINUX_CONTAINER_MOUNT${_NUMBER}_ENTRY`" - echo "LINUX_CONTAINER_MOUNT${_NUMBER}_ENTRY=\"${_ENTRY}\"" >> "${_TMPDIR}/debconf.default" - done -} - -Distribution -Parent_distribution - -case "$(dpkg --print-architecture)" in - amd64) - # Usage: Architecture CHOICES CHOICES_C Default - Architecture "32-bit PC (i386), 64-bit PC (amd64)" "i386, amd64" "amd64" - ;; -esac - -Archives -Parent_archives - -Mirror - -for _ARCHIVE in ${_ARCHIVES} -do - case "${_ARCHIVE}" in - *-security*) - Mirror_security - ;; - - *-backports*) - Mirror_backports - ;; - esac -done - -Parent_mirror - -for _PARENT_ARCHIVE in ${_PARENT_ARCHIVES} -do - case "${_PARENT_ARCHIVE}" in - *-security) - Parent_mirror_security - ;; - - *-backports) - Parent_mirror_backports - ;; - esac -done - -Archive_areas -Parent_archive_areas - -Packages -Local_repositories - -Root_password -Network -Auto - -Internal_options - -db_stop diff -Nru lxc-0.8.0~rc1/debian/local/lxc-debconf.d/03-debconf.templates lxc-1.0.0~alpha1/debian/local/lxc-debconf.d/03-debconf.templates --- lxc-0.8.0~rc1/debian/local/lxc-debconf.d/03-debconf.templates 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/local/lxc-debconf.d/03-debconf.templates 1970-01-01 00:00:00.000000000 +0000 @@ -1,123 +0,0 @@ -Template: linux-container/title -Type: title -Description: Linux Container (LXC) - -Template: linux-container/distribution -Type: select -Default: -Choices-C: ${CHOICES_C} -Choices: ${CHOICES} -Description: Distribution - Distribution. - -Template: linux-container/parent-distribution -Type: select -Default: -Choices-C: ${CHOICES_C} -Choices: ${CHOICES} -Description: for internal use; can be preseeded - Parent Distribution. - -Template: linux-container/architecture -Type: select -Default: -Choices-C: ${CHOICES_C} -Choices: ${CHOICES} -Description: Architecture - Architecture. - -Template: linux-container/archives -Type: multiselect -Default: -Choices-C: ${CHOICES_C} -Choices: ${CHOICES} -Description: Archives - Archives. - -Template: linux-container/parent-archives -Type: multiselect -Default: -Choices-C: ${CHOICES_C} -Choices: ${CHOICES} -Description: Parent Archives - Parent Archives. - -Template: linux-container/mirror -Type: string -Default: -Description: Mirror - Mirror. - -Template: linux-container/mirror-security -Type: string -Default: -Description: Mirror Security - Mirror Security. - -Template: linux-container/mirror-backports -Type: string -Default: -Description: Mirror Backports - Mirror Backports. - -Template: linux-container/parent-mirror -Type: string -Default: -Description: Parent Mirror - Parent Mirror. - -Template: linux-container/parent-mirror-security -Type: string -Default: -Description: Parent Mirror Security - Parent Mirror Security. - -Template: linux-container/parent-mirror-backports -Type: string -Default: -Description: Parent Mirror Backports - Parent Mirror Backports. - -Template: linux-container/archive-areas -Type: multiselect -Default: -Choices: ${CHOICES} -Description: Archive Areas - Archive Areas. - -Template: linux-container/parent-archive-areas -Type: multiselect -Default: -Choices: ${CHOICES} -Description: Parent Archive Areas - Parent Archive Areas. - -Template: linux-container/packages -Type: string -Default: -Description: Packages - Packages. - -Template: passwd/root-password -Type: string -Default: -Description: Root password - Root password. - -Template: linux-container/eth0/bridge -Type: string -Default: -Description: Bridge - Bridge. - -Template: linux-container/eth0/mac -Type: string -Default: -Description: MAC - MAC. - -Template: linux-container/auto -Type: boolean -Default: false -Description: Auto start container? - Should the container be automatically configured to be started on boot? diff -Nru lxc-0.8.0~rc1/debian/local/lxc-halt lxc-1.0.0~alpha1/debian/local/lxc-halt --- lxc-0.8.0~rc1/debian/local/lxc-halt 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/local/lxc-halt 1970-01-01 00:00:00.000000000 +0000 @@ -1,54 +0,0 @@ -#!/bin/sh - -set -e - -_OPTIONS="$(getopt -o n: -l name: -- "${@}")" - -if [ "${?}" -ne 0 ] -then - echo "Usage: $(basename ${0}) -n|--name CONTAINER" >&2 - exit 1 -fi - -eval set -- "${_OPTIONS}" - -while true -do - case "${1}" in - -n|--name) - _CONTAINER="${2}" - shift 2 - ;; - - --) - shift - break - ;; - - *) - echo "E: $(basename ${0}): internal error ${0}" >&2 - exit 1 - ;; - esac -done - -if [ -z "${_CONTAINER}" ] -then - echo "E: $(basename ${0}): missing container name, use --name option" >&2 - exit 1 -fi - -if lxc-info -n ${_CONTAINER} 2>&1 | grep -qs "STOPPED" -then - echo "P: ${_CONTAINER} - already stopped" - exit 0 -fi - -# FIXME: Assumption of /var/lib/lxc -if [ -e /var/lib/lxc/${_CONTAINER}/rootfs ] -then - chroot /var/lib/lxc/${_CONTAINER}/rootfs telinit 0 -else - echo "E: /var/lib/lxc/${_CONTAINER}/rootfs - no such directory" - exit 1 -fi diff -Nru lxc-0.8.0~rc1/debian/local/lxc-list lxc-1.0.0~alpha1/debian/local/lxc-list --- lxc-0.8.0~rc1/debian/local/lxc-list 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/local/lxc-list 1970-01-01 00:00:00.000000000 +0000 @@ -1,31 +0,0 @@ -#!/bin/sh - -set -e - -if [ ! -x "$(which lxc-info 2>/dev/null)" ] -then - echo "E: lxc-info - no such file" >&2 - exit 1 -fi - -for _STATUS in RUNNING FROZEN STOPPED -do - echo ${_STATUS} - - for _CONTAINER in $(lxc-ls | sort -u) - do - if lxc-info -n ${_CONTAINER} 2>&1 | grep -qs "${_STATUS}" - then - echo -n " ${_CONTAINER}" - - if [ -e /etc/lxc/auto/${_CONTAINER} ] || [ -e /etc/lxc/auto/${_CONTAINER}.conf ] - then - echo " (auto)" - else - echo - fi - fi - done - - echo -done diff -Nru lxc-0.8.0~rc1/debian/local/lxc-ls lxc-1.0.0~alpha1/debian/local/lxc-ls --- lxc-0.8.0~rc1/debian/local/lxc-ls 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/local/lxc-ls 1970-01-01 00:00:00.000000000 +0000 @@ -1,20 +0,0 @@ -#!/bin/sh - -set -e - -_LXC_DIRECTORY="/var/lib/lxc" - -if [ ! -e "${_LXC_DIRECTORY}" ] -then - echo "E: ${_LXC_DIRECTORY}: no such directory." >&2 - exit 1 -fi - -cd "${_LXC_DIRECTORY}" - -_DIRECTORIES="$(find . -maxdepth 1 -type d -and -not -name ".*" -and -not -name lost+found | sort)" - -for _DIRECTORY in ${_DIRECTORIES} -do - ls -d ${@} $(basename ${_DIRECTORY}) -done diff -Nru lxc-0.8.0~rc1/debian/local/lxc-restore lxc-1.0.0~alpha1/debian/local/lxc-restore --- lxc-0.8.0~rc1/debian/local/lxc-restore 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/local/lxc-restore 1970-01-01 00:00:00.000000000 +0000 @@ -1,55 +0,0 @@ -#!/bin/sh - -set -e - -_CONTAINER="${1}" - -if [ -n "${_CONTAINER}" ] -then - shift -else -# echo "Usage: ${0} CONTAINER [BACKUP_NUMBER]" - echo "Usage: ${0} CONTAINER" - exit 1 -fi - -if [ ! -x "$(which rsync 2>/dev/null)" ] -then - echo "E: rsync - no such file" >&2 - exit 1 -fi - -if [ ! -x "$(which lxc-info 2>/dev/null)" ] -then - echo "E: lxc-info - no such file" >&2 - exit 1 -fi - -if ! lxc-info -n ${_CONTAINER} 2>&1 | grep -qs "STOPPED" -then - echo "E: ${_CONTAINER} - not stopped" >&2 - exit 1 -fi - -# FIXME: Assumption of /var/lib/lxc -if ls /var/lib/lxc/${_CONTAINER}/rootfs.backup* > /dev/null 2>&1 -then -# if [ -n "${2}" ] -# then -# _BACKUP="${2}" -# else -# _BACKUP="1" -# -# while [ -e "/var/lib/lxc/${_CONTAINER}/rootfs.backup${_BACKUP}" ] -# do -# _BACKUP="$((${_BACKUP} + 1))" -# done -# -# _BACKUP="$((${_BACKUP} - 1))" -# fi - - rsync -aPHv --delete --progress /var/lib/lxc/${_CONTAINER}/rootfs.backup${_BACKUP}/ /var/lib/lxc/${_CONTAINER}/rootfs -else - echo "E: /var/lib/lxc/${_CONTAINER}/rootfs.backup* - no such directories" >&2 - exit 1 -fi diff -Nru lxc-0.8.0~rc1/debian/local/lxc-start-ephemeral lxc-1.0.0~alpha1/debian/local/lxc-start-ephemeral --- lxc-0.8.0~rc1/debian/local/lxc-start-ephemeral 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/local/lxc-start-ephemeral 1970-01-01 00:00:00.000000000 +0000 @@ -1,351 +0,0 @@ -#!/bin/bash - -# (C) Copyright Canonical 2011,2012 - -# What lxc container to clone -LXC_BASE="" -# $2 is a path to bind mount e.g. /tmp/foo. -LXC_BIND="" -UNION="overlayfs" - -usage() { - echo "usage: lxc-start-ephemeral [-U uniontype] [-d|--daemon] [-h] [-b bdir] [-u user] [-S key] -o orig -- [COMMAND [ARGS...]]" -} - -help() { - usage - echo - echo "Runs an ephemeral (one-off) container" - echo - echo "Options:" - echo "orig : name of the original container" - echo "bdir : directory to bind mount into container" - echo "user : the user to connect to the container as" - echo "key : the path to the SSH key to use to connect" - echo "-d : run in the background" - echo "-U : type of union (aufs or overlayfs)" - echo " Default is overlayfs" - echo - echo "if a COMMAND is given, then the container will run only as long" - echo "as the command runs. If no COMMAND is given, this command will" - echo "wait until the container is shut down" -} - -shortoptions='hb:o:u:S:dU:' -longoptions='help,orig:,bdir:,user:,ssh-key:,daemon,union:' - -LXC_RUNNING=0 -LXC_MOUNTED=0 -DAEMON=0 - -cleanup_dirs() -{ - # echo "umounting ephemeral_bind_dir $EPHEMERAL_BIND_DIR" >&2 - sudo umount $EPHEMERAL_BIND_DIR - # echo "umounting lxc_dir $LXC_DIR" >&2 - sudo umount $LXC_DIR/rootfs - # echo "umounting overlay" >&2 - sudo umount $OVERLAY_DIR - - # remove all contents of the content dir - sudo rmdir $LXC_DIR/ephemeralbind - sudo rmdir $LXC_DIR/rootfs - sudo rm -f $LXC_DIR/* - - # echo "rming lxc_dir $LXC_DIR" >&2 - sudo rmdir $LXC_DIR - # echo "rming overlay dir $OVERLAY_DIR" >&2 - sudo rmdir $OVERLAY_DIR -} - -cleanup() { - if [ $LXC_RUNNING -eq 1 ]; then - sudo lxc-stop -n $LXC_NAME - fi - if [ $LXC_MOUNTED -eq 1 ]; then - cleanup_dirs - fi - exit 1 -} - -do_mount() { - lower=$1 - upper=$2 - target=$3 - if [ $UNION = "aufs" ]; then - sudo mount -t aufs -o br=${upper}=rw:${lower}=ro,noplink none ${target} - else - sudo mount -t overlayfs -oupperdir=${upper},lowerdir=${lower} none ${target} - fi -} - -trap cleanup SIGTERM SIGINT SIGQUIT - -getopt=$(getopt -o $shortoptions --longoptions $longoptions -- "$@") -if [ $? != 0 ]; then - usage - exit 1; -fi - -eval set -- "$getopt" - -while true; do - case "$1" in - -h|--help) - help - exit 1 - ;; - -o|--orig) - shift - LXC_BASE=$1 - shift - ;; - -b|--bdir) - shift - LXC_BIND=$1 - shift - ;; - -u|--user) - shift - LXC_USER=$1 - shift - ;; - -S|--ssh-key) - shift - LXC_KEY="-i $1" - shift - ;; - -d|--detach) - DAEMON=1 - shift - ;; - -U|--union) - shift - UNION=$1 - shift - ;; - --) - shift - break;; - *) - echo $1 - usage - exit 1 - ;; - esac -done - -COMMAND=$@ -COMMAND_LENGTH=$# -LXC_USER=${LXC_USER:-`id -un`} - -# validation - -if [ -z $LXC_BASE ]; then - echo "original container must be specified" - usage - exit 1 -fi -if [ ! -d /var/lib/lxc/$LXC_BASE ] ; then - echo "no such lxc container $LXC_BASE" - exit 1 -fi - -if [ "$UNION" != "overlayfs" -a "$UNION" != "aufs" ]; then - echo "Invalid option for union: choose overlayfs or aufs." - exit 1 -fi - -setup_container() -{ - echo "Setting up ephemeral container..." - OVERLAY_DIR=`mktemp -d /tmp/lxc-lp-XXXXXXX` - sudo mount -t tmpfs none $OVERLAY_DIR - LXC_DIR=`sudo mktemp -d --tmpdir=/var/lib/lxc $LXC_BASE-temp-XXXXXXX` - sudo chmod 755 ${LXC_DIR} - LXC_NAME=`basename $LXC_DIR` - sudo mkdir ${LXC_DIR}/rootfs - do_mount "/var/lib/lxc/$LXC_BASE/rootfs" "${OVERLAY_DIR}" ${LXC_DIR}/rootfs - EPHEMERAL_BIND_DIR=$LXC_DIR/ephemeralbind - sudo mkdir $EPHEMERAL_BIND_DIR - sudo mount -t tmpfs none $EPHEMERAL_BIND_DIR - LXC_MOUNTED=1 - { - d1=/var/lib/lxc/${LXC_BASE} - for f in ${d1}/*; do - if [ -f $f ]; then - sudo cp $f $LXC_DIR/ - fi - done - } - - # Update the ephemeral lxc's configuration to reflect the new container name. - # Check all the places known distros keep hostnames. - # FIXME: should we sanity check the hostname to make sure it contains no bad chars? - for file in $LXC_DIR/fstab $LXC_DIR/config \ - $LXC_DIR/rootfs/etc/hostname \ - $LXC_DIR/rootfs/etc/hosts \ - $LXC_DIR/rootfs/etc/sysconfig/network \ - $LXC_DIR/rootfs/etc/sysconfig/network-scripts/ifcfg-eth0 - do - if test -f "$file" - then - sudo sed -i -e "s/$LXC_BASE/$LXC_NAME/" $file - fi - done - - # Update the fstab to have all bind mounts be ephemeral. - sudo cp $LXC_DIR/fstab $LXC_DIR/fstab.old - while read line; do - # Pull out the second field of the current line of fstab info - path=`echo -n $line | awk '{print $2}'` - # If LXC_BIND is not set, or the mount destination of this line is not - # LXC_BIND... - if [ -z "$LXC_BIND" -o "`readlink -f $path`" != "`readlink -f $LXC_DIR/rootfs$LXC_BIND`" ]; - then - # ...then we should write some form of this line. - # If this line is a bind... - if [ `echo -n $line | awk '{print $4}'` == "bind" ]; then - # ...we should rewrite it as an overlay. - source=`echo -n $line | awk '{print $1}'` - upperdir=$EPHEMERAL_BIND_DIR$source - sudo mkdir -p $upperdir - sudo chown `sudo stat -c '%U.%G' $source` $upperdir - if [ $UNION = "overlayfs" ]; then - echo "none $path overlayfs upperdir=$upperdir,lowerdir=$source 0 0"; - else - echo "none $path aufs br=${upperdir}=rw:${lowerdir}=ro,noplink 0 0"; - fi - else - # Otherwise, we can pass it through unchanged. - echo "$line"; - fi - fi - done < $LXC_DIR/fstab.old | sudo tee $LXC_DIR/fstab >/dev/null - - # If LXC_BIND is defined, add it to fstab. - if [ -n "$LXC_BIND" ]; then - sudo mkdir -p $LXC_DIR/rootfs$LXC_BIND - echo "$LXC_BIND $LXC_DIR/rootfs$LXC_BIND none bind 0 0" | sudo tee -a $LXC_DIR/fstab >/dev/null - fi - - # update the ephemeral container's MAC address (lifted from lxc-clone) - c=$LXC_DIR/config - # change hwaddrs - sudo mv ${c} ${c}.old - ( - while read line; do - if [ "${line:0:18}" = "lxc.network.hwaddr" ]; then - echo "lxc.network.hwaddr= 00:16:3e:$(openssl rand -hex 3| sed 's/\(..\)/\1:/g; s/.$//')" - else - echo "$line" - fi - done - ) < ${c}.old | sudo tee ${c} >/dev/null - sudo rm -f ${c}.old -} - -get_ip() -{ - # Get init's PID - PID=$(sudo lxc-info -n $1 -p | awk '{print $2}') - [ "$PID" = "-1" ] && return 1 - - # Get some unique path - DST=$(sudo mktemp -u --tmpdir=/run/netns/) - NAME=$(basename $DST) - - # Prepare the /run/netns entry for "ip netns" - sudo mkdir -p /run/netns - sudo ln -s /proc/$PID/ns/net $DST - - # Grab all the public globally routed IPv4 and IPv6 addresses - (sudo ip netns exec $NAME ip -4 addr show scope global && \ - sudo ip netns exec $NAME ip -6 addr show scope global) | grep inet | while read line; do - ip=$(echo $line | awk '{print $2}' | cut -d '/' -f1) - echo "$ip" - done - - sudo rm $DST -} - -start_container() -{ - echo "Starting up the container..." - sudo lxc-start -n $LXC_NAME -d - sudo lxc-wait -s RUNNING -n $LXC_NAME - LXC_RUNNING=1 - - if [ $COMMAND_LENGTH -gt 0 ]; then - # When lxc-attach support arrives in the kernel, we can switch to - # that. - # Meanwhile, we use get_ip to wait for container's network to be up - # and to obtain the ip address, then we can ssh to the lxc. - TRIES=60 - FAILED=1 - - # Repeatedly try to connect over SSH until we either succeed - # or time out. - for i in $(seq 1 $TRIES); do - # We call get_ip inside the loop to ensure the correct ip - # is retrieved even in the case the DHCP ip assignment - # changes during the process. - IP_ADDRESS=$(get_ip $LXC_NAME) - if [ -z "$IP_ADDRESS" ]; then - sleep 1 - continue - fi - - # Iterate through all the addresses (if multiple) - for ip in $IP_ADDRESS; do - ssh -n -o StrictHostKeyChecking=no \ - -o UserKnownHostsFile=/dev/null \ - $LXC_KEY $LXC_USER@$IP_ADDRESS -- "$COMMAND" - SSH_RET=$? - if [ ! 255 -eq $SSH_RET ]; then - # If ssh returns 255 then its connection failed. - # Anything else is either success (status 0) or a - # failure from whatever we ran over the SSH connection. - # In those cases we want to stop looping, so we break - # here - return $SSH_RET - fi - done - sleep 1 - done - - echo "could not get IP address - aborting." >&2 - return 255 - else - sudo lxc-wait -n $LXC_NAME -s RUNNING - echo "$LXC_NAME is running" - echo "You connect with the command:" - echo " sudo lxc-console -n $LXC_NAME" - sudo lxc-wait -n $LXC_NAME -s STOPPED - fi -} - -stop_container() -{ - echo "Stopping lxc" >&2 - sudo lxc-stop -n $LXC_NAME - sleep 2 - LXC_RUNNING=0 - cleanup_dirs -} - -handle_container() -{ - setup_container - start_container - RET=$? - stop_container - exit $RET -} - -if [ $DAEMON -eq 1 ]; then - handle_container & - exit 0 -fi - -handle_container diff -Nru lxc-0.8.0~rc1/debian/local/lxc-wait lxc-1.0.0~alpha1/debian/local/lxc-wait --- lxc-0.8.0~rc1/debian/local/lxc-wait 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/local/lxc-wait 1970-01-01 00:00:00.000000000 +0000 @@ -1,171 +0,0 @@ -#!/bin/bash - -# (C) Copyright Canonical 2011,2012 - -# 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 - -usage() { - echo "Usage: lxc-wait --name=NAME --state=STATE" -} - -help() { - usage - echo - echo "lxc-wait waits for NAME container state to reach STATE" - echo - echo "Options :" - echo " -n, --name=NAME NAME for name of the container" - echo " -s, --state=STATE ORed states to wait for" - echo " STOPPED, STARTING, RUNNING, STOPPING," - echo " ABORTING, FREEZING, FROZEN" -} - -set -e - -valid_states=("STOPPED" "STARTING" "RUNNING" "STOPPING" -"ABORTING" "FREEZING" "FROZEN" "THAWED" "MAX_STATE") - -container_exists() { - local c=$1 - local list=`lxc-ls -1` - local name - - for name in $list; do - if [ "$c" = "$name" ]; then - echo "yes" - fi - echo "no" - done -} - -verify_state() { - local s="$1" - local i - - for((i=0;i<${#valid_states[@]};i++)); do - if [ "$s" = "${valid_states[$i]}" ]; then - echo "ok"; return; - fi - done - echo "bad"; return; -} - -badstate="" -verify_states() { - local states=$1 - local s - local v - - for s in $states; do - echo "verifying $s" - v=$(verify_state "$s") - if [ $v = "bad" ]; then - echo "bad"; - badstate="$s" - return; - fi - done - echo "ok"; -} - -state_is_in() { - local state=$1 - local states=$2 - local s - - for s in $states; do - if [ "$state" = "$s" ]; then - echo "yes"; return; - fi - done - echo "no" -} - -shortoptions='hn:s:' -longoptions='help,name:,states:' - -getopt=$(getopt -o $shortoptions --longoptions $longoptions -- "$@") -if [ $? != 0 ]; then - usage - exit 1; -fi - -eval set -- "$getopt" - -states="RUNNING" - -while true; do - case "$1" in - -h|--help) - help - exit 1 - ;; - -n|--name) - shift - lxc_name=$1 - shift - ;; - -s|--states) - shift - states=$1 - shift - ;; - --) - shift - break;; - *) - echo $1 - usage - exit 1 - ;; - esac -done - -if [ -z "$lxc_name" ]; then - echo "no container name specified" - usage - exit 1 -fi - -if [ "$(id -u)" != "0" ]; then - echo "This command has to be run as root" - exit 1 -fi - -type lxc-info > /dev/null || { echo "lxc-info not found."; exit 1; } - -v=$(container_exists $lxc_name) -if [ "$v" = "no" ]; then - echo "Container $lxc_name does not exist" - exit 1 -fi -states2="`echo $states | sed -e 's/|/ /g'`" -v=$(verify_states "${states2}") -if [ "$v" = "bad" ]; then - echo "invalid state $badstate in provided set" - exit 1 -fi - - -while [ 1 ]; do - o=`lxc-info -s -n $lxc_name` - s=`echo $o | awk '{ print $2 }'` - if [ $(state_is_in "$s" "${states2}") = "yes" ]; then - break; - fi - sleep 1 -done - -exit 0 diff -Nru lxc-0.8.0~rc1/debian/local/manpages/Makefile lxc-1.0.0~alpha1/debian/local/manpages/Makefile --- lxc-0.8.0~rc1/debian/local/manpages/Makefile 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/local/manpages/Makefile 1970-01-01 00:00:00.000000000 +0000 @@ -1,41 +0,0 @@ -# Makefile - -SHELL := sh -e - -LANGUAGES = $(shell cd po && ls) - -all: build - -po4a.cfg: - echo "[po4a_langs] $(LANGUAGES)" > po4a.cfg - echo "[po4a_paths] pot/\$$master.pot \$$lang:po/\$$lang/\$$master.po" >> po4a.cfg - - for MANPAGE in en/*; \ - do \ - SECTION="$$(basename $${MANPAGE} | awk -F. '{ print $$2 }')"; \ - echo "[type: man] $${MANPAGE} \$$lang:\$$lang/$$(basename $${MANPAGE} .$${SECTION}).\$$lang.$${SECTION}" >> po4a.cfg; \ - done - -update: - ./bin/update-version.sh - -build: po4a.cfg - @if [ ! -x "$$(which po4a 2>/dev/null)" ]; \ - then \ - echo "E: po4a - command not found"; \ - echo "I: po4a can be optained from:"; \ - echo "I: http://po4a.alioth.debian.org/"; \ - echo "I: On Debian systems, po4a can be installed with:"; \ - echo "I: apt-get install po4a"; \ - exit 1; \ - fi - - po4a --keep 0 --no-backups --package-name lxc po4a.cfg - -clean: - rm -rf $(LANGUAGES) - -distclean: clean - rm -f po4a.cfg - -rebuild: distclean update build diff -Nru lxc-0.8.0~rc1/debian/local/manpages/bin/update-version.sh lxc-1.0.0~alpha1/debian/local/manpages/bin/update-version.sh --- lxc-0.8.0~rc1/debian/local/manpages/bin/update-version.sh 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/local/manpages/bin/update-version.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,16 +0,0 @@ -#!/bin/sh - -set -e - -DATE="$(LC_ALL=C date +%Y\\\\-%m\\\\-%d)" -PROGRAM="LXC" -VERSION="$(cd ../../../ && dpkg-parsechangelog | awk '/^Version: / { print $2 }' | cut -d: -f 2-)" - -echo "Updating version headers..." - -for MANPAGE in en/* -do - SECTION="$(basename ${MANPAGE} | awk -F. '{ print $2 }')" - - sed -i -e "s|^.TH.*$|.TH ${PROGRAM} ${SECTION} ${DATE} ${VERSION} \"Linux Containers\"|" ${MANPAGE} -done diff -Nru lxc-0.8.0~rc1/debian/local/manpages/de/lxc-debconf.de.1 lxc-1.0.0~alpha1/debian/local/manpages/de/lxc-debconf.de.1 --- lxc-0.8.0~rc1/debian/local/manpages/de/lxc-debconf.de.1 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/local/manpages/de/lxc-debconf.de.1 1970-01-01 00:00:00.000000000 +0000 @@ -1,59 +0,0 @@ -.\" lxc-debconf(1) - LXC template to create Debian and Debian based containers -.\" Copyright (C) 2006-2011 Daniel Baumann -.\" -.\" lxc-debconf comes with ABSOLUTELY NO WARRANTY; for details see COPYING. -.\" This is free software, and you are welcome to redistribute it -.\" under certain conditions; see COPYING for details. -.\" -.\" -.\"******************************************************************* -.\" -.\" This file was generated with po4a. Translate the source file. -.\" -.\"******************************************************************* -.TH LXC 1 08.12.2011 0.7.5\-12 "Linux Containers" - -.SH NAME -\fBlxc\-debconf\fP \- LXC template to create Debian and Debian based containers - -.SH SYNTAX -\fBlxc\-create\fP \-t debian \-n|\-\-name \fICONTAINER\fP \-\- [\-\-apt\-recommends] -[\-\-debconf\-frontend \fIDEBCONF_FRONTEND\fP] [\-\-debconf\-priority -\fIDEBCONF_PRIORITY\fP] [\-\-preseed\-file \fIPRESEED_FILE\fP] -.PP -\fBlxc\-create\fP \-t progress \-n|\-\-name \fICONTAINER\fP \-\- [\-\-apt\-recommends] -[\-\-debconf\-frontend \fIDEBCONF_FRONTEND\fP] [\-\-debconf\-priority -\fIDEBCONF_PRIORITY\fP] [\-\-preseed\-file \fIPRESEED_FILE\fP] - -.SH BESCHREIBUNG -LXC(7) uses so called templates to create Linux Container -systems. \fBlxc\-debconf\fP is such a template script to create Debian and -Debian based containers. -.PP -\fBlxc\-debconf\fP can be invoked through lxc\-create(1) in three modes: debconf, -debian, and progress. In debconf mode, it currently falls automatically back -to debian mode. In debian mode, it will allow offer to choose to create -Debian GNU/Linux containers. In progress mode, it will allow to choose to -create Progress Linux containers. -.PP - -.SH OPTIONEN -\fBFIXME\fP - -.SH EXAMPLES -\fBFIXME\fP - -.SH FILES -\fBFIXME\fP - -.SH "SIEHE AUCH" -\fIlxc\fP(7), \fIlxc\fP(1), \fIlxc\-halt\fP(1), \fIlxc\-list\fP(1). - -.SH FEHLER -Fehler können durch Einreichen eines Fehlerberichtes für das lxc Paket im -Debian Bug Tracking System unter <\fIhttp://bugs.debian.org/\fP> oder -durch Senden einer E\-Mail an den Autor mitgeteilt werden. - -.SH AUTOR -lxc\-debconf wurde von Daniel Baumann -<\fIdaniel.baumann@progress\-technologies.net\fP> geschrieben. diff -Nru lxc-0.8.0~rc1/debian/local/manpages/de/lxc-halt.de.1 lxc-1.0.0~alpha1/debian/local/manpages/de/lxc-halt.de.1 --- lxc-0.8.0~rc1/debian/local/manpages/de/lxc-halt.de.1 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/local/manpages/de/lxc-halt.de.1 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ -.\" lxc-halt(1) - shutdown a Linux Container -.\" Copyright (C) 2006-2011 Daniel Baumann -.\" -.\" lxc-halt comes with ABSOLUTELY NO WARRANTY; for details see COPYING. -.\" This is free software, and you are welcome to redistribute it -.\" under certain conditions; see COPYING for details. -.\" -.\" -.\"******************************************************************* -.\" -.\" This file was generated with po4a. Translate the source file. -.\" -.\"******************************************************************* -.TH LXC 1 08.12.2011 0.7.5\-12 "Linux Containers" - -.SH NAME -\fBlxc\-halt\fP \- fährt einen Linux Container herunter - -.SH SYNTAX -\fBlxc\-halt\fP \fICONTAINER\fP - -.SH BESCHREIBUNG -\fBlxc\-halt\fP fährt einen Linux Container herunter ohne alle dessen Prozesse -zu killen wie es lxc\-stop tut. Es führt einen ordentlichen Shutdown mittels -eines Wechsel zu Runlevel 0 innerhalb des Containers durch. - -.SH OPTIONEN -.IP \fICONTAINER\fP 4 -bezeichnet einen Linux Container im LXC Pfad (Standardeinstellung -/var/lib/lxc). - -.SH "SIEHE AUCH" -\fIlxc\fP(7), \fIlxc\fP(1), \fIlxc\-debconf\fP(1), \fIlxc\-list\fP(1). - -.SH FEHLER -Fehler können durch Einreichen eines Fehlerberichtes für das lxc Paket im -Debian Bug Tracking System unter <\fIhttp://bugs.debian.org/\fP> oder -durch Senden einer E\-Mail an den Autor mitgeteilt werden. - -.SH AUTOR -lxc\-halt wurde von Daniel Baumann -<\fIdaniel.baumann@progress\-technologies.net\fP> geschrieben. diff -Nru lxc-0.8.0~rc1/debian/local/manpages/de/lxc-list.de.1 lxc-1.0.0~alpha1/debian/local/manpages/de/lxc-list.de.1 --- lxc-0.8.0~rc1/debian/local/manpages/de/lxc-list.de.1 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/local/manpages/de/lxc-list.de.1 1970-01-01 00:00:00.000000000 +0000 @@ -1,38 +0,0 @@ -.\" lxc-list(1) - list Linux Containers by state -.\" Copyright (C) 2006-2011 Daniel Baumann -.\" -.\" lxc-list comes with ABSOLUTELY NO WARRANTY; for details see COPYING. -.\" This is free software, and you are welcome to redistribute it -.\" under certain conditions; see COPYING for details. -.\" -.\" -.\"******************************************************************* -.\" -.\" This file was generated with po4a. Translate the source file. -.\" -.\"******************************************************************* -.TH LXC 1 08.12.2011 0.7.5\-12 "Linux Containers" - -.SH NAME -\fBlxc\-list\fP \- listet Linux Container nach Status - -.SH SYNTAX -\fBlxc\-list\fP - -.SH BESCHREIBUNG -\fBlxc\-list\fP listed Linux Container nach Status - -.SH OPTIONEN -lxc\-list hat keine Optionen. - -.SH "SIEHE AUCH" -\fIlxc\fP(7), \fIlxc\fP(1), \fIlxc\-debconf\fP(1), \fIlxc\-halt\fP(1). - -.SH FEHLER -Fehler können durch Einreichen eines Fehlerberichtes für das lxc Paket im -Debian Bug Tracking System unter <\fIhttp://bugs.debian.org/\fP> oder -durch Senden einer E\-Mail an den Autor mitgeteilt werden. - -.SH AUTOR -lxc\-list wurde von Daniel Baumann -<\fIdaniel.baumann@progress\-technologies.net\fP> geschrieben. diff -Nru lxc-0.8.0~rc1/debian/local/manpages/de/lxc.de.1 lxc-1.0.0~alpha1/debian/local/manpages/de/lxc.de.1 --- lxc-0.8.0~rc1/debian/local/manpages/de/lxc.de.1 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/local/manpages/de/lxc.de.1 1970-01-01 00:00:00.000000000 +0000 @@ -1,47 +0,0 @@ -.\" lxc(1) - convenience Wrapper for LXC programs -.\" Copyright (C) 2006-2011 Daniel Baumann -.\" -.\" lxc comes with ABSOLUTELY NO WARRANTY; for details see COPYING. -.\" This is free software, and you are welcome to redistribute it -.\" under certain conditions; see COPYING for details. -.\" -.\" -.\"******************************************************************* -.\" -.\" This file was generated with po4a. Translate the source file. -.\" -.\"******************************************************************* -.TH LXC 1 08.12.2011 0.7.5\-12 "Linux Containers" - -.SH NAME -\fBlxc\fP \- Convenience Wrapper für LXC Programme - -.SH SYNTAX -\fBlxc\fP \fIPROGRAMM\fP \fICONTAINER\fP - -.SH BESCHREIBUNG -\fBlxc\fP ist ein Convenience Wrapper für LXC Programme. Siehe \fIlxc\fP(7) für -mehr Informationen über die Linux Container Tools (LXC). -.PP -Beispiel (normal): lxc \-n example.org start -.PP -Example (Wrapper): lxc start example.org - -.SH OPTIONEN -.IP \fIPROGRAMM\fP 4 -bezeichnet ein Programm der Linux Container Tools (LXC), siehe \fIlxc\fP(7). -.IP \fICONTAINER\fP 4 -bezeichnet einen Linux Container im LXC Pfad (Standardeinstellung -/var/lib/lxc). - -.SH "SIEHE AUCH" -\fIlxc\fP(7), \fIlxc\-debconf\fP(1), \fIlxc\-halt\fP(1), \fIlxc\-list\fP(1). - -.SH FEHLER -Fehler können durch Einreichen eines Fehlerberichtes für das lxc Paket im -Debian Bug Tracking System unter <\fIhttp://bugs.debian.org/\fP> oder -durch Senden einer E\-Mail an den Autor mitgeteilt werden. - -.SH AUTOR -lxc wurde von Daniel Baumann -<\fIdaniel.baumann@progress\-technologies.net\fP> geschrieben. diff -Nru lxc-0.8.0~rc1/debian/local/manpages/en/lxc-debconf.1 lxc-1.0.0~alpha1/debian/local/manpages/en/lxc-debconf.1 --- lxc-0.8.0~rc1/debian/local/manpages/en/lxc-debconf.1 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/local/manpages/en/lxc-debconf.1 1970-01-01 00:00:00.000000000 +0000 @@ -1,44 +0,0 @@ -.\" lxc-debconf(1) - LXC template to create Debian and Debian based containers -.\" Copyright (C) 2006-2011 Daniel Baumann -.\" -.\" lxc-debconf comes with ABSOLUTELY NO WARRANTY; for details see COPYING. -.\" This is free software, and you are welcome to redistribute it -.\" under certain conditions; see COPYING for details. -.\" -.\" -.TH LXC 1 2011\-12\-08 0.7.5-12 "Linux Containers" - -.SH NAME -\fBlxc\-debconf\fR \- LXC template to create Debian and Debian based containers - -.SH SYNOPSIS -\fBlxc\-create\fR \-t debian \-n|\-\-name \fICONTAINER\fR \-\- [\-\-apt\-recommends] [\-\-debconf\-frontend \fIDEBCONF_FRONTEND\fR] [\-\-debconf\-priority \fIDEBCONF_PRIORITY\fR] [\-\-preseed\-file \fIPRESEED_FILE\fR] -.PP -\fBlxc\-create\fR \-t progress \-n|\-\-name \fICONTAINER\fR \-\- [\-\-apt\-recommends] [\-\-debconf\-frontend \fIDEBCONF_FRONTEND\fR] [\-\-debconf\-priority \fIDEBCONF_PRIORITY\fR] [\-\-preseed\-file \fIPRESEED_FILE\fR] - -.SH DESCRIPTION -LXC(7) uses so called templates to create Linux Container systems. \fBlxc\-debconf\fR is such a template script to create Debian and Debian based containers. -.PP -\fBlxc\-debconf\fR can be invoked through lxc\-create(1) in three modes: debconf, debian, and progress. In debconf mode, it currently falls automatically back to debian mode. In debian mode, it will allow offer to choose to create Debian GNU/Linux containers. In progress mode, it will allow to choose to create Progress Linux containers. -.PP - -.SH OPTIONS -\fBFIXME\fR - -.SH EXAMPLES -\fBFIXME\fR - -.SH FILES -\fBFIXME\fR - -.SH SEE ALSO -\fIlxc\fR(7), -\fIlxc\fR(1), -\fIlxc\-halt\fR(1), -\fIlxc\-list\fR(1). - -.SH BUGS -Bugs can be reported by submitting a bugreport for the lxc package in the Debian Bug Tracking System at <\fIhttp://bugs.debian.org/\fR> or by writing a mail to the author. - -.SH AUTHOR -lxc\-debconf was written by Daniel Baumann <\fIdaniel.baumann@progress-technologies.net\fR>. diff -Nru lxc-0.8.0~rc1/debian/local/manpages/en/lxc-halt.1 lxc-1.0.0~alpha1/debian/local/manpages/en/lxc-halt.1 --- lxc-0.8.0~rc1/debian/local/manpages/en/lxc-halt.1 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/local/manpages/en/lxc-halt.1 1970-01-01 00:00:00.000000000 +0000 @@ -1,34 +0,0 @@ -.\" lxc-halt(1) - shutdown a Linux Container -.\" Copyright (C) 2006-2011 Daniel Baumann -.\" -.\" lxc-halt comes with ABSOLUTELY NO WARRANTY; for details see COPYING. -.\" This is free software, and you are welcome to redistribute it -.\" under certain conditions; see COPYING for details. -.\" -.\" -.TH LXC 1 2011\-12\-08 0.7.5-12 "Linux Containers" - -.SH NAME -\fBlxc\-halt\fR \- shutdown Linux Containers by state - -.SH SYNOPSIS -\fBlxc\-halt\fR \fICONTAINER\fR - -.SH DESCRIPTION -\fBlxc\-halt\fR shuts down a Linux Container by not killing all processes of it like lxc\-stop does. It does an ordinary shutdown by issueing a switch to runlevel 0 within the container. - -.SH OPTIONS -.IP "\fICONTAINER\fR" 4 -specifies a Linux Container in the LXC path (default /var/lib/lxc). - -.SH SEE ALSO -\fIlxc\fR(7), -\fIlxc\fR(1), -\fIlxc\-debconf\fR(1), -\fIlxc\-list\fR(1). - -.SH BUGS -Bugs can be reported by submitting a bugreport for the lxc package in the Debian Bug Tracking System at <\fIhttp://bugs.debian.org/\fR> or by writing a mail to the author. - -.SH AUTHOR -lxc\-halt was written by Daniel Baumann <\fIdaniel.baumann@progress-technologies.net\fR>. diff -Nru lxc-0.8.0~rc1/debian/local/manpages/en/lxc-list.1 lxc-1.0.0~alpha1/debian/local/manpages/en/lxc-list.1 --- lxc-0.8.0~rc1/debian/local/manpages/en/lxc-list.1 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/local/manpages/en/lxc-list.1 1970-01-01 00:00:00.000000000 +0000 @@ -1,33 +0,0 @@ -.\" lxc-list(1) - list Linux Containers by state -.\" Copyright (C) 2006-2011 Daniel Baumann -.\" -.\" lxc-list comes with ABSOLUTELY NO WARRANTY; for details see COPYING. -.\" This is free software, and you are welcome to redistribute it -.\" under certain conditions; see COPYING for details. -.\" -.\" -.TH LXC 1 2011\-12\-08 0.7.5-12 "Linux Containers" - -.SH NAME -\fBlxc\-list\fR \- list Linux Containers by state - -.SH SYNOPSIS -\fBlxc\-list\fR - -.SH DESCRIPTION -\fBlxc\-list\fR lists Linux Containers by state. - -.SH OPTIONS -lxc\-list has no options. - -.SH SEE ALSO -\fIlxc\fR(7), -\fIlxc\fR(1), -\fIlxc\-debconf\fR(1), -\fIlxc\-halt\fR(1). - -.SH BUGS -Bugs can be reported by submitting a bugreport for the lxc package in the Debian Bug Tracking System at <\fIhttp://bugs.debian.org/\fR> or by writing a mail to the author. - -.SH AUTHOR -lxc\-list was written by Daniel Baumann <\fIdaniel.baumann@progress-technologies.net\fR>. diff -Nru lxc-0.8.0~rc1/debian/local/manpages/en/lxc.1 lxc-1.0.0~alpha1/debian/local/manpages/en/lxc.1 --- lxc-0.8.0~rc1/debian/local/manpages/en/lxc.1 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/local/manpages/en/lxc.1 1970-01-01 00:00:00.000000000 +0000 @@ -1,40 +0,0 @@ -.\" lxc(1) - convenience Wrapper for LXC programs -.\" Copyright (C) 2006-2011 Daniel Baumann -.\" -.\" lxc comes with ABSOLUTELY NO WARRANTY; for details see COPYING. -.\" This is free software, and you are welcome to redistribute it -.\" under certain conditions; see COPYING for details. -.\" -.\" -.TH LXC 1 2011\-12\-08 0.7.5-12 "Linux Containers" - -.SH NAME -\fBlxc\fR \- convenience Wrapper for LXC programs - -.SH SYNOPSIS -\fBlxc\fR \fIPROGRAM\fR \fICONTAINER\fR - -.SH DESCRIPTION -\fBlxc\fR is a convenience Wrapper for LXC programs. See \fIlxc\fR(7) for more information about the Linux Container tools (LXC). -.PP -Example (normal): lxc -n example.org start -.PP -Example (wrapper): lxc start example.org - -.SH OPTIONS -.IP "\fIPROGRAM\fR" 4 -specifies a program of the Linux Container tools (LXC), see \fIlxc\fR(7). -.IP "\fICONTAINER\fR" 4 -specifies a Linux Container in the LXC path (default /var/lib/lxc). - -.SH SEE ALSO -\fIlxc\fR(7), -\fIlxc\-debconf\fR(1), -\fIlxc\-halt\fR(1), -\fIlxc\-list\fR(1). - -.SH BUGS -Bugs can be reported by submitting a bugreport for the lxc package in the Debian Bug Tracking System at <\fIhttp://bugs.debian.org/\fR> or by writing a mail to the author. - -.SH AUTHOR -lxc was written by Daniel Baumann <\fIdaniel.baumann@progress-technologies.net\fR>. diff -Nru lxc-0.8.0~rc1/debian/local/manpages/po/de/lxc-debconf.1.po lxc-1.0.0~alpha1/debian/local/manpages/po/de/lxc-debconf.1.po --- lxc-0.8.0~rc1/debian/local/manpages/po/de/lxc-debconf.1.po 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/local/manpages/po/de/lxc-debconf.1.po 1970-01-01 00:00:00.000000000 +0000 @@ -1,165 +0,0 @@ -# German translations for lxc package -# Copyright (C) 2011 Free Software Foundation, Inc. -# This file is distributed under the same license as the lxc package. -# Automatically generated, 2011. -# -msgid "" -msgstr "" -"Project-Id-Version: lxc VERSION\n" -"POT-Creation-Date: 2011-12-08 12:31+0100\n" -"PO-Revision-Date: 2011-12-08 12:31+0100\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" -"Language: de\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#. type: TH -#: en/lxc-debconf.1:9 en/lxc-halt.1:9 en/lxc-list.1:9 en/lxc.1:9 -#, no-wrap -msgid "LXC" -msgstr "LXC" - -#. type: TH -#: en/lxc-debconf.1:9 en/lxc-halt.1:9 en/lxc-list.1:9 en/lxc.1:9 -#, no-wrap -msgid "2011-12-08" -msgstr "08.12.2011" - -#. type: TH -#: en/lxc-debconf.1:9 en/lxc-halt.1:9 en/lxc-list.1:9 en/lxc.1:9 -#, no-wrap -msgid "0.7.5-12" -msgstr "0.7.5-12" - -#. type: TH -#: en/lxc-debconf.1:9 en/lxc-halt.1:9 en/lxc-list.1:9 en/lxc.1:9 -#, no-wrap -msgid "Linux Containers" -msgstr "Linux Containers" - -#. type: SH -#: en/lxc-debconf.1:11 en/lxc-halt.1:11 en/lxc-list.1:11 en/lxc.1:11 -#, no-wrap -msgid "NAME" -msgstr "NAME" - -#. type: Plain text -#: en/lxc-debconf.1:13 -msgid "" -"B - LXC template to create Debian and Debian based containers" -msgstr "" - -#. type: SH -#: en/lxc-debconf.1:14 en/lxc-halt.1:14 en/lxc-list.1:14 en/lxc.1:14 -#, no-wrap -msgid "SYNOPSIS" -msgstr "SYNTAX" - -#. type: Plain text -#: en/lxc-debconf.1:16 -msgid "" -"B -t debian -n|--name I -- [--apt-recommends] [--" -"debconf-frontend I] [--debconf-priority " -"I] [--preseed-file I]" -msgstr "" - -#. type: Plain text -#: en/lxc-debconf.1:18 -msgid "" -"B -t progress -n|--name I -- [--apt-recommends] [--" -"debconf-frontend I] [--debconf-priority " -"I] [--preseed-file I]" -msgstr "" - -#. type: SH -#: en/lxc-debconf.1:19 en/lxc-halt.1:17 en/lxc-list.1:17 en/lxc.1:17 -#, no-wrap -msgid "DESCRIPTION" -msgstr "BESCHREIBUNG" - -#. type: Plain text -#: en/lxc-debconf.1:21 -msgid "" -"LXC(7) uses so called templates to create Linux Container systems. B is such a template script to create Debian and Debian based " -"containers." -msgstr "" - -#. type: Plain text -#: en/lxc-debconf.1:23 -msgid "" -"B can be invoked through lxc-create(1) in three modes: debconf, " -"debian, and progress. In debconf mode, it currently falls automatically back " -"to debian mode. In debian mode, it will allow offer to choose to create " -"Debian GNU/Linux containers. In progress mode, it will allow to choose to " -"create Progress Linux containers." -msgstr "" - -#. type: SH -#: en/lxc-debconf.1:25 en/lxc-halt.1:20 en/lxc-list.1:20 en/lxc.1:24 -#, no-wrap -msgid "OPTIONS" -msgstr "OPTIONEN" - -#. type: Plain text -#: en/lxc-debconf.1:27 en/lxc-debconf.1:30 en/lxc-debconf.1:33 -msgid "B" -msgstr "" - -#. type: SH -#: en/lxc-debconf.1:28 -#, no-wrap -msgid "EXAMPLES" -msgstr "" - -#. type: SH -#: en/lxc-debconf.1:31 -#, no-wrap -msgid "FILES" -msgstr "" - -#. type: SH -#: en/lxc-debconf.1:34 en/lxc-halt.1:24 en/lxc-list.1:23 en/lxc.1:30 -#, no-wrap -msgid "SEE ALSO" -msgstr "SIEHE AUCH" - -#. type: Plain text -#: en/lxc-debconf.1:39 -msgid "I(7), I(1), I(1), I(1)." -msgstr "I(7), I(1), I(1), I(1)." - -#. type: SH -#: en/lxc-debconf.1:40 en/lxc-halt.1:30 en/lxc-list.1:29 en/lxc.1:36 -#, no-wrap -msgid "BUGS" -msgstr "FEHLER" - -#. type: Plain text -#: en/lxc-debconf.1:42 en/lxc-halt.1:32 en/lxc-list.1:31 en/lxc.1:38 -msgid "" -"Bugs can be reported by submitting a bugreport for the lxc package in the " -"Debian Bug Tracking System at EIE or by " -"writing a mail to the author." -msgstr "" -"Fehler können durch Einreichen eines Fehlerberichtes für das lxc Paket im " -"Debian Bug Tracking System unter EIE oder " -"durch Senden einer E-Mail an den Autor mitgeteilt werden." - -#. type: SH -#: en/lxc-debconf.1:43 en/lxc-halt.1:33 en/lxc-list.1:32 en/lxc.1:39 -#, no-wrap -msgid "AUTHOR" -msgstr "AUTOR" - -#. type: Plain text -#: en/lxc-debconf.1:44 -msgid "" -"lxc-debconf was written by Daniel Baumann EIE." -msgstr "" -"lxc-debconf wurde von Daniel Baumann EIE geschrieben." diff -Nru lxc-0.8.0~rc1/debian/local/manpages/po/de/lxc-halt.1.po lxc-1.0.0~alpha1/debian/local/manpages/po/de/lxc-halt.1.po --- lxc-0.8.0~rc1/debian/local/manpages/po/de/lxc-halt.1.po 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/local/manpages/po/de/lxc-halt.1.po 1970-01-01 00:00:00.000000000 +0000 @@ -1,141 +0,0 @@ -# German translations for lxc-list -# 2011 Daniel Baumann -# This file is distributed under the same license as the lxc packaging. -# -msgid "" -msgstr "" -"Project-Id-Version: lxc\n" -"POT-Creation-Date: 2011-12-08 12:31+0100\n" -"PO-Revision-Date: 2010-05-24 09:59+0300\n" -"Last-Translator: Daniel Baumann \n" -"Language-Team: none\n" -"Language: de\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#. type: TH -#: en/lxc-debconf.1:9 en/lxc-halt.1:9 en/lxc-list.1:9 en/lxc.1:9 -#, no-wrap -msgid "LXC" -msgstr "LXC" - -#. type: TH -#: en/lxc-debconf.1:9 en/lxc-halt.1:9 en/lxc-list.1:9 en/lxc.1:9 -#, no-wrap -msgid "2011-12-08" -msgstr "08.12.2011" - -#. type: TH -#: en/lxc-debconf.1:9 en/lxc-halt.1:9 en/lxc-list.1:9 en/lxc.1:9 -#, no-wrap -msgid "0.7.5-12" -msgstr "0.7.5-12" - -#. type: TH -#: en/lxc-debconf.1:9 en/lxc-halt.1:9 en/lxc-list.1:9 en/lxc.1:9 -#, no-wrap -msgid "Linux Containers" -msgstr "Linux Containers" - -#. type: SH -#: en/lxc-debconf.1:11 en/lxc-halt.1:11 en/lxc-list.1:11 en/lxc.1:11 -#, no-wrap -msgid "NAME" -msgstr "NAME" - -#. type: SH -#: en/lxc-debconf.1:14 en/lxc-halt.1:14 en/lxc-list.1:14 en/lxc.1:14 -#, no-wrap -msgid "SYNOPSIS" -msgstr "SYNTAX" - -#. type: SH -#: en/lxc-debconf.1:19 en/lxc-halt.1:17 en/lxc-list.1:17 en/lxc.1:17 -#, no-wrap -msgid "DESCRIPTION" -msgstr "BESCHREIBUNG" - -#. type: SH -#: en/lxc-debconf.1:25 en/lxc-halt.1:20 en/lxc-list.1:20 en/lxc.1:24 -#, no-wrap -msgid "OPTIONS" -msgstr "OPTIONEN" - -#. type: SH -#: en/lxc-debconf.1:34 en/lxc-halt.1:24 en/lxc-list.1:23 en/lxc.1:30 -#, no-wrap -msgid "SEE ALSO" -msgstr "SIEHE AUCH" - -#. type: SH -#: en/lxc-debconf.1:40 en/lxc-halt.1:30 en/lxc-list.1:29 en/lxc.1:36 -#, no-wrap -msgid "BUGS" -msgstr "FEHLER" - -#. type: Plain text -#: en/lxc-debconf.1:42 en/lxc-halt.1:32 en/lxc-list.1:31 en/lxc.1:38 -msgid "" -"Bugs can be reported by submitting a bugreport for the lxc package in the " -"Debian Bug Tracking System at EIE or by " -"writing a mail to the author." -msgstr "" -"Fehler können durch Einreichen eines Fehlerberichtes für das lxc Paket im " -"Debian Bug Tracking System unter EIE oder " -"durch Senden einer E-Mail an den Autor mitgeteilt werden." - -#. type: SH -#: en/lxc-debconf.1:43 en/lxc-halt.1:33 en/lxc-list.1:32 en/lxc.1:39 -#, no-wrap -msgid "AUTHOR" -msgstr "AUTOR" - -#. type: Plain text -#: en/lxc-halt.1:13 -msgid "B - shutdown Linux Containers by state" -msgstr "B - fährt einen Linux Container herunter" - -#. type: Plain text -#: en/lxc-halt.1:16 -msgid "B I" -msgstr "B I" - -#. type: Plain text -#: en/lxc-halt.1:19 -msgid "" -"B shuts down a Linux Container by not killing all processes of it " -"like lxc-stop does. It does an ordinary shutdown by issueing a switch to " -"runlevel 0 within the container." -msgstr "" -"B fährt einen Linux Container herunter ohne alle dessen Prozesse " -"zu killen wie es lxc-stop tut. Es führt einen ordentlichen Shutdown mittels " -"eines Wechsel zu Runlevel 0 innerhalb des Containers durch." - -#. type: IP -#: en/lxc-halt.1:21 en/lxc.1:27 -#, no-wrap -msgid "I" -msgstr "I" - -#. type: Plain text -#: en/lxc-halt.1:23 en/lxc.1:29 -msgid "specifies a Linux Container in the LXC path (default /var/lib/lxc)." -msgstr "" -"bezeichnet einen Linux Container im LXC Pfad (Standardeinstellung /var/lib/" -"lxc)." - -#. type: Plain text -#: en/lxc-halt.1:29 -msgid "I(7), I(1), I(1), I(1)." -msgstr "I(7), I(1), I(1), I(1)." - -#. type: Plain text -#: en/lxc-halt.1:34 -msgid "" -"lxc-halt was written by Daniel Baumann EIE." -msgstr "" -"lxc-halt wurde von Daniel Baumann EIE geschrieben." diff -Nru lxc-0.8.0~rc1/debian/local/manpages/po/de/lxc-list.1.po lxc-1.0.0~alpha1/debian/local/manpages/po/de/lxc-list.1.po --- lxc-0.8.0~rc1/debian/local/manpages/po/de/lxc-list.1.po 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/local/manpages/po/de/lxc-list.1.po 1970-01-01 00:00:00.000000000 +0000 @@ -1,127 +0,0 @@ -# German translations for lxc-list -# 2011 Daniel Baumann -# This file is distributed under the same license as the lxc packaging. -# -msgid "" -msgstr "" -"Project-Id-Version: lxc\n" -"POT-Creation-Date: 2011-12-08 12:31+0100\n" -"PO-Revision-Date: 2010-05-24 09:59+0300\n" -"Last-Translator: Daniel Baumann \n" -"Language-Team: none\n" -"Language: de\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#. type: TH -#: en/lxc-debconf.1:9 en/lxc-halt.1:9 en/lxc-list.1:9 en/lxc.1:9 -#, no-wrap -msgid "LXC" -msgstr "LXC" - -#. type: TH -#: en/lxc-debconf.1:9 en/lxc-halt.1:9 en/lxc-list.1:9 en/lxc.1:9 -#, no-wrap -msgid "2011-12-08" -msgstr "08.12.2011" - -#. type: TH -#: en/lxc-debconf.1:9 en/lxc-halt.1:9 en/lxc-list.1:9 en/lxc.1:9 -#, no-wrap -msgid "0.7.5-12" -msgstr "0.7.5-12" - -#. type: TH -#: en/lxc-debconf.1:9 en/lxc-halt.1:9 en/lxc-list.1:9 en/lxc.1:9 -#, no-wrap -msgid "Linux Containers" -msgstr "Linux Containers" - -#. type: SH -#: en/lxc-debconf.1:11 en/lxc-halt.1:11 en/lxc-list.1:11 en/lxc.1:11 -#, no-wrap -msgid "NAME" -msgstr "NAME" - -#. type: SH -#: en/lxc-debconf.1:14 en/lxc-halt.1:14 en/lxc-list.1:14 en/lxc.1:14 -#, no-wrap -msgid "SYNOPSIS" -msgstr "SYNTAX" - -#. type: SH -#: en/lxc-debconf.1:19 en/lxc-halt.1:17 en/lxc-list.1:17 en/lxc.1:17 -#, no-wrap -msgid "DESCRIPTION" -msgstr "BESCHREIBUNG" - -#. type: SH -#: en/lxc-debconf.1:25 en/lxc-halt.1:20 en/lxc-list.1:20 en/lxc.1:24 -#, no-wrap -msgid "OPTIONS" -msgstr "OPTIONEN" - -#. type: SH -#: en/lxc-debconf.1:34 en/lxc-halt.1:24 en/lxc-list.1:23 en/lxc.1:30 -#, no-wrap -msgid "SEE ALSO" -msgstr "SIEHE AUCH" - -#. type: SH -#: en/lxc-debconf.1:40 en/lxc-halt.1:30 en/lxc-list.1:29 en/lxc.1:36 -#, no-wrap -msgid "BUGS" -msgstr "FEHLER" - -#. type: Plain text -#: en/lxc-debconf.1:42 en/lxc-halt.1:32 en/lxc-list.1:31 en/lxc.1:38 -msgid "" -"Bugs can be reported by submitting a bugreport for the lxc package in the " -"Debian Bug Tracking System at EIE or by " -"writing a mail to the author." -msgstr "" -"Fehler können durch Einreichen eines Fehlerberichtes für das lxc Paket im " -"Debian Bug Tracking System unter EIE oder " -"durch Senden einer E-Mail an den Autor mitgeteilt werden." - -#. type: SH -#: en/lxc-debconf.1:43 en/lxc-halt.1:33 en/lxc-list.1:32 en/lxc.1:39 -#, no-wrap -msgid "AUTHOR" -msgstr "AUTOR" - -#. type: Plain text -#: en/lxc-list.1:13 -msgid "B - list Linux Containers by state" -msgstr "B - listet Linux Container nach Status" - -#. type: Plain text -#: en/lxc-list.1:16 -msgid "B" -msgstr "B" - -#. type: Plain text -#: en/lxc-list.1:19 -msgid "B lists Linux Containers by state." -msgstr "B listed Linux Container nach Status" - -#. type: Plain text -#: en/lxc-list.1:22 -msgid "lxc-list has no options." -msgstr "lxc-list hat keine Optionen." - -#. type: Plain text -#: en/lxc-list.1:28 -msgid "I(7), I(1), I(1), I(1)." -msgstr "I(7), I(1), I(1), I(1)." - -#. type: Plain text -#: en/lxc-list.1:33 -msgid "" -"lxc-list was written by Daniel Baumann EIE." -msgstr "" -"lxc-list wurde von Daniel Baumann EIE geschrieben." diff -Nru lxc-0.8.0~rc1/debian/local/manpages/po/de/lxc.1.po lxc-1.0.0~alpha1/debian/local/manpages/po/de/lxc.1.po --- lxc-0.8.0~rc1/debian/local/manpages/po/de/lxc.1.po 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/local/manpages/po/de/lxc.1.po 1970-01-01 00:00:00.000000000 +0000 @@ -1,161 +0,0 @@ -# German translations for lxc-list -# 2011 Daniel Baumann -# This file is distributed under the same license as the lxc packaging. -# -msgid "" -msgstr "" -"Project-Id-Version: lxc\n" -"POT-Creation-Date: 2011-12-08 12:31+0100\n" -"PO-Revision-Date: 2010-05-24 09:59+0300\n" -"Last-Translator: Daniel Baumann \n" -"Language-Team: none\n" -"Language: de\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#. type: TH -#: en/lxc-debconf.1:9 en/lxc-halt.1:9 en/lxc-list.1:9 en/lxc.1:9 -#, no-wrap -msgid "LXC" -msgstr "LXC" - -#. type: TH -#: en/lxc-debconf.1:9 en/lxc-halt.1:9 en/lxc-list.1:9 en/lxc.1:9 -#, no-wrap -msgid "2011-12-08" -msgstr "08.12.2011" - -#. type: TH -#: en/lxc-debconf.1:9 en/lxc-halt.1:9 en/lxc-list.1:9 en/lxc.1:9 -#, no-wrap -msgid "0.7.5-12" -msgstr "0.7.5-12" - -#. type: TH -#: en/lxc-debconf.1:9 en/lxc-halt.1:9 en/lxc-list.1:9 en/lxc.1:9 -#, no-wrap -msgid "Linux Containers" -msgstr "Linux Containers" - -#. type: SH -#: en/lxc-debconf.1:11 en/lxc-halt.1:11 en/lxc-list.1:11 en/lxc.1:11 -#, no-wrap -msgid "NAME" -msgstr "NAME" - -#. type: SH -#: en/lxc-debconf.1:14 en/lxc-halt.1:14 en/lxc-list.1:14 en/lxc.1:14 -#, no-wrap -msgid "SYNOPSIS" -msgstr "SYNTAX" - -#. type: SH -#: en/lxc-debconf.1:19 en/lxc-halt.1:17 en/lxc-list.1:17 en/lxc.1:17 -#, no-wrap -msgid "DESCRIPTION" -msgstr "BESCHREIBUNG" - -#. type: SH -#: en/lxc-debconf.1:25 en/lxc-halt.1:20 en/lxc-list.1:20 en/lxc.1:24 -#, no-wrap -msgid "OPTIONS" -msgstr "OPTIONEN" - -#. type: SH -#: en/lxc-debconf.1:34 en/lxc-halt.1:24 en/lxc-list.1:23 en/lxc.1:30 -#, no-wrap -msgid "SEE ALSO" -msgstr "SIEHE AUCH" - -#. type: SH -#: en/lxc-debconf.1:40 en/lxc-halt.1:30 en/lxc-list.1:29 en/lxc.1:36 -#, no-wrap -msgid "BUGS" -msgstr "FEHLER" - -#. type: Plain text -#: en/lxc-debconf.1:42 en/lxc-halt.1:32 en/lxc-list.1:31 en/lxc.1:38 -msgid "" -"Bugs can be reported by submitting a bugreport for the lxc package in the " -"Debian Bug Tracking System at EIE or by " -"writing a mail to the author." -msgstr "" -"Fehler können durch Einreichen eines Fehlerberichtes für das lxc Paket im " -"Debian Bug Tracking System unter EIE oder " -"durch Senden einer E-Mail an den Autor mitgeteilt werden." - -#. type: SH -#: en/lxc-debconf.1:43 en/lxc-halt.1:33 en/lxc-list.1:32 en/lxc.1:39 -#, no-wrap -msgid "AUTHOR" -msgstr "AUTOR" - -#. type: IP -#: en/lxc-halt.1:21 en/lxc.1:27 -#, no-wrap -msgid "I" -msgstr "I" - -#. type: Plain text -#: en/lxc-halt.1:23 en/lxc.1:29 -msgid "specifies a Linux Container in the LXC path (default /var/lib/lxc)." -msgstr "" -"bezeichnet einen Linux Container im LXC Pfad (Standardeinstellung /var/lib/" -"lxc)." - -#. type: Plain text -#: en/lxc.1:13 -msgid "B - convenience Wrapper for LXC programs" -msgstr "B - Convenience Wrapper für LXC Programme" - -#. type: Plain text -#: en/lxc.1:16 -msgid "B I I" -msgstr "B I I" - -#. type: Plain text -#: en/lxc.1:19 -msgid "" -"B is a convenience Wrapper for LXC programs. See I(7) for more " -"information about the Linux Container tools (LXC)." -msgstr "" -"B ist ein Convenience Wrapper für LXC Programme. Siehe I(7) für " -"mehr Informationen über die Linux Container Tools (LXC)." - -#. type: Plain text -#: en/lxc.1:21 -msgid "Example (normal): lxc -n example.org start" -msgstr "Beispiel (normal): lxc -n example.org start" - -#. type: Plain text -#: en/lxc.1:23 -msgid "Example (wrapper): lxc start example.org" -msgstr "Example (Wrapper): lxc start example.org" - -#. type: IP -#: en/lxc.1:25 -#, no-wrap -msgid "I" -msgstr "I" - -#. type: Plain text -#: en/lxc.1:27 -msgid "specifies a program of the Linux Container tools (LXC), see I(7)." -msgstr "" -"bezeichnet ein Programm der Linux Container Tools (LXC), siehe I(7)." - -#. type: Plain text -#: en/lxc.1:35 -msgid "I(7), I(1), I(1), I(1)." -msgstr "I(7), I(1), I(1), I(1)." - -#. type: Plain text -#: en/lxc.1:40 -msgid "" -"lxc was written by Daniel Baumann EIE." -msgstr "" -"lxc wurde von Daniel Baumann EIE geschrieben." diff -Nru lxc-0.8.0~rc1/debian/local/manpages/po4a.cfg lxc-1.0.0~alpha1/debian/local/manpages/po4a.cfg --- lxc-0.8.0~rc1/debian/local/manpages/po4a.cfg 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/local/manpages/po4a.cfg 1970-01-01 00:00:00.000000000 +0000 @@ -1,6 +0,0 @@ -[po4a_langs] de -[po4a_paths] pot/$master.pot $lang:po/$lang/$master.po -[type: man] en/lxc-debconf.1 $lang:$lang/lxc-debconf.$lang.1 -[type: man] en/lxc-halt.1 $lang:$lang/lxc-halt.$lang.1 -[type: man] en/lxc-list.1 $lang:$lang/lxc-list.$lang.1 -[type: man] en/lxc.1 $lang:$lang/lxc.$lang.1 diff -Nru lxc-0.8.0~rc1/debian/local/manpages/pot/lxc-debconf.1.pot lxc-1.0.0~alpha1/debian/local/manpages/pot/lxc-debconf.1.pot --- lxc-0.8.0~rc1/debian/local/manpages/pot/lxc-debconf.1.pot 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/local/manpages/pot/lxc-debconf.1.pot 1970-01-01 00:00:00.000000000 +0000 @@ -1,160 +0,0 @@ -# SOME DESCRIPTIVE TITLE -# Copyright (C) YEAR Free Software Foundation, Inc. -# This file is distributed under the same license as the lxc package. -# FIRST AUTHOR , YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: lxc VERSION\n" -"POT-Creation-Date: 2011-12-08 12:31+0100\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"Language: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=CHARSET\n" -"Content-Transfer-Encoding: 8bit\n" - -#. type: TH -#: en/lxc-debconf.1:9 en/lxc-halt.1:9 en/lxc-list.1:9 en/lxc.1:9 -#, no-wrap -msgid "LXC" -msgstr "" - -#. type: TH -#: en/lxc-debconf.1:9 en/lxc-halt.1:9 en/lxc-list.1:9 en/lxc.1:9 -#, no-wrap -msgid "2011-12-08" -msgstr "" - -#. type: TH -#: en/lxc-debconf.1:9 en/lxc-halt.1:9 en/lxc-list.1:9 en/lxc.1:9 -#, no-wrap -msgid "0.7.5-12" -msgstr "" - -#. type: TH -#: en/lxc-debconf.1:9 en/lxc-halt.1:9 en/lxc-list.1:9 en/lxc.1:9 -#, no-wrap -msgid "Linux Containers" -msgstr "" - -#. type: SH -#: en/lxc-debconf.1:11 en/lxc-halt.1:11 en/lxc-list.1:11 en/lxc.1:11 -#, no-wrap -msgid "NAME" -msgstr "" - -#. type: Plain text -#: en/lxc-debconf.1:13 -msgid "" -"B - LXC template to create Debian and Debian based containers" -msgstr "" - -#. type: SH -#: en/lxc-debconf.1:14 en/lxc-halt.1:14 en/lxc-list.1:14 en/lxc.1:14 -#, no-wrap -msgid "SYNOPSIS" -msgstr "" - -#. type: Plain text -#: en/lxc-debconf.1:16 -msgid "" -"B -t debian -n|--name I -- [--apt-recommends] [--" -"debconf-frontend I] [--debconf-priority " -"I] [--preseed-file I]" -msgstr "" - -#. type: Plain text -#: en/lxc-debconf.1:18 -msgid "" -"B -t progress -n|--name I -- [--apt-recommends] [--" -"debconf-frontend I] [--debconf-priority " -"I] [--preseed-file I]" -msgstr "" - -#. type: SH -#: en/lxc-debconf.1:19 en/lxc-halt.1:17 en/lxc-list.1:17 en/lxc.1:17 -#, no-wrap -msgid "DESCRIPTION" -msgstr "" - -#. type: Plain text -#: en/lxc-debconf.1:21 -msgid "" -"LXC(7) uses so called templates to create Linux Container systems. B is such a template script to create Debian and Debian based " -"containers." -msgstr "" - -#. type: Plain text -#: en/lxc-debconf.1:23 -msgid "" -"B can be invoked through lxc-create(1) in three modes: debconf, " -"debian, and progress. In debconf mode, it currently falls automatically back " -"to debian mode. In debian mode, it will allow offer to choose to create " -"Debian GNU/Linux containers. In progress mode, it will allow to choose to " -"create Progress Linux containers." -msgstr "" - -#. type: SH -#: en/lxc-debconf.1:25 en/lxc-halt.1:20 en/lxc-list.1:20 en/lxc.1:24 -#, no-wrap -msgid "OPTIONS" -msgstr "" - -#. type: Plain text -#: en/lxc-debconf.1:27 en/lxc-debconf.1:30 en/lxc-debconf.1:33 -msgid "B" -msgstr "" - -#. type: SH -#: en/lxc-debconf.1:28 -#, no-wrap -msgid "EXAMPLES" -msgstr "" - -#. type: SH -#: en/lxc-debconf.1:31 -#, no-wrap -msgid "FILES" -msgstr "" - -#. type: SH -#: en/lxc-debconf.1:34 en/lxc-halt.1:24 en/lxc-list.1:23 en/lxc.1:30 -#, no-wrap -msgid "SEE ALSO" -msgstr "" - -#. type: Plain text -#: en/lxc-debconf.1:39 -msgid "I(7), I(1), I(1), I(1)." -msgstr "" - -#. type: SH -#: en/lxc-debconf.1:40 en/lxc-halt.1:30 en/lxc-list.1:29 en/lxc.1:36 -#, no-wrap -msgid "BUGS" -msgstr "" - -#. type: Plain text -#: en/lxc-debconf.1:42 en/lxc-halt.1:32 en/lxc-list.1:31 en/lxc.1:38 -msgid "" -"Bugs can be reported by submitting a bugreport for the lxc package in the " -"Debian Bug Tracking System at EIE or by " -"writing a mail to the author." -msgstr "" - -#. type: SH -#: en/lxc-debconf.1:43 en/lxc-halt.1:33 en/lxc-list.1:32 en/lxc.1:39 -#, no-wrap -msgid "AUTHOR" -msgstr "" - -#. type: Plain text -#: en/lxc-debconf.1:44 -msgid "" -"lxc-debconf was written by Daniel Baumann EIE." -msgstr "" diff -Nru lxc-0.8.0~rc1/debian/local/manpages/pot/lxc-halt.1.pot lxc-1.0.0~alpha1/debian/local/manpages/pot/lxc-halt.1.pot --- lxc-0.8.0~rc1/debian/local/manpages/pot/lxc-halt.1.pot 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/local/manpages/pot/lxc-halt.1.pot 1970-01-01 00:00:00.000000000 +0000 @@ -1,132 +0,0 @@ -# SOME DESCRIPTIVE TITLE -# Copyright (C) YEAR Free Software Foundation, Inc. -# This file is distributed under the same license as the lxc package. -# FIRST AUTHOR , YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: lxc VERSION\n" -"POT-Creation-Date: 2011-12-08 12:31+0100\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"Language: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=CHARSET\n" -"Content-Transfer-Encoding: 8bit\n" - -#. type: TH -#: en/lxc-debconf.1:9 en/lxc-halt.1:9 en/lxc-list.1:9 en/lxc.1:9 -#, no-wrap -msgid "LXC" -msgstr "" - -#. type: TH -#: en/lxc-debconf.1:9 en/lxc-halt.1:9 en/lxc-list.1:9 en/lxc.1:9 -#, no-wrap -msgid "2011-12-08" -msgstr "" - -#. type: TH -#: en/lxc-debconf.1:9 en/lxc-halt.1:9 en/lxc-list.1:9 en/lxc.1:9 -#, no-wrap -msgid "0.7.5-12" -msgstr "" - -#. type: TH -#: en/lxc-debconf.1:9 en/lxc-halt.1:9 en/lxc-list.1:9 en/lxc.1:9 -#, no-wrap -msgid "Linux Containers" -msgstr "" - -#. type: SH -#: en/lxc-debconf.1:11 en/lxc-halt.1:11 en/lxc-list.1:11 en/lxc.1:11 -#, no-wrap -msgid "NAME" -msgstr "" - -#. type: SH -#: en/lxc-debconf.1:14 en/lxc-halt.1:14 en/lxc-list.1:14 en/lxc.1:14 -#, no-wrap -msgid "SYNOPSIS" -msgstr "" - -#. type: SH -#: en/lxc-debconf.1:19 en/lxc-halt.1:17 en/lxc-list.1:17 en/lxc.1:17 -#, no-wrap -msgid "DESCRIPTION" -msgstr "" - -#. type: SH -#: en/lxc-debconf.1:25 en/lxc-halt.1:20 en/lxc-list.1:20 en/lxc.1:24 -#, no-wrap -msgid "OPTIONS" -msgstr "" - -#. type: SH -#: en/lxc-debconf.1:34 en/lxc-halt.1:24 en/lxc-list.1:23 en/lxc.1:30 -#, no-wrap -msgid "SEE ALSO" -msgstr "" - -#. type: SH -#: en/lxc-debconf.1:40 en/lxc-halt.1:30 en/lxc-list.1:29 en/lxc.1:36 -#, no-wrap -msgid "BUGS" -msgstr "" - -#. type: Plain text -#: en/lxc-debconf.1:42 en/lxc-halt.1:32 en/lxc-list.1:31 en/lxc.1:38 -msgid "" -"Bugs can be reported by submitting a bugreport for the lxc package in the " -"Debian Bug Tracking System at EIE or by " -"writing a mail to the author." -msgstr "" - -#. type: SH -#: en/lxc-debconf.1:43 en/lxc-halt.1:33 en/lxc-list.1:32 en/lxc.1:39 -#, no-wrap -msgid "AUTHOR" -msgstr "" - -#. type: Plain text -#: en/lxc-halt.1:13 -msgid "B - shutdown Linux Containers by state" -msgstr "" - -#. type: Plain text -#: en/lxc-halt.1:16 -msgid "B I" -msgstr "" - -#. type: Plain text -#: en/lxc-halt.1:19 -msgid "" -"B shuts down a Linux Container by not killing all processes of it " -"like lxc-stop does. It does an ordinary shutdown by issueing a switch to " -"runlevel 0 within the container." -msgstr "" - -#. type: IP -#: en/lxc-halt.1:21 en/lxc.1:27 -#, no-wrap -msgid "I" -msgstr "" - -#. type: Plain text -#: en/lxc-halt.1:23 en/lxc.1:29 -msgid "specifies a Linux Container in the LXC path (default /var/lib/lxc)." -msgstr "" - -#. type: Plain text -#: en/lxc-halt.1:29 -msgid "I(7), I(1), I(1), I(1)." -msgstr "" - -#. type: Plain text -#: en/lxc-halt.1:34 -msgid "" -"lxc-halt was written by Daniel Baumann EIE." -msgstr "" diff -Nru lxc-0.8.0~rc1/debian/local/manpages/pot/lxc-list.1.pot lxc-1.0.0~alpha1/debian/local/manpages/pot/lxc-list.1.pot --- lxc-0.8.0~rc1/debian/local/manpages/pot/lxc-list.1.pot 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/local/manpages/pot/lxc-list.1.pot 1970-01-01 00:00:00.000000000 +0000 @@ -1,123 +0,0 @@ -# SOME DESCRIPTIVE TITLE -# Copyright (C) YEAR Free Software Foundation, Inc. -# This file is distributed under the same license as the lxc package. -# FIRST AUTHOR , YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: lxc VERSION\n" -"POT-Creation-Date: 2011-12-08 12:31+0100\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"Language: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=CHARSET\n" -"Content-Transfer-Encoding: 8bit\n" - -#. type: TH -#: en/lxc-debconf.1:9 en/lxc-halt.1:9 en/lxc-list.1:9 en/lxc.1:9 -#, no-wrap -msgid "LXC" -msgstr "" - -#. type: TH -#: en/lxc-debconf.1:9 en/lxc-halt.1:9 en/lxc-list.1:9 en/lxc.1:9 -#, no-wrap -msgid "2011-12-08" -msgstr "" - -#. type: TH -#: en/lxc-debconf.1:9 en/lxc-halt.1:9 en/lxc-list.1:9 en/lxc.1:9 -#, no-wrap -msgid "0.7.5-12" -msgstr "" - -#. type: TH -#: en/lxc-debconf.1:9 en/lxc-halt.1:9 en/lxc-list.1:9 en/lxc.1:9 -#, no-wrap -msgid "Linux Containers" -msgstr "" - -#. type: SH -#: en/lxc-debconf.1:11 en/lxc-halt.1:11 en/lxc-list.1:11 en/lxc.1:11 -#, no-wrap -msgid "NAME" -msgstr "" - -#. type: SH -#: en/lxc-debconf.1:14 en/lxc-halt.1:14 en/lxc-list.1:14 en/lxc.1:14 -#, no-wrap -msgid "SYNOPSIS" -msgstr "" - -#. type: SH -#: en/lxc-debconf.1:19 en/lxc-halt.1:17 en/lxc-list.1:17 en/lxc.1:17 -#, no-wrap -msgid "DESCRIPTION" -msgstr "" - -#. type: SH -#: en/lxc-debconf.1:25 en/lxc-halt.1:20 en/lxc-list.1:20 en/lxc.1:24 -#, no-wrap -msgid "OPTIONS" -msgstr "" - -#. type: SH -#: en/lxc-debconf.1:34 en/lxc-halt.1:24 en/lxc-list.1:23 en/lxc.1:30 -#, no-wrap -msgid "SEE ALSO" -msgstr "" - -#. type: SH -#: en/lxc-debconf.1:40 en/lxc-halt.1:30 en/lxc-list.1:29 en/lxc.1:36 -#, no-wrap -msgid "BUGS" -msgstr "" - -#. type: Plain text -#: en/lxc-debconf.1:42 en/lxc-halt.1:32 en/lxc-list.1:31 en/lxc.1:38 -msgid "" -"Bugs can be reported by submitting a bugreport for the lxc package in the " -"Debian Bug Tracking System at EIE or by " -"writing a mail to the author." -msgstr "" - -#. type: SH -#: en/lxc-debconf.1:43 en/lxc-halt.1:33 en/lxc-list.1:32 en/lxc.1:39 -#, no-wrap -msgid "AUTHOR" -msgstr "" - -#. type: Plain text -#: en/lxc-list.1:13 -msgid "B - list Linux Containers by state" -msgstr "" - -#. type: Plain text -#: en/lxc-list.1:16 -msgid "B" -msgstr "" - -#. type: Plain text -#: en/lxc-list.1:19 -msgid "B lists Linux Containers by state." -msgstr "" - -#. type: Plain text -#: en/lxc-list.1:22 -msgid "lxc-list has no options." -msgstr "" - -#. type: Plain text -#: en/lxc-list.1:28 -msgid "I(7), I(1), I(1), I(1)." -msgstr "" - -#. type: Plain text -#: en/lxc-list.1:33 -msgid "" -"lxc-list was written by Daniel Baumann EIE." -msgstr "" diff -Nru lxc-0.8.0~rc1/debian/local/manpages/pot/lxc.1.pot lxc-1.0.0~alpha1/debian/local/manpages/pot/lxc.1.pot --- lxc-0.8.0~rc1/debian/local/manpages/pot/lxc.1.pot 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/local/manpages/pot/lxc.1.pot 1970-01-01 00:00:00.000000000 +0000 @@ -1,152 +0,0 @@ -# SOME DESCRIPTIVE TITLE -# Copyright (C) YEAR Free Software Foundation, Inc. -# This file is distributed under the same license as the lxc package. -# FIRST AUTHOR , YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: lxc VERSION\n" -"POT-Creation-Date: 2011-12-08 12:31+0100\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"Language: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=CHARSET\n" -"Content-Transfer-Encoding: 8bit\n" - -#. type: TH -#: en/lxc-debconf.1:9 en/lxc-halt.1:9 en/lxc-list.1:9 en/lxc.1:9 -#, no-wrap -msgid "LXC" -msgstr "" - -#. type: TH -#: en/lxc-debconf.1:9 en/lxc-halt.1:9 en/lxc-list.1:9 en/lxc.1:9 -#, no-wrap -msgid "2011-12-08" -msgstr "" - -#. type: TH -#: en/lxc-debconf.1:9 en/lxc-halt.1:9 en/lxc-list.1:9 en/lxc.1:9 -#, no-wrap -msgid "0.7.5-12" -msgstr "" - -#. type: TH -#: en/lxc-debconf.1:9 en/lxc-halt.1:9 en/lxc-list.1:9 en/lxc.1:9 -#, no-wrap -msgid "Linux Containers" -msgstr "" - -#. type: SH -#: en/lxc-debconf.1:11 en/lxc-halt.1:11 en/lxc-list.1:11 en/lxc.1:11 -#, no-wrap -msgid "NAME" -msgstr "" - -#. type: SH -#: en/lxc-debconf.1:14 en/lxc-halt.1:14 en/lxc-list.1:14 en/lxc.1:14 -#, no-wrap -msgid "SYNOPSIS" -msgstr "" - -#. type: SH -#: en/lxc-debconf.1:19 en/lxc-halt.1:17 en/lxc-list.1:17 en/lxc.1:17 -#, no-wrap -msgid "DESCRIPTION" -msgstr "" - -#. type: SH -#: en/lxc-debconf.1:25 en/lxc-halt.1:20 en/lxc-list.1:20 en/lxc.1:24 -#, no-wrap -msgid "OPTIONS" -msgstr "" - -#. type: SH -#: en/lxc-debconf.1:34 en/lxc-halt.1:24 en/lxc-list.1:23 en/lxc.1:30 -#, no-wrap -msgid "SEE ALSO" -msgstr "" - -#. type: SH -#: en/lxc-debconf.1:40 en/lxc-halt.1:30 en/lxc-list.1:29 en/lxc.1:36 -#, no-wrap -msgid "BUGS" -msgstr "" - -#. type: Plain text -#: en/lxc-debconf.1:42 en/lxc-halt.1:32 en/lxc-list.1:31 en/lxc.1:38 -msgid "" -"Bugs can be reported by submitting a bugreport for the lxc package in the " -"Debian Bug Tracking System at EIE or by " -"writing a mail to the author." -msgstr "" - -#. type: SH -#: en/lxc-debconf.1:43 en/lxc-halt.1:33 en/lxc-list.1:32 en/lxc.1:39 -#, no-wrap -msgid "AUTHOR" -msgstr "" - -#. type: IP -#: en/lxc-halt.1:21 en/lxc.1:27 -#, no-wrap -msgid "I" -msgstr "" - -#. type: Plain text -#: en/lxc-halt.1:23 en/lxc.1:29 -msgid "specifies a Linux Container in the LXC path (default /var/lib/lxc)." -msgstr "" - -#. type: Plain text -#: en/lxc.1:13 -msgid "B - convenience Wrapper for LXC programs" -msgstr "" - -#. type: Plain text -#: en/lxc.1:16 -msgid "B I I" -msgstr "" - -#. type: Plain text -#: en/lxc.1:19 -msgid "" -"B is a convenience Wrapper for LXC programs. See I(7) for more " -"information about the Linux Container tools (LXC)." -msgstr "" - -#. type: Plain text -#: en/lxc.1:21 -msgid "Example (normal): lxc -n example.org start" -msgstr "" - -#. type: Plain text -#: en/lxc.1:23 -msgid "Example (wrapper): lxc start example.org" -msgstr "" - -#. type: IP -#: en/lxc.1:25 -#, no-wrap -msgid "I" -msgstr "" - -#. type: Plain text -#: en/lxc.1:27 -msgid "specifies a program of the Linux Container tools (LXC), see I(7)." -msgstr "" - -#. type: Plain text -#: en/lxc.1:35 -msgid "I(7), I(1), I(1), I(1)." -msgstr "" - -#. type: Plain text -#: en/lxc.1:40 -msgid "" -"lxc was written by Daniel Baumann EIE." -msgstr "" diff -Nru lxc-0.8.0~rc1/debian/lxc-dev.install lxc-1.0.0~alpha1/debian/lxc-dev.install --- lxc-0.8.0~rc1/debian/lxc-dev.install 2013-02-08 21:28:52.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/lxc-dev.install 2013-10-07 21:33:27.000000000 +0000 @@ -1,3 +1,3 @@ usr/include usr/lib/*/*.so -usr/share/pkgconfig +usr/lib/*/pkgconfig diff -Nru lxc-0.8.0~rc1/debian/lxc-dev.install.in lxc-1.0.0~alpha1/debian/lxc-dev.install.in --- lxc-0.8.0~rc1/debian/lxc-dev.install.in 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/lxc-dev.install.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -usr/include -usr/lib/*/*.so -usr/share/pkgconfig diff -Nru lxc-0.8.0~rc1/debian/lxc-templates.install lxc-1.0.0~alpha1/debian/lxc-templates.install --- lxc-0.8.0~rc1/debian/lxc-templates.install 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/lxc-templates.install 2013-10-07 21:33:27.000000000 +0000 @@ -0,0 +1 @@ +usr/share/lxc/templates diff -Nru lxc-0.8.0~rc1/debian/lxc.README.Debian lxc-1.0.0~alpha1/debian/lxc.README.Debian --- lxc-0.8.0~rc1/debian/lxc.README.Debian 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/lxc.README.Debian 1970-01-01 00:00:00.000000000 +0000 @@ -1,55 +0,0 @@ -LXC for Debian --------------- - - -1. Kernel - -LXC needs various cgroup related features enabled in the Linux kernel. - -If you use a non-Debian kernel, you can check your kernel configuration with the -lxc-checkconfig tool. - -If you use a Debian squeeze kernel, all of the features are enable except the -resource controller, means, you can use LXC just fine but cannot limit the use -of RAM per container. Every container can use as much RAM as the host system -offers. See http://bugs.debian.org/534964 for more information. - -If you use a Debian wheezy kernel or newer, all of the features are enabled -including the resource controller. - -Note: Kernel version before 2.6.36 do crash when using two bridge network -interfaces with LXC. If you need more than one bridge on the host system, -make sure you upgrade your kernel first. - - -2. Cgroup - -LXC requires that the cgroup pseudo-filesystem is mounted. This can manually be -done with the following command, executed as root on the host system: - - # mount cgroup -t cgroup /sys/fs/cgroup - -The corresponding entry for /etc/fstab looks like this: - - cgroup /sys/fs/cgroup cgroup defaults 0 0 - -This will eventually be done automatically as part of the mountkernfs initscript -in sysvinit. See http://bugs.debian.org/601757 for more information. - - -3. Root - -LXC container can be made usable for non-root users by running lxc-setcap. It -will set some capabilities so that normal users will be able to use the -container utilities. This is not done by default and you have to explicitly -allow it. - - -4. Autostart - -LXC container can be automatically started on boot. In order to enable this, the -LXC init script has to be enabled in /etc/default/lxc and and container that -should be automatically start needs its configuration file symlinked (or copied) -into the /etc/lxc/auto directory. - - -- Daniel Baumann Tue, 12 Jul 2011 20:32:16 +0200 diff -Nru lxc-0.8.0~rc1/debian/lxc.TODO lxc-1.0.0~alpha1/debian/lxc.TODO --- lxc-0.8.0~rc1/debian/lxc.TODO 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/lxc.TODO 1970-01-01 00:00:00.000000000 +0000 @@ -1,35 +0,0 @@ -lxc: - * clear tty and enable them dynamically - * enable console log by default and rotate them if necessary - * add debconf multi-select for autostarts in /etc/lxc/auto - * extend README.Debian to include all information from http://wiki.progress-linux.org/software/lxc/ - * update package description - * expose lxc-setcap run with debconf - * integrate example debian packages that contain /usr/share/lxc/cache/* - * add debconf question to ask for level of mac conflict check - * add debconf question to ask for putting linux-container local package in /u/s/l-c/ - * support 'all' in lxc convenience wrapper - * add a lxc-reboot command - * add a timeout to lxc-halt after which the container is forcefully stopped - * since the required kernel patches will not make it to wheezy, - add a watchdog so that containers are started again after a reboot/halt - * add lxc-console script as valid shell so that that unprivleged users can - access lxc containers on the host - * add lxc 'control' user with sudo magics so that unprivileged users can - start/stop/restart/create/destroy their containers - -lxc-debconf: - * if invoked as lxc-debconf, ask for mode (debian, progress, ubuntu, etc.) - * allow to have templates (that do not get modified) in /etc/lxc/debconf - * write preseed file into /etc/lxc/debconf after lxc-debconf is done - * create /etc/lxc/{debian,progress} and respect it depending on mode - * add a warning when building squeeze but no linux-container in /usr/share/lxc - * allow using architecture=auto - * save last used IP, use this +1 as default for next container - * add manpage - * handle mac (arp; local; etc.) - * guess bridge device - * get rid of /bin/bash - * use same perseeds as d-i does - * check that veth-foo is not overly long - * don't embedd lxc config, use a template from etc diff -Nru lxc-0.8.0~rc1/debian/lxc.apport lxc-1.0.0~alpha1/debian/lxc.apport --- lxc-0.8.0~rc1/debian/lxc.apport 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/lxc.apport 2013-10-07 21:32:53.000000000 +0000 @@ -19,3 +19,8 @@ # should we attach all lxc apparmor files #command_output(['ls', '-l', '/etc/apparmor.d/lxc'] #command_output(['cat', '/etc/apparmor.d/lxc/*'] + attach_file_if_exists(report, '/etc/default/lxc-net', key='lxc-net.default') + attach_file_if_exists(report, '/etc/default/lxc', key='lxc.default') + attach_file_if_exists(report, '/etc/lxc/lxc.conf', key='lxc.conf') + attach_file_if_exists(report, '/etc/lxc/default.conf', key='defaults.conf') + attach_file_if_exists(report, '/etc/lxc/dnsmasq.conf', key='dnsmasq.conf') diff -Nru lxc-0.8.0~rc1/debian/lxc.conf lxc-1.0.0~alpha1/debian/lxc.conf --- lxc-0.8.0~rc1/debian/lxc.conf 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/lxc.conf 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -lxc.network.type=veth -lxc.network.link=lxcbr0 -lxc.network.flags=up diff -Nru lxc-0.8.0~rc1/debian/lxc.config lxc-1.0.0~alpha1/debian/lxc.config --- lxc-0.8.0~rc1/debian/lxc.config 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/lxc.config 1970-01-01 00:00:00.000000000 +0000 @@ -1,35 +0,0 @@ -#!/bin/sh - -set -e - -. /usr/share/debconf/confmodule - -_CONFFILE="/etc/default/lxc" - -if [ -e "${_CONFFILE}" ] -then - . ${_CONFFILE} || true - - db_set lxc/auto "${LXC_AUTO}" - db_fset lxc/auto seen false - - db_set lxc/shutdown "${LXC_SHUTDOWN}" - db_fset lxc/shutdown seen false - - db_set lxc/directory "${LXC_DIRECTORY}" - db_fset lxc/directory seen false -fi - -db_settitle lxc/title -db_input low lxc/auto "${LXC_AUTO}" || true -db_go - -db_settitle lxc/title -db_input low lxc/shutdown "${LXC_SHUTDOWN}" || true -db_go - -db_settitle lxc/title -db_input high lxc/directory "${LXC_DIRECTORY}" || true -db_go - -db_stop diff -Nru lxc-0.8.0~rc1/debian/lxc.default lxc-1.0.0~alpha1/debian/lxc.default --- lxc-0.8.0~rc1/debian/lxc.default 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/lxc.default 2013-10-07 21:32:53.000000000 +0000 @@ -8,23 +8,7 @@ # /etc/lxc/auto LXC_AUTO="true" -# Leave USE_LXC_BRIDGE as "true" if you want to use lxcbr0 for your -# containers. Set to "false" if you'll use virbr0 or another existing -# bridge, or mavlan to your host's NIC. -USE_LXC_BRIDGE="true" - -# If you change the LXC_BRIDGE to something other than lxcbr0, then -# you will also need to update your /etc/lxc/lxc.conf as well as the -# configuration (/var/lib/lxc//config) for any containers -# already created using the default config to reflect the new bridge -# name. -# If you have the dnsmasq daemon installed, you'll also have to update -# /etc/dnsmasq.d/lxc and restart the system wide dnsmasq daemon. -LXC_BRIDGE="lxcbr0" -LXC_ADDR="10.0.3.1" -LXC_NETMASK="255.255.255.0" -LXC_NETWORK="10.0.3.0/24" -LXC_DHCP_RANGE="10.0.3.2,10.0.3.254" -LXC_DHCP_MAX="253" +USE_LXC_BRIDGE="false" # overridden in lxc-net +[ -f /etc/default/lxc-net ] && . /etc/default/lxc-net LXC_SHUTDOWN_TIMEOUT=120 diff -Nru lxc-0.8.0~rc1/debian/lxc.dirs lxc-1.0.0~alpha1/debian/lxc.dirs --- lxc-0.8.0~rc1/debian/lxc.dirs 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/lxc.dirs 2013-10-07 21:32:53.000000000 +0000 @@ -0,0 +1,2 @@ +etc/lxc/auto +var/log/lxc diff -Nru lxc-0.8.0~rc1/debian/lxc.examples lxc-1.0.0~alpha1/debian/lxc.examples --- lxc-0.8.0~rc1/debian/lxc.examples 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/lxc.examples 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -debian/local/examples/* diff -Nru lxc-0.8.0~rc1/debian/lxc.init lxc-1.0.0~alpha1/debian/lxc.init --- lxc-0.8.0~rc1/debian/lxc.init 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/lxc.init 1970-01-01 00:00:00.000000000 +0000 @@ -1,134 +0,0 @@ -#!/bin/sh - -### BEGIN INIT INFO -# Provides: lxc -# Required-Start: $syslog $remote_fs -# Required-Stop: $syslog $remote_fs -# Should-Start: -# Should-Stop: -# Default-Start: 2 3 4 5 -# Default-Stop: 0 1 6 -# Short-Description: Linux Containers -# Description: Linux Containers -# X-Start-Before: -# X-Stop-After: -# X-Interactive: true -### END INIT INFO - -if [ ! -x /usr/bin/lxc ] -then - exit 0 -fi - -PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin - -. /lib/lsb/init-functions - -if [ -f /etc/default/lxc ] -then - . /etc/default/lxc -fi - -LXC_AUTO="${LXC_AUTO:-true}" - -Lxc () -{ - _PROGRAM="${@}" - - # no containers available - if ! ls /etc/lxc/auto/* > /dev/null 2>&1 - then - log_progress_msg "(none)" - log_end_msg 0 - - exit 0 - fi - - for _CONFIG in /etc/lxc/auto/* - do - _CONTAINER="$(basename ${_CONFIG})" - - if [ -L "${_CONFIG}" ] && [ ! -e "${_CONFIG}" ] - then - # dangling symlink - log_progress_msg "${_CONTAINER} (broken)" - - continue - fi - - case "${_PROGRAM}" in - start) - # initscript is disabled - case "${LXC_AUTO}" in - false) - log_progress_msg "(disabled)" - log_end_msg 0 - - exit 0 - ;; - esac - - if ! lxc-info -n ${_CONTAINER} 2>&1 | grep -qs "RUNNING" - then - log_progress_msg "${_CONTAINER}" - - lxc-${_PROGRAM} -n ${_CONTAINER} -f ${_CONFIG} -d - else - log_progress_msg "${_CONTAINER} (skip)" - fi - ;; - - *) - log_progress_msg "${_CONTAINER}" - - lxc ${_PROGRAM} ${_CONTAINER} - ;; - esac - done - - log_end_msg 0 -} - -case "${1}" in - start) - log_daemon_msg "Starting Linux Containers" - - Lxc start - ;; - - stop) - log_daemon_msg "Stopping Linux Containers" - - Lxc shutdown - ;; - - restart|force-reload) - log_daemon_msg "Restarting Linux Containers" - - Lxc shutdown - Lxc start - ;; - - freeze) - log_daemon_msg "Freezing Linux Containers" - - Lxc freeze - ;; - - unfreeze) - log_daemon_msg "Unfreezing Linux Containers" - - Lxc unfreeze - ;; - - status) - lxc-list - ;; - - *) - log_success_msg "Usage: ${0} {start|stop|restart|force-reload|freeze|unfreeze|status}" - exit 1 - ;; -esac - -exit 0 diff -Nru lxc-0.8.0~rc1/debian/lxc.install lxc-1.0.0~alpha1/debian/lxc.install --- lxc-0.8.0~rc1/debian/lxc.install 2013-02-08 21:28:52.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/lxc.install 2013-10-07 21:33:27.000000000 +0000 @@ -1,18 +1,12 @@ + +debian/local/lxc-aa-custom-profile /usr/bin +debian/local/lxc.sh /etc/bash_completion.d etc usr/bin usr/lib/*/lxc/lxc-* usr/share/doc -usr/share/lxc +usr/share/lxc/hooks +usr/share/lxc/lxc.functions usr/share/man -var - -debian/local/lxc /usr/bin -debian/local/lxc-backup /usr/bin -debian/local/lxc-halt /usr/bin -debian/local/lxc-list /usr/bin -debian/local/lxc-restore /usr/bin -debian/local/lxc.sh /etc/bash_completion.d -debian/local/lxc-start-ephemeral /usr/bin -debian/local/lxc-aa-custom-profile /usr/bin - -debian/lxc.conf etc/lxc/ +var/cache/lxc +var/lib/lxc diff -Nru lxc-0.8.0~rc1/debian/lxc.install.in lxc-1.0.0~alpha1/debian/lxc.install.in --- lxc-0.8.0~rc1/debian/lxc.install.in 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/lxc.install.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,18 +0,0 @@ -etc -usr/bin -usr/lib/*/lxc/lxc-* -usr/share/doc -usr/share/lxc -usr/share/man -var - -debian/local/lxc /usr/bin -debian/local/lxc-backup /usr/bin -debian/local/lxc-halt /usr/bin -debian/local/lxc-list /usr/bin -debian/local/lxc-restore /usr/bin -debian/local/lxc.sh /etc/bash_completion.d -debian/local/lxc-start-ephemeral /usr/bin -debian/local/lxc-aa-custom-profile /usr/bin - -debian/lxc.conf etc/lxc/ diff -Nru lxc-0.8.0~rc1/debian/lxc.links lxc-1.0.0~alpha1/debian/lxc.links --- lxc-0.8.0~rc1/debian/lxc.links 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/lxc.links 2013-10-07 21:32:53.000000000 +0000 @@ -0,0 +1,4 @@ +/usr/bin/lxc-ls /usr/bin/lxc-list +/usr/bin/lxc-shutdown /usr/bin/lxc-halt +/usr/share/man/man1/lxc-list.1.gz /usr/share/man/man1/lxc-ls.1.gz +/usr/share/man/man1/lxc-halt.1.gz /usr/share/man/man1/lxc-shutdown.1.gz diff -Nru lxc-0.8.0~rc1/debian/lxc.lintian-overrides lxc-1.0.0~alpha1/debian/lxc.lintian-overrides --- lxc-0.8.0~rc1/debian/lxc.lintian-overrides 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/lxc.lintian-overrides 2013-10-07 21:32:53.000000000 +0000 @@ -1,9 +1,3 @@ -# bugs.debian.org/204975 (debhelper) -lxc postinst-has-useless-call-to-ldconfig -lxc postrm-has-useless-call-to-ldconfig -# false-positive for lxc-debconf -lxc debconf-is-not-a-registry -# false-positive for private console logs -lxc non-standard-dir-perm var/log/lxc/ -# we don't want a debconf template for now -lxc no-debconf-templates +postrm-does-not-call-updaterc.d-for-init.d-script etc/init.d/lxc +postrm-does-not-call-updaterc.d-for-init.d-script etc/init.d/lxc-instance +postrm-does-not-call-updaterc.d-for-init.d-script etc/init.d/lxc-net diff -Nru lxc-0.8.0~rc1/debian/lxc.lxc-instance.upstart lxc-1.0.0~alpha1/debian/lxc.lxc-instance.upstart --- lxc-0.8.0~rc1/debian/lxc.lxc-instance.upstart 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/lxc.lxc-instance.upstart 2013-10-07 21:32:53.000000000 +0000 @@ -0,0 +1,23 @@ +description "lxc instance" +author "Christian Kampka " + +stop on stopping lxc + +# wait for 120 seconds for container to shutdown before killing it +kill timeout 120 + +# send SIGPWR to container to trigger a shutdown (see lxc-shutdown(1)) +kill signal SIGPWR + + +instance $NAME +usage "NAME=name of LXC instance, CONFIG=full path to configuration file" + +pre-start script + + lxc-info -n $NAME 2>/dev/null | grep state | grep -q "RUNNING" && {stop; exit 0; } + [ -f $CONFIG ] || {stop; exit 0; } + +end script + +exec lxc-start -n $NAME -f $CONFIG diff -Nru lxc-0.8.0~rc1/debian/lxc.lxc-net.upstart lxc-1.0.0~alpha1/debian/lxc.lxc-net.upstart --- lxc-0.8.0~rc1/debian/lxc.lxc-net.upstart 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/lxc.lxc-net.upstart 2013-10-07 21:32:53.000000000 +0000 @@ -11,7 +11,9 @@ env LXC_NETWORK="10.0.3.0/24" env LXC_DHCP_RANGE="10.0.3.2,10.0.3.254" env LXC_DHCP_MAX="253" +env LXC_DHCP_CONFILE="" env varrun="/var/run/lxc" +env LXC_DOMAIN="" pre-start script [ -f /etc/default/lxc ] && . /etc/default/lxc @@ -34,12 +36,17 @@ fi # set up the lxc network + brctl addbr ${LXC_BRIDGE} || { echo "Missing bridge support in kernel"; stop; exit 0; } echo 1 > /proc/sys/net/ipv4/ip_forward mkdir -p ${varrun} - brctl addbr ${LXC_BRIDGE} ifconfig ${LXC_BRIDGE} ${LXC_ADDR} netmask ${LXC_NETMASK} up iptables -t nat -A POSTROUTING -s ${LXC_NETWORK} ! -d ${LXC_NETWORK} -j MASQUERADE - dnsmasq -u lxc-dnsmasq --strict-order --bind-interfaces --pid-file=${varrun}/dnsmasq.pid --conf-file= --listen-address ${LXC_ADDR} --dhcp-range ${LXC_DHCP_RANGE} --dhcp-lease-max=${LXC_DHCP_MAX} --dhcp-no-override --except-interface=lo --interface=${LXC_BRIDGE} || cleanup + + LXC_DOMAIN_ARG="" + if [ -n "$LXC_DOMAIN" ]; then + LXC_DOMAIN_ARG="-s $LXC_DOMAIN" + fi + dnsmasq $LXC_DOMAIN_ARG -u lxc-dnsmasq --strict-order --bind-interfaces --pid-file=${varrun}/dnsmasq.pid --conf-file=${LXC_DHCP_CONFILE} --listen-address ${LXC_ADDR} --dhcp-range ${LXC_DHCP_RANGE} --dhcp-lease-max=${LXC_DHCP_MAX} --dhcp-no-override --except-interface=lo --interface=${LXC_BRIDGE} --dhcp-leasefile=/var/lib/misc/dnsmasq.${LXC_BRIDGE}.leases --dhcp-authoritative || cleanup touch ${varrun}/network_up end script diff -Nru lxc-0.8.0~rc1/debian/lxc.maintscript lxc-1.0.0~alpha1/debian/lxc.maintscript --- lxc-0.8.0~rc1/debian/lxc.maintscript 2013-02-07 19:29:33.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/lxc.maintscript 2013-10-07 21:32:53.000000000 +0000 @@ -1,3 +1,4 @@ mv_conffile /etc/apparmor.d/abstractions/lxc-container-default /etc/apparmor.d/abstractions/lxc/container-base 0.8.0~rc1-4ubuntu18 lxc mv_conffile /etc/apparmor.d/abstractions/lxc-start-container /etc/apparmor.d/abstractions/lxc/start-container 0.8.0~rc1-4ubuntu18 lxc -mv_conffile /etc/dnsmasq.d/lxc /etc/dnsmasq.d-available/lxc 0.8.0~rc1-4ubuntu39.12.10.1 lxc +mv_conffile /etc/dnsmasq.d/lxc /etc/dnsmasq.d-available/lxc 0.8.0~rc1-4ubuntu48 lxc +mv_conffile /etc/lxc/lxc.conf /etc/lxc/default.conf 0.9.0~alpha2-0ubuntu1+b1~bzr1108-28~ lxc diff -Nru lxc-0.8.0~rc1/debian/lxc.manpages lxc-1.0.0~alpha1/debian/lxc.manpages --- lxc-0.8.0~rc1/debian/lxc.manpages 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/lxc.manpages 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -debian/local/manpages/*/*.1 diff -Nru lxc-0.8.0~rc1/debian/lxc.postinst lxc-1.0.0~alpha1/debian/lxc.postinst --- lxc-0.8.0~rc1/debian/lxc.postinst 2013-02-08 21:28:48.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/lxc.postinst 2013-11-04 14:12:24.000000000 +0000 @@ -72,6 +72,30 @@ # We need this after the debhelper generated code so that dpkg-maintscript # can do its renamming first. if [ "$1" = "configure" ]; then + + # The dnsmasq hook has been introduced through SRU into Ubuntu 12.04 + # and Ubuntu 12.10. + # + # This means that even though we version-guard the maintscripts entry + # it'll fire multiple times for users doing 12.04 => 12.10 => 13.04 + # or even just 12.10 => 13.04. + # + # As there's unfortunately no way to specify per-series base versions + # for maintscripts hooks, we let it fire multiple times and then fix up + # the mess it creates. + # + # This migration code can be removed after Ubuntu 14.04 LTS is released. + if [ -L /etc/dnsmasq.d-available/lxc ] && + [ "$(readlink /etc/dnsmasq.d-available/lxc)" = "/etc/dnsmasq.d-available/lxc" ] && + [ -e /etc/dnsmasq.d-available/lxc.dpkg-new ]; then + echo "The dnsmasq configuration has been migrated twice, fixing it." + mv /etc/dnsmasq.d-available/lxc /etc/dnsmasq.d/lxc + mv /etc/dnsmasq.d-available/lxc.dpkg-new /etc/dnsmasq.d-available/lxc + + # Try to restart a potential system wide dnsmasq + invoke-rc.d dnsmasq restart 2>/dev/null || true + fi + # Configure dnsmasq if [ -f /etc/dnsmasq.d-available/lxc ]; then echo "Setting up lxc dnsmasq configuration." @@ -83,5 +107,14 @@ # Try to restart a potential system wide dnsmasq invoke-rc.d dnsmasq restart 2>/dev/null || true fi + + # Up to version 1.0.0~alpha1-0ubuntu12 lxc was installed world + # readable. After that version if users want it that way for + # convenience, then that's fine. But one time go ahead and + # forcibly change the permissions. + if dpkg --compare-versions "$2" lt "1.0.0~alpha1-0ubuntu13"; then + chmod 700 /var/lib/lxc + chmod 700 /var/cache/lxc + fi fi exit 0 diff -Nru lxc-0.8.0~rc1/debian/lxc.preinst lxc-1.0.0~alpha1/debian/lxc.preinst --- lxc-0.8.0~rc1/debian/lxc.preinst 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/lxc.preinst 2013-10-07 21:32:53.000000000 +0000 @@ -0,0 +1,83 @@ +#!/bin/sh + +set -e + +write_lxc_net() +{ + local i=$1 + cat >> /etc/default/lxc-net << EOF +# Leave USE_LXC_BRIDGE as "true" if you want to use lxcbr0 for your +# containers. Set to "false" if you'll use virbr0 or another existing +# bridge, or mavlan to your host's NIC. +USE_LXC_BRIDGE="true" + +# If you change the LXC_BRIDGE to something other than lxcbr0, then +# you will also need to update your /etc/lxc/default.conf as well as the +# configuration (/var/lib/lxc//config) for any containers +# already created using the default config to reflect the new bridge +# name. +# If you have the dnsmasq daemon installed, you'll also have to update +# /etc/dnsmasq.d/lxc and restart the system wide dnsmasq daemon. +LXC_BRIDGE="lxcbr0" +LXC_ADDR="10.0.$i.1" +LXC_NETMASK="255.255.255.0" +LXC_NETWORK="10.0.$i.0/24" +LXC_DHCP_RANGE="10.0.$i.2,10.0.$i.254" +LXC_DHCP_MAX="253" +# Uncomment the next line if you'd like to use a conf-file for the lxcbr0 +# dnsmasq. For instance, you can use 'dhcp-host=mail1,10.0.3.100' to have +# container 'mail1' always get ip address 10.0.3.100. +#LXC_DHCP_CONFILE=/etc/lxc/dnsmasq.conf + +# Uncomment the next line if you want lxcbr0's dnsmasq to resolve the .lxc +# domain. You can then add "server=/lxc/10.0.3.1' (or your actual $LXC_ADDR) +# to /etc/dnsmasq.conf, after which 'container1.lxc' will resolve on your +# host. +#LXC_DOMAIN="lxc" +EOF +} + +configure_lxcbr0() +{ + local i=3 + cat > /etc/default/lxc-net << EOF +# This file is auto-generated by lxc.postinst if it does not +# exist. Customizations will not be overridden. +EOF + # if lxcbr0 exists, keep using the same network + if ip addr show lxcbr0 > /dev/null 2>&1 ; then + i=`ip addr show lxcbr0 | grep "inet\>" | awk '{ print $2 }' | awk -F. '{ print $3 }'` + write_lxc_net $i + return + fi + # if no lxcbr0, find an open 10.0.a.0 network + for l in `ip addr show | grep "inet\>" |awk '{ print $2 }' | grep '^10\.0\.' | sort -n`; do + j=`echo $l | awk -F. '{ print $3 }'` + if [ $j -gt $i ]; then + write_lxc_net $i + return + fi + i=$((j+1)) + done + if [ $i -ne 254 ]; then + write_lxc_net $i + fi +} + +case "${1}" in + install|upgrade) + if [ ! -f /etc/default/lxc-net ]; then + configure_lxcbr0 + fi + ;; + abort-upgrade) + ;; + *) + echo "preinst called with unknown argument (${1})" + exit 1 + ;; +esac + +#DEBHELPER# + +exit 0 diff -Nru lxc-0.8.0~rc1/debian/lxc.upstart lxc-1.0.0~alpha1/debian/lxc.upstart --- lxc-0.8.0~rc1/debian/lxc.upstart 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/lxc.upstart 2013-10-07 21:32:53.000000000 +0000 @@ -5,7 +5,6 @@ stop on starting rc RUNLEVEL=[016] env LXC_AUTO="false" -env LXC_SHUTDOWN_TIMEOUT="120" pre-start script [ -f /etc/default/lxc ] && . /etc/default/lxc @@ -24,20 +23,6 @@ ls /etc/lxc/auto/* > /dev/null 2>&1 || exit 0; for f in /etc/lxc/auto/*; do c="$(basename $f .conf)" - lxc-info -n $c 2>/dev/null | grep state | grep -q "RUNNING" || lxc-start -n $c -f $f -d + start lxc-instance NAME=$c CONFIG=$f done end script - -post-stop script - [ -f /etc/default/lxc ] && . /etc/default/lxc - - [ "x$LXC_AUTO" = "xtrue" ] || { exit 0; } - - ls /etc/lxc/auto/* > /dev/null 2>&1 || exit 0; - for f in /etc/lxc/auto/*; do - c="$(basename $f .conf)" - lxc-shutdown -n $c -w -t $LXC_SHUTDOWN_TIMEOUT & - done - - wait -end script diff -Nru lxc-0.8.0~rc1/debian/patches/0000-add-autostart.patch lxc-1.0.0~alpha1/debian/patches/0000-add-autostart.patch --- lxc-0.8.0~rc1/debian/patches/0000-add-autostart.patch 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0000-add-autostart.patch 2013-10-07 21:32:53.000000000 +0000 @@ -0,0 +1,33 @@ +Description: Add autostart support to LXC + Autostart isn't currently upstream yet, so we need a patch to lxc-destroy + and lxc-ls to properly managed the flag. +Author: Stéphane Graber +Origin: vendor +Forwarded: no + +Index: saucy-lxc/src/lxc/lxc-ls +=================================================================== +--- saucy-lxc.orig/src/lxc/lxc-ls 2013-09-10 18:40:46.024436751 -0400 ++++ saucy-lxc/src/lxc/lxc-ls 2013-09-10 18:40:46.020436751 -0400 +@@ -132,7 +132,8 @@ + parser.add_argument("--fancy", action="store_true", + help=_("use fancy output")) + +-parser.add_argument("--fancy-format", type=str, default="name,state,ipv4,ipv6", ++parser.add_argument("--fancy-format", type=str, default="name,state,ipv4,ipv6" ++ ",autostart", + help=_("comma separated list of fields to show")) + + parser.add_argument("--nesting", dest="nesting", action="store_true", +@@ -207,6 +208,11 @@ + entry['pid'] = "-" + if container.init_pid != -1: + entry['pid'] = str(container.init_pid) ++ if (os.path.exists("/etc/lxc/auto/%s.conf" % container_name) or ++ os.path.exists("/etc/lxc/%s" % container_name)): ++ entry['autostart'] = "YES" ++ else: ++ entry['autostart'] = "NO" + + # Get the IPs + for family, protocol in {'inet': 'ipv4', 'inet6': 'ipv6'}.items(): diff -Nru lxc-0.8.0~rc1/debian/patches/0001-debian-template-set-hwaddr lxc-1.0.0~alpha1/debian/patches/0001-debian-template-set-hwaddr --- lxc-0.8.0~rc1/debian/patches/0001-debian-template-set-hwaddr 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0001-debian-template-set-hwaddr 2013-10-07 21:32:53.000000000 +0000 @@ -0,0 +1,23 @@ +Description: set hwaddr in debian template +Author: Serge Hallyn +Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/1080681 +Forwarded: no + +Index: saucy-lxc/templates/lxc-debian.in +=================================================================== +--- saucy-lxc.orig/templates/lxc-debian.in 2013-09-10 18:44:49.608427600 -0400 ++++ saucy-lxc/templates/lxc-debian.in 2013-09-10 18:44:49.604427600 -0400 +@@ -213,6 +213,13 @@ + rootfs=$2 + hostname=$3 + ++ # if there is exactly one veth network entry, make sure it has an ++ # associated hwaddr. ++ nics=`grep -e '^lxc\.network\.type[ \t]*=[ \t]*veth' $path/config | wc -l` ++ if [ $nics -eq 1 ]; then ++ grep -q "^lxc.network.hwaddr" $path/config || sed -i -e "/^lxc\.network\.type[ \t]*=[ \t]*veth/a lxc.network.hwaddr = 00:16:3e:$(openssl rand -hex 3| sed 's/\(..\)/\1:/g; s/.$//')" $path/config ++ fi ++ + grep -q "^lxc.rootfs" $path/config 2>/dev/null || echo "lxc.rootfs = $rootfs" >> $path/config + cat <> $path/config + lxc.tty = 4 diff -Nru lxc-0.8.0~rc1/debian/patches/0002-pin_rootfs-be-quiet-and-don-t-fail-container-start.patch lxc-1.0.0~alpha1/debian/patches/0002-pin_rootfs-be-quiet-and-don-t-fail-container-start.patch --- lxc-0.8.0~rc1/debian/patches/0002-pin_rootfs-be-quiet-and-don-t-fail-container-start.patch 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0002-pin_rootfs-be-quiet-and-don-t-fail-container-start.patch 2013-10-07 21:32:53.000000000 +0000 @@ -0,0 +1,73 @@ +From 00ec333b2e6c7a29e99da196979a496fb05ee923 Mon Sep 17 00:00:00 2001 +From: Serge Hallyn +Date: Tue, 10 Sep 2013 23:17:46 -0500 +Subject: [PATCH 1/6] pin_rootfs: be quiet and don't fail container start + +It's a legitimate use case to use read-only $lxcpath. If we can't +create the pin file, then we're not worried about marking the fs +readonly on exit. + +Signed-off-by: Serge Hallyn +--- + src/lxc/conf.c | 17 ++++------------- + src/lxc/start.c | 6 ++---- + 2 files changed, 6 insertions(+), 17 deletions(-) + +Index: saucy-lxc/src/lxc/conf.c +=================================================================== +--- saucy-lxc.orig/src/lxc/conf.c 2013-09-11 23:13:23.251925309 -0400 ++++ saucy-lxc/src/lxc/conf.c 2013-09-11 23:13:23.243925310 -0400 +@@ -687,32 +687,23 @@ + if (rootfs == NULL || strlen(rootfs) == 0) + return -2; + +- if (!realpath(rootfs, absrootfs)) { +- INFO("failed to get real path for '%s', not pinning", rootfs); ++ if (!realpath(rootfs, absrootfs)) + return -2; +- } + +- if (access(absrootfs, F_OK)) { +- SYSERROR("'%s' is not accessible", absrootfs); ++ if (access(absrootfs, F_OK)) + return -1; +- } + +- if (stat(absrootfs, &s)) { +- SYSERROR("failed to stat '%s'", absrootfs); ++ if (stat(absrootfs, &s)) + return -1; +- } + + if (!S_ISDIR(s.st_mode)) + return -2; + + ret = snprintf(absrootfspin, MAXPATHLEN, "%s%s", absrootfs, ".hold"); +- if (ret >= MAXPATHLEN) { +- SYSERROR("pathname too long for rootfs hold file"); ++ if (ret >= MAXPATHLEN) + return -1; +- } + + fd = open(absrootfspin, O_CREAT | O_RDWR, S_IWUSR|S_IRUSR); +- INFO("opened %s as fd %d\n", absrootfspin, fd); + return fd; + } + +Index: saucy-lxc/src/lxc/start.c +=================================================================== +--- saucy-lxc.orig/src/lxc/start.c 2013-09-11 23:13:23.251925309 -0400 ++++ saucy-lxc/src/lxc/start.c 2013-09-11 23:13:23.243925310 -0400 +@@ -652,10 +652,8 @@ + */ + + handler->pinfd = pin_rootfs(handler->conf->rootfs.path); +- if (handler->pinfd == -1) { +- ERROR("failed to pin the container's rootfs"); +- goto out_delete_net; +- } ++ if (handler->pinfd == -1) ++ INFO("failed to pin the container's rootfs"); + + /* Create a process in a new set of namespaces */ + handler->pid = lxc_clone(do_start, handler, handler->clone_flags); diff -Nru lxc-0.8.0~rc1/debian/patches/0003-move-monitor-fifo-and-monitor-sock-to-run.patch lxc-1.0.0~alpha1/debian/patches/0003-move-monitor-fifo-and-monitor-sock-to-run.patch --- lxc-0.8.0~rc1/debian/patches/0003-move-monitor-fifo-and-monitor-sock-to-run.patch 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0003-move-monitor-fifo-and-monitor-sock-to-run.patch 2013-10-07 21:32:53.000000000 +0000 @@ -0,0 +1,212 @@ +From 9e60f51d0d1d295bdd77f2fa848f3046e04e6804 Mon Sep 17 00:00:00 2001 +From: Dwight Engen +Date: Wed, 11 Sep 2013 11:44:19 -0400 +Subject: [PATCH 5/6] move monitor-fifo and monitor-sock to /run + +Moving these files should allow $lxcpath to be a read-only fs. + +Signed-off-by: Dwight Engen +Signed-off-by: Serge Hallyn +--- + src/lxc/lxc_monitord.c | 17 +++++++-------- + src/lxc/lxclock.c | 5 +---- + src/lxc/monitor.c | 56 ++++++++++++++++++++++++++++++++++++++++++++------ + src/lxc/monitor.h | 2 ++ + src/lxc/utils.c | 10 +++++++++ + src/lxc/utils.h | 2 ++ + 6 files changed, 72 insertions(+), 20 deletions(-) + +Index: saucy-lxc/src/lxc/lxc_monitord.c +=================================================================== +--- saucy-lxc.orig/src/lxc/lxc_monitord.c 2013-09-11 23:13:23.283925308 -0400 ++++ saucy-lxc/src/lxc/lxc_monitord.c 2013-09-11 23:13:23.275925308 -0400 +@@ -76,11 +76,9 @@ + char fifo_path[PATH_MAX]; + int ret; + +- ret = snprintf(fifo_path, sizeof(fifo_path), "%s/monitor-fifo", mon->lxcpath); +- if (ret < 0 || ret >= sizeof(fifo_path)) { +- ERROR("lxcpath too long to monitor fifo"); +- return -1; +- } ++ ret = lxc_monitor_fifo_name(mon->lxcpath, fifo_path, sizeof(fifo_path), 1); ++ if (ret < 0) ++ return ret; + + ret = mknod(fifo_path, S_IFIFO|S_IRUSR|S_IWUSR, 0); + if (ret < 0) { +@@ -102,11 +100,10 @@ + char fifo_path[PATH_MAX]; + int ret; + +- ret = snprintf(fifo_path, sizeof(fifo_path), "%s/monitor-fifo", mon->lxcpath); +- if (ret < 0 || ret >= sizeof(fifo_path)) { +- ERROR("lxcpath too long to monitor fifo"); +- return -1; +- } ++ ret = lxc_monitor_fifo_name(mon->lxcpath, fifo_path, sizeof(fifo_path), 0); ++ if (ret < 0) ++ return ret; ++ + unlink(fifo_path); + return 0; + } +Index: saucy-lxc/src/lxc/lxclock.c +=================================================================== +--- saucy-lxc.orig/src/lxc/lxclock.c 2013-09-11 23:13:23.283925308 -0400 ++++ saucy-lxc/src/lxc/lxclock.c 2013-09-11 23:13:23.275925308 -0400 +@@ -56,10 +56,7 @@ + + /* length of "/lock/lxc/" + $lxcpath + "/" + $lxcname + '\0' */ + len = strlen("/lock/lxc/") + strlen(n) + strlen(p) + 2; +- rundir = getenv("XDG_RUNTIME_DIR"); +- if (geteuid() == 0 || rundir == NULL) +- rundir = "/run"; +- ++ rundir = get_rundir(); + len += strlen(rundir); + + if ((dest = malloc(len)) == NULL) +Index: saucy-lxc/src/lxc/monitor.c +=================================================================== +--- saucy-lxc.orig/src/lxc/monitor.c 2013-09-11 23:13:23.283925308 -0400 ++++ saucy-lxc/src/lxc/monitor.c 2013-09-11 23:13:23.275925308 -0400 +@@ -40,6 +40,7 @@ + #include "af_unix.h" + + #include ++#include + #include + #include + #include +@@ -47,17 +48,45 @@ + lxc_log_define(lxc_monitor, lxc); + + /* routines used by monitor publishers (containers) */ ++int lxc_monitor_fifo_name(const char *lxcpath, char *fifo_path, size_t fifo_path_sz, ++ int do_mkdirp) ++{ ++ int ret; ++ const char *rundir; ++ ++ rundir = get_rundir(); ++ if (do_mkdirp) { ++ ret = snprintf(fifo_path, fifo_path_sz, "%s/lxc/%s", rundir, lxcpath); ++ if (ret < 0 || ret >= fifo_path_sz) { ++ ERROR("rundir/lxcpath (%s/%s) too long for monitor fifo", rundir, lxcpath); ++ return -1; ++ } ++ process_lock(); ++ ret = mkdir_p(fifo_path, 0755); ++ process_unlock(); ++ if (ret < 0) { ++ ERROR("unable to create monitor fifo dir %s", fifo_path); ++ return ret; ++ } ++ } ++ ret = snprintf(fifo_path, fifo_path_sz, "%s/lxc/%s/monitor-fifo", rundir, lxcpath); ++ if (ret < 0 || ret >= fifo_path_sz) { ++ ERROR("rundir/lxcpath (%s/%s) too long for monitor fifo", rundir, lxcpath); ++ return -1; ++ } ++ return 0; ++} ++ + static void lxc_monitor_fifo_send(struct lxc_msg *msg, const char *lxcpath) + { + int fd,ret; + char fifo_path[PATH_MAX]; + + BUILD_BUG_ON(sizeof(*msg) > PIPE_BUF); /* write not guaranteed atomic */ +- ret = snprintf(fifo_path, sizeof(fifo_path), "%s/monitor-fifo", lxcpath); +- if (ret < 0 || ret >= sizeof(fifo_path)) { +- ERROR("lxcpath too long to open monitor fifo"); ++ ++ ret = lxc_monitor_fifo_name(lxcpath, fifo_path, sizeof(fifo_path), 0); ++ if (ret < 0) + return; +- } + + fd = open(fifo_path, O_WRONLY); + if (fd < 0) { +@@ -98,6 +127,7 @@ + size_t len; + int ret; + char *sockname = &addr->sun_path[0]; // 1 for abstract ++ const char *rundir; + + /* addr.sun_path is only 108 bytes. + * should we take a hash of lxcpath? a subset of it? ftok()? we need +@@ -106,9 +136,23 @@ + memset(addr, 0, sizeof(*addr)); + addr->sun_family = AF_UNIX; + len = sizeof(addr->sun_path) - 1; +- ret = snprintf(sockname, len, "%s/monitor-sock", lxcpath); ++ rundir = get_rundir(); ++ ret = snprintf(sockname, len, "%s/lxc/%s", rundir, lxcpath); ++ if (ret < 0 || ret >= len) { ++ ERROR("rundir/lxcpath (%s/%s) too long for monitor unix socket", rundir, lxcpath); ++ return -1; ++ } ++ process_lock(); ++ ret = mkdir_p(sockname, 0755); ++ process_unlock(); ++ if (ret < 0) { ++ ERROR("unable to create monitor sock %s", sockname); ++ return ret; ++ } ++ ++ ret = snprintf(sockname, len, "%s/lxc/%s/monitor-sock", rundir, lxcpath); + if (ret < 0 || ret >= len) { +- ERROR("lxcpath too long for unix socket"); ++ ERROR("rundir/lxcpath (%s/%s) too long for monitor unix socket", rundir, lxcpath); + return -1; + } + return 0; +Index: saucy-lxc/src/lxc/monitor.h +=================================================================== +--- saucy-lxc.orig/src/lxc/monitor.h 2013-09-11 23:13:23.283925308 -0400 ++++ saucy-lxc/src/lxc/monitor.h 2013-09-11 23:13:23.275925308 -0400 +@@ -41,6 +41,8 @@ + + extern int lxc_monitor_open(const char *lxcpath); + extern int lxc_monitor_sock_name(const char *lxcpath, struct sockaddr_un *addr); ++extern int lxc_monitor_fifo_name(const char *lxcpath, char *fifo_path, ++ size_t fifo_path_sz, int do_mkdirp); + extern void lxc_monitor_send_state(const char *name, lxc_state_t state, + const char *lxcpath); + extern int lxc_monitord_spawn(const char *lxcpath); +Index: saucy-lxc/src/lxc/utils.c +=================================================================== +--- saucy-lxc.orig/src/lxc/utils.c 2013-09-11 23:13:23.283925308 -0400 ++++ saucy-lxc/src/lxc/utils.c 2013-09-11 23:13:23.275925308 -0400 +@@ -328,6 +328,16 @@ + return default_lxcpath; + } + ++const char *get_rundir() ++{ ++ const char *rundir; ++ ++ rundir = getenv("XDG_RUNTIME_DIR"); ++ if (geteuid() == 0 || rundir == NULL) ++ rundir = "/run"; ++ return rundir; ++} ++ + int wait_for_pid(pid_t pid) + { + int status, ret; +Index: saucy-lxc/src/lxc/utils.h +=================================================================== +--- saucy-lxc.orig/src/lxc/utils.h 2013-09-11 23:13:23.283925308 -0400 ++++ saucy-lxc/src/lxc/utils.h 2013-09-11 23:13:23.279925308 -0400 +@@ -35,6 +35,8 @@ + extern int lxc_setup_fs(void); + extern int get_u16(unsigned short *val, const char *arg, int base); + extern int mkdir_p(const char *dir, mode_t mode); ++extern const char *get_rundir(void); ++ + /* + * Return a newly allocated buffer containing the default container + * path. Caller must free this buffer. diff -Nru lxc-0.8.0~rc1/debian/patches/0004-hash-lxcname-for-use-in-monitor-unix-socket-sun_path.patch lxc-1.0.0~alpha1/debian/patches/0004-hash-lxcname-for-use-in-monitor-unix-socket-sun_path.patch --- lxc-0.8.0~rc1/debian/patches/0004-hash-lxcname-for-use-in-monitor-unix-socket-sun_path.patch 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0004-hash-lxcname-for-use-in-monitor-unix-socket-sun_path.patch 2013-10-07 21:32:53.000000000 +0000 @@ -0,0 +1,107 @@ +From b45c701178cdc705d26c95f31035c39bab9edf20 Mon Sep 17 00:00:00 2001 +From: Dwight Engen +Date: Wed, 11 Sep 2013 18:16:15 -0400 +Subject: [PATCH] hash lxcname for use in monitor unix socket sun_path[108] + +- Also convert to unix abstract socket +- A simple FNV hash is used instead of SHA-1 since we may not HAVE_GNUTLS + +Signed-off-by: Dwight Engen +Signed-off-by: Serge Hallyn +--- + src/lxc/monitor.c | 60 ++++++++++++++++++++++++++++++++++++------------------- + 1 file changed, 40 insertions(+), 20 deletions(-) + +diff --git a/src/lxc/monitor.c b/src/lxc/monitor.c +index bdcc581..64e9987 100644 +--- a/src/lxc/monitor.c ++++ b/src/lxc/monitor.c +@@ -28,6 +28,8 @@ + #include + #include + #include ++#include ++#include + #include + #include + #include +@@ -123,38 +125,56 @@ int lxc_monitor_close(int fd) + return close(fd); + } + ++/* 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; ++} ++ + int lxc_monitor_sock_name(const char *lxcpath, struct sockaddr_un *addr) { + size_t len; + int ret; +- char *sockname = &addr->sun_path[0]; // 1 for abstract +- const char *rundir; ++ char *sockname = &addr->sun_path[1]; ++ char path[PATH_MAX+18]; ++ uint64_t hash; + +- /* addr.sun_path is only 108 bytes. +- * should we take a hash of lxcpath? a subset of it? ftok()? we need +- * to make sure it is unique. ++ /* addr.sun_path is only 108 bytes, so we hash the full name and ++ * then append as much of the name as we can fit. + */ + memset(addr, 0, sizeof(*addr)); + addr->sun_family = AF_UNIX; + len = sizeof(addr->sun_path) - 1; +- rundir = get_rundir(); +- ret = snprintf(sockname, len, "%s/lxc/%s", rundir, lxcpath); +- if (ret < 0 || ret >= len) { +- ERROR("rundir/lxcpath (%s/%s) too long for monitor unix socket", rundir, lxcpath); ++ ret = snprintf(path, sizeof(path), "lxc/%s/monitor-sock", lxcpath); ++ if (ret < 0 || ret >= sizeof(path)) { ++ ERROR("lxcpath %s too long for monitor unix socket", lxcpath); + return -1; + } +- process_lock(); +- ret = mkdir_p(sockname, 0755); +- process_unlock(); +- if (ret < 0) { +- ERROR("unable to create monitor sock %s", sockname); +- return ret; +- } + +- ret = snprintf(sockname, len, "%s/lxc/%s/monitor-sock", rundir, lxcpath); +- if (ret < 0 || ret >= len) { +- ERROR("rundir/lxcpath (%s/%s) too long for monitor unix socket", rundir, lxcpath); ++ hash = fnv_64a_buf(path, ret, FNV1A_64_INIT); ++ ret = snprintf(sockname, len, "lxc/%016" PRIx64 "/%s", hash, lxcpath); ++ if (ret < 0) + return -1; +- } ++ sockname[sizeof(addr->sun_path)-2] = '\0'; ++ INFO("using monitor sock name %s", sockname); + return 0; + } + +-- +1.8.3.2 + diff -Nru lxc-0.8.0~rc1/debian/patches/0005-ignore-ability-to-init-lxc-monitord.log.patch lxc-1.0.0~alpha1/debian/patches/0005-ignore-ability-to-init-lxc-monitord.log.patch --- lxc-0.8.0~rc1/debian/patches/0005-ignore-ability-to-init-lxc-monitord.log.patch 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0005-ignore-ability-to-init-lxc-monitord.log.patch 2013-10-07 21:32:53.000000000 +0000 @@ -0,0 +1,30 @@ +From b336d7246a324e8973bc449cb35db40b1627be47 Mon Sep 17 00:00:00 2001 +From: Serge Hallyn +Date: Thu, 12 Sep 2013 11:17:11 -0500 +Subject: [PATCH] ignore ability to init /lxc-monitord.log + +We may long-term want to instead decide on a convention under +/var/log, but for now just ignore it. This will only happen +if lxcpath is read-only. + +Signed-off-by: Serge Hallyn +--- + src/lxc/lxc_monitord.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/lxc/lxc_monitord.c b/src/lxc/lxc_monitord.c +index fda6cf4..4049345 100644 +--- a/src/lxc/lxc_monitord.c ++++ b/src/lxc/lxc_monitord.c +@@ -342,7 +342,7 @@ int main(int argc, char *argv[]) + + ret = lxc_log_init(NULL, logpath, "NOTICE", "lxc-monitord", 0, lxcpath); + if (ret) +- return ret; ++ INFO("Failed to open log file %s, log will be lost", lxcpath); + + pipefd = atoi(argv[2]); + +-- +1.8.3.2 + diff -Nru lxc-0.8.0~rc1/debian/patches/0006-add-pstore-to-container-fstab.patch lxc-1.0.0~alpha1/debian/patches/0006-add-pstore-to-container-fstab.patch --- lxc-0.8.0~rc1/debian/patches/0006-add-pstore-to-container-fstab.patch 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0006-add-pstore-to-container-fstab.patch 2013-10-07 21:32:53.000000000 +0000 @@ -0,0 +1,41 @@ +From 84bce17b8bc5c69e8dce03457a5f7859e0b46940 Mon Sep 17 00:00:00 2001 +From: Serge Hallyn +Date: Fri, 13 Sep 2013 15:43:56 -0500 +Subject: [PATCH] add pstore to container fstab +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Otherwise user-namespace containers will hang on mountall. + +Signed-off-by: Serge Hallyn +Acked-by: Stéphane Graber +--- + templates/lxc-ubuntu-cloud.in | 1 + + templates/lxc-ubuntu.in | 1 + + 2 files changed, 2 insertions(+) + +Index: lxc-1.0.0~alpha1/templates/lxc-ubuntu-cloud.in +=================================================================== +--- lxc-1.0.0~alpha1.orig/templates/lxc-ubuntu-cloud.in 2013-09-10 17:22:00.000000000 -0500 ++++ lxc-1.0.0~alpha1/templates/lxc-ubuntu-cloud.in 2013-09-16 11:49:57.373028184 -0500 +@@ -116,6 +116,7 @@ sysfs sys sysfs defau + /sys/fs/fuse/connections sys/fs/fuse/connections none bind 0 0 + /sys/kernel/debug sys/kernel/debug none bind 0 0 + /sys/kernel/security sys/kernel/security none bind 0 0 ++/sys/fs/pstore sys/fs/pstore none bind,optional 0 0 + EOF + + # unprivileged user can't mknod these. One day we may allow +Index: lxc-1.0.0~alpha1/templates/lxc-ubuntu.in +=================================================================== +--- lxc-1.0.0~alpha1.orig/templates/lxc-ubuntu.in 2013-09-10 17:22:00.000000000 -0500 ++++ lxc-1.0.0~alpha1/templates/lxc-ubuntu.in 2013-09-16 11:50:02.525028383 -0500 +@@ -430,6 +430,7 @@ sysfs sys sysfs defau + /sys/fs/fuse/connections sys/fs/fuse/connections none bind 0 0 + /sys/kernel/debug sys/kernel/debug none bind 0 0 + /sys/kernel/security sys/kernel/security none bind 0 0 ++/sys/fs/pstore sys/fs/pstore none bind,optional 0 0 + EOF + + if [ $? -ne 0 ]; then diff -Nru lxc-0.8.0~rc1/debian/patches/0007-apparmor.c-drop-newline-when-reading-current-profile.patch lxc-1.0.0~alpha1/debian/patches/0007-apparmor.c-drop-newline-when-reading-current-profile.patch --- lxc-0.8.0~rc1/debian/patches/0007-apparmor.c-drop-newline-when-reading-current-profile.patch 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0007-apparmor.c-drop-newline-when-reading-current-profile.patch 2013-10-07 21:32:53.000000000 +0000 @@ -0,0 +1,34 @@ +From c3cb8580407b6f6b49949e6c58e175eec81db692 Mon Sep 17 00:00:00 2001 +From: Serge Hallyn +Date: Tue, 10 Sep 2013 17:23:22 -0500 +Subject: [PATCH 1/1] apparmor.c: drop newline when reading current profile + +Otherwise we fail to recognize if we are already unconfined. Then, +if we want to *start* unconfined, and /proc is readonly, start fails +even though it should be able to proceed. + +With this patch, that situation works. + +Signed-off-by: Serge Hallyn +Reported-by: Andre nathan +--- + src/lxc/apparmor.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/lxc/apparmor.c b/src/lxc/apparmor.c +index 3941d3f..4dad801 100644 +--- a/src/lxc/apparmor.c ++++ b/src/lxc/apparmor.c +@@ -77,6 +77,9 @@ again: + free(buf); + return NULL; + } ++ space = index(buf, '\n'); ++ if (space) ++ *space = '\0'; + space = index(buf, ' '); + if (space) + *space = '\0'; +-- +1.8.1.2 + diff -Nru lxc-0.8.0~rc1/debian/patches/0008-Fix-crasher-in-get_ips.patch lxc-1.0.0~alpha1/debian/patches/0008-Fix-crasher-in-get_ips.patch --- lxc-0.8.0~rc1/debian/patches/0008-Fix-crasher-in-get_ips.patch 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0008-Fix-crasher-in-get_ips.patch 2013-10-07 21:32:53.000000000 +0000 @@ -0,0 +1,33 @@ +From fe218ca38358dd69dd51fca6433088ac631d6240 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?St=C3=A9phane=20Graber?= +Date: Sun, 29 Sep 2013 19:41:52 -0400 +Subject: [PATCH] Fix crasher in get_ips +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Check that the interface structure is not NULL before trying to access +its members. + +Signed-off-by: Stéphane Graber +--- + src/lxc/lxccontainer.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c +index 1b3f2f5..3a2ae92 100644 +--- a/src/lxc/lxccontainer.c ++++ b/src/lxc/lxccontainer.c +@@ -1305,6 +1305,9 @@ static char** lxcapi_get_ips(struct lxc_container *c, char* interface, char* fam + + /* Iterate through the interfaces */ + for (tempIfAddr = interfaceArray; tempIfAddr != NULL; tempIfAddr = tempIfAddr->ifa_next) { ++ if (tempIfAddr->ifa_addr == NULL) ++ continue; ++ + if(tempIfAddr->ifa_addr->sa_family == AF_INET) { + if (family && strcmp(family, "inet")) + continue; +-- +1.8.3.2 + diff -Nru lxc-0.8.0~rc1/debian/patches/0009-lxc-ubuntu-cloud-pass-numeric-owner-and-p-to-untar.patch lxc-1.0.0~alpha1/debian/patches/0009-lxc-ubuntu-cloud-pass-numeric-owner-and-p-to-untar.patch --- lxc-0.8.0~rc1/debian/patches/0009-lxc-ubuntu-cloud-pass-numeric-owner-and-p-to-untar.patch 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0009-lxc-ubuntu-cloud-pass-numeric-owner-and-p-to-untar.patch 2013-10-08 14:30:38.000000000 +0000 @@ -0,0 +1,50 @@ +From 494fd6b390ecae077375e171230ce78d6784dd43 Mon Sep 17 00:00:00 2001 +From: Scott Moser +Date: Mon, 7 Oct 2013 20:41:23 -0400 +Subject: [PATCH] lxc-ubuntu-cloud: pass --numeric-owner and -p to untar +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Just following up here, Serge raised the question of whether or not the +other two invocations of 'tar' in this script need '--numeric-owner'. +They probably should have it, although its of little concern because the +'build_root_tgz' path is only taken if there is no '-root.tar.gz' file for +download, and the only supported ubuntu release without the -root.tar.gz +download is 10.04 at this point. + +Anyway, below is a more complete diff, also including a fix as +'--numeric-uid' is not a valid option to tar. The name is +'--numeric-owner'. + +Signed-off-by: Scott Moser +Acked-by: Stéphane Graber +--- + templates/lxc-ubuntu-cloud.in | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/templates/lxc-ubuntu-cloud.in b/templates/lxc-ubuntu-cloud.in +index 47a5fca..a2af003 100644 +--- a/templates/lxc-ubuntu-cloud.in ++++ b/templates/lxc-ubuntu-cloud.in +@@ -340,7 +340,7 @@ build_root_tgz() + echo "Creating new cached cloud image rootfs" + tar --wildcards -zxf $tarname $imgname + mount -o loop $imgname $xdir +- (cd $xdir; tar zcf ../$filename .) ++ (cd $xdir; tar --numeric-owner -cpzf ../$filename .) + umount $xdir + rm -f $tarname $imgname + rmdir $xdir +@@ -371,7 +371,7 @@ do_extract_rootfs() { + echo "Extracting container rootfs" + mkdir -p $rootfs + cd $rootfs +- tar -zxf $cache/$filename ++ tar --numeric-owner -xpzf $cache/$filename + } + + if [ -n "$tarball" ]; then +-- +1.8.3.2 + diff -Nru lxc-0.8.0~rc1/debian/patches/0010-lxc-ubuntu-cloud-Cope-with-spaces-in-paths.patch lxc-1.0.0~alpha1/debian/patches/0010-lxc-ubuntu-cloud-Cope-with-spaces-in-paths.patch --- lxc-0.8.0~rc1/debian/patches/0010-lxc-ubuntu-cloud-Cope-with-spaces-in-paths.patch 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0010-lxc-ubuntu-cloud-Cope-with-spaces-in-paths.patch 2013-10-08 14:52:29.000000000 +0000 @@ -0,0 +1,42 @@ +From 9c3bc32c5789b76b8c42b75d7625377d61e052c1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?St=C3=A9phane=20Graber?= +Date: Tue, 8 Oct 2013 10:51:53 -0400 +Subject: [PATCH] lxc-ubuntu-cloud: Cope with spaces in paths +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reported-by: Scott Moser +Signed-off-by: Stéphane Graber +--- + templates/lxc-ubuntu-cloud.in | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/templates/lxc-ubuntu-cloud.in b/templates/lxc-ubuntu-cloud.in +index a2af003..82a7f74 100644 +--- a/templates/lxc-ubuntu-cloud.in ++++ b/templates/lxc-ubuntu-cloud.in +@@ -338,9 +338,9 @@ build_root_tgz() + wget $url || { echo "Couldn't find cloud image $url."; exit 1; } + fi + echo "Creating new cached cloud image rootfs" +- tar --wildcards -zxf $tarname $imgname ++ tar --wildcards -zxf "$tarname" "$imgname" + mount -o loop $imgname $xdir +- (cd $xdir; tar --numeric-owner -cpzf ../$filename .) ++ (cd $xdir; tar --numeric-owner -cpzf "../$filename" .) + umount $xdir + rm -f $tarname $imgname + rmdir $xdir +@@ -371,7 +371,7 @@ do_extract_rootfs() { + echo "Extracting container rootfs" + mkdir -p $rootfs + cd $rootfs +- tar --numeric-owner -xpzf $cache/$filename ++ tar --numeric-owner -xpzf "$cache/$filename" + } + + if [ -n "$tarball" ]; then +-- +1.8.3.2 + diff -Nru lxc-0.8.0~rc1/debian/patches/0011-ubuntu-cloud-prep-hook-fix-debug-helper-to-not-inapp.patch lxc-1.0.0~alpha1/debian/patches/0011-ubuntu-cloud-prep-hook-fix-debug-helper-to-not-inapp.patch --- lxc-0.8.0~rc1/debian/patches/0011-ubuntu-cloud-prep-hook-fix-debug-helper-to-not-inapp.patch 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0011-ubuntu-cloud-prep-hook-fix-debug-helper-to-not-inapp.patch 2013-10-09 18:03:11.000000000 +0000 @@ -0,0 +1,30 @@ +From 1e0f62acaacb4e7639d6203a9f008c66be712026 Mon Sep 17 00:00:00 2001 +From: Serge Hallyn +Date: Wed, 9 Oct 2013 13:01:18 -0500 +Subject: [PATCH 1/1] ubuntu-cloud-prep hook: fix debug helper to not + inappropriately fail + +Bug found by Vincent Ladeuil +Fix suggested by Scott Moser + +Signed-off-by: Serge Hallyn +--- + hooks/ubuntu-cloud-prep | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hooks/ubuntu-cloud-prep b/hooks/ubuntu-cloud-prep +index f0b30ea..b3cf232 100755 +--- a/hooks/ubuntu-cloud-prep ++++ b/hooks/ubuntu-cloud-prep +@@ -16,7 +16,7 @@ set -f + VERBOSITY="0" + + error() { echo "$@" 1>&2; } +-debug() { [ "$VERBOSITY" -ge "$1" ] || return; shift; error "$@"; } ++debug() { [ "$VERBOSITY" -ge "$1" ] || return 0; shift; error "$@"; } + fail() { [ $# -eq 0 ] || error "$@"; exit 1; } + + prep_usage() { +-- +1.8.1.2 + diff -Nru lxc-0.8.0~rc1/debian/patches/0012-ubuntu-Improper-pty-permissions.patch lxc-1.0.0~alpha1/debian/patches/0012-ubuntu-Improper-pty-permissions.patch --- lxc-0.8.0~rc1/debian/patches/0012-ubuntu-Improper-pty-permissions.patch 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0012-ubuntu-Improper-pty-permissions.patch 2013-10-25 20:42:22.000000000 +0000 @@ -0,0 +1,35 @@ +commit 67e5a20ad1b5579a571f43f7dd8a1556a8bea7a1 +Author: Stéphane Graber +Date: Tue Oct 15 14:54:41 2013 -0400 + + Improper pty permissions - missing mode=0620, gid=5 + + This fix is coming from Debian bug: + http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=720122 + + The reason for the hardcoded gid= and mode= is because of the fix for + CVE-2013-2207 which removes pt_chown from glibc and so requires proper + write access to devpts. + + It looks like the "tty" group is guaranteed to be gid=5 on at least all + RedHat based and Debian based systems. So this hardcode gid shouldn't be + a big problem. If we however support any distro where that's not the + case, we'll need to implement an extra lxc.conf option and matching + template changes. + + Signed-off-by: Stéphane Graber + Signed-off-by: Serge Hallyn + +Index: lxc-1.0.0~alpha1/src/lxc/conf.c +=================================================================== +--- lxc-1.0.0~alpha1.orig/src/lxc/conf.c 2013-10-25 15:42:19.682893000 -0500 ++++ lxc-1.0.0~alpha1/src/lxc/conf.c 2013-10-25 15:42:19.662893000 -0500 +@@ -1297,7 +1297,7 @@ + } + + if (mount("devpts", "/dev/pts", "devpts", MS_MGC_VAL, +- "newinstance,ptmxmode=0666")) { ++ "newinstance,ptmxmode=0666,mode=0620,gid=5")) { + SYSERROR("failed to mount a new instance of '/dev/pts'"); + return -1; + } diff -Nru lxc-0.8.0~rc1/debian/patches/0013-get-rid-of-lxcpath_anon-idea.patch lxc-1.0.0~alpha1/debian/patches/0013-get-rid-of-lxcpath_anon-idea.patch --- lxc-0.8.0~rc1/debian/patches/0013-get-rid-of-lxcpath_anon-idea.patch 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0013-get-rid-of-lxcpath_anon-idea.patch 2013-10-25 20:43:56.000000000 +0000 @@ -0,0 +1,62 @@ +commit 69733b5dd27e6963267ff6473d9b41dfb59a3f0f +Author: Serge Hallyn +Date: Mon Oct 21 18:44:03 2013 -0500 + + get rid of '${lxcpath}_anon' idea + + The idea was simply misguided. + + If you provide a custom configuration file, you still should be + putting the command sock into the real lxcpath, not an 'anon' one. + + Signed-off-by: Serge Hallyn + Acked-by: Stéphane Graber + +diff --git a/src/lxc/lxc_start.c b/src/lxc/lxc_start.c +index a894513..2e3c3b3 100644 +--- a/src/lxc/lxc_start.c ++++ b/src/lxc/lxc_start.c +@@ -153,7 +153,6 @@ int main(int argc, char *argv[]) + }; + FILE *pid_fp = NULL; + struct lxc_container *c; +- char *anonpath; + + lxc_list_init(&defines); + +@@ -172,8 +171,8 @@ int main(int argc, char *argv[]) + my_args.progname, my_args.quiet, my_args.lxcpath[0])) + return err; + +- anonpath = alloca(strlen(LXCPATH) + 6); +- sprintf(anonpath, "%s_anon", LXCPATH); ++ const char *lxcpath = my_args.lxcpath[0]; ++ + /* + * rcfile possibilities: + * 1. rcfile from random path specified in cli option +@@ -183,7 +182,7 @@ int main(int argc, char *argv[]) + /* rcfile is specified in the cli option */ + if (my_args.rcfile) { + rcfile = (char *)my_args.rcfile; +- c = lxc_container_new(my_args.name, anonpath); ++ c = lxc_container_new(my_args.name, lxcpath); + if (!c) { + ERROR("Failed to create lxc_container"); + return err; +@@ -195,7 +194,6 @@ int main(int argc, char *argv[]) + } + } else { + int rc; +- const char *lxcpath = my_args.lxcpath[0]; + + rc = asprintf(&rcfile, "%s/%s/config", lxcpath, my_args.name); + if (rc == -1) { +@@ -208,7 +206,6 @@ int main(int argc, char *argv[]) + if (access(rcfile, F_OK)) { + free(rcfile); + rcfile = NULL; +- lxcpath = anonpath; + } + c = lxc_container_new(my_args.name, lxcpath); + if (!c) { diff -Nru lxc-0.8.0~rc1/debian/patches/0013-lxc-create-use-default-config.patch lxc-1.0.0~alpha1/debian/patches/0013-lxc-create-use-default-config.patch --- lxc-0.8.0~rc1/debian/patches/0013-lxc-create-use-default-config.patch 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0013-lxc-create-use-default-config.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,48 +0,0 @@ -Description: If no config is specified, use our new default. -Author: Serge Hallyn -Forwarded: no - -Index: lxc-0.8.0~rc1/src/lxc/lxc-create.in -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/lxc-create.in 2012-04-25 14:16:08.309100884 -0500 -+++ lxc-0.8.0~rc1/src/lxc/lxc-create.in 2012-04-25 14:16:49.193100192 -0500 -@@ -239,16 +239,18 @@ - mkdir -p $lxc_path/$lxc_name - - if [ -z "$lxc_config" ]; then -- touch $lxc_path/$lxc_name/config --else -- if [ ! -r "$lxc_config" ]; then -- echo "'$lxc_config' configuration file not found" -- exit 1 -- fi -+ echo -+ echo "No config file specified, using the default config" -+ lxc_config="/etc/lxc/lxc.conf" -+fi - -- cp $lxc_config $lxc_path/$lxc_name/config -+if [ ! -r "$lxc_config" ]; then -+ echo "'$lxc_config' configuration file not found" -+ exit 1 - fi - -+cp $lxc_config $lxc_path/$lxc_name/config -+ - # Create the fs as needed - if [ $backingstore = "lvm" ]; then - [ -d "$rootfs" ] || mkdir $rootfs -@@ -266,13 +268,6 @@ - cleanup - fi - -- if [ -z "$lxc_config" ]; then -- echo "Note: Usually the template option is called with a configuration" -- echo "file option too, mostly to configure the network." -- echo "For more information look at lxc.conf (5)" -- echo -- fi -- - ${templatedir}/lxc-$lxc_template --path=$lxc_path/$lxc_name --name=$lxc_name $* - if [ $? -ne 0 ]; then - echo "failed to execute template '$lxc_template'" diff -Nru lxc-0.8.0~rc1/debian/patches/0030-ubuntu-template-fail.patch lxc-1.0.0~alpha1/debian/patches/0030-ubuntu-template-fail.patch --- lxc-0.8.0~rc1/debian/patches/0030-ubuntu-template-fail.patch 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0030-ubuntu-template-fail.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,20 +0,0 @@ -Description: ubuntu template: set -e to return error on failures. - Otherwise callers can get bad containers without knowing it. - This will be forwarded upstream -Author: Serge Hallyn -Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/922645 -Forwarded: yes - -Index: lxc-0.8.0~rc1/templates/lxc-ubuntu.in -=================================================================== ---- lxc-0.8.0~rc1.orig/templates/lxc-ubuntu.in 2012-04-23 23:09:19.579940778 -0500 -+++ lxc-0.8.0~rc1/templates/lxc-ubuntu.in 2012-04-23 23:09:28.627940625 -0500 -@@ -24,6 +24,8 @@ - # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - # - -+set -e -+ - if [ -r /etc/default/lxc ]; then - . /etc/default/lxc - fi diff -Nru lxc-0.8.0~rc1/debian/patches/0031-ubuntu-template-resolvconf.patch lxc-1.0.0~alpha1/debian/patches/0031-ubuntu-template-resolvconf.patch --- lxc-0.8.0~rc1/debian/patches/0031-ubuntu-template-resolvconf.patch 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0031-ubuntu-template-resolvconf.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ -Description: handle /etc/resolv.conf being a symlink - This will be forwarded upstream. -Author: Serge Hallyn -Forwarded: yes -Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/922706 - -Index: lxc-0.8.0~rc1/templates/lxc-ubuntu.in -=================================================================== ---- lxc-0.8.0~rc1.orig/templates/lxc-ubuntu.in 2012-04-23 23:09:28.627940625 -0500 -+++ lxc-0.8.0~rc1/templates/lxc-ubuntu.in 2012-04-23 23:09:30.703940590 -0500 -@@ -468,9 +468,13 @@ - chroot $rootfs apt-get install --force-yes -y python-software-properties - chroot $rootfs add-apt-repository ppa:ubuntu-virt/ppa - fi -- cp /etc/resolv.conf "${rootfs}/etc" -+ cresolvonf="${rootfs}/etc/resolv.conf" -+ mv $cresolvonf ${cresolvonf}.lxcbak -+ cat /etc/resolv.conf > ${cresolvonf} - chroot $rootfs apt-get update - chroot $rootfs apt-get install --force-yes -y lxcguest -+ rm -f ${cresolvonf} -+ mv ${cresolvonf}.lxcbak ${cresolvonf} - fi - - # If the container isn't running a native architecture, setup multiarch diff -Nru lxc-0.8.0~rc1/debian/patches/0044-lxc-destroy-rm-autos lxc-1.0.0~alpha1/debian/patches/0044-lxc-destroy-rm-autos --- lxc-0.8.0~rc1/debian/patches/0044-lxc-destroy-rm-autos 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0044-lxc-destroy-rm-autos 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ -Description: remove autostart symlinks when deleting a container - Note autostart symlinks are not upstream. -Author: Serge Hallyn -Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/930525 -Forwarded: no - -Index: lxc-0.8.0~rc1/src/lxc/lxc-destroy.in -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/lxc-destroy.in 2012-04-23 23:09:19.379940780 -0500 -+++ lxc-0.8.0~rc1/src/lxc/lxc-destroy.in 2012-04-23 23:09:32.239940564 -0500 -@@ -108,3 +108,14 @@ - fi - # recursively remove the container to remove old container configuration - rm -rf --one-file-system --preserve-root $lxc_path/$lxc_name -+ -+# remove any autostart symlinks pointing to this container. -+ls /etc/lxc/auto/* > /dev/null 2>&1 || exit 0; -+for f in /etc/lxc/auto/*; do -+ if [ -h "$f" ]; then -+ l=`readlink $f` -+ if [ $l = $lxc_path/$lxc_name/config ]; then -+ rm -f $f -+ fi -+ fi -+done diff -Nru lxc-0.8.0~rc1/debian/patches/0045-fix-other-templates lxc-1.0.0~alpha1/debian/patches/0045-fix-other-templates --- lxc-0.8.0~rc1/debian/patches/0045-fix-other-templates 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0045-fix-other-templates 1970-01-01 00:00:00.000000000 +0000 @@ -1,333 +0,0 @@ -Description: make non-ubuntu templates work - busybox: check separately that /usr/lib64. - debian: don't add network segment to config (that's not for the template - to do). - sshd: run dhclient; allow adding a root ssh key - fedora: - 1. don't add network segment to config; 2. check for 'curl'; - 3. don't add $name to $path, it's already in there; - 4. don't add devpts to fstab, that's wrong. 5. $UTSNAME doesn't exist - 6. set root pwd to root. 7. install release-ver package. - 8. add a console on /dev/console. 9. create empty fstab - 10. allow adding a root ssh key. 11. don't mount devpts in rc.sysinit. - opensuse: not usable until zypper is packaged - lxc-ubuntu and lxc-ubuntu-cloud: fix inconsistent '--auth_key' option - The fedora part of this patch is NOT been forwarded upstream, the - rest has. -Author: Serge Hallyn -Forwarded: no - -Index: lxc-0.8.0~rc1/templates/lxc-busybox.in -=================================================================== ---- lxc-0.8.0~rc1.orig/templates/lxc-busybox.in 2012-04-23 23:09:19.231940783 -0500 -+++ lxc-0.8.0~rc1/templates/lxc-busybox.in 2012-04-23 23:09:33.707940539 -0500 -@@ -245,6 +245,11 @@ - if [ -d "/lib64" ] && [ -d "$rootfs/lib64" ]; then - cat <> $path/config - lxc.mount.entry=/lib64 $rootfs/lib64 none ro,bind 0 0 -+EOF -+fi -+ -+if [ -d "/usr/lib64" ] && [ -d "$rootfs/usr/lib64" ]; then -+cat <> $path/config - lxc.mount.entry=/usr/lib64 $rootfs/usr/lib64 none ro,bind 0 0 - EOF - fi -Index: lxc-0.8.0~rc1/templates/lxc-sshd.in -=================================================================== ---- lxc-0.8.0~rc1.orig/templates/lxc-sshd.in 2012-04-23 23:09:19.247940784 -0500 -+++ lxc-0.8.0~rc1/templates/lxc-sshd.in 2012-04-23 23:09:33.707940539 -0500 -@@ -43,7 +43,7 @@ - - mkdir -p $tree - if [ $? -ne 0 ]; then -- return 1 -+ return 1 - fi - - return 0 -@@ -88,6 +88,18 @@ - PermitEmptyPasswords yes - ChallengeResponseAuthentication no - EOF -+ -+ if [ -n "$auth_key" -a -f "$auth_key" ]; then -+ u_path="/root/.ssh" -+ root_u_path="$rootfs/$u_path" -+ mkdir -p $root_u_path -+ cp $auth_key "$root_u_path/authorized_keys" -+ chown -R 0:0 "$rootfs/$u_path" -+ chmod 700 "$rootfs/$u_path" -+ -+ echo "Inserted SSH public key from $auth_key into /home/ubuntu/.ssh/authorized_keys" -+ fi -+ - return 0 - } - -@@ -97,7 +109,7 @@ - rootfs=$2 - name=$3 - --cat <> $path/config -+ cat <> $path/config - lxc.utsname = $name - lxc.pts = 1024 - lxc.rootfs = $rootfs -@@ -108,13 +120,17 @@ - lxc.mount.entry=/sbin $rootfs/sbin none ro,bind 0 0 - lxc.mount.entry=tmpfs $rootfs/var/run/sshd tmpfs mode=0644 0 0 - lxc.mount.entry=@LXCTEMPLATEDIR@/lxc-sshd $rootfs/sbin/init none bind 0 0 -+lxc.mount.entry=proc $rootfs/proc proc nodev,noexec,nosuid 0 0 - EOF - --if [ "$(uname -m)" = "x86_64" ]; then -- cat <> $path/config -+ # if no .ipv4 section in config, then have the container run dhcp -+ grep -q "^lxc.network.ipv4" $path/config || touch $rootfs/run-dhcp -+ -+ if [ "$(uname -m)" = "x86_64" ]; then -+ cat <> $path/config - lxc.mount.entry=/lib64 $rootfs/lib64 none ro,bind 0 0 - EOF --fi -+ fi - } - - usage() -@@ -125,10 +141,10 @@ - return 0 - } - --options=$(getopt -o hp:n: -l help,path:,name: -- "$@") -+options=$(getopt -o hp:n:S: -l help,path:,name:,auth-key: -- "$@") - if [ $? -ne 0 ]; then - usage $(basename $0) -- exit 1 -+ exit 1 - fi - eval set -- "$options" - -@@ -137,7 +153,8 @@ - case "$1" in - -h|--help) usage $0 && exit 0;; - -p|--path) path=$2; shift 2;; -- -n|--name) name=$2; shift 2;; -+ -n|--name) name=$2; shift 2;; -+ -S|--auth-key) auth_key=$2; shift 2;; - --) shift 1; break ;; - *) break ;; - esac -@@ -152,14 +169,30 @@ - - type @LXCINITDIR@/lxc-init - if [ $? -ne 0 ]; then -- echo "'lxc-init is not accessible on the system" -- exit 1 -+ echo "'lxc-init is not accessible on the system" -+ exit 1 - fi - - type sshd - if [ $? -ne 0 ]; then -- echo "'sshd' is not accessible on the system " -- exit 1 -+ echo "'sshd' is not accessible on the system " -+ exit 1 -+ fi -+ -+ # run dhcp? -+ if [ -f /run-dhcp ]; then -+ type dhclient -+ if [ $? -ne 0 ]; then -+ echo "can't find dhclient" -+ exit 1 -+ fi -+ touch /etc/fstab -+ rm -f /dhclient.conf -+ cat > /dhclient.conf << EOF -+send host-name ""; -+EOF -+ ifconfig eth0 up -+ dhclient eth0 -cf /dhclient.conf - fi - - exec @LXCINITDIR@/lxc-init -- /usr/sbin/sshd -Index: lxc-0.8.0~rc1/templates/lxc-ubuntu-cloud.in -=================================================================== ---- lxc-0.8.0~rc1.orig/templates/lxc-ubuntu-cloud.in 2012-04-23 23:09:19.279940784 -0500 -+++ lxc-0.8.0~rc1/templates/lxc-ubuntu-cloud.in 2012-04-23 23:09:33.707940539 -0500 -@@ -108,7 +108,7 @@ - Options, mutually exclusive of "-C" and "--cloud": - [ -i | --hostid ]: HostID for cloud-init, defaults to random string - [ -u | --userdata ]: Cloud-init user-data file to configure container on start -- [ -S | --auth_key ]: SSH Public key file to inject into container -+ [ -S | --auth-key ]: SSH Public key file to inject into container - [ -L | --nolocales ]: Do not copy host's locales into container - - EOF -@@ -166,7 +166,7 @@ - -i|--hostid) host_id=$2; shift 2;; - -u|--userdata) userdata=$2; shift 2;; - -C|--cloud) cloud=1; shift 1;; -- -S|--auth_key) auth_key=$2; shift 2;; -+ -S|--auth-key) auth_key=$2; shift 2;; - -L|--no_locales) locales=0; shift 2;; - -T|--tarball) tarball=$2; shift 2;; - --) shift 1; break ;; -Index: lxc-0.8.0~rc1/templates/lxc-ubuntu.in -=================================================================== ---- lxc-0.8.0~rc1.orig/templates/lxc-ubuntu.in 2012-04-23 23:09:30.703940590 -0500 -+++ lxc-0.8.0~rc1/templates/lxc-ubuntu.in 2012-04-23 23:09:33.707940539 -0500 -@@ -526,12 +526,12 @@ - { - cat <] [--trim] -- [-F | --flush-cache] [-r|--release ] [ -S | --auth_key ] -+ [-F | --flush-cache] [-r|--release ] [ -S | --auth-key ] - release: lucid | maverick | natty | oneiric | precise - trim: make a minimal (faster, but not upgrade-safe) container - bindhome: bind 's home into the container - arch: amd64 or i386: defaults to host arch --auth_key: SSH Public key file to inject into container -+auth-key: SSH Public key file to inject into container - EOF - return 0 - } -@@ -586,7 +586,7 @@ - -b|--bindhome) bindhome=$2; shift 2;; - -a|--arch) arch=$2; shift 2;; - -x|--trim) trim_container=1; shift 1;; -- -S|--auth_key) auth_key=$2; shift 2;; -+ -S|--auth-key) auth_key=$2; shift 2;; - --) shift 1; break ;; - *) break ;; - esac -Index: lxc-0.8.0~rc1/templates/lxc-fedora.in -=================================================================== ---- lxc-0.8.0~rc1.orig/templates/lxc-fedora.in 2012-04-23 23:09:19.215940785 -0500 -+++ lxc-0.8.0~rc1/templates/lxc-fedora.in 2012-04-23 23:09:33.707940539 -0500 -@@ -29,9 +29,7 @@ - arch=$(arch) - cache_base=/var/cache/lxc/fedora/$arch - default_path=/var/lib/lxc --root_password=rooter --lxc_network_type=veth --lxc_network_link=virbr0 -+root_password=root - - # is this fedora? - [ -f /etc/fedora-release ] && is_fedora=true -@@ -52,7 +50,7 @@ - DEVICE=eth0 - BOOTPROTO=dhcp - ONBOOT=yes --HOSTNAME=${UTSNAME} -+HOSTNAME=${name} - NM_CONTROLLED=no - TYPE=Ethernet - MTU=${MTU} -@@ -61,7 +59,7 @@ - # set the hostname - cat < ${rootfs_path}/etc/sysconfig/network - NETWORKING=yes --HOSTNAME=${UTSNAME} -+HOSTNAME=${name} - EOF - - # set minimal hosts -@@ -71,6 +69,10 @@ - - sed -i 's|.sbin.start_udev||' ${rootfs_path}/etc/rc.sysinit - sed -i 's|.sbin.start_udev||' ${rootfs_path}/etc/rc.d/rc.sysinit -+ # don't mount devpts, for pete's sake -+ sed -i 's/^.*dev.pts.*$/#\0/' ${rootfs_path}/etc/rc.sysinit -+ sed -i 's/^.*dev.pts.*$/#\0/' ${rootfs_path}/etc/rc.d/rc.sysinit -+ - chroot ${rootfs_path} chkconfig udev-post off - chroot ${rootfs_path} chkconfig network on - -@@ -97,6 +99,17 @@ - echo "setting root passwd to $root_password" - echo "root:$root_password" | chroot $rootfs_path chpasswd - -+ # specifying this in the initial packages doesn't always work. -+ echo "installing fedora-release package" -+ chroot ${rootfs_path} yum --releasever=${release} -y install fedora-release -+ -+ # silence some needless startup errors -+ touch ${rootfs_path}/etc/fstab -+ -+ # give us a console on /dev/console -+ sed -i 's/ACTIVE_CONSOLES=.*$/ACTIVE_CONSOLES="\/dev\/console \/dev\/tty[1-4]"/' \ -+ ${rootfs_path}/etc/sysconfig/init -+ - return 0 - } - -@@ -114,7 +127,7 @@ - # download a mini fedora into a cache - echo "Downloading fedora minimal ..." - YUM="yum --installroot $INSTALL_ROOT -y --nogpgcheck" -- PKG_LIST="yum initscripts passwd rsyslog vim-minimal dhclient chkconfig rootfiles policycoreutils" -+ PKG_LIST="yum initscripts passwd rsyslog vim-minimal dhclient chkconfig rootfiles policycoreutils fedora-release" - MIRRORLIST_URL="http://mirrors.fedoraproject.org/mirrorlist?repo=fedora-$release&arch=$arch" - - DOWNLOAD_OK=no -@@ -224,12 +237,6 @@ - lxc.pts = 1024 - lxc.rootfs = $rootfs_path - lxc.mount = $config_path/fstab --#networking --lxc.network.type = $lxc_network_type --lxc.network.flags = up --lxc.network.link = $lxc_network_link --lxc.network.name = eth0 --lxc.network.mtu = 1500 - #cgroups - lxc.cgroup.devices.deny = a - # /dev/null and zero -@@ -251,7 +258,6 @@ - - cat < $config_path/fstab - proc $rootfs_path/proc proc nodev,noexec,nosuid 0 0 --devpts $rootfs_path/dev/pts devpts defaults 0 0 - sysfs $rootfs_path/sys sysfs defaults 0 0 - EOF - if [ $? -ne 0 ]; then -@@ -328,9 +334,20 @@ - exit 0 - fi - -+needed_pkgs="" - type yum >/dev/null 2>&1 - if [ $? -ne 0 ]; then -- echo "'yum' command is missing" -+ needed_pkgs="yum $needed_pkgs" -+fi -+ -+type curl >/dev/null 2>&1 -+if [ $? -ne 0 ]; then -+ needed_pkgs="curl $needed_pkgs" -+fi -+ -+if [ -n "$needed_pkgs" ]; then -+ echo "Missing commands: $needed_pkgs" -+ echo "Please install these using \"sudo apt-get install $needed_pkgs\"" - exit 1 - fi - -@@ -353,7 +370,7 @@ - fi - - --rootfs_path=$path/$name/rootfs -+rootfs_path=$path/rootfs - config_path=$default_path/$name - cache=$cache_base/$release - -@@ -394,4 +411,3 @@ - exit 0 - fi - echo "container rootfs and config created" --echo "container is configured for lxc.network.type=veth and lxc.network.link=virbr0 (which is default if you have libvirt runnig)" diff -Nru lxc-0.8.0~rc1/debian/patches/0046-lxc-clone-change-hwaddr lxc-1.0.0~alpha1/debian/patches/0046-lxc-clone-change-hwaddr --- lxc-0.8.0~rc1/debian/patches/0046-lxc-clone-change-hwaddr 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0046-lxc-clone-change-hwaddr 1970-01-01 00:00:00.000000000 +0000 @@ -1,33 +0,0 @@ -Description: lxc-clone: update any hwaddrs - Since we are creating a new container it should not share a macaddr with - the original container. - This patch will be forwarded upstream. -Author: Serge Hallyn -Forwarded: yes -Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/934256 - -Index: lxc-0.8.0~rc1/src/lxc/lxc-clone.in -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/lxc-clone.in 2012-04-23 23:09:19.047940787 -0500 -+++ lxc-0.8.0~rc1/src/lxc/lxc-clone.in 2012-04-23 23:09:35.103940516 -0500 -@@ -263,6 +263,20 @@ - sed -i "s/send host-name.*$/send host-name \"$hostname\";/" $rootfs/etc/dhcp/dhclient.conf - fi - -+c=$lxc_path/$lxc_new/config -+# change hwaddrs -+mv ${c} ${c}.old -+( -+while read line; do -+ if [ "${line:0:18}" = "lxc.network.hwaddr" ]; then -+ echo "lxc.network.hwaddr= 00:16:3e:$(openssl rand -hex 3| sed 's/\(..\)/\1:/g; s/.$//')" -+ else -+ echo $line -+ fi -+done -+) < ${c}.old > ${c} -+rm -f ${c}.old -+ - # set the hostname - cat < $rootfs/etc/hostname - $hostname diff -Nru lxc-0.8.0~rc1/debian/patches/0047-bindhome-check-shell lxc-1.0.0~alpha1/debian/patches/0047-bindhome-check-shell --- lxc-0.8.0~rc1/debian/patches/0047-bindhome-check-shell 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0047-bindhome-check-shell 1970-01-01 00:00:00.000000000 +0000 @@ -1,51 +0,0 @@ -Description: ubuntu template: install bound user's shell - If a host user is bound into the container (-b), make sure that his - shell is installed in the container. - This patch will be forwarded upstream. -Author: Serge Hallyn -Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/936762 -Forwarded: yes - -Index: lxc-0.8.0~rc1/templates/lxc-ubuntu.in -=================================================================== ---- lxc-0.8.0~rc1.orig/templates/lxc-ubuntu.in 2012-04-23 23:09:33.707940539 -0500 -+++ lxc-0.8.0~rc1/templates/lxc-ubuntu.in 2012-04-23 23:09:36.675940489 -0500 -@@ -506,20 +506,31 @@ - user=$2 - - # copy /etc/passwd, /etc/shadow, and /etc/group entries into container -- pwd=`getent passwd $user` -- if [ $? -ne 0 ]; then -- echo 'Warning: failed to copy password entry for $user' -- return -- else -- echo $pwd >> $rootfs/etc/passwd -+ pwd=`getent passwd $user` || { echo "Failed to copy password entry for $user"; false; } -+ echo $pwd >> $rootfs/etc/passwd -+ -+ # make sure user's shell exists in the container -+ shell=`echo $pwd | cut -d: -f 7` -+ if [ ! -x $rootfs/$shell ]; then -+ echo "shell $shell for user $user was not found in the container." -+ pkg=`dpkg -S $(readlink -m $shell) | cut -d ':' -f1` -+ echo "Installing $pkg" -+ chroot $rootfs apt-get --force-yes -y install $pkg - fi -+ - shad=`getent shadow $user` -- echo $shad >> $rootfs/etc/shadow -+ echo "$shad" >> $rootfs/etc/shadow - - # bind-mount the user's path into the container's /home - h=`getent passwd $user | cut -d: -f 6` - mkdir -p $rootfs/$h - echo "$h $rootfs/$h none bind 0 0" >> $path/fstab -+ -+ # Make sure the group exists in container -+ chroot $rootfs getent group $user || { \ -+ grp=`getent group $user` -+ echo "$grp" >> $rootfs/etc/group -+ } - } - - usage() diff -Nru lxc-0.8.0~rc1/debian/patches/0049-ubuntu-template-sudo-and-cleanup lxc-1.0.0~alpha1/debian/patches/0049-ubuntu-template-sudo-and-cleanup --- lxc-0.8.0~rc1/debian/patches/0049-ubuntu-template-sudo-and-cleanup 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0049-ubuntu-template-sudo-and-cleanup 1970-01-01 00:00:00.000000000 +0000 @@ -1,50 +0,0 @@ -Description: Always add the user to the 'sudo' group as it's been around - since at least Ubuntu 10.04. In addition make the user part - of the admin group until 12.04 where it's been removed. - Also fix a minor layout issue with devttydir. -Author: Stéphane Graber -Forwarded: yes - -=== modified file 'lxc/templates/lxc-ubuntu.in' -Index: lxc-0.8.0~rc1/templates/lxc-ubuntu.in -=================================================================== ---- lxc-0.8.0~rc1.orig/templates/lxc-ubuntu.in 2012-04-23 23:09:36.675940489 -0500 -+++ lxc-0.8.0~rc1/templates/lxc-ubuntu.in 2012-04-23 23:09:38.243940462 -0500 -@@ -55,9 +55,9 @@ - EOF - - if [ "$release" = "precise" ]; then -- group="sudo" -+ groups="sudo" - else -- group="admin" -+ groups="sudo admin" - - # suppress log level output for udev - sed -i "s/=\"err\"/=0/" $rootfs/etc/udev/udev.conf -@@ -67,9 +67,14 @@ - rm -f $rootfs/etc/init/tty{5,6}.conf - fi - -- chroot $rootfs groupadd --system $group >/dev/null 2>&1 || true -- chroot $rootfs useradd --create-home -s /bin/bash -G $group ubuntu -+ chroot $rootfs useradd --create-home -s /bin/bash ubuntu - echo "ubuntu:ubuntu" | chroot $rootfs chpasswd -+ -+ for group in $groups; do -+ chroot $rootfs groupadd --system $group >/dev/null 2>&1 || true -+ chroot $rootfs adduser ubuntu $group >/dev/null 2>&1 || true -+ done -+ - if [ -n "$auth_key" -a -f "$auth_key" ]; then - u_path="/home/ubuntu/.ssh" - root_u_path="$rootfs/$u_path" -@@ -307,7 +312,7 @@ - cat <> $path/config - lxc.utsname = $name - --lxc.devttydir = $ttydir -+lxc.devttydir =$ttydir - lxc.tty = 4 - lxc.pts = 1024 - lxc.rootfs = $rootfs diff -Nru lxc-0.8.0~rc1/debian/patches/0050-clone-lvm-sizes lxc-1.0.0~alpha1/debian/patches/0050-clone-lvm-sizes --- lxc-0.8.0~rc1/debian/patches/0050-clone-lvm-sizes 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0050-clone-lvm-sizes 1970-01-01 00:00:00.000000000 +0000 @@ -1,33 +0,0 @@ -Description: maintain size of lvm snapshot in lxc-clone - When creating a container as lvm snapshot, use the original size unless - user explicitly overrides it. - It's all well and good to day "use lvextend if you run out of space", but - in the meantime applications may become corrupted... -Author: Serge Hallyn -Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/939765 -Forwarded: yes - -Index: lxc-0.8.0~rc1/src/lxc/lxc-clone.in -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/lxc-clone.in 2012-04-23 23:09:35.103940516 -0500 -+++ lxc-0.8.0~rc1/src/lxc/lxc-clone.in 2012-04-23 23:09:39.795940436 -0500 -@@ -48,7 +48,8 @@ - lxc_path=@LXCPATH@ - bindir=@BINDIR@ - snapshot=no --lxc_size=2G -+lxc_defsize=2G -+lxc_size=_unset - lxc_vg=lxc - lxc_lv_prefix="" - fstype=ext3 -@@ -203,6 +204,9 @@ - lxc-freeze -n $lxc_orig - frozen=1 - fi -+ if [ $lxc_size = "_unset" ]; then -+ lxc_size=`lvdisplay $oldroot | grep Size | awk '{ print $3 $4 }'` -+ fi - lvcreate -s -L $lxc_size -n ${lxc_lv_prefix}${lxc_new}_snapshot $oldroot - if [ $container_running = "True" ]; then - lxc-unfreeze -n $lxc_orig diff -Nru lxc-0.8.0~rc1/debian/patches/0052-ubuntu-bind-user-conflict lxc-1.0.0~alpha1/debian/patches/0052-ubuntu-bind-user-conflict --- lxc-0.8.0~rc1/debian/patches/0052-ubuntu-bind-user-conflict 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0052-ubuntu-bind-user-conflict 1970-01-01 00:00:00.000000000 +0000 @@ -1,95 +0,0 @@ -Description: ubuntu template: if a user is bound in, don't define ubuntu user - It might have a conflicting uid, and isn't needed. Also put the bound user - into sudo group. -Author: Serge Hallyn -Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/942144 -Forwarded: yes - -Index: lxc-0.8.0~rc1/templates/lxc-ubuntu.in -=================================================================== ---- lxc-0.8.0~rc1.orig/templates/lxc-ubuntu.in 2012-04-23 23:09:38.243940462 -0500 -+++ lxc-0.8.0~rc1/templates/lxc-ubuntu.in 2012-04-23 23:09:41.295940409 -0500 -@@ -54,11 +54,7 @@ - 127.0.0.1 localhost $hostname - EOF - -- if [ "$release" = "precise" ]; then -- groups="sudo" -- else -- groups="sudo admin" -- -+ if [ "$release" != "precise" ]; then - # suppress log level output for udev - sed -i "s/=\"err\"/=0/" $rootfs/etc/udev/udev.conf - -@@ -67,22 +63,40 @@ - rm -f $rootfs/etc/init/tty{5,6}.conf - fi - -- chroot $rootfs useradd --create-home -s /bin/bash ubuntu -- echo "ubuntu:ubuntu" | chroot $rootfs chpasswd -+ if [ -z "$bindhome" ]; then -+ chroot $rootfs useradd --create-home -s /bin/bash ubuntu -+ echo "ubuntu:ubuntu" | chroot $rootfs chpasswd -+ fi -+ -+ return 0 -+} -+ -+# finish setting up the user in the container by injecting ssh key and -+# adding sudo group membership. -+# passed-in user is either 'ubuntu' or the user to bind in from host. -+finalize_user() -+{ -+ user=$1 -+ -+ if [ "$release" = "precise" ]; then -+ groups="sudo" -+ else -+ groups="sudo admin" -+ fi - - for group in $groups; do - chroot $rootfs groupadd --system $group >/dev/null 2>&1 || true -- chroot $rootfs adduser ubuntu $group >/dev/null 2>&1 || true -+ chroot $rootfs adduser ${user} $group >/dev/null 2>&1 || true - done - - if [ -n "$auth_key" -a -f "$auth_key" ]; then -- u_path="/home/ubuntu/.ssh" -+ u_path="/home/${user}/.ssh" - root_u_path="$rootfs/$u_path" - mkdir -p $root_u_path - cp $auth_key "$root_u_path/authorized_keys" -- chroot $rootfs chown -R ubuntu: "$u_path" -+ chroot $rootfs chown -R ${user}: "$u_path" - -- echo "Inserted SSH public key from $auth_key into /home/ubuntu/.ssh/authorized_keys" -+ echo "Inserted SSH public key from $auth_key into /home/${user}/.ssh/authorized_keys" - fi - return 0 - } -@@ -546,6 +560,8 @@ - release: lucid | maverick | natty | oneiric | precise - trim: make a minimal (faster, but not upgrade-safe) container - bindhome: bind 's home into the container -+ The ubuntu user will not be created, and will have -+ sudo access. - arch: amd64 or i386: defaults to host arch - auth-key: SSH Public key file to inject into container - EOF -@@ -661,8 +677,12 @@ - fi - - post_process $rootfs $release $trim_container --if [ ! -z $bindhome ]; then -- do_bindhome $rootfs $bindhome -+ -+if [ -n "$bindhome" ]; then -+ do_bindhome $rootfs $bindhome -+ finalize_user $bindhome -+else -+ finalize_user ubuntu - fi - - echo "" diff -Nru lxc-0.8.0~rc1/debian/patches/0053-lxc-start-pin-rootfs lxc-1.0.0~alpha1/debian/patches/0053-lxc-start-pin-rootfs --- lxc-0.8.0~rc1/debian/patches/0053-lxc-start-pin-rootfs 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0053-lxc-start-pin-rootfs 1970-01-01 00:00:00.000000000 +0000 @@ -1,114 +0,0 @@ -Description: pin container's rootfs to prevent read-only remount -Author: Serge Hallyn -Forwarded: yes - -Index: lxc-0.8.0~rc1/src/lxc/conf.c -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/conf.c 2012-04-23 23:09:18.555940794 -0500 -+++ lxc-0.8.0~rc1/src/lxc/conf.c 2012-04-23 23:09:42.871940384 -0500 -@@ -452,6 +452,51 @@ - return mount_unknow_fs(rootfs, target, 0); - } - -+/* -+ * pin_rootfs -+ * if rootfs is a directory, then open ${rootfs}.hold for writing for the -+ * duration of the container run, to prevent the container from marking the -+ * underlying fs readonly on shutdown. -+ * return -1 on error. -+ * return -2 if nothing needed to be pinned. -+ * return an open fd (>=0) if we pinned it. -+ */ -+int pin_rootfs(const char *rootfs) -+{ -+ char absrootfs[MAXPATHLEN]; -+ char absrootfspin[MAXPATHLEN]; -+ struct stat s; -+ int ret, fd; -+ -+ if (!realpath(rootfs, absrootfs)) { -+ SYSERROR("failed to get real path for '%s'", rootfs); -+ return -1; -+ } -+ -+ if (access(absrootfs, F_OK)) { -+ SYSERROR("'%s' is not accessible", absrootfs); -+ return -1; -+ } -+ -+ if (stat(absrootfs, &s)) { -+ SYSERROR("failed to stat '%s'", absrootfs); -+ return -1; -+ } -+ -+ if (!__S_ISTYPE(s.st_mode, S_IFDIR)) -+ return -2; -+ -+ ret = snprintf(absrootfspin, MAXPATHLEN, "%s%s", absrootfs, ".hold"); -+ if (ret >= MAXPATHLEN) { -+ SYSERROR("pathname too long for rootfs hold file"); -+ return -1; -+ } -+ -+ fd = open(absrootfspin, O_CREAT | O_RDWR, S_IWUSR|S_IRUSR); -+ INFO("opened %s as fd %d\n", absrootfspin, fd); -+ return fd; -+} -+ - static int mount_rootfs(const char *rootfs, const char *target) - { - char absrootfs[MAXPATHLEN]; -Index: lxc-0.8.0~rc1/src/lxc/conf.h -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/conf.h 2012-04-23 23:09:18.571940796 -0500 -+++ lxc-0.8.0~rc1/src/lxc/conf.h 2012-04-23 23:09:42.871940384 -0500 -@@ -223,6 +223,8 @@ - */ - extern struct lxc_conf *lxc_conf_init(void); - -+extern int pin_rootfs(const char *rootfs); -+ - extern int lxc_create_network(struct lxc_handler *handler); - extern void lxc_delete_network(struct lxc_list *networks); - extern int lxc_assign_network(struct lxc_list *networks, pid_t pid); -Index: lxc-0.8.0~rc1/src/lxc/start.c -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/start.c 2012-04-23 23:09:18.591940795 -0500 -+++ lxc-0.8.0~rc1/src/lxc/start.c 2012-04-23 23:09:42.871940384 -0500 -@@ -538,6 +538,7 @@ - int clone_flags; - int failed_before_rename = 0; - const char *name = handler->name; -+ int pinfd; - - if (lxc_sync_init(handler)) - return -1; -@@ -567,6 +568,17 @@ - } - } - -+ /* -+ * if the rootfs is not a blockdev, prevent the container from -+ * marking it readonly. -+ */ -+ -+ pinfd = pin_rootfs(handler->conf->rootfs.path); -+ if (pinfd == -1) { -+ ERROR("failed to pin the container's rootfs"); -+ goto out_abort; -+ } -+ - /* Create a process in a new set of namespaces */ - handler->pid = lxc_clone(do_start, handler, clone_flags); - if (handler->pid < 0) { -@@ -609,6 +621,10 @@ - } - - lxc_sync_fini(handler); -+ -+ if (pinfd >= 0) -+ close(pinfd); -+ - return 0; - - out_delete_net: diff -Nru lxc-0.8.0~rc1/debian/patches/0054-ubuntu-debug lxc-1.0.0~alpha1/debian/patches/0054-ubuntu-debug --- lxc-0.8.0~rc1/debian/patches/0054-ubuntu-debug 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0054-ubuntu-debug 1970-01-01 00:00:00.000000000 +0000 @@ -1,100 +0,0 @@ -Description: add --debug option to ubuntu templates - It does 'set -x' to help debug problems with container creation - Idea from lifeless and benji. -Author: Serge Hallyn -Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/942847 -Forwarded: yes - -Index: lxc-0.8.0~rc1/templates/lxc-ubuntu-cloud.in -=================================================================== ---- lxc-0.8.0~rc1.orig/templates/lxc-ubuntu-cloud.in 2012-04-23 23:09:33.707940539 -0500 -+++ lxc-0.8.0~rc1/templates/lxc-ubuntu-cloud.in 2012-04-23 23:09:44.447940356 -0500 -@@ -104,6 +104,7 @@ - [ -a | --arch ]: Arhcitecture of container, defaults to host arcitecture - [ -C | --cloud ]: Configure container for use with meta-data service, defaults to no - [ -T | --tarball ]: Location of tarball -+[ -d | --debug ]: Run with 'set -x' to debug errors - - Options, mutually exclusive of "-C" and "--cloud": - [ -i | --hostid ]: HostID for cloud-init, defaults to random string -@@ -115,7 +116,7 @@ - return 0 - } - --options=$(getopt -o a:hp:r:n:Fi:CLS:T: -l arch:,help,path:,release:,name:,flush-cache,hostid:,auth-key:,cloud,no_locales,tarball: -- "$@") -+options=$(getopt -o a:hp:r:n:Fi:CLS:T:d -l arch:,help,path:,release:,name:,flush-cache,hostid:,auth-key:,cloud,no_locales,tarball:,debug -- "$@") - if [ $? -ne 0 ]; then - usage $(basename $0) - exit 1 -@@ -150,6 +151,7 @@ - fi - fi - -+debug=0 - hostarch=$arch - cloud=0 - locales=1 -@@ -169,11 +171,16 @@ - -S|--auth-key) auth_key=$2; shift 2;; - -L|--no_locales) locales=0; shift 2;; - -T|--tarball) tarball=$2; shift 2;; -+ -d|--debug) debug=1; shift 1;; - --) shift 1; break ;; - *) break ;; - esac - done - -+if [ $debug -eq ]; then -+ set -x -+fi -+ - if [ "$arch" == "i686" ]; then - arch=i386 - fi -Index: lxc-0.8.0~rc1/templates/lxc-ubuntu.in -=================================================================== ---- lxc-0.8.0~rc1.orig/templates/lxc-ubuntu.in 2012-04-23 23:09:41.295940409 -0500 -+++ lxc-0.8.0~rc1/templates/lxc-ubuntu.in 2012-04-23 23:09:44.447940356 -0500 -@@ -555,7 +555,7 @@ - usage() - { - cat <] [--trim] -+$1 -h|--help [-a|--arch] [-b|--bindhome ] [--trim] [-d|--debug] - [-F | --flush-cache] [-r|--release ] [ -S | --auth-key ] - release: lucid | maverick | natty | oneiric | precise - trim: make a minimal (faster, but not upgrade-safe) container -@@ -568,7 +568,7 @@ - return 0 - } - --options=$(getopt -o a:b:hp:r:xn:FS: -l arch:,bindhome:,help,path:,release:,trim,name:,flush-cache,auth-key: -- "$@") -+options=$(getopt -o a:b:hp:r:xn:FS:d -l arch:,bindhome:,help,path:,release:,trim,name:,flush-cache,auth-key:,debug -- "$@") - if [ $? -ne 0 ]; then - usage $(basename $0) - exit 1 -@@ -604,6 +604,7 @@ - fi - fi - -+debug=0 - trim_container=0 - hostarch=$arch - flushcache=0 -@@ -619,11 +620,16 @@ - -a|--arch) arch=$2; shift 2;; - -x|--trim) trim_container=1; shift 1;; - -S|--auth-key) auth_key=$2; shift 2;; -+ -d|--debug) debug=1; shift 1;; - --) shift 1; break ;; - *) break ;; - esac - done - -+if [ $debug -eq 1 ]; then -+ set -x -+fi -+ - pwd=`getent passwd $bindhome` - if [ $? -ne 0 ]; then - echo "Error: no password entry found for $bindhome" diff -Nru lxc-0.8.0~rc1/debian/patches/0055-ubuntu-handle-badgrp lxc-1.0.0~alpha1/debian/patches/0055-ubuntu-handle-badgrp --- lxc-0.8.0~rc1/debian/patches/0055-ubuntu-handle-badgrp 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0055-ubuntu-handle-badgrp 1970-01-01 00:00:00.000000000 +0000 @@ -1,45 +0,0 @@ -Description: ubuntu: fix up the logic adding group for bound users - 1. 'getent group $user' assumes user's group is named $user. - 2. if 'getent group' returns error, just ignore the group in container - 3. (misc) while it happens to all work out fine anyway, don't do - getent passwd $bindhome if $bindhome isn't defined. (it will - successfully return all password entries) -Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/942850 -Author: Serge Hallyn -Forwarded: yes - -Index: lxc-0.8.0~rc1/templates/lxc-ubuntu.in -=================================================================== ---- lxc-0.8.0~rc1.orig/templates/lxc-ubuntu.in 2012-04-23 23:09:44.447940356 -0500 -+++ lxc-0.8.0~rc1/templates/lxc-ubuntu.in 2012-04-23 23:09:46.179940328 -0500 -@@ -546,10 +546,9 @@ - echo "$h $rootfs/$h none bind 0 0" >> $path/fstab - - # Make sure the group exists in container -- chroot $rootfs getent group $user || { \ -- grp=`getent group $user` -- echo "$grp" >> $rootfs/etc/group -- } -+ grp=`echo $pwd | cut -d: -f 4` # group number for $user -+ grpe=`getent group $grp` || return 0 # if host doesn't define grp, ignore in container -+ chroot $rootfs getent group "$grpe" || echo "$grpe" >> $rootfs/etc/group - } - - usage() -@@ -630,10 +629,12 @@ - set -x - fi - --pwd=`getent passwd $bindhome` --if [ $? -ne 0 ]; then -- echo "Error: no password entry found for $bindhome" -- exit 1 -+if [ -n "$bindhome" ]; then -+ pwd=`getent passwd $bindhome` -+ if [ $? -ne 0 ]; then -+ echo "Error: no password entry found for $bindhome" -+ exit 1 -+ fi - fi - - diff -Nru lxc-0.8.0~rc1/debian/patches/0056-dont-watch-utmp lxc-1.0.0~alpha1/debian/patches/0056-dont-watch-utmp --- lxc-0.8.0~rc1/debian/patches/0056-dont-watch-utmp 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0056-dont-watch-utmp 1970-01-01 00:00:00.000000000 +0000 @@ -1,45 +0,0 @@ -Description: do check for utmp checking at the right time - We were doing the check for whether we need to watch utmp from a - thread cloned from that which will actually do the utmp watching. - Move the check to the parent thread. -Author: Serge Hallyn -Forwarded: yes -Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/948623 - -Index: lxc-0.8.0~rc1/src/lxc/start.c -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/start.c 2012-04-23 23:09:42.871940384 -0500 -+++ lxc-0.8.0~rc1/src/lxc/start.c 2012-04-23 23:09:47.843940298 -0500 -@@ -503,16 +503,12 @@ - if (lxc_sync_barrier_parent(handler, LXC_SYNC_CONFIGURE)) - return -1; - -- if (must_drop_cap_sys_boot()) { -+ if (handler->conf->need_utmp_watch) { - if (prctl(PR_CAPBSET_DROP, CAP_SYS_BOOT, 0, 0, 0)) { - SYSERROR("failed to remove CAP_SYS_BOOT capability"); - return -1; - } -- handler->conf->need_utmp_watch = 1; - DEBUG("Dropped cap_sys_boot\n"); -- } else { -- DEBUG("Not dropping cap_sys_boot or watching utmp\n"); -- handler->conf->need_utmp_watch = 0; - } - - /* Setup the container, ip, names, utsname, ... */ -@@ -651,6 +647,14 @@ - handler->ops = ops; - handler->data = data; - -+ if (must_drop_cap_sys_boot()) { -+ handler->conf->need_utmp_watch = 1; -+ DEBUG("Dropping cap_sys_boot and watching utmp\n"); -+ } else { -+ DEBUG("Not dropping cap_sys_boot or watching utmp\n"); -+ handler->conf->need_utmp_watch = 0; -+ } -+ - err = lxc_spawn(handler); - if (err) { - ERROR("failed to spawn '%s'", name); diff -Nru lxc-0.8.0~rc1/debian/patches/0057-update-manpages lxc-1.0.0~alpha1/debian/patches/0057-update-manpages --- lxc-0.8.0~rc1/debian/patches/0057-update-manpages 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0057-update-manpages 1970-01-01 00:00:00.000000000 +0000 @@ -1,194 +0,0 @@ -From c774908818f8ab22175edf9015c3396a222c3fa8 Mon Sep 17 00:00:00 2001 -From: Ubuntu -Date: Wed, 14 Mar 2012 02:30:41 +0000 -Subject: [PATCH] Update manpages to reflect some updated options. - -Signed-off-by: Serge Hallyn ---- - doc/lxc-create.sgml.in | 45 ++++++++++++++++++++++++++++++++++++++++++++- - doc/lxc-destroy.sgml.in | 25 ++++++++++++++++++++++++- - doc/lxc-start.sgml.in | 17 ++++++++++++++++- - doc/lxc.conf.sgml.in | 29 +++++++++++++++++++++++++++++ - 4 files changed, 113 insertions(+), 3 deletions(-) - -Index: lxc-0.8.0~rc1/doc/lxc-create.sgml.in -=================================================================== ---- lxc-0.8.0~rc1.orig/doc/lxc-create.sgml.in 2012-04-23 23:09:15.015940855 -0500 -+++ lxc-0.8.0~rc1/doc/lxc-create.sgml.in 2012-04-23 23:09:49.559940269 -0500 -@@ -50,7 +50,10 @@ - - lxc-create -n name - -f config_file -- -t template -+ -t template -+ -B backingstore -+ -- template-options -+ - - - -@@ -114,6 +117,46 @@ - - - -+ -+ -+ -+ -+ -+ -+ 'backingstore' is one of 'none', 'lvm', or 'btrfs'. The -+ default is 'none', meaning that the container root filesystem -+ will be a directory under @LXCPATH@/container/rootfs. -+ The option 'btrfs' need not be specified as it will be used -+ automatically if the @LXCPATH@ filesystem is found to -+ be btrfs. If backingstore is 'lvm', then an lvm block device will be -+ used and the following further options are available: -+ --lvname lvname1 will create an LV -+ named lvname1 rather than the default, which -+ is the container name. --vgname vgname1 -+ will create the LV in volume group vgname1 -+ rather than the default, lxc. -+ --fstype FSTYPE will create an FSTYPE -+ filesystem on the LV, rather than the default, which is ext4. -+ --fssize SIZE will create a LV (and -+ filesystem) of size SIZE rather than the default, which is 1G. -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ This will pass template-options to the -+ template as arguments. To see the list of options supported by -+ the template, you can run -+ lxc-create -t TEMPLATE -h. -+ -+ -+ -+ -+ - - - -Index: lxc-0.8.0~rc1/doc/lxc-destroy.sgml.in -=================================================================== ---- lxc-0.8.0~rc1.orig/doc/lxc-destroy.sgml.in 2012-04-23 23:09:14.999940856 -0500 -+++ lxc-0.8.0~rc1/doc/lxc-destroy.sgml.in 2012-04-23 23:09:49.559940269 -0500 -@@ -49,7 +49,9 @@ - - - lxc-destroy -n -- name -+ name -+ -f -+ - - - -@@ -63,6 +65,27 @@ - - - -+ -+ -+ Options -+ -+ -+ -+ -+ -+ -+ -+ -+ If a container is running, stop it first. If this option is -+ not specified and the container is running, then -+ lxc-destroy will be aborted. -+ -+ -+ -+ -+ -+ -+ - - Diagnostic - -Index: lxc-0.8.0~rc1/doc/lxc-start.sgml.in -=================================================================== ---- lxc-0.8.0~rc1.orig/doc/lxc-start.sgml.in 2012-04-23 23:09:15.047940855 -0500 -+++ lxc-0.8.0~rc1/doc/lxc-start.sgml.in 2012-04-23 23:09:49.559940269 -0500 -@@ -51,7 +51,7 @@ - name -f - config_file -c - console_file -d -s -- KEY=VAL -+ KEY=VAL -C - command - - -@@ -146,6 +146,21 @@ - - - -+ -+ -+ -+ -+ -+ -+ -+ If any file descriptors are inherited, close them. If this option -+ is not specified, then lxc-start will exit with -+ failure instead. Note: --daemon implies -+ --close-all-fds. -+ -+ -+ - - - -Index: lxc-0.8.0~rc1/doc/lxc.conf.sgml.in -=================================================================== ---- lxc-0.8.0~rc1.orig/doc/lxc.conf.sgml.in 2012-04-23 23:09:15.031940855 -0500 -+++ lxc-0.8.0~rc1/doc/lxc.conf.sgml.in 2012-04-23 23:09:49.559940269 -0500 -@@ -453,6 +453,35 @@ - - - -+ Console devices location -+ -+ LXC consoles are provided through Unix98 PTYs created on the -+ host and bind-mounted over the expected devices in the container. -+ By default, they are bind-mounted over /dev/console -+ and /dev/ttyN. This can prevent package upgrades -+ in the guest. Therefore you can specify a directory location (under -+ /dev under which LXC will create the files and -+ bind-mount over them. These will then be symbolically linked to -+ /dev/console and /dev/ttyN. -+ A package upgrade can then succeed as it is able to remove and replace -+ the symbolic links. -+ -+ -+ -+ -+ -+ -+ -+ -+ Specify a directory under /dev -+ under which to create the container console devices. -+ -+ -+ -+ -+ -+ -+ - Mount points - - The mount points section specifies the different places to be diff -Nru lxc-0.8.0~rc1/debian/patches/0058-fixup-ubuntu-cloud lxc-1.0.0~alpha1/debian/patches/0058-fixup-ubuntu-cloud --- lxc-0.8.0~rc1/debian/patches/0058-fixup-ubuntu-cloud 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0058-fixup-ubuntu-cloud 1970-01-01 00:00:00.000000000 +0000 @@ -1,106 +0,0 @@ -Description: fix handling of non-precise cloud image format -Author: Serge Hallyn -Forwarded: yes - -Index: lxc-0.8.0~rc1/templates/lxc-ubuntu-cloud.in -=================================================================== ---- lxc-0.8.0~rc1.orig/templates/lxc-ubuntu-cloud.in 2012-04-23 23:09:44.447940356 -0500 -+++ lxc-0.8.0~rc1/templates/lxc-ubuntu-cloud.in 2012-04-23 23:09:51.255940242 -0500 -@@ -1,6 +1,6 @@ - #!/bin/bash - --# template script for generating ubuntu container for LXC based on daily cloud -+# template script for generating ubuntu container for LXC based on released cloud - # images - # - # Copyright © 2012 Serge Hallyn -@@ -147,6 +147,10 @@ - elif [ "$arch" = "x86_64" ]; then - arch="amd64" - elif [ "$arch" = "armv7l" ]; then -+ # note: arm images don't exist before oneiric; are called armhf in -+ # precise; and are not supported by the query, so we don't actually -+ # support them yet (see check later on). When Query2 is available, -+ # we'll use that to enable arm images. - arch="armel" - fi - fi -@@ -177,7 +181,7 @@ - esac - done - --if [ $debug -eq ]; then -+if [ $debug -eq 1 ]; then - set -x - fi - -@@ -219,12 +223,47 @@ - if [ -n "$tarball" ]; then - url2="$tarball" - else -- url1=`ubuntu-cloudimg-query precise daily $arch --format "%{url}\n"` -+ url1=`ubuntu-cloudimg-query $release released $arch --format "%{url}\n"` - url2=`echo $url1 | sed -e 's/.tar.gz/-root\0/'` - fi - - filename=`basename $url2` - -+buildcleanup() -+{ -+ cd $rootfs -+ umount -l $cache/$xdir || true -+ rm -rf $cache -+} -+ -+# if the release doesn't have a *-rootfs.tar.gz, then create one from the -+# cloudimg.tar.gz by extracting the .img, mounting it loopback, and creating -+# a tarball from the mounted image. -+build_root_tgz() -+{ -+ url=$1 -+ filename=$2 -+ -+ xdir=`mktemp -d -p .` -+ tarname=`basename $url` -+ imgname="`basename $tarname .tar.gz`.img" -+ trap buildcleanup EXIT -+ if [ $flushcache -eq 1 -o ! -f $cache/$tarname ]; then -+ rm -f $tarname -+ echo "Downloading cloud image from $url" -+ wget $url || { echo "Couldn't find cloud image $url."; exit 1; } -+ fi -+ echo "Creating new cached cloud image rootfs" -+ tar zxf $tarname $imgname -+ mount -o loop $imgname $xdir -+ (cd $xdir; tar zcf ../$filename .) -+ umount $xdir -+ rm -f $tarname $imgname -+ rmdir $xdir -+ echo "New cloud image cache created" -+ trap EXIT -+} -+ - mkdir -p /var/lock/subsys/ - ( - flock -n -x 200 -@@ -236,10 +275,10 @@ - fi - - if [ ! -f $filename ]; then -- wget $url2 -+ wget $url2 || build_root_tgz $url1 $filename - fi - -- echo "Extracting rootfs" -+ echo "Extracting container rootfs" - mkdir -p $rootfs - cd $rootfs - tar -zxf $cache/$filename -@@ -294,6 +333,7 @@ - fi - - chroot $rootfs /usr/sbin/usermod -U ubuntu -+ echo "ubuntu:ubuntu" | chroot $rootfs chpasswd - echo "Please login as user ubuntu with password ubuntu." - - else diff -Nru lxc-0.8.0~rc1/debian/patches/0059-reenable-daily-cloudimg lxc-1.0.0~alpha1/debian/patches/0059-reenable-daily-cloudimg --- lxc-0.8.0~rc1/debian/patches/0059-reenable-daily-cloudimg 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0059-reenable-daily-cloudimg 1970-01-01 00:00:00.000000000 +0000 @@ -1,65 +0,0 @@ -Description: re-enable use of daily cloud images - There are two types of cloud images - released and daily ones. We were - always using daily ones, instead of using released by default with an - option for daily. Fix that. -Author: Serge Hallyn -Forwarded: yes - -Index: lxc-0.8.0~rc1/templates/lxc-ubuntu-cloud.in -=================================================================== ---- lxc-0.8.0~rc1.orig/templates/lxc-ubuntu-cloud.in 2012-04-23 23:09:51.255940242 -0500 -+++ lxc-0.8.0~rc1/templates/lxc-ubuntu-cloud.in 2012-04-23 23:09:52.855940215 -0500 -@@ -105,6 +105,7 @@ - [ -C | --cloud ]: Configure container for use with meta-data service, defaults to no - [ -T | --tarball ]: Location of tarball - [ -d | --debug ]: Run with 'set -x' to debug errors -+[ -s | --stream]: Use specified stream rather than 'released' - - Options, mutually exclusive of "-C" and "--cloud": - [ -i | --hostid ]: HostID for cloud-init, defaults to random string -@@ -116,7 +117,7 @@ - return 0 - } - --options=$(getopt -o a:hp:r:n:Fi:CLS:T:d -l arch:,help,path:,release:,name:,flush-cache,hostid:,auth-key:,cloud,no_locales,tarball:,debug -- "$@") -+options=$(getopt -o a:hp:r:n:Fi:CLS:T:ds: -l arch:,help,path:,release:,name:,flush-cache,hostid:,auth-key:,cloud,no_locales,tarball:,debug,stream: -- "$@") - if [ $? -ne 0 ]; then - usage $(basename $0) - exit 1 -@@ -160,6 +161,7 @@ - cloud=0 - locales=1 - flushcache=0 -+stream="released" - while true - do - case "$1" in -@@ -176,6 +178,7 @@ - -L|--no_locales) locales=0; shift 2;; - -T|--tarball) tarball=$2; shift 2;; - -d|--debug) debug=1; shift 1;; -+ -s|--stream) stream=$2; shift 2;; - --) shift 1; break ;; - *) break ;; - esac -@@ -199,6 +202,11 @@ - exit 1 - fi - -+if [ "$stream" != "daily" -a "$stream" != "released" ]; then -+ echo "Only 'daily' and 'released' streams are supported" -+ exit 1 -+fi -+ - if [ -z "$path" ]; then - echo "'path' parameter is required" - exit 1 -@@ -223,7 +231,7 @@ - if [ -n "$tarball" ]; then - url2="$tarball" - else -- url1=`ubuntu-cloudimg-query $release released $arch --format "%{url}\n"` -+ url1=`ubuntu-cloudimg-query $release $stream $arch --format "%{url}\n"` - url2=`echo $url1 | sed -e 's/.tar.gz/-root\0/'` - fi - diff -Nru lxc-0.8.0~rc1/debian/patches/0060-lxc-shutdown lxc-1.0.0~alpha1/debian/patches/0060-lxc-shutdown --- lxc-0.8.0~rc1/debian/patches/0060-lxc-shutdown 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0060-lxc-shutdown 1970-01-01 00:00:00.000000000 +0000 @@ -1,370 +0,0 @@ -Description: Add lxc-shutdown script - It optionally waits (an optional timeout # of seconds) for the container to - be STOPPED. If given -r, it reboots the container (and exits immediately). - I decided to add the timeout after all because it's harder to finagle into - an upstart post-stop script than a full bash script. -Author: Serge Hallyn -Forwarded: yes - -Index: lxc-0.8.0~rc1/configure -=================================================================== ---- lxc-0.8.0~rc1.orig/configure 2012-04-23 23:09:14.751940860 -0500 -+++ lxc-0.8.0~rc1/configure 2012-04-23 23:09:54.355940190 -0500 -@@ -4970,7 +4970,7 @@ - CFLAGS="$CFLAGS -Wall" - fi - --ac_config_files="$ac_config_files Makefile lxc.pc lxc.spec config/Makefile doc/Makefile doc/lxc-create.sgml doc/lxc-destroy.sgml doc/lxc-execute.sgml doc/lxc-start.sgml doc/lxc-checkpoint.sgml doc/lxc-restart.sgml doc/lxc-stop.sgml doc/lxc-console.sgml doc/lxc-freeze.sgml doc/lxc-unfreeze.sgml doc/lxc-monitor.sgml doc/lxc-wait.sgml doc/lxc-ls.sgml doc/lxc-ps.sgml doc/lxc-cgroup.sgml doc/lxc-kill.sgml doc/lxc-attach.sgml doc/lxc.conf.sgml doc/lxc.sgml doc/common_options.sgml doc/see_also.sgml doc/rootfs/Makefile doc/examples/Makefile doc/examples/lxc-macvlan.conf doc/examples/lxc-vlan.conf doc/examples/lxc-no-netns.conf doc/examples/lxc-empty-netns.conf doc/examples/lxc-phys.conf doc/examples/lxc-veth.conf doc/examples/lxc-complex.conf templates/Makefile templates/lxc-lenny templates/lxc-debian templates/lxc-ubuntu templates/lxc-ubuntu-cloud templates/lxc-opensuse templates/lxc-busybox templates/lxc-fedora templates/lxc-altlinux templates/lxc-sshd templates/lxc-archlinux src/Makefile src/lxc/Makefile src/lxc/lxc-ps src/lxc/lxc-ls src/lxc/lxc-netstat src/lxc/lxc-checkconfig src/lxc/lxc-setcap src/lxc/lxc-setuid src/lxc/lxc-version src/lxc/lxc-create src/lxc/lxc-clone src/lxc/lxc-destroy" -+ac_config_files="$ac_config_files Makefile lxc.pc lxc.spec config/Makefile doc/Makefile doc/lxc-create.sgml doc/lxc-destroy.sgml doc/lxc-execute.sgml doc/lxc-start.sgml doc/lxc-checkpoint.sgml doc/lxc-restart.sgml doc/lxc-stop.sgml doc/lxc-console.sgml doc/lxc-freeze.sgml doc/lxc-unfreeze.sgml doc/lxc-monitor.sgml doc/lxc-wait.sgml doc/lxc-ls.sgml doc/lxc-ps.sgml doc/lxc-cgroup.sgml doc/lxc-kill.sgml doc/lxc-attach.sgml doc/lxc.conf.sgml doc/lxc.sgml doc/common_options.sgml doc/see_also.sgml doc/rootfs/Makefile doc/examples/Makefile doc/examples/lxc-macvlan.conf doc/examples/lxc-vlan.conf doc/examples/lxc-no-netns.conf doc/examples/lxc-empty-netns.conf doc/examples/lxc-phys.conf doc/examples/lxc-veth.conf doc/examples/lxc-complex.conf templates/Makefile templates/lxc-lenny templates/lxc-debian templates/lxc-ubuntu templates/lxc-ubuntu-cloud templates/lxc-opensuse templates/lxc-busybox templates/lxc-fedora templates/lxc-altlinux templates/lxc-sshd templates/lxc-archlinux src/Makefile src/lxc/Makefile src/lxc/lxc-ps src/lxc/lxc-ls src/lxc/lxc-netstat src/lxc/lxc-checkconfig src/lxc/lxc-setcap src/lxc/lxc-setuid src/lxc/lxc-version src/lxc/lxc-create src/lxc/lxc-clone src/lxc/lxc-shutdown src/lxc/lxc-destroy" - - ac_config_commands="$ac_config_commands default" - -@@ -5775,6 +5775,7 @@ - "src/lxc/lxc-version") CONFIG_FILES="$CONFIG_FILES src/lxc/lxc-version" ;; - "src/lxc/lxc-create") CONFIG_FILES="$CONFIG_FILES src/lxc/lxc-create" ;; - "src/lxc/lxc-clone") CONFIG_FILES="$CONFIG_FILES src/lxc/lxc-clone" ;; -+ "src/lxc/lxc-shutdown") CONFIG_FILES="$CONFIG_FILES src/lxc/lxc-shutdown" ;; - "src/lxc/lxc-destroy") CONFIG_FILES="$CONFIG_FILES src/lxc/lxc-destroy" ;; - "default") CONFIG_COMMANDS="$CONFIG_COMMANDS default" ;; - -Index: lxc-0.8.0~rc1/configure.ac -=================================================================== ---- lxc-0.8.0~rc1.orig/configure.ac 2012-04-23 23:09:14.651940861 -0500 -+++ lxc-0.8.0~rc1/configure.ac 2012-04-23 23:09:54.355940190 -0500 -@@ -160,6 +160,7 @@ - src/lxc/lxc-version - src/lxc/lxc-create - src/lxc/lxc-clone -+ src/lxc/lxc-shutdown - src/lxc/lxc-destroy - - ]) -Index: lxc-0.8.0~rc1/doc/lxc-shutdown.sgml.in -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ lxc-0.8.0~rc1/doc/lxc-shutdown.sgml.in 2012-04-23 23:09:54.355940190 -0500 -@@ -0,0 +1,97 @@ -+ -+ -+ -+ -+]> -+ -+ -+ -+ @LXC_GENERATE_DATE@ -+ -+ -+ lxc-shutdown -+ 1 -+ -+ -+ -+ lxc-shutdown -+ -+ -+ externally shut down or reboot a container -+ -+ -+ -+ -+ -+ lxc-shutdown -n name -+ -w -r -+ -+ -+ -+ -+ -+ Description -+ -+ -+ lxc-shutdown sends a SIGPWR signal to the -+ specified container to request it to cleanly shut down. If -+ -w is specified, then lxc-shutdown -+ will wait until the container has shut down before exiting. -+ If -r is specified, the container will be -+ asked to reboot (using a SIGINT signal), and -w -+ will be ignored. If the container ignore these signals, then -+ nothing will happen. In that case, you can use lxc-stop -+ to force the container to stop. -+ -+ -+ -+ -+ &commonoptions; -+ -+ &seealso; -+ -+ -+ Author -+ Serge Hallyn serge.hallyn@canonical.com -+ -+ -+ -+ -+ -Index: lxc-0.8.0~rc1/lxc.spec -=================================================================== ---- lxc-0.8.0~rc1.orig/lxc.spec 2012-04-23 23:09:14.735940860 -0500 -+++ lxc-0.8.0~rc1/lxc.spec 2012-04-23 23:09:54.359940190 -0500 -@@ -83,6 +83,7 @@ - %attr(4111,root,root) %{_bindir}/lxc-attach - %attr(4111,root,root) %{_bindir}/lxc-create - %attr(4111,root,root) %{_bindir}/lxc-clone -+%attr(4111,root,root) %{_bindir}/lxc-shutdown - %attr(4111,root,root) %{_bindir}/lxc-start - %attr(4111,root,root) %{_bindir}/lxc-netstat - %attr(4111,root,root) %{_bindir}/lxc-unshare -Index: lxc-0.8.0~rc1/lxc.spec.in -=================================================================== ---- lxc-0.8.0~rc1.orig/lxc.spec.in 2012-04-23 23:09:14.667940862 -0500 -+++ lxc-0.8.0~rc1/lxc.spec.in 2012-04-23 23:09:54.359940190 -0500 -@@ -83,6 +83,7 @@ - %attr(4111,root,root) %{_bindir}/lxc-attach - %attr(4111,root,root) %{_bindir}/lxc-create - %attr(4111,root,root) %{_bindir}/lxc-clone -+%attr(4111,root,root) %{_bindir}/lxc-shutdown - %attr(4111,root,root) %{_bindir}/lxc-start - %attr(4111,root,root) %{_bindir}/lxc-netstat - %attr(4111,root,root) %{_bindir}/lxc-unshare -Index: lxc-0.8.0~rc1/src/lxc/Makefile.am -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/Makefile.am 2012-04-23 23:09:14.683940860 -0500 -+++ lxc-0.8.0~rc1/src/lxc/Makefile.am 2012-04-23 23:09:54.359940190 -0500 -@@ -78,6 +78,7 @@ - lxc-version \ - lxc-create \ - lxc-clone \ -+ lxc-shutdown \ - lxc-destroy - - bin_PROGRAMS = \ -Index: lxc-0.8.0~rc1/src/lxc/Makefile.in -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/Makefile.in 2012-04-23 23:09:14.711940859 -0500 -+++ lxc-0.8.0~rc1/src/lxc/Makefile.in 2012-04-23 23:09:54.359940190 -0500 -@@ -52,7 +52,7 @@ - $(srcdir)/lxc-destroy.in $(srcdir)/lxc-ls.in \ - $(srcdir)/lxc-netstat.in $(srcdir)/lxc-ps.in \ - $(srcdir)/lxc-setcap.in $(srcdir)/lxc-setuid.in \ -- $(srcdir)/lxc-version.in -+ $(srcdir)/lxc-version.in $(srcdir)/lxc-shutdown.in - ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 - am__aclocal_m4_deps = $(top_srcdir)/config/acinclude.m4 \ - $(top_srcdir)/config/linux.m4 $(top_srcdir)/configure.ac -@@ -62,7 +62,7 @@ - CONFIG_HEADER = $(top_builddir)/src/config.h - CONFIG_CLEAN_FILES = lxc-ps lxc-ls lxc-netstat lxc-checkconfig \ - lxc-setcap lxc-setuid lxc-version lxc-create lxc-clone \ -- lxc-destroy -+ lxc-shutdown lxc-destroy - CONFIG_CLEAN_VPATH_FILES = - am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkglibexecdir)" \ - "$(DESTDIR)$(sodir)" "$(DESTDIR)$(bindir)" \ -@@ -389,6 +389,7 @@ - lxc-version \ - lxc-create \ - lxc-clone \ -+ lxc-shutdown \ - lxc-destroy - - AM_LDFLAGS = -Wl,-E $(am__append_1) -@@ -461,6 +462,8 @@ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ - lxc-clone: $(top_builddir)/config.status $(srcdir)/lxc-clone.in - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ -+lxc-shutdown: $(top_builddir)/config.status $(srcdir)/lxc-shutdown.in -+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ - lxc-destroy: $(top_builddir)/config.status $(srcdir)/lxc-destroy.in - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ - install-binPROGRAMS: $(bin_PROGRAMS) -Index: lxc-0.8.0~rc1/src/lxc/lxc-shutdown.in -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ lxc-0.8.0~rc1/src/lxc/lxc-shutdown.in 2012-04-23 23:09:54.359940190 -0500 -@@ -0,0 +1,147 @@ -+#!/bin/bash -+ -+# (C) Copyright Canonical 2011,2012 -+ -+# 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 -+ -+set -e -+ -+usage() { -+ echo "usage: lxc-shutdown -n name [-w] [-r]" -+ echo " Cleanly shut down a container." -+ echo " -w: wait for shutdown to complete." -+ echo " -r: reboot (ignore -w)." -+ echo " -t timeout: wait at most timeout seconds (implies -w), then kill" -+ echo " the container." -+} -+ -+alarm() { -+ pid=$1 -+ timeout=$2 -+ sleep $timeout -+ kill $pid -+} -+ -+dolxcstop() -+{ -+ echo "Calling lxc-stop on $lxc_name" -+ lxc-stop -n $lxc_name -+ exit 0 -+} -+ -+shortoptions='hn:rwt:' -+longoptions='help,name:,wait,reboot,timeout:' -+ -+timeout="-1" -+ -+getopt=$(getopt -o $shortoptions --longoptions $longoptions -- "$@") -+if [ $? != 0 ]; then -+ usage -+ exit 1; -+fi -+ -+eval set -- "$getopt" -+ -+reboot=0 -+dowait=0 -+ -+while true; do -+ case "$1" in -+ -h|--help) -+ help -+ exit 1 -+ ;; -+ -n|--name) -+ shift -+ lxc_name=$1 -+ shift -+ ;; -+ -w|--wait) -+ dowait=1 -+ shift -+ ;; -+ -r|--reboot) -+ reboot=1 -+ shift -+ ;; -+ -t|--timeout) -+ shift -+ timeout=$1 -+ dowait=1 -+ shift -+ ;; -+ --) -+ shift -+ break;; -+ *) -+ echo $1 -+ usage -+ exit 1 -+ ;; -+ esac -+done -+ -+if [ -z "$lxc_name" ]; then -+ echo "no container name specified" -+ usage -+ exit 1 -+fi -+ -+if [ "$(id -u)" != "0" ]; then -+ echo "This command has to be run as root" -+ exit 1 -+fi -+ -+type lxc-info > /dev/null || { echo "lxc-info not found."; exit 1; } -+type lxc-wait > /dev/null || { echo "lxc-wait not found."; exit 1; } -+ -+pid=`lxc-info -n $lxc_name -p 2>/dev/null | awk '{ print $2 }'` -+if [ "$pid" = "-1" ]; then -+ echo "$lxc_name is not running" -+ exit 1 -+fi -+ -+if [ $reboot -eq 1 ]; then -+ kill -INT $pid -+ exit 0 -+else -+ kill -PWR $pid -+fi -+ -+if [ $dowait -eq 0 ]; then -+ exit 0 -+fi -+ -+if [ $timeout != "-1" ]; then -+ trap dolxcstop EXIT -+ alarm $$ $timeout & -+ alarmpid=$! -+fi -+ -+while [ 1 ]; do -+ s=`lxc-info -s -n $lxc_name | awk '{ print $2 }'` -+ if [ "$s" = "STOPPED" ]; then -+ break; -+ fi -+ sleep 1 -+done -+ -+if [ $timeout != "-1" ]; then -+ kill $alarmpid -+fi -+ -+echo "Container $lxc_name has shut down" -+ -+exit 0 diff -Nru lxc-0.8.0~rc1/debian/patches/0061-lxc-start-apparmor lxc-1.0.0~alpha1/debian/patches/0061-lxc-start-apparmor --- lxc-0.8.0~rc1/debian/patches/0061-lxc-start-apparmor 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0061-lxc-start-apparmor 1970-01-01 00:00:00.000000000 +0000 @@ -1,216 +0,0 @@ -Description: support per-container apparmor profiles - It doesn't yet support selinux or smack. -Author: Serge Hallyn -Forwarded: no - -Index: lxc-0.8.0~rc1/src/lxc/conf.h -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/conf.h 2012-04-23 23:09:42.871940384 -0500 -+++ lxc-0.8.0~rc1/src/lxc/conf.h 2012-04-23 23:09:55.735940166 -0500 -@@ -198,6 +198,7 @@ - * @tty_info : tty data - * @console : console data - * @ttydir : directory (under /dev) in which to create console and ttys -+ * @aa_profile : apparmor profile to switch to - */ - struct lxc_conf { - char *fstab; -@@ -216,6 +217,7 @@ - struct lxc_rootfs rootfs; - char *ttydir; - int close_all_fds; -+ char *aa_profile; - }; - - /* -Index: lxc-0.8.0~rc1/src/lxc/start.c -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/start.c 2012-04-23 23:09:47.843940298 -0500 -+++ lxc-0.8.0~rc1/src/lxc/start.c 2012-04-23 23:09:55.735940166 -0500 -@@ -44,6 +44,7 @@ - #include - #include - #include -+#include - - #ifdef HAVE_SYS_SIGNALFD_H - # include -@@ -465,7 +466,7 @@ - return -1; - } - if (wait(&status) < 0) { -- SYSERROR("unexpected wait error: %m\n"); -+ SYSERROR("unexpected wait error: %m"); - return -1; - } - -@@ -475,6 +476,36 @@ - return 0; - } - -+#if 0 -+/* aa_getcon is not working right now. Use our hand-rolled version below */ -+static int aa_am_unconfined(void) -+{ -+ char *con; -+ int ret = 0; -+ if (aa_getcon(&con, NULL) == 0 && strcmp(con, "unconfined") == 0) -+ ret = 1; -+ free(con); -+ return ret; -+} -+#else -+static int aa_am_unconfined(void) -+{ -+ int ret; -+ char path[100], p[100]; -+ sprintf(path, "/proc/%d/attr/current", getpid()); -+ FILE *f = fopen(path, "r"); -+ if (!f) -+ return 0; -+ ret = fscanf(f, "%99s", p); -+ fclose(f); -+ if (ret < 1) -+ return 0; -+ if (strcmp(p, "unconfined") == 0) -+ return 1; -+ return 0; -+} -+#endif -+ - static int do_start(void *data) - { - struct lxc_handler *handler = data; -@@ -519,6 +550,31 @@ - - close(handler->sigfd); - -+#define AA_DEF_PROFILE "lxc-container-default" -+ -+ if (!handler->conf->aa_profile) -+ handler->conf->aa_profile = AA_DEF_PROFILE; -+ -+ if (strcmp(handler->conf->aa_profile, "unconfined") == 0 && -+ aa_am_unconfined()) { -+ INFO("apparmor profile unchanged"); -+ goto skip_profile; -+ } -+ -+ /* aa_change_onexec makes more sense since we want to transition when -+ * /sbin/init is exec'd. But the transitions doesn't seem to work -+ * then (refused). aa_change_onexec will work since we're doing it -+ * right before the exec, so we'll just use that for now. -+ */ -+ //if (aa_change_onexec(handler->conf->aa_profile) < 0) { -+ if (aa_change_profile(handler->conf->aa_profile) < 0) { -+ SYSERROR("failed to change apparmor profile to %s", handler->conf->aa_profile); -+ return -1; -+ } -+ INFO("changed apparmor profile to %s", handler->conf->aa_profile); -+ -+skip_profile: -+ - /* after this call, we are in error because this - * ops should not return as it execs */ - if (handler->ops->start(handler, handler->data)) -Index: lxc-0.8.0~rc1/src/lxc/conf.c -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/conf.c 2012-04-23 23:09:42.871940384 -0500 -+++ lxc-0.8.0~rc1/src/lxc/conf.c 2012-04-23 23:09:55.739940166 -0500 -@@ -1636,6 +1636,7 @@ - lxc_list_init(&new->network); - lxc_list_init(&new->mount_list); - lxc_list_init(&new->caps); -+ new->aa_profile = NULL; - - return new; - } -Index: lxc-0.8.0~rc1/src/lxc/confile.c -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/confile.c 2012-04-23 23:09:14.435940866 -0500 -+++ lxc-0.8.0~rc1/src/lxc/confile.c 2012-04-23 23:09:55.739940166 -0500 -@@ -49,6 +49,7 @@ - static int config_pts(const char *, char *, struct lxc_conf *); - static int config_tty(const char *, char *, struct lxc_conf *); - static int config_ttydir(const char *, char *, struct lxc_conf *); -+static int config_aa_profile(const char *, char *, struct lxc_conf *); - static int config_cgroup(const char *, char *, struct lxc_conf *); - static int config_mount(const char *, char *, struct lxc_conf *); - static int config_rootfs(const char *, char *, struct lxc_conf *); -@@ -85,6 +86,7 @@ - { "lxc.pts", config_pts }, - { "lxc.tty", config_tty }, - { "lxc.devttydir", config_ttydir }, -+ { "lxc.aa_profile", config_aa_profile }, - { "lxc.cgroup", config_cgroup }, - { "lxc.mount", config_mount }, - { "lxc.rootfs.mount", config_rootfs_mount }, -@@ -632,6 +634,24 @@ - - return 0; - } -+ -+static int config_aa_profile(const char *key, char *value, -+ struct lxc_conf *lxc_conf) -+{ -+ char *path; -+ -+ if (!value || strlen(value) == 0) -+ return 0; -+ path = strdup(value); -+ if (!path) { -+ SYSERROR("failed to strdup '%s': %m", value); -+ return -1; -+ } -+ -+ lxc_conf->aa_profile = path; -+ -+ return 0; -+} - - static int config_cgroup(const char *key, char *value, struct lxc_conf *lxc_conf) - { -Index: lxc-0.8.0~rc1/src/lxc/Makefile.am -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/Makefile.am 2012-04-23 23:09:54.359940190 -0500 -+++ lxc-0.8.0~rc1/src/lxc/Makefile.am 2012-04-23 23:09:55.739940166 -0500 -@@ -66,7 +66,7 @@ - -shared \ - -Wl,-soname,liblxc.so.$(firstword $(subst ., ,$(VERSION))) - --liblxc_so_LDADD = -lutil $(CAP_LIBS) -+liblxc_so_LDADD = -lutil $(CAP_LIBS) -lapparmor - - bin_SCRIPTS = \ - lxc-ps \ -@@ -105,7 +105,7 @@ - if ENABLE_RPATH - AM_LDFLAGS += -Wl,-rpath -Wl,$(libdir) - endif --LDADD=liblxc.so @CAP_LIBS@ -+LDADD=liblxc.so @CAP_LIBS@ -lapparmor - - lxc_attach_SOURCES = lxc_attach.c - lxc_cgroup_SOURCES = lxc_cgroup.c -Index: lxc-0.8.0~rc1/src/lxc/Makefile.in -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/Makefile.in 2012-04-23 23:09:54.359940190 -0500 -+++ lxc-0.8.0~rc1/src/lxc/Makefile.in 2012-04-23 23:09:55.739940166 -0500 -@@ -378,7 +378,7 @@ - -shared \ - -Wl,-soname,liblxc.so.$(firstword $(subst ., ,$(VERSION))) - --liblxc_so_LDADD = -lutil $(CAP_LIBS) -+liblxc_so_LDADD = -lutil $(CAP_LIBS) -lapparmor - bin_SCRIPTS = \ - lxc-ps \ - lxc-netstat \ -@@ -393,7 +393,7 @@ - lxc-destroy - - AM_LDFLAGS = -Wl,-E $(am__append_1) --LDADD = liblxc.so @CAP_LIBS@ -+LDADD = liblxc.so @CAP_LIBS@ -lapparmor - lxc_attach_SOURCES = lxc_attach.c - lxc_cgroup_SOURCES = lxc_cgroup.c - lxc_checkpoint_SOURCES = lxc_checkpoint.c diff -Nru lxc-0.8.0~rc1/debian/patches/0062-templates-relative-paths lxc-1.0.0~alpha1/debian/patches/0062-templates-relative-paths --- lxc-0.8.0~rc1/debian/patches/0062-templates-relative-paths 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0062-templates-relative-paths 1970-01-01 00:00:00.000000000 +0000 @@ -1,271 +0,0 @@ -Description: use relative paths when creating containers - At the same time, allow lxc.mount.entry to specify an absolute target - path relative to /var/lib/lxc/CN/rootfs, even if rootfs is a blockdev. - Otherwise all such entries are ignored for blockdev-backed containers. -Author: Serge Hallyn -Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/960860 -Forwarded: yes - -Index: lxc-0.8.0~rc1/templates/lxc-debian.in -=================================================================== ---- lxc-0.8.0~rc1.orig/templates/lxc-debian.in 2012-04-23 23:09:19.259940782 -0500 -+++ lxc-0.8.0~rc1/templates/lxc-debian.in 2012-04-23 23:09:57.155940142 -0500 -@@ -212,8 +212,8 @@ - lxc.cgroup.devices.allow = c 254:0 rwm - - # mounts point --lxc.mount.entry=proc $rootfs/proc proc nodev,noexec,nosuid 0 0 --lxc.mount.entry=sysfs $rootfs/sys sysfs defaults 0 0 -+lxc.mount.entry=proc proc proc nodev,noexec,nosuid 0 0 -+lxc.mount.entry=sysfs sys sysfs defaults 0 0 - EOF - - if [ $? -ne 0 ]; then -Index: lxc-0.8.0~rc1/templates/lxc-fedora.in -=================================================================== ---- lxc-0.8.0~rc1.orig/templates/lxc-fedora.in 2012-04-23 23:09:33.707940539 -0500 -+++ lxc-0.8.0~rc1/templates/lxc-fedora.in 2012-04-23 23:09:57.159940142 -0500 -@@ -257,8 +257,8 @@ - EOF - - cat < $config_path/fstab --proc $rootfs_path/proc proc nodev,noexec,nosuid 0 0 --sysfs $rootfs_path/sys sysfs defaults 0 0 -+proc proc proc nodev,noexec,nosuid 0 0 -+sysfs sys sysfs defaults 0 0 - EOF - if [ $? -ne 0 ]; then - echo "Failed to add configuration" -Index: lxc-0.8.0~rc1/templates/lxc-lenny.in -=================================================================== ---- lxc-0.8.0~rc1.orig/templates/lxc-lenny.in 2012-04-23 23:09:14.251940869 -0500 -+++ lxc-0.8.0~rc1/templates/lxc-lenny.in 2012-04-23 23:09:57.159940142 -0500 -@@ -200,8 +200,8 @@ - lxc.cgroup.devices.allow = c 254:0 rwm - - # mounts point --lxc.mount.entry=proc $rootfs/proc proc nodev,noexec,nosuid 0 0 --lxc.mount.entry=sysfs $rootfs/sys sysfs defaults 0 0 -+lxc.mount.entry=proc proc proc nodev,noexec,nosuid 0 0 -+lxc.mount.entry=sysfs sys sysfs defaults 0 0 - EOF - - if [ $? -ne 0 ]; then -Index: lxc-0.8.0~rc1/templates/lxc-opensuse.in -=================================================================== ---- lxc-0.8.0~rc1.orig/templates/lxc-opensuse.in 2012-04-23 23:09:14.159940870 -0500 -+++ lxc-0.8.0~rc1/templates/lxc-opensuse.in 2012-04-23 23:09:57.159940142 -0500 -@@ -281,8 +281,8 @@ - EOF - - cat < $path/fstab --proc $rootfs/proc proc nodev,noexec,nosuid 0 0 --sysfs $rootfs/sys sysfs defaults 0 0 -+proc proc proc nodev,noexec,nosuid 0 0 -+sysfs sys sysfs defaults 0 0 - EOF - - if [ $? -ne 0 ]; then -Index: lxc-0.8.0~rc1/templates/lxc-sshd.in -=================================================================== ---- lxc-0.8.0~rc1.orig/templates/lxc-sshd.in 2012-04-23 23:09:33.707940539 -0500 -+++ lxc-0.8.0~rc1/templates/lxc-sshd.in 2012-04-23 23:09:57.159940142 -0500 -@@ -113,14 +113,14 @@ - lxc.utsname = $name - lxc.pts = 1024 - lxc.rootfs = $rootfs --lxc.mount.entry=/dev $rootfs/dev none ro,bind 0 0 --lxc.mount.entry=/lib $rootfs/lib none ro,bind 0 0 --lxc.mount.entry=/bin $rootfs/bin none ro,bind 0 0 --lxc.mount.entry=/usr /$rootfs/usr none ro,bind 0 0 --lxc.mount.entry=/sbin $rootfs/sbin none ro,bind 0 0 --lxc.mount.entry=tmpfs $rootfs/var/run/sshd tmpfs mode=0644 0 0 --lxc.mount.entry=@LXCTEMPLATEDIR@/lxc-sshd $rootfs/sbin/init none bind 0 0 --lxc.mount.entry=proc $rootfs/proc proc nodev,noexec,nosuid 0 0 -+lxc.mount.entry=/dev dev none ro,bind 0 0 -+lxc.mount.entry=/lib lib none ro,bind 0 0 -+lxc.mount.entry=/bin bin none ro,bind 0 0 -+lxc.mount.entry=/usr usr none ro,bind 0 0 -+lxc.mount.entry=/sbin sbin none ro,bind 0 0 -+lxc.mount.entry=tmpfs var/run/sshd tmpfs mode=0644 0 0 -+lxc.mount.entry=@LXCTEMPLATEDIR@/lxc-sshd sbin/init none bind 0 0 -+lxc.mount.entry=proc proc proc nodev,noexec,nosuid 0 0 - EOF - - # if no .ipv4 section in config, then have the container run dhcp -@@ -128,7 +128,7 @@ - - if [ "$(uname -m)" = "x86_64" ]; then - cat <> $path/config --lxc.mount.entry=/lib64 $rootfs/lib64 none ro,bind 0 0 -+lxc.mount.entry=/lib64 lib64 none ro,bind 0 0 - EOF - fi - } -Index: lxc-0.8.0~rc1/templates/lxc-ubuntu-cloud.in -=================================================================== ---- lxc-0.8.0~rc1.orig/templates/lxc-ubuntu-cloud.in 2012-04-23 23:09:52.855940215 -0500 -+++ lxc-0.8.0~rc1/templates/lxc-ubuntu-cloud.in 2012-04-23 23:09:57.159940142 -0500 -@@ -87,8 +87,8 @@ - EOF - - cat < $path/fstab --proc $rootfs/proc proc nodev,noexec,nosuid 0 0 --sysfs $rootfs/sys sysfs defaults 0 0 -+proc proc proc nodev,noexec,nosuid 0 0 -+sysfs sys sysfs defaults 0 0 - EOF - - return 0 -Index: lxc-0.8.0~rc1/templates/lxc-ubuntu.in -=================================================================== ---- lxc-0.8.0~rc1.orig/templates/lxc-ubuntu.in 2012-04-23 23:09:46.179940328 -0500 -+++ lxc-0.8.0~rc1/templates/lxc-ubuntu.in 2012-04-23 23:09:57.159940142 -0500 -@@ -366,8 +366,8 @@ - EOF - - cat < $path/fstab --proc $rootfs/proc proc nodev,noexec,nosuid 0 0 --sysfs $rootfs/sys sysfs defaults 0 0 -+proc proc proc nodev,noexec,nosuid 0 0 -+sysfs sys sysfs defaults 0 0 - EOF - - if [ $? -ne 0 ]; then -@@ -543,7 +543,7 @@ - # bind-mount the user's path into the container's /home - h=`getent passwd $user | cut -d: -f 6` - mkdir -p $rootfs/$h -- echo "$h $rootfs/$h none bind 0 0" >> $path/fstab -+ echo "$h $h none bind 0 0" >> $path/fstab - - # Make sure the group exists in container - grp=`echo $pwd | cut -d: -f 4` # group number for $user -Index: lxc-0.8.0~rc1/src/lxc/conf.c -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/conf.c 2012-04-23 23:09:55.739940166 -0500 -+++ lxc-0.8.0~rc1/src/lxc/conf.c 2012-04-23 23:09:57.163940142 -0500 -@@ -1142,27 +1142,50 @@ - } - - static int mount_entry_on_absolute_rootfs(struct mntent *mntent, -- const struct lxc_rootfs *rootfs) -+ const struct lxc_rootfs *rootfs, -+ const char *lxc_name) - { - char *aux; - char path[MAXPATHLEN]; - unsigned long mntflags; - char *mntdata; -- int ret = 0; -+ int r, ret = 0, offset; - - if (parse_mntopts(mntent->mnt_opts, &mntflags, &mntdata) < 0) { - ERROR("failed to parse mount option '%s'", mntent->mnt_opts); - return -1; - } - -+ /* if rootfs->path is a blockdev path, allow container fstab to -+ * use /var/lib/lxc/CN/rootfs as the target prefix */ -+ r = snprintf(path, MAXPATHLEN, "/var/lib/lxc/%s/rootfs", lxc_name); -+ if (r < 0 || r >= MAXPATHLEN) -+ goto skipvarlib; -+ -+ aux = strstr(mntent->mnt_dir, path); -+ if (aux) { -+ offset = strlen(path); -+ goto skipabs; -+ } -+ -+skipvarlib: - aux = strstr(mntent->mnt_dir, rootfs->path); - if (!aux) { - WARN("ignoring mount point '%s'", mntent->mnt_dir); - goto out; - } -+ offset = strlen(rootfs->path); -+ -+skipabs: - - snprintf(path, MAXPATHLEN, "%s/%s", rootfs->mount, -- aux + strlen(rootfs->path)); -+ aux + offset); -+ if (r < 0 || r >= MAXPATHLEN) { -+ WARN("pathnme too long for '%s'", mntent->mnt_dir); -+ ret = -1; -+ goto out; -+ } -+ - - ret = mount_entry(mntent->mnt_fsname, path, mntent->mnt_type, - mntflags, mntdata); -@@ -1196,7 +1219,8 @@ - return ret; - } - --static int mount_file_entries(const struct lxc_rootfs *rootfs, FILE *file) -+static int mount_file_entries(const struct lxc_rootfs *rootfs, FILE *file, -+ const char *lxc_name) - { - struct mntent *mntent; - int ret = -1; -@@ -1217,7 +1241,7 @@ - continue; - } - -- if (mount_entry_on_absolute_rootfs(mntent, rootfs)) -+ if (mount_entry_on_absolute_rootfs(mntent, rootfs, lxc_name)) - goto out; - } - -@@ -1228,7 +1252,8 @@ - return ret; - } - --static int setup_mount(const struct lxc_rootfs *rootfs, const char *fstab) -+static int setup_mount(const struct lxc_rootfs *rootfs, const char *fstab, -+ const char *lxc_name) - { - FILE *file; - int ret; -@@ -1242,13 +1267,14 @@ - return -1; - } - -- ret = mount_file_entries(rootfs, file); -+ ret = mount_file_entries(rootfs, file, lxc_name); - - endmntent(file); - return ret; - } - --static int setup_mount_entries(const struct lxc_rootfs *rootfs, struct lxc_list *mount) -+static int setup_mount_entries(const struct lxc_rootfs *rootfs, struct lxc_list *mount, -+ const char *lxc_name) - { - FILE *file; - struct lxc_list *iterator; -@@ -1268,7 +1294,7 @@ - - rewind(file); - -- ret = mount_file_entries(rootfs, file); -+ ret = mount_file_entries(rootfs, file, lxc_name); - - fclose(file); - return ret; -@@ -2048,12 +2074,12 @@ - return -1; - } - -- if (setup_mount(&lxc_conf->rootfs, lxc_conf->fstab)) { -+ if (setup_mount(&lxc_conf->rootfs, lxc_conf->fstab, name)) { - ERROR("failed to setup the mounts for '%s'", name); - return -1; - } - -- if (setup_mount_entries(&lxc_conf->rootfs, &lxc_conf->mount_list)) { -+ if (setup_mount_entries(&lxc_conf->rootfs, &lxc_conf->mount_list, name)) { - ERROR("failed to setup the mount entries for '%s'", name); - return -1; - } diff -Nru lxc-0.8.0~rc1/debian/patches/0063-check-apparmor-enabled lxc-1.0.0~alpha1/debian/patches/0063-check-apparmor-enabled --- lxc-0.8.0~rc1/debian/patches/0063-check-apparmor-enabled 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0063-check-apparmor-enabled 1970-01-01 00:00:00.000000000 +0000 @@ -1,142 +0,0 @@ -Description: don't try apparmor transitions if aa not loaded - If apparmor is not enabled, or the kernel doesn't support mount - restrictions, then don't try apparmor transition. - Also, ignore mount failures in lxc_init. Apparmor does not - allow lxc_init to do those mounts. -Author: Serge Hallyn -Forwarded: no - -Index: lxc-0.8.0~rc1/src/lxc/start.c -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/start.c 2012-04-23 23:09:55.735940166 -0500 -+++ lxc-0.8.0~rc1/src/lxc/start.c 2012-04-23 23:09:58.959940112 -0500 -@@ -46,6 +46,8 @@ - #include - #include - -+int apparmor_enabled = 0; -+ - #ifdef HAVE_SYS_SIGNALFD_H - # include - #else -@@ -506,6 +508,38 @@ - } - #endif - -+#define AA_DEF_PROFILE "lxc-container-default" -+static int apparmor_load(struct lxc_handler *handler) -+{ -+ if (!apparmor_enabled) { -+ INFO("apparmor not enabled"); -+ return 0; -+ } -+ -+ if (!handler->conf->aa_profile) -+ handler->conf->aa_profile = AA_DEF_PROFILE; -+ -+ if (strcmp(handler->conf->aa_profile, "unconfined") == 0 && -+ aa_am_unconfined()) { -+ INFO("apparmor profile unchanged"); -+ return 0; -+ } -+ -+ /* aa_change_onexec makes more sense since we want to transition when -+ * /sbin/init is exec'd. But the transitions doesn't seem to work -+ * then (refused). aa_change_onexec will work since we're doing it -+ * right before the exec, so we'll just use that for now. -+ */ -+ //if (aa_change_onexec(handler->conf->aa_profile) < 0) { -+ if (aa_change_profile(handler->conf->aa_profile) < 0) { -+ SYSERROR("failed to change apparmor profile to %s", handler->conf->aa_profile); -+ return -1; -+ } -+ INFO("changed apparmor profile to %s", handler->conf->aa_profile); -+ -+ return 0; -+} -+ - static int do_start(void *data) - { - struct lxc_handler *handler = data; -@@ -550,30 +584,8 @@ - - close(handler->sigfd); - --#define AA_DEF_PROFILE "lxc-container-default" -- -- if (!handler->conf->aa_profile) -- handler->conf->aa_profile = AA_DEF_PROFILE; -- -- if (strcmp(handler->conf->aa_profile, "unconfined") == 0 && -- aa_am_unconfined()) { -- INFO("apparmor profile unchanged"); -- goto skip_profile; -- } -- -- /* aa_change_onexec makes more sense since we want to transition when -- * /sbin/init is exec'd. But the transitions doesn't seem to work -- * then (refused). aa_change_onexec will work since we're doing it -- * right before the exec, so we'll just use that for now. -- */ -- //if (aa_change_onexec(handler->conf->aa_profile) < 0) { -- if (aa_change_profile(handler->conf->aa_profile) < 0) { -- SYSERROR("failed to change apparmor profile to %s", handler->conf->aa_profile); -+ if (apparmor_load(handler) < 0) - return -1; -- } -- INFO("changed apparmor profile to %s", handler->conf->aa_profile); -- --skip_profile: - - /* after this call, we are in error because this - * ops should not return as it execs */ -@@ -786,12 +798,36 @@ - .post_start = post_start - }; - -+#define AA_MOUNT_RESTR "/sys/kernel/security/apparmor/features/mount/mask" -+#define AA_ENABLED_FILE "/sys/module/apparmor/parameters/enabled" -+static int check_apparmor_enabled(void) -+{ -+ struct stat statbuf; -+ FILE *fin; -+ char e; -+ int ret; -+ -+ ret = stat(AA_MOUNT_RESTR, &statbuf); -+ if (ret != 0) -+ return 0; -+ fin = fopen(AA_ENABLED_FILE, "r"); -+ if (!fin) -+ return 0; -+ fscanf(fin, "%c", &e); -+ fclose(fin); -+ if (e == 'Y') -+ return 1; -+ return 0; -+} -+ - int lxc_start(const char *name, char *const argv[], struct lxc_conf *conf) - { - struct start_args start_arg = { - .argv = argv, - }; - -+ apparmor_enabled = check_apparmor_enabled(); -+ - if (lxc_check_inherited(conf, -1)) - return -1; - -Index: lxc-0.8.0~rc1/src/lxc/lxc_init.c -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/lxc_init.c 2012-04-23 23:09:13.935940874 -0500 -+++ lxc-0.8.0~rc1/src/lxc/lxc_init.c 2012-04-23 23:09:58.963940112 -0500 -@@ -126,7 +126,7 @@ - } - - if (lxc_setup_fs()) -- exit(err); -+ INFO("Ignoring error in setting up fs"); - - if (lxc_caps_reset()) - exit(err); diff -Nru lxc-0.8.0~rc1/debian/patches/0064-apparmor-mount-proc lxc-1.0.0~alpha1/debian/patches/0064-apparmor-mount-proc --- lxc-0.8.0~rc1/debian/patches/0064-apparmor-mount-proc 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0064-apparmor-mount-proc 1970-01-01 00:00:00.000000000 +0000 @@ -1,150 +0,0 @@ -Description: mount /proc in container if needed. Otherwise we can't - change its apparmor profile. When aa_change_onexec() is fixed, we - want to use that, and simply call it in start.c before the setup_lxc() - call. - The part of this patch fixing the error paths in do_start() to goto - out_warn_father instead of return -1 should however be kept -Author: Serge Hallyn -Forwarded: no - -Index: lxc-0.8.0~rc1/src/lxc/start.c -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/start.c 2012-04-23 23:03:55.207946270 -0500 -+++ lxc-0.8.0~rc1/src/lxc/start.c 2012-04-23 23:04:04.399946115 -0500 -@@ -511,6 +511,8 @@ - #define AA_DEF_PROFILE "lxc-container-default" - static int apparmor_load(struct lxc_handler *handler) - { -+ int mounted; -+ - if (!apparmor_enabled) { - INFO("apparmor not enabled"); - return 0; -@@ -525,16 +527,14 @@ - return 0; - } - -- /* aa_change_onexec makes more sense since we want to transition when -- * /sbin/init is exec'd. But the transitions doesn't seem to work -- * then (refused). aa_change_onexec will work since we're doing it -- * right before the exec, so we'll just use that for now. -- */ - //if (aa_change_onexec(handler->conf->aa_profile) < 0) { - if (aa_change_profile(handler->conf->aa_profile) < 0) { - SYSERROR("failed to change apparmor profile to %s", handler->conf->aa_profile); - return -1; - } -+ if (handler->conf->umount_proc == 1) -+ umount("/proc"); -+ - INFO("changed apparmor profile to %s", handler->conf->aa_profile); - - return 0; -@@ -571,7 +571,7 @@ - if (handler->conf->need_utmp_watch) { - if (prctl(PR_CAPBSET_DROP, CAP_SYS_BOOT, 0, 0, 0)) { - SYSERROR("failed to remove CAP_SYS_BOOT capability"); -- return -1; -+ goto out_warn_father; - } - DEBUG("Dropped cap_sys_boot\n"); - } -@@ -582,10 +582,10 @@ - goto out_warn_father; - } - -- close(handler->sigfd); -- - if (apparmor_load(handler) < 0) -- return -1; -+ goto out_warn_father; -+ -+ close(handler->sigfd); - - /* after this call, we are in error because this - * ops should not return as it execs */ -Index: lxc-0.8.0~rc1/src/lxc/conf.c -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/conf.c 2012-04-23 23:03:05.015947121 -0500 -+++ lxc-0.8.0~rc1/src/lxc/conf.c 2012-04-23 23:04:04.399946115 -0500 -@@ -1651,6 +1651,7 @@ - } - memset(new, 0, sizeof(*new)); - -+ new->umount_proc = 0; - new->personality = -1; - new->console.path = NULL; - new->console.peer = -1; -@@ -2057,8 +2058,39 @@ - tty_info->nbtty = 0; - } - -+/* -+ * make sure /proc/1 exists, else mount /proc. Return 0 if proc was -+ * already mounted, 1 if we mounted it, -1 if we failed. -+ */ -+static int mount_proc_if_needed(char *rootfs_tgt) -+{ -+ struct stat statbuf; -+ char path[MAXPATHLEN]; -+ int ret; -+ -+ ret = snprintf(path, MAXPATHLEN, "%s/proc/1/cmdline", rootfs_tgt); -+ if (ret < 0 || ret >= MAXPATHLEN) { -+ SYSERROR("proc path name too long"); -+ return -1; -+ } -+ ret = stat(path, &statbuf); -+ INFO("checking if proc mount needed\n"); -+ if (ret == 0) { -+ INFO("no proc mount needed\n"); -+ return 0; -+ } -+ ret = snprintf(path, MAXPATHLEN, "%s/proc", rootfs_tgt); -+ INFO("proc mount needed, mounting to %s\n", path); -+ if (mount("proc", path, "proc", 0, NULL)) -+ return -1; -+ INFO("Mounted /proc for the container\n"); -+ return 1; -+} -+ - int lxc_setup(const char *name, struct lxc_conf *lxc_conf) - { -+ int mounted; -+ - if (setup_utsname(lxc_conf->utsname)) { - ERROR("failed to setup the utsname for '%s'", name); - return -1; -@@ -2099,6 +2131,20 @@ - return -1; - } - -+ /* aa_change_onexec makes more sense since we want to transition when -+ * /sbin/init is exec'd. But the transitions doesn't seem to work -+ * then (refused). aa_change_onexec will work since we're doing it -+ * right before the exec, so we'll just use that for now. -+ * In case the container fstab didn't mount /proc, we mount it. -+ */ -+ mounted = mount_proc_if_needed(lxc_conf->rootfs.mount); -+ if (mounted == -1) { -+ SYSERROR("failed to mount /proc in the container."); -+ return -1; -+ } else if (mounted == 1) { -+ lxc_conf->umount_proc = 1; -+ } -+ - if (setup_pivot_root(&lxc_conf->rootfs)) { - ERROR("failed to set rootfs for '%s'", name); - return -1; -Index: lxc-0.8.0~rc1/src/lxc/conf.h -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/conf.h 2012-04-23 23:02:00.935948206 -0500 -+++ lxc-0.8.0~rc1/src/lxc/conf.h 2012-04-23 23:04:04.399946115 -0500 -@@ -218,6 +218,7 @@ - char *ttydir; - int close_all_fds; - char *aa_profile; -+ int umount_proc; - }; - - /* diff -Nru lxc-0.8.0~rc1/debian/patches/0065-fix-bindhome-relpath lxc-1.0.0~alpha1/debian/patches/0065-fix-bindhome-relpath --- lxc-0.8.0~rc1/debian/patches/0065-fix-bindhome-relpath 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0065-fix-bindhome-relpath 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -Description: lxc-ubuntu: use relative path as target for bind mount - An absolute path will be interpreted as absolute with respect to the - parent's namespace. - This patch will be forwarded. -Author: Serge Hallyn -Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/968371 -Forwarded: yes - -Index: lxc-0.8.0~rc1/templates/lxc-ubuntu.in -=================================================================== ---- lxc-0.8.0~rc1.orig/templates/lxc-ubuntu.in 2012-04-23 23:03:05.015947121 -0500 -+++ lxc-0.8.0~rc1/templates/lxc-ubuntu.in 2012-04-23 23:04:13.823945956 -0500 -@@ -543,7 +543,12 @@ - # bind-mount the user's path into the container's /home - h=`getent passwd $user | cut -d: -f 6` - mkdir -p $rootfs/$h -- echo "$h $h none bind 0 0" >> $path/fstab -+ # use relative path in container -+ h2=${h#/} -+ while [ ${h2:0:1} = "/" ]; do -+ h2=${h2#/} -+ done -+ echo "$h $h2 none bind 0 0" >> $path/fstab - - # Make sure the group exists in container - grp=`echo $pwd | cut -d: -f 4` # group number for $user diff -Nru lxc-0.8.0~rc1/debian/patches/0066-confile-typo lxc-1.0.0~alpha1/debian/patches/0066-confile-typo --- lxc-0.8.0~rc1/debian/patches/0066-confile-typo 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0066-confile-typo 1970-01-01 00:00:00.000000000 +0000 @@ -1,17 +0,0 @@ -Description: fix typo in confile.c (noticed by stgraber) -Author: Serge Hallyn -Forwarded: yes - -Index: lxc-0.8.0~rc1/src/lxc/confile.c -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/confile.c 2012-04-23 23:02:00.935948206 -0500 -+++ lxc-0.8.0~rc1/src/lxc/confile.c 2012-04-23 23:04:23.535945791 -0500 -@@ -945,7 +945,7 @@ - - config = getconfig(key); - if (!config) { -- ERROR("unknow key %s", key); -+ ERROR("unknown key %s", key); - goto out; - } - diff -Nru lxc-0.8.0~rc1/debian/patches/0067-templates-lxc-profile lxc-1.0.0~alpha1/debian/patches/0067-templates-lxc-profile --- lxc-0.8.0~rc1/debian/patches/0067-templates-lxc-profile 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0067-templates-lxc-profile 1970-01-01 00:00:00.000000000 +0000 @@ -1,114 +0,0 @@ -Description: templates: add commented lxc.aa_profile line to configs - Containers by default run in the lxc-container-default profile. Leave - a commented example in every container config we create to show how to - run the container unconfined. -Author: Serge Hallyn -Forwarded: no - -Index: lxc-0.8.0~rc1/templates/lxc-busybox.in -=================================================================== ---- lxc-0.8.0~rc1.orig/templates/lxc-busybox.in 2012-04-23 22:50:32.000000000 -0500 -+++ lxc-0.8.0~rc1/templates/lxc-busybox.in 2012-04-23 23:04:35.371945591 -0500 -@@ -233,6 +233,8 @@ - lxc.tty = 1 - lxc.pts = 1 - lxc.rootfs = $rootfs -+# uncomment the next line to run the container unconfined: -+#lxc.aa_profile = unconfined - EOF - - if [ -d "$rootfs/lib" ]; then -Index: lxc-0.8.0~rc1/templates/lxc-debian.in -=================================================================== ---- lxc-0.8.0~rc1.orig/templates/lxc-debian.in 2012-04-23 23:03:36.000000000 -0500 -+++ lxc-0.8.0~rc1/templates/lxc-debian.in 2012-04-23 23:05:11.659944975 -0500 -@@ -194,6 +194,8 @@ - lxc.pts = 1024 - lxc.rootfs = $rootfs - lxc.utsname = $hostname -+# uncomment the next line to run the container unconfined: -+#lxc.aa_profile = unconfined - lxc.cgroup.devices.deny = a - # /dev/null and zero - lxc.cgroup.devices.allow = c 1:3 rwm -Index: lxc-0.8.0~rc1/templates/lxc-fedora.in -=================================================================== ---- lxc-0.8.0~rc1.orig/templates/lxc-fedora.in 2012-04-23 23:03:05.000000000 -0500 -+++ lxc-0.8.0~rc1/templates/lxc-fedora.in 2012-04-23 23:04:35.375945591 -0500 -@@ -237,6 +237,10 @@ - lxc.pts = 1024 - lxc.rootfs = $rootfs_path - lxc.mount = $config_path/fstab -+ -+# uncomment the next line to run the container unconfined: -+#lxc.aa_profile = unconfined -+ - #cgroups - lxc.cgroup.devices.deny = a - # /dev/null and zero -Index: lxc-0.8.0~rc1/templates/lxc-lenny.in -=================================================================== ---- lxc-0.8.0~rc1.orig/templates/lxc-lenny.in 2012-04-23 23:03:05.000000000 -0500 -+++ lxc-0.8.0~rc1/templates/lxc-lenny.in 2012-04-23 23:04:35.375945591 -0500 -@@ -182,6 +182,9 @@ - lxc.tty = 4 - lxc.pts = 1024 - lxc.rootfs = $rootfs -+# uncomment the next line to run the container unconfined: -+#lxc.aa_profile = unconfined -+ - lxc.cgroup.devices.deny = a - # /dev/null and zero - lxc.cgroup.devices.allow = c 1:3 rwm -Index: lxc-0.8.0~rc1/templates/lxc-opensuse.in -=================================================================== ---- lxc-0.8.0~rc1.orig/templates/lxc-opensuse.in 2012-04-23 23:03:05.000000000 -0500 -+++ lxc-0.8.0~rc1/templates/lxc-opensuse.in 2012-04-23 23:04:35.375945591 -0500 -@@ -261,6 +261,8 @@ - lxc.pts = 1024 - lxc.rootfs = $rootfs - lxc.mount = $path/fstab -+# uncomment the next line to run the container unconfined: -+#lxc.aa_profile = unconfined - - lxc.cgroup.devices.deny = a - # /dev/null and zero -Index: lxc-0.8.0~rc1/templates/lxc-sshd.in -=================================================================== ---- lxc-0.8.0~rc1.orig/templates/lxc-sshd.in 2012-04-23 23:03:05.000000000 -0500 -+++ lxc-0.8.0~rc1/templates/lxc-sshd.in 2012-04-23 23:04:35.375945591 -0500 -@@ -113,6 +113,8 @@ - lxc.utsname = $name - lxc.pts = 1024 - lxc.rootfs = $rootfs -+# uncomment the next line to run the container unconfined: -+#lxc.aa_profile = unconfined - lxc.mount.entry=/dev dev none ro,bind 0 0 - lxc.mount.entry=/lib lib none ro,bind 0 0 - lxc.mount.entry=/bin bin none ro,bind 0 0 -Index: lxc-0.8.0~rc1/templates/lxc-ubuntu-cloud.in -=================================================================== ---- lxc-0.8.0~rc1.orig/templates/lxc-ubuntu-cloud.in 2012-04-23 23:03:05.000000000 -0500 -+++ lxc-0.8.0~rc1/templates/lxc-ubuntu-cloud.in 2012-04-23 23:04:35.375945591 -0500 -@@ -54,6 +54,8 @@ - lxc.mount = $path/fstab - lxc.arch = $arch - lxc.cap.drop = sys_module mac_admin -+# uncomment the next line to run the container unconfined: -+#lxc.aa_profile = unconfined - - lxc.cgroup.devices.deny = a - # Allow any mknod (but not using the node) -Index: lxc-0.8.0~rc1/templates/lxc-ubuntu.in -=================================================================== ---- lxc-0.8.0~rc1.orig/templates/lxc-ubuntu.in 2012-04-23 23:04:13.000000000 -0500 -+++ lxc-0.8.0~rc1/templates/lxc-ubuntu.in 2012-04-23 23:06:28.423943675 -0500 -@@ -333,6 +333,8 @@ - lxc.mount = $path/fstab - lxc.arch = $arch - lxc.cap.drop = sys_module mac_admin mac_override -+# uncomment the next line to run the container unconfined: -+#lxc.aa_profile = unconfined - - lxc.cgroup.devices.deny = a - # Allow any mknod (but not using the node) diff -Nru lxc-0.8.0~rc1/debian/patches/0068-fix-lxc-config-layout lxc-1.0.0~alpha1/debian/patches/0068-fix-lxc-config-layout --- lxc-0.8.0~rc1/debian/patches/0068-fix-lxc-config-layout 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0068-fix-lxc-config-layout 1970-01-01 00:00:00.000000000 +0000 @@ -1,30 +0,0 @@ -Description: Minor lxc config template layout fix -Author: Stéphane Graber -Forwarded: yes - -Index: lxc-0.8.0~rc1/templates/lxc-ubuntu-cloud.in -=================================================================== ---- lxc-0.8.0~rc1.orig/templates/lxc-ubuntu-cloud.in 2012-04-23 23:04:35.375945591 -0500 -+++ lxc-0.8.0~rc1/templates/lxc-ubuntu-cloud.in 2012-04-23 23:06:58.183943173 -0500 -@@ -41,7 +41,7 @@ - nics=`grep -e '^lxc\.network\.type[ \t]*=[ \t]*veth' $path/config | wc -l` - if [ $nics -eq 1 ]; then - grep -q "^lxc.network.hwaddr" $path/config || cat <> $path/config --lxc.network.hwaddr= 00:16:3e:$(openssl rand -hex 3| sed 's/\(..\)/\1:/g; s/.$//') -+lxc.network.hwaddr = 00:16:3e:$(openssl rand -hex 3| sed 's/\(..\)/\1:/g; s/.$//') - EOF - fi - -Index: lxc-0.8.0~rc1/templates/lxc-ubuntu.in -=================================================================== ---- lxc-0.8.0~rc1.orig/templates/lxc-ubuntu.in 2012-04-23 23:06:28.423943675 -0500 -+++ lxc-0.8.0~rc1/templates/lxc-ubuntu.in 2012-04-23 23:06:58.187943173 -0500 -@@ -319,7 +319,7 @@ - nics=`grep -e '^lxc\.network\.type[ \t]*=[ \t]*veth' $path/config | wc -l` - if [ $nics -eq 1 ]; then - grep -q "^lxc.network.hwaddr" $path/config || cat <> $path/config --lxc.network.hwaddr= 00:16:3e:$(openssl rand -hex 3| sed 's/\(..\)/\1:/g; s/.$//') -+lxc.network.hwaddr = 00:16:3e:$(openssl rand -hex 3| sed 's/\(..\)/\1:/g; s/.$//') - EOF - fi - diff -Nru lxc-0.8.0~rc1/debian/patches/0069-ubuntu-cloud-fix lxc-1.0.0~alpha1/debian/patches/0069-ubuntu-cloud-fix --- lxc-0.8.0~rc1/debian/patches/0069-ubuntu-cloud-fix 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0069-ubuntu-cloud-fix 1970-01-01 00:00:00.000000000 +0000 @@ -1,51 +0,0 @@ -Description: Fix handling of user-data in ubuntu-cloud template - This patch will be forwarded, but has not yet been -Author: Ben Howard -Bug-Ubuntu: https://bugs.launchpad.net/bugs/977376 -Forwarded: yes - -Index: lxc-0.8.0~rc1/templates/lxc-ubuntu-cloud.in -=================================================================== ---- lxc-0.8.0~rc1.orig/templates/lxc-ubuntu-cloud.in 2012-04-23 23:06:58.183943173 -0500 -+++ lxc-0.8.0~rc1/templates/lxc-ubuntu-cloud.in 2012-04-23 23:07:05.315943050 -0500 -@@ -119,7 +119,7 @@ - return 0 - } - --options=$(getopt -o a:hp:r:n:Fi:CLS:T:ds: -l arch:,help,path:,release:,name:,flush-cache,hostid:,auth-key:,cloud,no_locales,tarball:,debug,stream: -- "$@") -+options=$(getopt -o a:hp:r:n:Fi:CLS:T:ds: -l arch:,help,path:,release:,name:,flush-cache,hostid:,auth-key:,cloud,no_locales,tarball:,debug,stream:,userdata: -- "$@") - if [ $? -ne 0 ]; then - usage $(basename $0) - exit 1 -@@ -209,6 +209,11 @@ - exit 1 - fi - -+if [ -n "$userdata" -a ! -f "$userdata" ]; then -+ echo "Userdata does not exist" -+ exit 1 -+fi -+ - if [ -z "$path" ]; then - echo "'path' parameter is required" - exit 1 -@@ -324,8 +329,9 @@ - echo "Inserted SSH public key from $auth_key into /home/ubuntu/.ssh/authorized_keys" - fi - -- if [ ! -f $userdata ]; then -- cp $userdata $data_d/user-data -+ if [ -f "$userdata" ]; then -+ echo "Using custom user-data" -+ cp $userdata $seed_d/user-data - else - - if [ -z "$MIRROR" ]; then -@@ -339,7 +345,6 @@ - manage_etc_hosts: localhost - locale: $(/usr/bin/locale | awk -F= '/LANG=/ {print$NF}') - EOF -- - fi - - chroot $rootfs /usr/sbin/usermod -U ubuntu diff -Nru lxc-0.8.0~rc1/debian/patches/0070-templates-rmdir-dev-shm lxc-1.0.0~alpha1/debian/patches/0070-templates-rmdir-dev-shm --- lxc-0.8.0~rc1/debian/patches/0070-templates-rmdir-dev-shm 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0070-templates-rmdir-dev-shm 1970-01-01 00:00:00.000000000 +0000 @@ -1,66 +0,0 @@ -Description: in precise, make /dev/shm a symbolic link to /run/shm - This would be done (though done wrongly) by mounted-dev.conf, but - that doesn't run because we don't mount /dev. -Author: Serge Hallyn -Forwarded: yes -Bug-Ubuntu: https://bugs.launchpad.net/launchpad/+bug/974584 - -Index: lxc-0.8.0~rc1/templates/lxc-ubuntu-cloud.in -=================================================================== ---- lxc-0.8.0~rc1.orig/templates/lxc-ubuntu-cloud.in 2012-04-23 23:07:05.315943050 -0500 -+++ lxc-0.8.0~rc1/templates/lxc-ubuntu-cloud.in 2012-04-23 23:07:12.383942932 -0500 -@@ -31,6 +31,7 @@ - rootfs=$2 - name=$3 - arch=$4 -+ release=$5 - - if [ $arch = "i386" ]; then - arch="i686" -@@ -93,6 +94,16 @@ - sysfs sys sysfs defaults 0 0 - EOF - -+ # rmdir /dev/shm in precise containers. -+ # I'm afraid of doing rm -rf $rootfs/dev/shm, in case it did -+ # get bind mounted to the host's /run/shm. So try to rmdir -+ # it, and in case that fails move it out of the way. -+ if [ $release = "precise" ]; then -+ [ -d "$rootfs/dev/shm" ] && rmdir $rootfs/dev/shm -+ [ -e "$rootfs/dev/shm" ] && mv $rootfs/dev/shm $rootfs/dev/shm.bak -+ ln -s /run/shm $rootfs/dev/shm -+ fi -+ - return 0 - } - -@@ -360,7 +371,7 @@ - - ) 200>/var/lock/subsys/lxc-ubucloud - --copy_configuration $path $rootfs $name $arch -+copy_configuration $path $rootfs $name $arch $release - - echo "Container $name created." - exit 0 -Index: lxc-0.8.0~rc1/templates/lxc-ubuntu.in -=================================================================== ---- lxc-0.8.0~rc1.orig/templates/lxc-ubuntu.in 2012-04-23 23:06:58.187943173 -0500 -+++ lxc-0.8.0~rc1/templates/lxc-ubuntu.in 2012-04-23 23:07:12.383942932 -0500 -@@ -519,6 +519,16 @@ - chroot $rootfs apt-get update - chroot $rootfs apt-get install --force-yes -y --no-install-recommends upstart:${hostarch} mountall:amd64 iproute:amd64 isc-dhcp-client:amd64 - fi -+ -+ # rmdir /dev/shm in precise containers. -+ # I'm afraid of doing rm -rf $rootfs/dev/shm, in case it did -+ # get bind mounted to the host's /run/shm. So try to rmdir -+ # it, and in case that fails move it out of the way. -+ if [ $release = "precise" ]; then -+ [ -d "$rootfs/dev/shm" ] && rmdir $rootfs/dev/shm -+ [ -e "$rootfs/dev/shm" ] && mv $rootfs/dev/shm $rootfs/dev/shm.bak -+ ln -s /run/shm $rootfs/dev/shm -+ fi - } - - do_bindhome() diff -Nru lxc-0.8.0~rc1/debian/patches/0071-ubuntu-cloud-fix-image-extraction lxc-1.0.0~alpha1/debian/patches/0071-ubuntu-cloud-fix-image-extraction --- lxc-0.8.0~rc1/debian/patches/0071-ubuntu-cloud-fix-image-extraction 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0071-ubuntu-cloud-fix-image-extraction 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +0,0 @@ -Description: lxc-ubuntu-cloud: extract the right filenames from tarball -Author: Ben Howard -Forwarded: yes -Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/979996 - -Index: lxc-0.8.0~rc1/templates/lxc-ubuntu-cloud.in -=================================================================== ---- lxc-0.8.0~rc1.orig/templates/lxc-ubuntu-cloud.in 2012-04-23 23:07:12.383942932 -0500 -+++ lxc-0.8.0~rc1/templates/lxc-ubuntu-cloud.in 2012-04-23 23:07:18.723942823 -0500 -@@ -272,7 +272,7 @@ - - xdir=`mktemp -d -p .` - tarname=`basename $url` -- imgname="`basename $tarname .tar.gz`.img" -+ imgname="$release-*-cloudimg-$arch.img" - trap buildcleanup EXIT - if [ $flushcache -eq 1 -o ! -f $cache/$tarname ]; then - rm -f $tarname -@@ -280,7 +280,7 @@ - wget $url || { echo "Couldn't find cloud image $url."; exit 1; } - fi - echo "Creating new cached cloud image rootfs" -- tar zxf $tarname $imgname -+ tar --wildcards -zxf $tarname $imgname - mount -o loop $imgname $xdir - (cd $xdir; tar zcf ../$filename .) - umount $xdir diff -Nru lxc-0.8.0~rc1/debian/patches/0072-lxc-shutdown-help lxc-1.0.0~alpha1/debian/patches/0072-lxc-shutdown-help --- lxc-0.8.0~rc1/debian/patches/0072-lxc-shutdown-help 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0072-lxc-shutdown-help 1970-01-01 00:00:00.000000000 +0000 @@ -1,19 +0,0 @@ -Description: make lxc-shutdown -h work - It was calling non-existent 'help' -Author: Timothy Chen -Forwarded: yes -Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/980905 - -Index: lxc-0.7.5/src/lxc/lxc-shutdown.in -=================================================================== ---- lxc-0.7.5.orig/src/lxc/lxc-shutdown.in 2012-04-16 11:57:48.000000000 -0500 -+++ lxc-0.7.5/src/lxc/lxc-shutdown.in 2012-04-16 11:59:11.158129013 -0500 -@@ -60,7 +60,7 @@ - while true; do - case "$1" in - -h|--help) -- help -+ usage - exit 1 - ;; - -n|--name) diff -Nru lxc-0.8.0~rc1/debian/patches/0073-lxc-destroy-waits-before-destroy lxc-1.0.0~alpha1/debian/patches/0073-lxc-destroy-waits-before-destroy --- lxc-0.8.0~rc1/debian/patches/0073-lxc-destroy-waits-before-destroy 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0073-lxc-destroy-waits-before-destroy 1970-01-01 00:00:00.000000000 +0000 @@ -1,17 +0,0 @@ -Description: Make lxc-destroy wait until the container is stopped -Author: Timothy Chen -Forwarded: yes -Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/980902 - -Index: lxc-0.8.0~rc1/src/lxc/lxc-destroy.in -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/lxc-destroy.in 2012-04-23 22:49:49.931960583 -0500 -+++ lxc-0.8.0~rc1/src/lxc/lxc-destroy.in 2012-04-23 23:07:43.971942396 -0500 -@@ -87,6 +87,7 @@ - if [ $? -eq 0 ]; then - if [ $force -eq 1 ]; then - lxc-stop -n $lxc_name -+ lxc-wait -n $lxc_name -s STOPPED - else - echo "Container $lxc_name is running, aborting the deletion." - exit 1 diff -Nru lxc-0.8.0~rc1/debian/patches/0074-lxc-execute-find-init lxc-1.0.0~alpha1/debian/patches/0074-lxc-execute-find-init --- lxc-0.8.0~rc1/debian/patches/0074-lxc-execute-find-init 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0074-lxc-execute-find-init 1970-01-01 00:00:00.000000000 +0000 @@ -1,81 +0,0 @@ -Description: lxc-init used to be under /usr/lib/lxc. Now it is under - /usr/lib//lxc, but old containers will still have it under - /usr/lib/lxc. So search for a valid lxc-init to run. -Author: Serge Hallyn -Forwarded: yes - -Index: lxc-0.8.0~rc1/src/lxc/execute.c -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/execute.c 2012-03-01 21:42:19.000000000 +0000 -+++ lxc-0.8.0~rc1/src/lxc/execute.c 2012-05-07 19:49:02.636971556 +0000 -@@ -21,10 +21,13 @@ - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -+#include -+#include - #include - #include - #include - -+ - #include "log.h" - #include "start.h" - -@@ -35,12 +38,42 @@ - int quiet; - }; - -+/* historically lxc-init has been under /usr/lib/lxc. Now with -+ * multi-arch it can be under /usr/lib/$ARCH/lxc. Serge thinks -+ * it makes more sense to put it under /sbin. -+ * If /usr/lib/$ARCH/lxc exists and is used, then LXCINITDIR will -+ * point to it. -+ */ -+static char *choose_init(void) -+{ -+ char *retv = malloc(PATH_MAX); -+ int ret; -+ struct stat mystat; -+ if (!retv) -+ return NULL; -+ -+ snprintf(retv, PATH_MAX-1, LXCINITDIR "/lxc/lxc-init"); -+ ret = stat(retv, &mystat); -+ if (ret == 0) -+ return retv; -+ snprintf(retv, PATH_MAX-1, "/usr/lib/lxc/lxc-init"); -+ ret = stat(retv, &mystat); -+ if (ret == 0) -+ return retv; -+ snprintf(retv, PATH_MAX-1, "/sbin/lxc-init"); -+ ret = stat(retv, &mystat); -+ if (ret == 0) -+ return retv; -+ return NULL; -+} -+ - static int execute_start(struct lxc_handler *handler, void* data) - { - int j, i = 0; - struct execute_args *my_args = data; - char **argv; - int argc = 0; -+ char *initpath; - - while (my_args->argv[argc++]); - -@@ -48,7 +81,12 @@ - if (!argv) - return 1; - -- argv[i++] = LXCINITDIR "/lxc-init"; -+ initpath = choose_init(); -+ if (!initpath) { -+ ERROR("Failed to find an lxc-init"); -+ return 1; -+ } -+ argv[i++] = initpath; - if (my_args->quiet) - argv[i++] = "--quiet"; - argv[i++] = "--"; diff -Nru lxc-0.8.0~rc1/debian/patches/0075-lxc-ls-bash lxc-1.0.0~alpha1/debian/patches/0075-lxc-ls-bash --- lxc-0.8.0~rc1/debian/patches/0075-lxc-ls-bash 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0075-lxc-ls-bash 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ -Description: lxc-ls needs bash - It uses bash upstream, patch doesn't need to be forwarded. -Author: Serge Hallyn -Forwarded: no - -Index: lxc-0.8.0~rc1/src/lxc/lxc-ls.in -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/lxc-ls.in 2012-05-07 19:47:40.208968028 +0000 -+++ lxc-0.8.0~rc1/src/lxc/lxc-ls.in 2012-05-07 19:49:05.668968004 +0000 -@@ -1,4 +1,4 @@ --#!/bin/sh -+#!/bin/bash - - localstatedir=@LOCALSTATEDIR@ - lxcpath=@LXCPATH@ -Index: lxc-0.8.0~rc1/src/lxc/lxc-clone.in -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/lxc-clone.in 2012-05-07 21:16:59.157911001 +0000 -+++ lxc-0.8.0~rc1/src/lxc/lxc-clone.in 2012-05-07 21:17:15.309903359 +0000 -@@ -1,4 +1,4 @@ --#!/bin/sh -+#!/bin/bash - - # - # lxc: linux Container library diff -Nru lxc-0.8.0~rc1/debian/patches/0076-fix-sprintfs lxc-1.0.0~alpha1/debian/patches/0076-fix-sprintfs --- lxc-0.8.0~rc1/debian/patches/0076-fix-sprintfs 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0076-fix-sprintfs 1970-01-01 00:00:00.000000000 +0000 @@ -1,543 +0,0 @@ -Description: switch all sprintfs which can overrun to snprintfs - This will be forwarded upstream -Author: Serge Hallyn -Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/988918 -Forwarded: no - -Index: lxc-0.8.0~rc1/src/lxc/commands.c -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/commands.c 2012-05-07 19:47:40.000000000 +0000 -+++ lxc-0.8.0~rc1/src/lxc/commands.c 2012-05-07 19:50:00.728968064 +0000 -@@ -75,8 +75,14 @@ - int sock, ret = -1; - char path[sizeof(((struct sockaddr_un *)0)->sun_path)] = { 0 }; - char *offset = &path[1]; -+ int rc, len; - -- sprintf(offset, abstractname, name); -+ len = sizeof(path)-1; -+ rc = snprintf(offset, len, abstractname, name); -+ if (rc < 0 || rc >= len) { -+ ERROR("Name too long"); -+ return -1; -+ } - - sock = lxc_af_unix_connect(path); - if (sock < 0 && errno == ECONNREFUSED) { -@@ -266,8 +272,14 @@ - int ret, fd; - char path[sizeof(((struct sockaddr_un *)0)->sun_path)] = { 0 }; - char *offset = &path[1]; -+ int rc, len; - -- sprintf(offset, abstractname, name); -+ len = sizeof(path)-1; -+ rc = snprintf(offset, len, abstractname, name); -+ if (rc < 0 || rc >= len) { -+ ERROR("Name too long"); -+ return -1; -+ } - - fd = lxc_af_unix_open(path, SOCK_STREAM, 0); - if (fd < 0) { -Index: lxc-0.8.0~rc1/src/lxc/lxc_monitor.c -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/lxc_monitor.c 2012-05-07 19:47:40.000000000 +0000 -+++ lxc-0.8.0~rc1/src/lxc/lxc_monitor.c 2012-05-07 19:50:00.732967975 +0000 -@@ -60,6 +60,7 @@ - struct lxc_msg msg; - regex_t preg; - int fd; -+ int len, rc; - - if (lxc_arguments_parse(&my_args, argc, argv)) - return -1; -@@ -68,12 +69,18 @@ - my_args.progname, my_args.quiet)) - return -1; - -- regexp = malloc(strlen(my_args.name) + 3); -+ len = strlen(my_args.name) + 3; -+ regexp = malloc(len + 3); - if (!regexp) { - ERROR("failed to allocate memory"); - return -1; - } -- sprintf(regexp, "^%s$", my_args.name); -+ rc = snprintf(regexp, len, "^%s$", my_args.name); -+ if (rc < 0 || rc >= len) { -+ ERROR("Name too long"); -+ free(regexp); -+ return -1; -+ } - - if (regcomp(&preg, regexp, REG_NOSUB|REG_EXTENDED)) { - ERROR("failed to compile the regex '%s'", my_args.name); -Index: lxc-0.8.0~rc1/src/lxc/conf.c -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/conf.c 2012-05-07 19:47:40.000000000 +0000 -+++ lxc-0.8.0~rc1/src/lxc/conf.c 2012-05-07 19:50:00.732967975 +0000 -@@ -241,11 +241,25 @@ - return -1; - } - -- ret = sprintf(buffer, "%s %s %s", script, name, section); -+ ret = snprintf(buffer, size, "%s %s %s", script, name, section); -+ if (ret < 0 || ret >= size) { -+ ERROR("Script name too long"); -+ free(buffer); -+ return -1; -+ } - - va_start(ap, script); -- while ((p = va_arg(ap, char *))) -- ret += sprintf(buffer + ret, " %s", p); -+ while ((p = va_arg(ap, char *))) { -+ int len = size-ret; -+ int rc; -+ rc = snprintf(buffer + ret, len, " %s", p); -+ if (rc < 0 || rc >= len) { -+ free(buffer); -+ ERROR("Script args too long"); -+ return -1; -+ } -+ ret += rc; -+ } - va_end(ap); - - f = popen(buffer, "r"); -@@ -391,7 +405,7 @@ - { - struct dirent dirent, *direntp; - struct loop_info64 loinfo; -- int ret = -1, fd = -1; -+ int ret = -1, fd = -1, rc; - DIR *dir; - char path[MAXPATHLEN]; - -@@ -415,7 +429,10 @@ - if (strncmp(direntp->d_name, "loop", 4)) - continue; - -- sprintf(path, "/dev/%s", direntp->d_name); -+ rc = snprintf(path, MAXPATHLEN, "/dev/%s", direntp->d_name); -+ if (rc < 0 || rc >= MAXPATHLEN) -+ continue; -+ - fd = open(path, O_RDWR); - if (fd < 0) - continue; -@@ -577,7 +594,7 @@ - } - if (ttydir) { - /* create dev/lxc/tty%d" */ -- snprintf(lxcpath, sizeof(lxcpath), "%s/dev/%s/tty%d", -+ ret = snprintf(lxcpath, sizeof(lxcpath), "%s/dev/%s/tty%d", - rootfs->mount, ttydir, i + 1); - if (ret >= sizeof(lxcpath)) { - ERROR("pathname too long for ttys"); -@@ -601,7 +618,11 @@ - continue; - } - -- snprintf(lxcpath, sizeof(lxcpath), "%s/tty%d", ttydir, i+1); -+ ret = snprintf(lxcpath, sizeof(lxcpath), "%s/tty%d", ttydir, i+1); -+ if (ret >= sizeof(lxcpath)) { -+ ERROR("tty pathname too long"); -+ return -1; -+ } - ret = symlink(lxcpath, path); - if (ret) { - SYSERROR("failed to create symlink for tty %d\n", i+1); -@@ -682,12 +703,17 @@ - void *cbparm[2]; - struct lxc_list mountlist, *iterator; - int ok, still_mounted, last_still_mounted; -+ int rc; - - /* read and parse /proc/mounts in old root fs */ - lxc_list_init(&mountlist); - - /* oldrootfs is on the top tree directory now */ -- snprintf(path, sizeof(path), "/%s", oldrootfs); -+ rc = snprintf(path, sizeof(path), "/%s", oldrootfs); -+ if (rc >= sizeof(path)) { -+ ERROR("rootfs name too long"); -+ return -1; -+ } - cbparm[0] = &mountlist; - - cbparm[1] = strdup(path); -@@ -696,7 +722,11 @@ - return -1; - } - -- snprintf(path, sizeof(path), "%s/proc/mounts", oldrootfs); -+ rc = snprintf(path, sizeof(path), "%s/proc/mounts", oldrootfs); -+ if (rc >= sizeof(path)) { -+ ERROR("container proc/mounts name too long"); -+ return -1; -+ } - - ok = lxc_file_for_each_line(path, - setup_rootfs_pivot_root_cb, &cbparm); -@@ -750,6 +780,7 @@ - { - char path[MAXPATHLEN]; - int remove_pivotdir = 0; -+ int rc; - - /* change into new root fs */ - if (chdir(rootfs)) { -@@ -761,7 +792,11 @@ - pivotdir = "mnt"; - - /* compute the full path to pivotdir under rootfs */ -- snprintf(path, sizeof(path), "%s/%s", rootfs, pivotdir); -+ rc = snprintf(path, sizeof(path), "%s/%s", rootfs, pivotdir); -+ if (rc >= sizeof(path)) { -+ ERROR("pivot dir name too long"); -+ return -1; -+ } - - if (access(path, F_OK)) { - -@@ -984,7 +1019,11 @@ - } - - /* create symlink from rootfs/dev/console to 'lxc/console' */ -- snprintf(lxcpath, sizeof(lxcpath), "%s/console", ttydir); -+ ret = snprintf(lxcpath, sizeof(lxcpath), "%s/console", ttydir); -+ if (ret >= sizeof(lxcpath)) { -+ ERROR("lxc/console path too long"); -+ return -1; -+ } - ret = symlink(lxcpath, path); - if (ret) { - SYSERROR("failed to create symlink for console"); -@@ -1178,7 +1217,7 @@ - - skipabs: - -- snprintf(path, MAXPATHLEN, "%s/%s", rootfs->mount, -+ r = snprintf(path, MAXPATHLEN, "%s/%s", rootfs->mount, - aux + offset); - if (r < 0 || r >= MAXPATHLEN) { - WARN("pathnme too long for '%s'", mntent->mnt_dir); -@@ -1209,7 +1248,11 @@ - } - - /* relative to root mount point */ -- snprintf(path, sizeof(path), "%s/%s", rootfs, mntent->mnt_dir); -+ ret = snprintf(path, sizeof(path), "%s/%s", rootfs, mntent->mnt_dir); -+ if (ret >= sizeof(path)) { -+ ERROR("path name too long"); -+ return -1; -+ } - - ret = mount_entry(mntent->mnt_fsname, path, mntent->mnt_type, - mntflags, mntdata); -@@ -1677,7 +1720,11 @@ - if (netdev->priv.veth_attr.pair) - veth1 = netdev->priv.veth_attr.pair; - else { -- snprintf(veth1buf, sizeof(veth1buf), "vethXXXXXX"); -+ err = snprintf(veth1buf, sizeof(veth1buf), "vethXXXXXX"); -+ if (err >= sizeof(veth1buf)) { /* can't *really* happen, but... */ -+ ERROR("veth1 name too long"); -+ return -1; -+ } - veth1 = mktemp(veth1buf); - } - -@@ -1765,7 +1812,9 @@ - return -1; - } - -- snprintf(peerbuf, sizeof(peerbuf), "mcXXXXXX"); -+ err = snprintf(peerbuf, sizeof(peerbuf), "mcXXXXXX"); -+ if (err >= sizeof(peerbuf)) -+ return -1; - - peer = mktemp(peerbuf); - if (!strlen(peer)) { -@@ -1812,7 +1861,11 @@ - return -1; - } - -- snprintf(peer, sizeof(peer), "vlan%d", netdev->priv.vlan_attr.vid); -+ err = snprintf(peer, sizeof(peer), "vlan%d", netdev->priv.vlan_attr.vid); -+ if (err >= sizeof(peer)) { -+ ERROR("peer name too long"); -+ return -1; -+ } - - err = lxc_vlan_create(netdev->link, peer, netdev->priv.vlan_attr.vid); - if (err) { -Index: lxc-0.8.0~rc1/src/lxc/network.c -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/network.c 2012-05-07 19:47:40.000000000 +0000 -+++ lxc-0.8.0~rc1/src/lxc/network.c 2012-05-07 19:50:00.732967975 +0000 -@@ -582,12 +582,15 @@ - static int ip_forward_set(const char *ifname, int family, int flag) - { - char path[MAXPATHLEN]; -+ int rc; - - if (family != AF_INET && family != AF_INET6) - return -EINVAL; - -- snprintf(path, MAXPATHLEN, "/proc/sys/net/%s/conf/%s/forwarding", -+ rc = snprintf(path, MAXPATHLEN, "/proc/sys/net/%s/conf/%s/forwarding", - family == AF_INET?"ipv4":"ipv6" , ifname); -+ if (rc >= MAXPATHLEN) -+ return -E2BIG; - - return proc_sys_net_write(path, flag?"1":"0"); - } -@@ -605,13 +608,16 @@ - static int neigh_proxy_set(const char *ifname, int family, int flag) - { - char path[MAXPATHLEN]; -+ int ret; - - if (family != AF_INET && family != AF_INET6) - return -EINVAL; - -- sprintf(path, "/proc/sys/net/%s/conf/%s/%s", -+ ret = snprintf(path, MAXPATHLEN, "/proc/sys/net/%s/conf/%s/%s", - family == AF_INET?"ipv4":"ipv6" , ifname, - family == AF_INET?"proxy_arp":"proxy_ndp"); -+ if (ret < 0 || ret >= MAXPATHLEN) -+ return -E2BIG; - - return proc_sys_net_write(path, flag?"1":"0"); - } -Index: lxc-0.8.0~rc1/src/lxc/cgroup.c -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/cgroup.c 2012-05-07 19:47:40.000000000 +0000 -+++ lxc-0.8.0~rc1/src/lxc/cgroup.c 2012-05-07 19:50:00.732967975 +0000 -@@ -201,8 +201,13 @@ - static int cgroup_rename_nsgroup(const char *mnt, const char *name, pid_t pid) - { - char oldname[MAXPATHLEN]; -+ int ret; - -- snprintf(oldname, MAXPATHLEN, "%s/%d", mnt, pid); -+ ret = snprintf(oldname, MAXPATHLEN, "%s/%d", mnt, pid); -+ if (ret < 0 || ret >= MAXPATHLEN) { -+ ERROR("Name too long"); -+ return -1; -+ } - - if (rename(oldname, name)) { - SYSERROR("failed to rename cgroup %s->%s", oldname, name); -@@ -240,8 +245,13 @@ - FILE *f; - char tasks[MAXPATHLEN]; - int ret = 0; -+ int rc; - -- snprintf(tasks, MAXPATHLEN, "%s/tasks", path); -+ rc = snprintf(tasks, MAXPATHLEN, "%s/tasks", path); -+ if (rc < 0 || rc >= MAXPATHLEN) { -+ ERROR("pathname too long"); -+ return -1; -+ } - - f = fopen(tasks, "w"); - if (!f) { -@@ -435,6 +445,7 @@ - - while (!readdir_r(dir, &dirent, &direntp)) { - struct stat mystat; -+ int rc; - - if (!direntp) - break; -@@ -443,7 +454,11 @@ - !strcmp(direntp->d_name, "..")) - continue; - -- snprintf(pathname, MAXPATHLEN, "%s/%s", dirname, direntp->d_name); -+ rc = snprintf(pathname, MAXPATHLEN, "%s/%s", dirname, direntp->d_name); -+ if (rc < 0 || rc >= MAXPATHLEN) { -+ ERROR("pathname too long"); -+ continue; -+ } - ret = stat(pathname, &mystat); - if (ret) - continue; -@@ -464,9 +479,14 @@ - { - char cgname[MAXPATHLEN], initcgroup[MAXPATHLEN]; - char *cgmnt = mntent->mnt_dir; -+ int rc; - -- snprintf(cgname, MAXPATHLEN, "%s%s/lxc/%s", cgmnt, -+ rc = snprintf(cgname, MAXPATHLEN, "%s%s/lxc/%s", cgmnt, - get_init_cgroup(NULL, mntent, initcgroup), name); -+ if (rc < 0 || rc >= MAXPATHLEN) { -+ ERROR("name too long"); -+ return -1; -+ } - DEBUG("destroying %s\n", cgname); - if (recursive_rmdir(cgname)) { - SYSERROR("failed to remove cgroup '%s'", cgname); -@@ -517,11 +537,16 @@ - { - static char buf[MAXPATHLEN]; - static char retbuf[MAXPATHLEN]; -+ int rc; - - /* what lxc_cgroup_set calls subsystem is actually the filename, i.e. - 'devices.allow'. So for our purposee we trim it */ - if (subsystem) { -- snprintf(retbuf, MAXPATHLEN, "%s", subsystem); -+ rc = snprintf(retbuf, MAXPATHLEN, "%s", subsystem); -+ if (rc < 0 || rc >= MAXPATHLEN) { -+ ERROR("subsystem name too long"); -+ return -1; -+ } - char *s = index(retbuf, '.'); - if (s) - *s = '\0'; -@@ -532,7 +557,11 @@ - return -1; - } - -- snprintf(retbuf, MAXPATHLEN, "%s/%s", buf, name); -+ rc = snprintf(retbuf, MAXPATHLEN, "%s/%s", buf, name); -+ if (rc < 0 || rc >= MAXPATHLEN) { -+ ERROR("name too long"); -+ return -1; -+ } - - DEBUG("%s: returning %s for subsystem %s", __func__, retbuf, subsystem); - -@@ -545,12 +574,17 @@ - int fd, ret; - char *dirpath; - char path[MAXPATHLEN]; -+ int rc; - - ret = lxc_cgroup_path_get(&dirpath, filename, name); - if (ret) - return -1; - -- snprintf(path, MAXPATHLEN, "%s/%s", dirpath, filename); -+ rc = snprintf(path, MAXPATHLEN, "%s/%s", dirpath, filename); -+ if (rc < 0 || rc >= MAXPATHLEN) { -+ ERROR("pathname too long"); -+ return -1; -+ } - - fd = open(path, O_WRONLY); - if (fd < 0) { -@@ -576,12 +610,17 @@ - int fd, ret = -1; - char *dirpath; - char path[MAXPATHLEN]; -+ int rc; - - ret = lxc_cgroup_path_get(&dirpath, filename, name); - if (ret) - return -1; - -- snprintf(path, MAXPATHLEN, "%s/%s", dirpath, filename); -+ rc = snprintf(path, MAXPATHLEN, "%s/%s", dirpath, filename); -+ if (rc < 0 || rc >= MAXPATHLEN) { -+ ERROR("pathname too long"); -+ return -1; -+ } - - fd = open(path, O_RDONLY); - if (fd < 0) { -@@ -603,12 +642,17 @@ - char path[MAXPATHLEN]; - int pid, ret, count = 0; - FILE *file; -+ int rc; - - ret = lxc_cgroup_path_get(&dpath, NULL, name); - if (ret) - return -1; - -- snprintf(path, MAXPATHLEN, "%s/tasks", dpath); -+ rc = snprintf(path, MAXPATHLEN, "%s/tasks", dpath); -+ if (rc < 0 || rc >= MAXPATHLEN) { -+ ERROR("pathname too long"); -+ return -1; -+ } - - file = fopen(path, "r"); - if (!file) { -Index: lxc-0.8.0~rc1/src/lxc/state.c -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/state.c 2012-05-07 19:47:40.000000000 +0000 -+++ lxc-0.8.0~rc1/src/lxc/state.c 2012-05-07 19:50:00.732967975 +0000 -@@ -75,7 +75,9 @@ - if (err) - return -1; - -- snprintf(freezer, MAXPATHLEN, "%s/freezer.state", nsgroup); -+ err = snprintf(freezer, MAXPATHLEN, "%s/freezer.state", nsgroup); -+ if (err < 0 || err >= MAXPATHLEN) -+ return -1; - - file = fopen(freezer, "r"); - if (!file) -Index: lxc-0.8.0~rc1/src/lxc/freezer.c -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/freezer.c 2012-05-07 19:47:40.000000000 +0000 -+++ lxc-0.8.0~rc1/src/lxc/freezer.c 2012-05-07 19:50:00.736967976 +0000 -@@ -49,7 +49,11 @@ - if (ret) - return -1; - -- snprintf(freezer, MAXPATHLEN, "%s/freezer.state", nsgroup); -+ ret = snprintf(freezer, MAXPATHLEN, "%s/freezer.state", nsgroup); -+ if (ret >= MAXPATHLEN) { -+ ERROR("freezer.state name too long"); -+ return -1; -+ } - - fd = open(freezer, O_RDWR); - if (fd < 0) { -Index: lxc-0.8.0~rc1/src/lxc/execute.c -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/execute.c 2012-05-07 19:49:02.000000000 +0000 -+++ lxc-0.8.0~rc1/src/lxc/execute.c 2012-05-07 19:51:35.164968565 +0000 -@@ -52,15 +52,29 @@ - if (!retv) - return NULL; - -- snprintf(retv, PATH_MAX-1, LXCINITDIR "/lxc/lxc-init"); -+ ret = snprintf(retv, PATH_MAX, LXCINITDIR "/lxc/lxc-init"); -+ if (ret < 0 || ret >= PATH_MAX) { -+ ERROR("pathname too long"); -+ return NULL; -+ } -+ - ret = stat(retv, &mystat); - if (ret == 0) - return retv; -- snprintf(retv, PATH_MAX-1, "/usr/lib/lxc/lxc-init"); -+ -+ ret = snprintf(retv, PATH_MAX, "/usr/lib/lxc/lxc-init"); -+ if (ret < 0 || ret >= PATH_MAX) { -+ ERROR("pathname too long"); -+ return NULL; -+ } - ret = stat(retv, &mystat); - if (ret == 0) - return retv; -- snprintf(retv, PATH_MAX-1, "/sbin/lxc-init"); -+ ret = snprintf(retv, PATH_MAX, "/sbin/lxc-init"); -+ if (ret < 0 || ret >= PATH_MAX) { -+ ERROR("pathname too long"); -+ return NULL; -+ } - ret = stat(retv, &mystat); - if (ret == 0) - return retv; diff -Nru lxc-0.8.0~rc1/debian/patches/0077-execute-without-rootfs lxc-1.0.0~alpha1/debian/patches/0077-execute-without-rootfs --- lxc-0.8.0~rc1/debian/patches/0077-execute-without-rootfs 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0077-execute-without-rootfs 1970-01-01 00:00:00.000000000 +0000 @@ -1,40 +0,0 @@ -Description: Make lxc-execute without rootfs work. - That means, don't try to pin a null rootfs, and don't try to mount /proc - since /var/lib/lxc/root/proc doesn't exist to be mounted onto. - The apparmor patches are not yet upstream, so this patch will not go - upstream by itself. -Author: Serge Hallyn -Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/981955 -Forwarded: no - -Index: lxc-0.8.0~rc1/src/lxc/conf.c -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/conf.c 2012-04-26 15:10:50.059357146 -0500 -+++ lxc-0.8.0~rc1/src/lxc/conf.c 2012-04-26 15:18:22.567335951 -0500 -@@ -485,6 +485,9 @@ - struct stat s; - int ret, fd; - -+ if (rootfs == NULL || strlen(rootfs) == 0) -+ return 0; -+ - if (!realpath(rootfs, absrootfs)) { - SYSERROR("failed to get real path for '%s'", rootfs); - return -1; -@@ -2189,8 +2192,15 @@ - * then (refused). aa_change_onexec will work since we're doing it - * right before the exec, so we'll just use that for now. - * In case the container fstab didn't mount /proc, we mount it. -+ * -+ * But if there is no rootfs, then don't try to mount it. - */ -- mounted = mount_proc_if_needed(lxc_conf->rootfs.mount); -+ INFO("rootfs path is .%s., mount is .%s.", lxc_conf->rootfs.path, -+ lxc_conf->rootfs.mount); -+ if (lxc_conf->rootfs.path == NULL || strlen(lxc_conf->rootfs.path) == 0) -+ mounted = 0; -+ else -+ mounted = mount_proc_if_needed(lxc_conf->rootfs.mount); - if (mounted == -1) { - SYSERROR("failed to mount /proc in the container."); - return -1; diff -Nru lxc-0.8.0~rc1/debian/patches/0078-lxc-clone-quote-line lxc-1.0.0~alpha1/debian/patches/0078-lxc-clone-quote-line --- lxc-0.8.0~rc1/debian/patches/0078-lxc-clone-quote-line 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0078-lxc-clone-quote-line 1970-01-01 00:00:00.000000000 +0000 @@ -1,18 +0,0 @@ -Description: put $line in quotes to avoid its expansion -Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/993515 -Author: Serge Hallyn -Forwarded: yes - -Index: lxc-0.8.0~rc1/src/lxc/lxc-clone.in -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/lxc-clone.in 2012-05-02 15:22:07.000000000 -0500 -+++ lxc-0.8.0~rc1/src/lxc/lxc-clone.in 2012-05-02 15:23:06.469666635 -0500 -@@ -275,7 +275,7 @@ - if [ "${line:0:18}" = "lxc.network.hwaddr" ]; then - echo "lxc.network.hwaddr= 00:16:3e:$(openssl rand -hex 3| sed 's/\(..\)/\1:/g; s/.$//')" - else -- echo $line -+ echo "$line" - fi - done - ) < ${c}.old > ${c} diff -Nru lxc-0.8.0~rc1/debian/patches/0079-quantal-support lxc-1.0.0~alpha1/debian/patches/0079-quantal-support --- lxc-0.8.0~rc1/debian/patches/0079-quantal-support 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0079-quantal-support 1970-01-01 00:00:00.000000000 +0000 @@ -1,99 +0,0 @@ -Description: Update Ubuntu templates for quantal -Origin: vendor -Forwarded: no - ---- lxc-0.8.0~rc1.orig/templates/lxc-ubuntu-cloud.in -+++ lxc-0.8.0~rc1/templates/lxc-ubuntu-cloud.in -@@ -94,11 +94,11 @@ proc proc proc nod - sysfs sys sysfs defaults 0 0 - EOF - -- # rmdir /dev/shm in precise containers. -+ # rmdir /dev/shm in precise and quantal containers. - # I'm afraid of doing rm -rf $rootfs/dev/shm, in case it did - # get bind mounted to the host's /run/shm. So try to rmdir - # it, and in case that fails move it out of the way. -- if [ $release = "precise" ]; then -+ if [ $release = "precise" ] || [ $release = "quantal" ]; then - [ -d "$rootfs/dev/shm" ] && rmdir $rootfs/dev/shm - [ -e "$rootfs/dev/shm" ] && mv $rootfs/dev/shm $rootfs/dev/shm.bak - ln -s /run/shm $rootfs/dev/shm -@@ -141,7 +141,7 @@ release=lucid - if [ -f /etc/lsb-release ]; then - . /etc/lsb-release - case "$DISTRIB_CODENAME" in -- lucid|maverick|natty|oneiric|precise) -+ lucid|maverick|natty|oneiric|precise|quantal) - release=$DISTRIB_CODENAME - ;; - esac -@@ -162,7 +162,7 @@ else - arch="amd64" - elif [ "$arch" = "armv7l" ]; then - # note: arm images don't exist before oneiric; are called armhf in -- # precise; and are not supported by the query, so we don't actually -+ # precise and later; and are not supported by the query, so we don't actually - # support them yet (see check later on). When Query2 is available, - # we'll use that to enable arm images. - arch="armel" ---- lxc-0.8.0~rc1.orig/templates/lxc-ubuntu.in -+++ lxc-0.8.0~rc1/templates/lxc-ubuntu.in -@@ -54,7 +54,7 @@ EOF - 127.0.0.1 localhost $hostname - EOF - -- if [ "$release" != "precise" ]; then -+ if [ "$release" != "precise" ] && [ "$release" != "quantal" ]; then - # suppress log level output for udev - sed -i "s/=\"err\"/=0/" $rootfs/etc/udev/udev.conf - -@@ -78,7 +78,7 @@ finalize_user() - { - user=$1 - -- if [ "$release" = "precise" ]; then -+ if [ "$release" = "precise" ] || [ "$release" = "quantal" ]; then - groups="sudo" - else - groups="sudo admin" -@@ -310,7 +310,7 @@ copy_configuration() - fi - - ttydir="" -- if [ $release = "precise" ]; then -+ if [ $release = "precise" ] || [ $release = "quantal" ]; then - ttydir=" lxc" - fi - -@@ -520,11 +520,11 @@ post_process() - chroot $rootfs apt-get install --force-yes -y --no-install-recommends upstart:${hostarch} mountall:amd64 iproute:amd64 isc-dhcp-client:amd64 - fi - -- # rmdir /dev/shm in precise containers. -+ # rmdir /dev/shm in precise and quantal containers. - # I'm afraid of doing rm -rf $rootfs/dev/shm, in case it did - # get bind mounted to the host's /run/shm. So try to rmdir - # it, and in case that fails move it out of the way. -- if [ $release = "precise" ]; then -+ if [ $release = "precise" ] || [ $release = "quantal" ]; then - [ -d "$rootfs/dev/shm" ] && rmdir $rootfs/dev/shm - [ -e "$rootfs/dev/shm" ] && mv $rootfs/dev/shm $rootfs/dev/shm.bak - ln -s /run/shm $rootfs/dev/shm -@@ -573,7 +573,7 @@ usage() - cat <] [--trim] [-d|--debug] - [-F | --flush-cache] [-r|--release ] [ -S | --auth-key ] --release: lucid | maverick | natty | oneiric | precise -+release: lucid | maverick | natty | oneiric | precise | quantal - trim: make a minimal (faster, but not upgrade-safe) container - bindhome: bind 's home into the container - The ubuntu user will not be created, and will have -@@ -595,7 +595,7 @@ release=lucid - if [ -f /etc/lsb-release ]; then - . /etc/lsb-release - case "$DISTRIB_CODENAME" in -- lucid|maverick|natty|oneiric|precise) -+ lucid|maverick|natty|oneiric|precise|quantal) - release=$DISTRIB_CODENAME - ;; - esac diff -Nru lxc-0.8.0~rc1/debian/patches/0080-drop-maverick lxc-1.0.0~alpha1/debian/patches/0080-drop-maverick --- lxc-0.8.0~rc1/debian/patches/0080-drop-maverick 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0080-drop-maverick 1970-01-01 00:00:00.000000000 +0000 @@ -1,59 +0,0 @@ -Description: Remove maverick as it's end-of-life -Origin: vendor -Forwarded: no - ---- lxc-0.8.0~rc1.orig/templates/lxc-ubuntu-cloud.in -+++ lxc-0.8.0~rc1/templates/lxc-ubuntu-cloud.in -@@ -141,7 +141,7 @@ release=lucid - if [ -f /etc/lsb-release ]; then - . /etc/lsb-release - case "$DISTRIB_CODENAME" in -- lucid|maverick|natty|oneiric|precise|quantal) -+ lucid|natty|oneiric|precise|quantal) - release=$DISTRIB_CODENAME - ;; - esac ---- lxc-0.8.0~rc1.orig/templates/lxc-ubuntu.in -+++ lxc-0.8.0~rc1/templates/lxc-ubuntu.in -@@ -152,8 +152,6 @@ download_ubuntu() - - if [ $release = "lucid" ]; then - packages=dialog,apt,apt-utils,resolvconf,iproute,inetutils-ping,vim,dhcp3-client,ssh,lsb-release,gnupg -- elif [ $release = "maverick" ]; then -- packages=dialog,apt,apt-utils,resolvconf,iproute,inetutils-ping,vim,dhcp3-client,ssh,lsb-release,gnupg,netbase - elif [ $release = "natty" ]; then - packages=dialog,apt,apt-utils,resolvconf,iproute,inetutils-ping,vim,isc-dhcp-client,isc-dhcp-common,ssh,lsb-release,gnupg,netbase - else -@@ -481,11 +479,11 @@ post_process() - - if [ $trim_container -eq 1 ]; then - trim $rootfs $release -- elif [ $release = "lucid" -o $release = "maverick" -o $release = "natty" \ -+ elif [ $release = "lucid" -o $release = "natty" \ - -o $release = "oneiric" ]; then -- # for lucid and maverick, if not trimming, then add the ubuntu-virt -+ # for lucid, if not trimming, then add the ubuntu-virt - # ppa and install lxcguest -- if [ $release = "lucid" -o $release = "maverick" ]; then -+ if [ $release = "lucid" ]; then - chroot $rootfs apt-get install --force-yes -y python-software-properties - chroot $rootfs add-apt-repository ppa:ubuntu-virt/ppa - fi -@@ -573,7 +571,7 @@ usage() - cat <] [--trim] [-d|--debug] - [-F | --flush-cache] [-r|--release ] [ -S | --auth-key ] --release: lucid | maverick | natty | oneiric | precise | quantal -+release: lucid | natty | oneiric | precise | quantal - trim: make a minimal (faster, but not upgrade-safe) container - bindhome: bind 's home into the container - The ubuntu user will not be created, and will have -@@ -595,7 +593,7 @@ release=lucid - if [ -f /etc/lsb-release ]; then - . /etc/lsb-release - case "$DISTRIB_CODENAME" in -- lucid|maverick|natty|oneiric|precise|quantal) -+ lucid|natty|oneiric|precise|quantal) - release=$DISTRIB_CODENAME - ;; - esac diff -Nru lxc-0.8.0~rc1/debian/patches/0081-fix-multiarch-install lxc-1.0.0~alpha1/debian/patches/0081-fix-multiarch-install --- lxc-0.8.0~rc1/debian/patches/0081-fix-multiarch-install 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0081-fix-multiarch-install 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -Description: When installing a non-native architecture, the template - installs a bunch of packages of the native architecture to work around - existing limitations of qemu-user-static, mostly related to netlink. - . - The current code would install upstart of the host architecture but - force the amd64 version of the others. This was just a mistake done - while testing/developping the code. Fixing now to always install - the native architecture version of all of them. -Author: Stéphane Graber -Origin: vendor -Forwarded: no - ---- lxc-0.8.0~rc1.orig/templates/lxc-ubuntu.in -+++ lxc-0.8.0~rc1/templates/lxc-ubuntu.in -@@ -515,7 +515,7 @@ post_process() - - # Finally update the lists and install upstart using the host architecture - chroot $rootfs apt-get update -- chroot $rootfs apt-get install --force-yes -y --no-install-recommends upstart:${hostarch} mountall:amd64 iproute:amd64 isc-dhcp-client:amd64 -+ chroot $rootfs apt-get install --force-yes -y --no-install-recommends upstart:${hostarch} mountall:${hostarch} iproute:${hostarch} isc-dhcp-client:${hostarch} - fi - - # rmdir /dev/shm in precise and quantal containers. diff -Nru lxc-0.8.0~rc1/debian/patches/0082-umount-old-proc lxc-1.0.0~alpha1/debian/patches/0082-umount-old-proc --- lxc-0.8.0~rc1/debian/patches/0082-umount-old-proc 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0082-umount-old-proc 1970-01-01 00:00:00.000000000 +0000 @@ -1,174 +0,0 @@ -Description: umount proc if it isn't ours - If /proc is already mounted, make sure that /proc/self points to 1, - since we are container init. Otherwise, assume proc is an old one, and - umount it and remount our own. If we keep the old proc mounted, - apparmor transitions will by tried for wrong task and fail. - Also move the check for whether apparmor is enabled to inside __lxc_start() - so that lxc-execute can use it. - This won't be forwarded as it's part of the apparmorization which is - not yet upstream. -Author: Serge Hallyn -Forwarded: no -Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/993706 - -Index: lxc-0.8.0~rc1/src/lxc/conf.c -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/conf.c 2012-05-07 21:35:36.758139051 +0000 -+++ lxc-0.8.0~rc1/src/lxc/conf.c 2012-05-07 21:40:34.470135873 +0000 -@@ -2115,28 +2115,38 @@ - } - - /* -- * make sure /proc/1 exists, else mount /proc. Return 0 if proc was -+ * make sure /proc/self exists, and points to '1', since we are the -+ * container init. -+ * Else mount /proc. Return 0 if proc was - * already mounted, 1 if we mounted it, -1 if we failed. - */ --static int mount_proc_if_needed(char *rootfs_tgt) -+static int mount_proc_if_needed(char *root_src, char *rootfs_tgt) - { -- struct stat statbuf; - char path[MAXPATHLEN]; -- int ret; -+ char link[20]; -+ int linklen, ret; - -- ret = snprintf(path, MAXPATHLEN, "%s/proc/1/cmdline", rootfs_tgt); -+ ret = snprintf(path, MAXPATHLEN, "%s/proc/self", root_src ? rootfs_tgt : ""); - if (ret < 0 || ret >= MAXPATHLEN) { - SYSERROR("proc path name too long"); - return -1; - } -- ret = stat(path, &statbuf); -- INFO("checking if proc mount needed\n"); -- if (ret == 0) { -- INFO("no proc mount needed\n"); -- return 0; -+ memset(link, 0, 20); -+ linklen = readlink(path, link, 20); -+ INFO("I am %d, /proc/self points to %s\n", getpid(), link); -+ ret = snprintf(path, MAXPATHLEN, "%s/proc", root_src ? rootfs_tgt : ""); -+ if (linklen < 0) /* /proc not mounted */ -+ goto domount; -+ /* can't be longer than rootfs/proc/1 */ -+ if (strncmp(link, "1", linklen) != 0) { -+ /* wrong /procs mounted */ -+ umount2(path, MNT_DETACH); /* ignore failure */ -+ goto domount; - } -- ret = snprintf(path, MAXPATHLEN, "%s/proc", rootfs_tgt); -- INFO("proc mount needed, mounting to %s\n", path); -+ /* the right proc is already mounted */ -+ return 0; -+ -+domount: - if (mount("proc", path, "proc", 0, NULL)) - return -1; - INFO("Mounted /proc for the container\n"); -@@ -2192,15 +2202,11 @@ - * then (refused). aa_change_onexec will work since we're doing it - * right before the exec, so we'll just use that for now. - * In case the container fstab didn't mount /proc, we mount it. -- * -- * But if there is no rootfs, then don't try to mount it. - */ - INFO("rootfs path is .%s., mount is .%s.", lxc_conf->rootfs.path, - lxc_conf->rootfs.mount); -- if (lxc_conf->rootfs.path == NULL || strlen(lxc_conf->rootfs.path) == 0) -- mounted = 0; -- else -- mounted = mount_proc_if_needed(lxc_conf->rootfs.mount); -+ -+ mounted = mount_proc_if_needed(lxc_conf->rootfs.path, lxc_conf->rootfs.mount); - if (mounted == -1) { - SYSERROR("failed to mount /proc in the container."); - return -1; -Index: lxc-0.8.0~rc1/src/lxc/start.c -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/start.c 2012-05-07 21:35:36.646139051 +0000 -+++ lxc-0.8.0~rc1/src/lxc/start.c 2012-05-07 21:42:12.506139286 +0000 -@@ -511,8 +511,6 @@ - #define AA_DEF_PROFILE "lxc-container-default" - static int apparmor_load(struct lxc_handler *handler) - { -- int mounted; -- - if (!apparmor_enabled) { - INFO("apparmor not enabled"); - return 0; -@@ -700,6 +698,28 @@ - return -1; - } - -+#define AA_MOUNT_RESTR "/sys/kernel/security/apparmor/features/mount/mask" -+#define AA_ENABLED_FILE "/sys/module/apparmor/parameters/enabled" -+static int check_apparmor_enabled(void) -+{ -+ struct stat statbuf; -+ FILE *fin; -+ char e; -+ int ret; -+ -+ ret = stat(AA_MOUNT_RESTR, &statbuf); -+ if (ret != 0) -+ return 0; -+ fin = fopen(AA_ENABLED_FILE, "r"); -+ if (!fin) -+ return 0; -+ ret = fscanf(fin, "%c", &e); -+ fclose(fin); -+ if (ret == 1 && e == 'Y') -+ return 1; -+ return 0; -+} -+ - int __lxc_start(const char *name, struct lxc_conf *conf, - struct lxc_operations* ops, void *data) - { -@@ -707,6 +727,8 @@ - int err = -1; - int status; - -+ apparmor_enabled = check_apparmor_enabled(); -+ - handler = lxc_init(name, conf); - if (!handler) { - ERROR("failed to initialize the container"); -@@ -798,36 +820,12 @@ - .post_start = post_start - }; - --#define AA_MOUNT_RESTR "/sys/kernel/security/apparmor/features/mount/mask" --#define AA_ENABLED_FILE "/sys/module/apparmor/parameters/enabled" --static int check_apparmor_enabled(void) --{ -- struct stat statbuf; -- FILE *fin; -- char e; -- int ret; -- -- ret = stat(AA_MOUNT_RESTR, &statbuf); -- if (ret != 0) -- return 0; -- fin = fopen(AA_ENABLED_FILE, "r"); -- if (!fin) -- return 0; -- fscanf(fin, "%c", &e); -- fclose(fin); -- if (e == 'Y') -- return 1; -- return 0; --} -- - int lxc_start(const char *name, char *const argv[], struct lxc_conf *conf) - { - struct start_args start_arg = { - .argv = argv, - }; - -- apparmor_enabled = check_apparmor_enabled(); -- - if (lxc_check_inherited(conf, -1)) - return -1; - diff -Nru lxc-0.8.0~rc1/debian/patches/0083-ubuntu-simplify-template lxc-1.0.0~alpha1/debian/patches/0083-ubuntu-simplify-template --- lxc-0.8.0~rc1/debian/patches/0083-ubuntu-simplify-template 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0083-ubuntu-simplify-template 1970-01-01 00:00:00.000000000 +0000 @@ -1,335 +0,0 @@ -Description: Simplify the Ubuntu template a bit - - Update list of extra packages for debootstrap to only include vim - and ssh. The others were only relevant when we were still using the - minbase variant. (LP: #996839) - - Drop any hardcoded Ubuntu version check and replace by feature - checks instead. - - Format lxc-ubuntu to consistently use 4-spaces indent instead of - mixed spaces/tabs. - - Update default /etc/network/interfaces to include the header. - - Update default /etc/hosts to match that of a regular Ubuntu system. - - Drop support for end-of-life releases (gutsy on sparc). - - Make sure /etc/resolv.conf is valid before running any apt command. - - Update template help message for release and arch parameters. - - Switch default Ubuntu version from lucid to precise. -Author: Stéphane Graber - -Origin: vendor -Forwarded: no - ---- lxc-0.8.0~rc1.orig/templates/lxc-ubuntu.in -+++ lxc-0.8.0~rc1/templates/lxc-ubuntu.in -@@ -38,6 +38,10 @@ configure_ubuntu() - - # configure the network using the dhcp - cat < $rootfs/etc/network/interfaces -+# This file describes the network interfaces available on your system -+# and how to activate them. For more information, see interfaces(5). -+ -+# The loopback network interface - auto lo - iface lo inet loopback - -@@ -51,10 +55,18 @@ $hostname - EOF - # set minimal hosts - cat < $rootfs/etc/hosts --127.0.0.1 localhost $hostname -+127.0.0.1 localhost -+127.0.1.1 $hostname -+ -+# The following lines are desirable for IPv6 capable hosts -+::1 ip6-localhost ip6-loopback -+fe00::0 ip6-localnet -+ff00::0 ip6-mcastprefix -+ff02::1 ip6-allnodes -+ff02::2 ip6-allrouters - EOF - -- if [ "$release" != "precise" ] && [ "$release" != "quantal" ]; then -+ if [ ! -f $rootfs/etc/init/container-detect.conf ]; then - # suppress log level output for udev - sed -i "s/=\"err\"/=0/" $rootfs/etc/udev/udev.conf - -@@ -78,7 +90,9 @@ finalize_user() - { - user=$1 - -- if [ "$release" = "precise" ] || [ "$release" = "quantal" ]; then -+ sudo_version=$(chroot $rootfs dpkg-query -W -f='${Version}' sudo) -+ -+ if chroot $rootfs dpkg --compare-versions $sudo_version gt "1.8.3p1-1"; then - groups="sudo" - else - groups="sudo admin" -@@ -90,13 +104,14 @@ finalize_user() - done - - if [ -n "$auth_key" -a -f "$auth_key" ]; then -- u_path="/home/${user}/.ssh" -- root_u_path="$rootfs/$u_path" -- mkdir -p $root_u_path -- cp $auth_key "$root_u_path/authorized_keys" -- chroot $rootfs chown -R ${user}: "$u_path" -+ u_path="/home/${user}/.ssh" -+ root_u_path="$rootfs/$u_path" - -- echo "Inserted SSH public key from $auth_key into /home/${user}/.ssh/authorized_keys" -+ mkdir -p $root_u_path -+ cp $auth_key "$root_u_path/authorized_keys" -+ chroot $rootfs chown -R ${user}: "$u_path" -+ -+ echo "Inserted SSH public key from $auth_key into /home/${user}/.ssh/authorized_keys" - fi - return 0 - } -@@ -112,18 +127,6 @@ write_sourceslist() - MIRROR=${MIRROR:-http://archive.ubuntu.com/ubuntu} - SECURITY_MIRROR=${SECURITY_MIRROR:-http://security.ubuntu.com/ubuntu} - ;; -- sparc) -- case $SUITE in -- gutsy) -- MIRROR=${MIRROR:-http://archive.ubuntu.com/ubuntu} -- SECURITY_MIRROR=${SECURITY_MIRRORMIRROR:-http://security.ubuntu.com/ubuntu} -- ;; -- *) -- MIRROR=${MIRROR:-http://ports.ubuntu.com/ubuntu-ports} -- SECURITY_MIRROR=${SECURITY_MIRROR:-http://ports.ubuntu.com/ubuntu-ports} -- ;; -- esac -- ;; - *) - MIRROR=${MIRROR:-http://ports.ubuntu.com/ubuntu-ports} - SECURITY_MIRROR=${SECURITY_MIRROR:-http://ports.ubuntu.com/ubuntu-ports} -@@ -150,13 +153,7 @@ download_ubuntu() - arch=$2 - release=$3 - -- if [ $release = "lucid" ]; then -- packages=dialog,apt,apt-utils,resolvconf,iproute,inetutils-ping,vim,dhcp3-client,ssh,lsb-release,gnupg -- elif [ $release = "natty" ]; then -- packages=dialog,apt,apt-utils,resolvconf,iproute,inetutils-ping,vim,isc-dhcp-client,isc-dhcp-common,ssh,lsb-release,gnupg,netbase -- else -- packages=dialog,apt,apt-utils,iproute,inetutils-ping,vim,isc-dhcp-client,isc-dhcp-common,ssh,lsb-release,gnupg,netbase,ubuntu-keyring -- fi -+ packages=vim,ssh - echo "installing packages: $packages" - - # check the mini ubuntu was not already downloaded -@@ -258,39 +255,40 @@ install_ubuntu() - flushcache=$3 - cache="/var/cache/lxc/$release" - mkdir -p /var/lock/subsys/ -+ - ( -- flock -n -x 200 -- if [ $? -ne 0 ]; then -- echo "Cache repository is busy." -- return 1 -- fi -- -- -- if [ $flushcache -eq 1 ]; then -- echo "Flushing cache..." -- rm -rf "$cache/partial-$arch" -- rm -rf "$cache/rootfs-$arch" -- fi -- -- echo "Checking cache download in $cache/rootfs-$arch ... " -- if [ ! -e "$cache/rootfs-$arch" ]; then -- download_ubuntu $cache $arch $release -- if [ $? -ne 0 ]; then -- echo "Failed to download 'ubuntu $release base'" -- return 1 -- fi -- fi -- -- echo "Copy $cache/rootfs-$arch to $rootfs ... " -- copy_ubuntu $cache $arch $rootfs -- if [ $? -ne 0 ]; then -- echo "Failed to copy rootfs" -- return 1 -- fi -+ flock -n -x 200 -+ if [ $? -ne 0 ]; then -+ echo "Cache repository is busy." -+ return 1 -+ fi - -- return 0 - -- ) 200>/var/lock/subsys/lxc -+ if [ $flushcache -eq 1 ]; then -+ echo "Flushing cache..." -+ rm -rf "$cache/partial-$arch" -+ rm -rf "$cache/rootfs-$arch" -+ fi -+ -+ echo "Checking cache download in $cache/rootfs-$arch ... " -+ if [ ! -e "$cache/rootfs-$arch" ]; then -+ download_ubuntu $cache $arch $release -+ if [ $? -ne 0 ]; then -+ echo "Failed to download 'ubuntu $release base'" -+ return 1 -+ fi -+ fi -+ -+ echo "Copy $cache/rootfs-$arch to $rootfs ... " -+ copy_ubuntu $cache $arch $rootfs -+ if [ $? -ne 0 ]; then -+ echo "Failed to copy rootfs" -+ return 1 -+ fi -+ -+ return 0 -+ -+ ) 200>/var/lock/subsys/lxc - - return $? - } -@@ -308,7 +306,7 @@ copy_configuration() - fi - - ttydir="" -- if [ $release = "precise" ] || [ $release = "quantal" ]; then -+ if [ -f $rootfs/etc/init/container-detect.conf ]; then - ttydir=" lxc" - fi - -@@ -371,8 +369,8 @@ sysfs sys sysfs defau - EOF - - if [ $? -ne 0 ]; then -- echo "Failed to add configuration" -- return 1 -+ echo "Failed to add configuration" -+ return 1 - fi - - return 0 -@@ -449,11 +447,11 @@ EOF - - # reconfigure some services - if [ -z "$LANG" ]; then -- chroot $rootfs locale-gen en_US.UTF-8 -- chroot $rootfs update-locale LANG=en_US.UTF-8 -+ chroot $rootfs locale-gen en_US.UTF-8 -+ chroot $rootfs update-locale LANG=en_US.UTF-8 - else -- chroot $rootfs locale-gen $LANG -- chroot $rootfs update-locale LANG=$LANG -+ chroot $rootfs locale-gen $LANG -+ chroot $rootfs update-locale LANG=$LANG - fi - - # remove pointless services in a container -@@ -479,21 +477,25 @@ post_process() - - if [ $trim_container -eq 1 ]; then - trim $rootfs $release -- elif [ $release = "lucid" -o $release = "natty" \ -- -o $release = "oneiric" ]; then -+ elif [ ! -f $rootfs/etc/init/container-detect.conf ]; then -+ # Make sure we have a working resolv.conf -+ cresolvonf="${rootfs}/etc/resolv.conf" -+ mv $cresolvonf ${cresolvonf}.lxcbak -+ cat /etc/resolv.conf > ${cresolvonf} -+ - # for lucid, if not trimming, then add the ubuntu-virt - # ppa and install lxcguest - if [ $release = "lucid" ]; then - chroot $rootfs apt-get install --force-yes -y python-software-properties - chroot $rootfs add-apt-repository ppa:ubuntu-virt/ppa - fi -- cresolvonf="${rootfs}/etc/resolv.conf" -- mv $cresolvonf ${cresolvonf}.lxcbak -- cat /etc/resolv.conf > ${cresolvonf} -+ - chroot $rootfs apt-get update - chroot $rootfs apt-get install --force-yes -y lxcguest -- rm -f ${cresolvonf} -- mv ${cresolvonf}.lxcbak ${cresolvonf} -+ -+ # Restore old resolv.conf -+ rm -f ${cresolvonf} -+ mv ${cresolvonf}.lxcbak ${cresolvonf} - fi - - # If the container isn't running a native architecture, setup multiarch -@@ -518,11 +520,11 @@ post_process() - chroot $rootfs apt-get install --force-yes -y --no-install-recommends upstart:${hostarch} mountall:${hostarch} iproute:${hostarch} isc-dhcp-client:${hostarch} - fi - -- # rmdir /dev/shm in precise and quantal containers. -+ # rmdir /dev/shm for containers that have /run/shm - # I'm afraid of doing rm -rf $rootfs/dev/shm, in case it did - # get bind mounted to the host's /run/shm. So try to rmdir - # it, and in case that fails move it out of the way. -- if [ $release = "precise" ] || [ $release = "quantal" ]; then -+ if [ -d $rootfs/run/shm ]; then - [ -d "$rootfs/dev/shm" ] && rmdir $rootfs/dev/shm - [ -e "$rootfs/dev/shm" ] && mv $rootfs/dev/shm $rootfs/dev/shm.bak - ln -s /run/shm $rootfs/dev/shm -@@ -553,11 +555,12 @@ do_bindhome() - # bind-mount the user's path into the container's /home - h=`getent passwd $user | cut -d: -f 6` - mkdir -p $rootfs/$h -- # use relative path in container -- h2=${h#/} -- while [ ${h2:0:1} = "/" ]; do -- h2=${h2#/} -- done -+ -+ # use relative path in container -+ h2=${h#/} -+ while [ ${h2:0:1} = "/" ]; do -+ h2=${h2#/} -+ done - echo "$h $h2 none bind 0 0" >> $path/fstab - - # Make sure the group exists in container -@@ -571,12 +574,12 @@ usage() - cat <] [--trim] [-d|--debug] - [-F | --flush-cache] [-r|--release ] [ -S | --auth-key ] --release: lucid | natty | oneiric | precise | quantal -+release: the ubuntu release (e.g. precise): defaults to host release on ubuntu, otherwise uses latest LTS - trim: make a minimal (faster, but not upgrade-safe) container - bindhome: bind 's home into the container - The ubuntu user will not be created, and will have -- sudo access. --arch: amd64 or i386: defaults to host arch -+ sudo access. -+arch: the container architecture (e.g. amd64): defaults to host arch - auth-key: SSH Public key file to inject into container - EOF - return 0 -@@ -589,14 +592,12 @@ if [ $? -ne 0 ]; then - fi - eval set -- "$options" - --release=lucid -+release=precise # Default to the last Ubuntu LTS release for non-Ubuntu systems - if [ -f /etc/lsb-release ]; then - . /etc/lsb-release -- case "$DISTRIB_CODENAME" in -- lucid|natty|oneiric|precise|quantal) -- release=$DISTRIB_CODENAME -- ;; -- esac -+ if [ "$DISTRIB_ID" = "Ubuntu" ]; then -+ release=$DISTRIB_CODENAME -+ fi - fi - - bindhome= -@@ -641,7 +642,7 @@ do - done - - if [ $debug -eq 1 ]; then -- set -x -+ set -x - fi - - if [ -n "$bindhome" ]; then diff -Nru lxc-0.8.0~rc1/debian/patches/0084-lxc-ubuntu-drop-duplicate-code.patch lxc-1.0.0~alpha1/debian/patches/0084-lxc-ubuntu-drop-duplicate-code.patch --- lxc-0.8.0~rc1/debian/patches/0084-lxc-ubuntu-drop-duplicate-code.patch 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0084-lxc-ubuntu-drop-duplicate-code.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,53 +0,0 @@ -From d163cf279f26f44ad0d2a43c087d97c2b1063e7e Mon Sep 17 00:00:00 2001 -From: Serge Hallyn -Date: Thu, 24 May 2012 14:19:57 -0500 -Subject: [PATCH 1/1] lxc-ubuntu.in: drop duplicate code - -Commits 15da01b3938d7ba45472e6c9d3b183a94dd86ca9 and -2e44ed1e647d9fd1544b7ad855bda22ca71abd12 conflicted and resulted in -some duplicate functionality. Drop the poorer version of that block. - -Signed-off-by: Serge Hallyn ---- - templates/lxc-ubuntu.in | 28 ---------------------------- - 1 file changed, 28 deletions(-) - -Index: lxc/templates/lxc-ubuntu.in -=================================================================== ---- lxc.orig/templates/lxc-ubuntu.in 2012-05-24 14:24:14.836363000 -0500 -+++ lxc/templates/lxc-ubuntu.in 2012-05-24 14:26:55.384221133 -0500 -@@ -176,34 +176,6 @@ - return 1 - fi - -- echo "Installing updates" -- if [ -z "$MIRROR" ]; then -- MIRROR="http://archive.ubuntu.com/ubuntu" -- fi -- cat >> "$1/partial-${arch}/etc/apt/sources.list" << EOF --deb $MIRROR ${release}-updates main universe --deb http://security.ubuntu.com/ubuntu ${release}-security main universe --EOF -- chroot "$1/partial-${arch}" apt-get update -- if [ $? -ne 0 ]; then -- echo "Failed to update the apt cache" -- return 1 -- fi -- cat > "$1/partial-${arch}"/usr/sbin/policy-rc.d << EOF --#!/bin/sh --exit 101 --EOF -- chmod +x "$1/partial-${arch}"/usr/sbin/policy-rc.d -- -- chroot "$1/partial-${arch}" apt-get dist-upgrade -y -- ret=$? -- -- rm -f "$1/partial-${arch}"/usr/sbin/policy-rc.d -- if [ $ret -ne 0 ]; then -- echo "Failed to upgrade the cache" -- return 1 -- fi -- - # Serge isn't sure whether we should avoid doing this when - # $release == `distro-info -d` - echo "Installing updates" diff -Nru lxc-0.8.0~rc1/debian/patches/0085-pivot-dir lxc-1.0.0~alpha1/debian/patches/0085-pivot-dir --- lxc-0.8.0~rc1/debian/patches/0085-pivot-dir 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0085-pivot-dir 1970-01-01 00:00:00.000000000 +0000 @@ -1,33 +0,0 @@ -Description: use lxc_putold as the pivot_root put dir - By default we use mnt, but that means that lxc fstab entries do not work - when placed under the container's /mnt/. -Author: Serge Hallyn -Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/986385 -Forwarded: yes - -Index: lxc/templates/lxc-ubuntu-cloud.in -=================================================================== ---- lxc.orig/templates/lxc-ubuntu-cloud.in 2012-05-24 14:24:14.836363000 -0500 -+++ lxc/templates/lxc-ubuntu-cloud.in 2012-05-25 11:24:39.800430880 -0500 -@@ -55,6 +55,8 @@ - lxc.mount = $path/fstab - lxc.arch = $arch - lxc.cap.drop = sys_module mac_admin -+lxc.pivotdir = lxc_putold -+ - # uncomment the next line to run the container unconfined: - #lxc.aa_profile = unconfined - -Index: lxc/templates/lxc-ubuntu.in -=================================================================== ---- lxc.orig/templates/lxc-ubuntu.in 2012-05-24 14:26:55.384221133 -0500 -+++ lxc/templates/lxc-ubuntu.in 2012-05-25 11:24:28.688431175 -0500 -@@ -301,6 +301,8 @@ - lxc.mount = $path/fstab - lxc.arch = $arch - lxc.cap.drop = sys_module mac_admin mac_override -+lxc.pivotdir = lxc_putold -+ - # uncomment the next line to run the container unconfined: - #lxc.aa_profile = unconfined - diff -Nru lxc-0.8.0~rc1/debian/patches/0086-lxc-unshare-zero-args lxc-1.0.0~alpha1/debian/patches/0086-lxc-unshare-zero-args --- lxc-0.8.0~rc1/debian/patches/0086-lxc-unshare-zero-args 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0086-lxc-unshare-zero-args 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ -Description: Require an argument for lxc-unshare - It segfaults otherwise trying to execute &NULL. -Author: Serge Hallyn -Forwarded: yes -Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/1011603 - -Index: lxc-0.8.0~rc1/src/lxc/lxc_unshare.c -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/lxc_unshare.c 2011-10-25 12:02:11.000000000 +0000 -+++ lxc-0.8.0~rc1/src/lxc/lxc_unshare.c 2012-06-11 15:44:52.906269292 +0000 -@@ -44,12 +44,11 @@ - - void usage(char *cmd) - { -- fprintf(stderr, "%s [command]\n", basename(cmd)); -+ fprintf(stderr, "%s command [command_arguments]\n", basename(cmd)); - fprintf(stderr, "Options are:\n"); - fprintf(stderr, "\t -s flags: ORed list of flags to unshare:\n" \ - "\t MOUNT, PID, UTSNAME, IPC, USER, NETWORK\n"); - fprintf(stderr, "\t -u : new id to be set if -s USER is specified\n"); -- fprintf(stderr, "\t if -s PID is specified, is mandatory)\n"); - _exit(1); - } - -@@ -184,6 +183,11 @@ - } - } - -+ if (argv[optind] == NULL) { -+ ERROR("a command to execute in the new namespace is required"); -+ return 1; -+ } -+ - args = &argv[optind]; - - ret = lxc_caps_init(); diff -Nru lxc-0.8.0~rc1/debian/patches/0087-lxc-ls-dash lxc-1.0.0~alpha1/debian/patches/0087-lxc-ls-dash --- lxc-0.8.0~rc1/debian/patches/0087-lxc-ls-dash 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0087-lxc-ls-dash 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +0,0 @@ -Description: lxc-ls: prepend container name with -- when calling ls - Otherwise a container name with a dash confuses ls -Author: Serge Hallyn -Forwarded: yes -Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/1006332 - -Index: lxc-0.8.0~rc1/src/lxc/lxc-ls.in -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/lxc-ls.in 2012-06-11 15:53:55.620963177 +0000 -+++ lxc-0.8.0~rc1/src/lxc/lxc-ls.in 2012-06-11 15:55:54.205526460 +0000 -@@ -23,7 +23,7 @@ - mount_point=`echo "$mount_string" |cut -d' ' -f2`; - } - --ls "$@" $lxcpath -+ls "$@" -- $lxcpath - - active=$(netstat -xl 2>/dev/null | grep $lxcpath | \ - sed -e 's#.*'"$lxcpath/"'\(.*\)/command#\1#'); -@@ -34,6 +34,6 @@ - # get cgroup for init - init_cgroup=`cat /proc/1/cgroup | awk -F: '{ print $3 }' | head -1` - cd $mount_point/$init_cgroup/lxc -- ls "$@" -d $active -+ ls "$@" -d -- $active - fi - fi diff -Nru lxc-0.8.0~rc1/debian/patches/0088-ubuntu-template-flock lxc-1.0.0~alpha1/debian/patches/0088-ubuntu-template-flock --- lxc-0.8.0~rc1/debian/patches/0088-ubuntu-template-flock 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0088-ubuntu-template-flock 1970-01-01 00:00:00.000000000 +0000 @@ -1,125 +0,0 @@ -Description: templates: don't fail on busy flock - Just wait until the lock is available. That is a nicer behavior - for concurrent lxc-creates. -Author: Serge Hallyn -Forwarded: yes -Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/1007483 - -Index: lxc-0.8.0~rc1/templates/lxc-altlinux.in -=================================================================== ---- lxc-0.8.0~rc1.orig/templates/lxc-altlinux.in 2012-03-01 21:42:19.000000000 +0000 -+++ lxc-0.8.0~rc1/templates/lxc-altlinux.in 2012-06-11 16:13:33.057526360 +0000 -@@ -198,7 +198,7 @@ - { - mkdir -p /var/lock/subsys/ - ( -- flock -n -x 200 -+ flock -x 200 - if [ $? -ne 0 ]; then - echo "Cache repository is busy." - return 1 -Index: lxc-0.8.0~rc1/templates/lxc-debian.in -=================================================================== ---- lxc-0.8.0~rc1.orig/templates/lxc-debian.in 2012-06-11 15:13:42.000000000 +0000 -+++ lxc-0.8.0~rc1/templates/lxc-debian.in 2012-06-11 16:13:41.093526201 +0000 -@@ -153,7 +153,7 @@ - rootfs=$1 - mkdir -p @LOCALSTATEDIR@/lock/subsys/ - ( -- flock -n -x 200 -+ flock -x 200 - if [ $? -ne 0 ]; then - echo "Cache repository is busy." - return 1 -Index: lxc-0.8.0~rc1/templates/lxc-fedora.in -=================================================================== ---- lxc-0.8.0~rc1.orig/templates/lxc-fedora.in 2012-06-11 15:13:42.000000000 +0000 -+++ lxc-0.8.0~rc1/templates/lxc-fedora.in 2012-06-11 16:13:48.873526476 +0000 -@@ -190,7 +190,7 @@ - { - mkdir -p /var/lock/subsys/ - ( -- flock -n -x 200 -+ flock -x 200 - if [ $? -ne 0 ]; then - echo "Cache repository is busy." - return 1 -@@ -281,7 +281,7 @@ - - # lock, so we won't purge while someone is creating a repository - ( -- flock -n -x 200 -+ flock -x 200 - if [ $? != 0 ]; then - echo "Cache repository is busy." - exit 1 -Index: lxc-0.8.0~rc1/templates/lxc-lenny.in -=================================================================== ---- lxc-0.8.0~rc1.orig/templates/lxc-lenny.in 2012-06-11 15:13:42.000000000 +0000 -+++ lxc-0.8.0~rc1/templates/lxc-lenny.in 2012-06-11 16:13:56.801534092 +0000 -@@ -142,7 +142,7 @@ - rootfs=$1 - mkdir -p @LOCALSTATEDIR@/lock/subsys/ - ( -- flock -n -x 200 -+ flock -x 200 - if [ $? -ne 0 ]; then - echo "Cache repository is busy." - return 1 -@@ -225,7 +225,7 @@ - - # lock, so we won't purge while someone is creating a repository - ( -- flock -n -x 200 -+ flock -x 200 - if [ $? != 0 ]; then - echo "Cache repository is busy." - exit 1 -Index: lxc-0.8.0~rc1/templates/lxc-opensuse.in -=================================================================== ---- lxc-0.8.0~rc1.orig/templates/lxc-opensuse.in 2012-06-11 15:13:42.000000000 +0000 -+++ lxc-0.8.0~rc1/templates/lxc-opensuse.in 2012-06-11 16:14:02.077525043 +0000 -@@ -217,7 +217,7 @@ - rootfs=$1 - mkdir -p /var/lock/subsys/ - ( -- flock -n -x 200 -+ flock -x 200 - if [ $? -ne 0 ]; then - echo "Cache repository is busy." - return 1 -@@ -305,7 +305,7 @@ - - # lock, so we won't purge while someone is creating a repository - ( -- flock -n -x 200 -+ flock -x 200 - if [ $? != 0 ]; then - echo "Cache repository is busy." - exit 1 -Index: lxc-0.8.0~rc1/templates/lxc-ubuntu-cloud.in -=================================================================== ---- lxc-0.8.0~rc1.orig/templates/lxc-ubuntu-cloud.in 2012-06-11 15:13:42.000000000 +0000 -+++ lxc-0.8.0~rc1/templates/lxc-ubuntu-cloud.in 2012-06-11 16:12:51.481524346 +0000 -@@ -294,7 +294,7 @@ - - mkdir -p /var/lock/subsys/ - ( -- flock -n -x 200 -+ flock -x 200 - - cd $cache - if [ $flushcache -eq 1 ]; then -Index: lxc-0.8.0~rc1/templates/lxc-ubuntu.in -=================================================================== ---- lxc-0.8.0~rc1.orig/templates/lxc-ubuntu.in 2012-06-11 15:13:42.000000000 +0000 -+++ lxc-0.8.0~rc1/templates/lxc-ubuntu.in 2012-06-11 16:12:37.029527081 +0000 -@@ -229,7 +229,7 @@ - mkdir -p /var/lock/subsys/ - - ( -- flock -n -x 200 -+ flock -x 200 - if [ $? -ne 0 ]; then - echo "Cache repository is busy." - return 1 diff -Nru lxc-0.8.0~rc1/debian/patches/0089-lxc-netstat-exec lxc-1.0.0~alpha1/debian/patches/0089-lxc-netstat-exec --- lxc-0.8.0~rc1/debian/patches/0089-lxc-netstat-exec 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0089-lxc-netstat-exec 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ -Description: Fix two errors in lxc-netstat - s/lxc_name/name/ - --exec does not require an argument -Author: Serge Hallyn -Forwarded: yes -Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/1011739 - -Index: lxc-0.8.0~rc1/src/lxc/lxc-netstat.in -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/lxc-netstat.in 2012-06-11 17:34:27.000000000 +0000 -+++ lxc-0.8.0~rc1/src/lxc/lxc-netstat.in 2012-06-11 17:50:31.774178554 +0000 -@@ -19,7 +19,7 @@ - } - - shortoptions='hn:' --longoptions='help,name:,exec:' -+longoptions='help,name:,exec' - - getopt=$(getopt -o $shortoptions --longoptions $longoptions -- "$@") - if [ $? != 0 ]; then -@@ -39,7 +39,7 @@ - ;; - -n|--name) - shift -- lxc_name=$1 -+ name=$1 - shift - ;; - --exec) diff -Nru lxc-0.8.0~rc1/debian/patches/0090-lxc-ubuntu-use-dpkg-add-architecture lxc-1.0.0~alpha1/debian/patches/0090-lxc-ubuntu-use-dpkg-add-architecture --- lxc-0.8.0~rc1/debian/patches/0090-lxc-ubuntu-use-dpkg-add-architecture 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0090-lxc-ubuntu-use-dpkg-add-architecture 1970-01-01 00:00:00.000000000 +0000 @@ -1,28 +0,0 @@ -Description: Use dpkg --add-architecture in lxc-ubuntu - When a container has dpkg >= 1.16.2, use dpkg --add-architecture - for multi-arch configuration on foreign architecture containers. -Author: Stéphane Graber -Bug-Ubuntu: https://bugs.launchpad.net/bugs/1017862 - ---- -Origin: vendor -Forwarded: no - ---- lxc-0.8.0~rc1.orig/templates/lxc-ubuntu.in -+++ lxc-0.8.0~rc1/templates/lxc-ubuntu.in -@@ -474,8 +474,13 @@ post_process() - - # If the container isn't running a native architecture, setup multiarch - if [ -x "$(ls -1 ${rootfs}/usr/bin/qemu-*-static 2>/dev/null)" ]; then -- mkdir -p ${rootfs}/etc/dpkg/dpkg.cfg.d -- echo "foreign-architecture ${hostarch}" > ${rootfs}/etc/dpkg/dpkg.cfg.d/lxc-multiarch -+ dpkg_version=$(chroot $rootfs dpkg-query -W -f='${Version}' dpkg) -+ if chroot $rootfs dpkg --compare-versions $dpkg_version ge "1.16.2"; then -+ chroot $rootfs dpkg --add-architecture ${hostarch} -+ else -+ mkdir -p ${rootfs}/etc/dpkg/dpkg.cfg.d -+ echo "foreign-architecture ${hostarch}" > ${rootfs}/etc/dpkg/dpkg.cfg.d/lxc-multiarch -+ fi - - # Save existing value of MIRROR and SECURITY_MIRROR - DEFAULT_MIRROR=$MIRROR diff -Nru lxc-0.8.0~rc1/debian/patches/0091-introduce-container-hooks.patch lxc-1.0.0~alpha1/debian/patches/0091-introduce-container-hooks.patch --- lxc-0.8.0~rc1/debian/patches/0091-introduce-container-hooks.patch 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0091-introduce-container-hooks.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,232 +0,0 @@ -From 05a2c6f3cff93e07dd197b2e12244ec62a9450fb Mon Sep 17 00:00:00 2001 -From: Ubuntu -Date: Fri, 15 Jun 2012 21:57:57 +0000 -Subject: [PATCH 1/1] Introduce a first set of container hooks - -This patch introduces support for 4 hooks. We'd like to have 6 in -all to mirror the openvz ones (thanks to stgraber for pursuing this info): - -pre-start: in the host namespace before container mounting happens -mount: after container mounting (as per config and /var/lib/lxc/container/fstab) - but before pivot_root -start: immediately before exec'ing init -stop: in container namespace and in chroot before shutdown -umount: after other unmounting has happened -post-stop: outside of the container - -stop and umount are not possible because when the kernel kills the -container init, it kills the namespace. (we can probably work around -this, i.e. by keeping the /proc/pid/ns/mnt open, and using that, -though all container tasks including init would still be dead). - -start also presents a bit of an issue. openvz allows a script on -the host to be specified, apparently. My patch simply requires the -script or program to exist in the container. I'm fine with trying -to do it the openvz way, but I wasn't sure what the best way to do -that was. Openvz (I'm told) opens the script and passes its contents -to a bash in the container. But that limits the hooks to being only -scripts. - -Other than that, - -lxc.hook.pre-start = /var/lib/lxc/p1/pre-start -lxc.hook.mount = /var/lib/lxc/p1/mount -lxc.hook.start = /start -lxc.hook.post-stop = /var/lib/lxc/p1/post-stop - -is working for me. Comments on the patch, the hooks we want, and -the questions raised above would be appreciated. - -Signed-off-by: Serge Hallyn ---- - src/lxc/conf.c | 29 +++++++++++++++++++++++++++++ - src/lxc/conf.h | 12 ++++++++++++ - src/lxc/confile.c | 40 ++++++++++++++++++++++++++++++++++++++++ - src/lxc/start.c | 6 ++++++ - 4 files changed, 87 insertions(+) - -Index: bug-1017862/src/lxc/conf.c -=================================================================== ---- bug-1017862.orig/src/lxc/conf.c 2012-06-26 09:56:08.662575000 -0500 -+++ bug-1017862/src/lxc/conf.c 2012-06-26 15:17:04.105611238 -0500 -@@ -1689,6 +1689,7 @@ - struct lxc_conf *lxc_conf_init(void) - { - struct lxc_conf *new; -+ int i; - - new = malloc(sizeof(*new)); - if (!new) { -@@ -1710,6 +1711,8 @@ - lxc_list_init(&new->mount_list); - lxc_list_init(&new->caps); - new->aa_profile = NULL; -+ for (i=0; ihooks[i]); - - return new; - } -@@ -2186,6 +2189,7 @@ - ERROR("failed to setup the cgroups for '%s'", name); - return -1; - } -+ HOOK(name, "mount", lxc_conf); - - if (setup_console(&lxc_conf->rootfs, &lxc_conf->console, lxc_conf->ttydir)) { - ERROR("failed to setup the console for '%s'", name); -@@ -2238,3 +2242,28 @@ - - return 0; - } -+ -+int run_lxc_hooks(const char *name, char *hook, struct lxc_conf *conf) -+{ -+ int which = -1; -+ struct lxc_list *it; -+ -+ if (strcmp(hook, "pre-start") == 0) -+ which = LXCHOOK_PRESTART; -+ else if (strcmp(hook, "mount") == 0) -+ which = LXCHOOK_MOUNT; -+ else if (strcmp(hook, "start") == 0) -+ which = LXCHOOK_START; -+ else if (strcmp(hook, "post-stop") == 0) -+ which = LXCHOOK_POSTSTOP; -+ else -+ return -1; -+ lxc_list_for_each(it, &conf->hooks[which]) { -+ int ret; -+ char *hookname = it->elem; -+ ret = run_script(name, "lxc", hookname, hook, NULL); -+ if (ret) -+ return ret; -+ } -+ return 0; -+} -Index: bug-1017862/src/lxc/conf.h -=================================================================== ---- bug-1017862.orig/src/lxc/conf.h 2012-06-26 09:56:08.662575000 -0500 -+++ bug-1017862/src/lxc/conf.h 2012-06-26 13:03:58.677431734 -0500 -@@ -200,6 +200,9 @@ - * @ttydir : directory (under /dev) in which to create console and ttys - * @aa_profile : apparmor profile to switch to - */ -+enum lxchooks { -+ LXCHOOK_PRESTART, LXCHOOK_MOUNT, LXCHOOK_START, -+ LXCHOOK_POSTSTOP, NUM_LXC_HOOKS}; - struct lxc_conf { - char *fstab; - int tty; -@@ -219,8 +222,16 @@ - int close_all_fds; - char *aa_profile; - int umount_proc; -+ struct lxc_list hooks[NUM_LXC_HOOKS]; - }; - -+int run_lxc_hooks(const char *name, char *hook, struct lxc_conf *conf); -+#define HOOK(name, which, conf) \ -+ do { \ -+ int hookret = run_lxc_hooks(name, which, conf); \ -+ if (hookret) return -1; \ -+ } while (0); -+ - /* - * Initialize the lxc configuration structure - */ -Index: bug-1017862/src/lxc/confile.c -=================================================================== ---- bug-1017862.orig/src/lxc/confile.c 2012-06-26 09:56:08.662575000 -0500 -+++ bug-1017862/src/lxc/confile.c 2012-06-26 13:03:58.677431734 -0500 -@@ -56,6 +56,7 @@ - static int config_rootfs_mount(const char *, char *, struct lxc_conf *); - static int config_pivotdir(const char *, char *, struct lxc_conf *); - static int config_utsname(const char *, char *, struct lxc_conf *); -+static int config_hook(const char *key, char *value, struct lxc_conf *lxc_conf); - static int config_network_type(const char *, char *, struct lxc_conf *); - static int config_network_flags(const char *, char *, struct lxc_conf *); - static int config_network_link(const char *, char *, struct lxc_conf *); -@@ -93,6 +94,10 @@ - { "lxc.rootfs", config_rootfs }, - { "lxc.pivotdir", config_pivotdir }, - { "lxc.utsname", config_utsname }, -+ { "lxc.hook.pre-start", config_hook }, -+ { "lxc.hook.mount", config_hook }, -+ { "lxc.hook.start", config_hook }, -+ { "lxc.hook.post-stop", config_hook }, - { "lxc.network.type", config_network_type }, - { "lxc.network.flags", config_network_flags }, - { "lxc.network.link", config_network_link }, -@@ -584,6 +589,41 @@ - SYSERROR("Unknown key: %s", key); - free(copy); - return -1; -+} -+ -+static int add_hook(struct lxc_conf *lxc_conf, int which, char *hook) -+{ -+ struct lxc_list *hooklist; -+ -+ hooklist = malloc(sizeof(*hooklist)); -+ if (!hooklist) { -+ free(hook); -+ return -1; -+ } -+ hooklist->elem = hook; -+ lxc_list_add_tail(&lxc_conf->hooks[which], hooklist); -+ return 0; -+} -+ -+static int config_hook(const char *key, char *value, -+ struct lxc_conf *lxc_conf) -+{ -+ char *copy = strdup(value); -+ if (!copy) { -+ SYSERROR("failed to dup string '%s'", value); -+ return -1; -+ } -+ if (strcmp(key, "lxc.hook.pre-start") == 0) -+ return add_hook(lxc_conf, LXCHOOK_PRESTART, copy); -+ else if (strcmp(key, "lxc.hook.mount") == 0) -+ return add_hook(lxc_conf, LXCHOOK_MOUNT, copy); -+ else if (strcmp(key, "lxc.hook.start") == 0) -+ return add_hook(lxc_conf, LXCHOOK_START, copy); -+ else if (strcmp(key, "lxc.hook.post-stop") == 0) -+ return add_hook(lxc_conf, LXCHOOK_POSTSTOP, copy); -+ SYSERROR("Unknown key: %s", key); -+ free(copy); -+ return -1; - } - - static int config_personality(const char *key, char *value, -Index: bug-1017862/src/lxc/start.c -=================================================================== ---- bug-1017862.orig/src/lxc/start.c 2012-06-26 09:56:08.662575000 -0500 -+++ bug-1017862/src/lxc/start.c 2012-06-26 13:03:58.681431734 -0500 -@@ -360,6 +360,8 @@ - goto out_free_name; - } - -+ HOOK(name, "pre-start", conf); -+ - if (lxc_create_tty(name, conf)) { - ERROR("failed to create the ttys"); - goto out_aborting; -@@ -404,6 +406,8 @@ - lxc_set_state(name, handler, STOPPING); - lxc_set_state(name, handler, STOPPED); - -+ HOOK(name, "post-stop", handler->conf); -+ - /* reset mask set by setup_signal_fd */ - if (sigprocmask(SIG_SETMASK, &handler->oldmask, NULL)) - WARN("failed to restore sigprocmask"); -@@ -585,6 +589,8 @@ - - close(handler->sigfd); - -+ HOOK(handler->name, "start", handler->conf); -+ - /* after this call, we are in error because this - * ops should not return as it execs */ - if (handler->ops->start(handler, handler->data)) diff -Nru lxc-0.8.0~rc1/debian/patches/0092-clone-no-dhclient.conf-update-when-not-hardcoded lxc-1.0.0~alpha1/debian/patches/0092-clone-no-dhclient.conf-update-when-not-hardcoded --- lxc-0.8.0~rc1/debian/patches/0092-clone-no-dhclient.conf-update-when-not-hardcoded 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0092-clone-no-dhclient.conf-update-when-not-hardcoded 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ -Description: Don't update the host-name field in dhclient.conf when - it doesn't contain an hardcoded value. - - On Debian and Ubuntu, the default host-name field in dhclient.conf is - set to either "" or "gethostname()" both of which get replaced - by the machine's hostname at query time. - - The sed call currently present in lxc-clone hardcodes the hostname in - dhclient.conf, causing dpkg to prompt on isc-dhcp updates. - -Author: Stéphane Graber -Bug-Ubuntu: https://bugs.launchpad.net/bugs/1017862 -Forwarded: no - ---- lxc-0.8.0~rc1.orig/src/lxc/lxc-clone.in -+++ lxc-0.8.0~rc1/src/lxc/lxc-clone.in -@@ -263,7 +263,7 @@ fi - echo "Updating rootfs..." - - # so you can 'ssh $hostname.' or 'ssh $hostname.local' --if [ -f $rootfs/etc/dhcp/dhclient.conf ]; then -+if [ -f $rootfs/etc/dhcp/dhclient.conf ] && ! grep -q "^send host-name.*hostname" $rootfs/etc/dhcp/dhclient.conf; then - sed -i "s/send host-name.*$/send host-name \"$hostname\";/" $rootfs/etc/dhcp/dhclient.conf - fi - diff -Nru lxc-0.8.0~rc1/debian/patches/0093-lxc-clone-copy-fstab lxc-1.0.0~alpha1/debian/patches/0093-lxc-clone-copy-fstab --- lxc-0.8.0~rc1/debian/patches/0093-lxc-clone-copy-fstab 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0093-lxc-clone-copy-fstab 1970-01-01 00:00:00.000000000 +0000 @@ -1,20 +0,0 @@ -Description: lxc-clone: fix handling of lxc.mount entries - The 'lxc.mount =' entry can have more than one space, or tabs, before the =. - We only need to disambiguate from 'lxc.mount.entry'. So just check for a - space or tab after mount. -Author: Serge Hallyn -Forwarded: yes - -Index: lxc-0.8.0~rc1/src/lxc/lxc-clone.in -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/lxc-clone.in 2012-07-20 09:20:08.848993559 -0500 -+++ lxc-0.8.0~rc1/src/lxc/lxc-clone.in 2012-07-20 09:37:06.312976331 -0500 -@@ -180,7 +180,7 @@ - sed -i '/lxc.utsname/d' $lxc_path/$lxc_new/config - echo "lxc.utsname = $hostname" >> $lxc_path/$lxc_new/config - --grep "lxc.mount =" $lxc_path/$lxc_new/config >/dev/null 2>&1 && { sed -i '/lxc.mount =/d' $lxc_path/$lxc_new/config; echo "lxc.mount = $lxc_path/$lxc_new/fstab" >> $lxc_path/$lxc_new/config; } -+grep "lxc.mount[ \t]" $lxc_path/$lxc_new/config >/dev/null 2>&1 && { sed -i '/lxc.mount[ \t]/d' $lxc_path/$lxc_new/config; echo "lxc.mount = $lxc_path/$lxc_new/fstab" >> $lxc_path/$lxc_new/config; } - - if [ -e $lxc_path/$lxc_orig/fstab ];then - cp $lxc_path/$lxc_orig/fstab $lxc_path/$lxc_new/fstab diff -Nru lxc-0.8.0~rc1/debian/patches/0094-fix-dev-shm-check lxc-1.0.0~alpha1/debian/patches/0094-fix-dev-shm-check --- lxc-0.8.0~rc1/debian/patches/0094-fix-dev-shm-check 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0094-fix-dev-shm-check 1970-01-01 00:00:00.000000000 +0000 @@ -1,44 +0,0 @@ -Description: Fix /dev/shm workaround to only trigger when /dev/shm is a directory -Author: Stéphane Graber - -Origin: vendor -Bug-Ubuntu: https://bugs.launchpad.net/launchpad/+bug/974584 -Forwarded: no - -Index: lxc/templates/lxc-ubuntu.in -=================================================================== ---- lxc.orig/templates/lxc-ubuntu.in 2012-07-26 13:07:32.000000000 -0400 -+++ lxc/templates/lxc-ubuntu.in 2012-07-26 13:11:20.604099863 -0400 -@@ -503,9 +503,8 @@ - # I'm afraid of doing rm -rf $rootfs/dev/shm, in case it did - # get bind mounted to the host's /run/shm. So try to rmdir - # it, and in case that fails move it out of the way. -- if [ -d $rootfs/run/shm ]; then -- [ -d "$rootfs/dev/shm" ] && rmdir $rootfs/dev/shm -- [ -e "$rootfs/dev/shm" ] && mv $rootfs/dev/shm $rootfs/dev/shm.bak -+ if [ ! -L $rootfs/dev/shm ] && [ -d $rootfs/run/shm ] && [ -e $rootfs/dev/shm ]; then -+ mv $rootfs/dev/shm $rootfs/dev/shm.bak - ln -s /run/shm $rootfs/dev/shm - fi - } -Index: lxc/templates/lxc-ubuntu-cloud.in -=================================================================== ---- lxc.orig/templates/lxc-ubuntu-cloud.in 2012-07-26 13:26:28.134423000 -0400 -+++ lxc/templates/lxc-ubuntu-cloud.in 2012-07-26 13:27:40.772127204 -0400 -@@ -96,13 +96,12 @@ - sysfs sys sysfs defaults 0 0 - EOF - -- # rmdir /dev/shm in precise and quantal containers. -+ # rmdir /dev/shm for containers that have /run/shm - # I'm afraid of doing rm -rf $rootfs/dev/shm, in case it did - # get bind mounted to the host's /run/shm. So try to rmdir - # it, and in case that fails move it out of the way. -- if [ $release = "precise" ] || [ $release = "quantal" ]; then -- [ -d "$rootfs/dev/shm" ] && rmdir $rootfs/dev/shm -- [ -e "$rootfs/dev/shm" ] && mv $rootfs/dev/shm $rootfs/dev/shm.bak -+ if [ ! -L $rootfs/dev/shm ] && [ -d $rootfs/run/shm ] && [ -e $rootfs/dev/shm ]; then -+ mv $rootfs/dev/shm $rootfs/dev/shm.bak - ln -s /run/shm $rootfs/dev/shm - fi - diff -Nru lxc-0.8.0~rc1/debian/patches/0095-lxc-clone-change-uuid-on-xfs.patch lxc-1.0.0~alpha1/debian/patches/0095-lxc-clone-change-uuid-on-xfs.patch --- lxc-0.8.0~rc1/debian/patches/0095-lxc-clone-change-uuid-on-xfs.patch 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0095-lxc-clone-change-uuid-on-xfs.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ -From ccdfabfc11d0620038b7517ab35a673bf3241771 Mon Sep 17 00:00:00 2001 -From: Serge Hallyn -Date: Thu, 12 Jul 2012 16:33:14 -0500 -Subject: [PATCH 1/1] lxc-clone: change uuid on xfs - -Signed-off-by: Serge Hallyn ---- - src/lxc/lxc-clone.in | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - -Index: lxc/src/lxc/lxc-clone.in -=================================================================== ---- lxc.orig/src/lxc/lxc-clone.in 2012-07-26 17:38:04.928037000 +0000 -+++ lxc/src/lxc/lxc-clone.in 2012-07-26 17:44:13.953353607 +0000 -@@ -207,7 +207,13 @@ - if [ $lxc_size = "_unset" ]; then - lxc_size=`lvdisplay $oldroot | grep Size | awk '{ print $3 $4 }'` - fi -- lvcreate -s -L $lxc_size -n ${lxc_lv_prefix}${lxc_new}_snapshot $oldroot -+ newlv="${lxc_lv_prefix}${lxc_new}_snapshot" -+ lvcreate -s -L $lxc_size -n $newlv $oldroot -+ type xfs_admin > /dev/null 2>&1 && { -+ # change filesystem UUID if it is an xfs filesystem -+ xfs_admin -u /dev/$lxc_vg/$newlv && xfs_admin -U generate /dev/$lxc_vg/$newlv -+ } -+ - if [ $container_running = "True" ]; then - lxc-unfreeze -n $lxc_orig - frozen=0 diff -Nru lxc-0.8.0~rc1/debian/patches/0096-lxc-wait-add-timeout.patch lxc-1.0.0~alpha1/debian/patches/0096-lxc-wait-add-timeout.patch --- lxc-0.8.0~rc1/debian/patches/0096-lxc-wait-add-timeout.patch 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0096-lxc-wait-add-timeout.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,113 +0,0 @@ -Allow to specify a timeout for waiting on state changes via lxc-wait. -Helpful for scripts that need to handle errors or excessive delays in -state changing procedures. - -Signed-off-by: Jan Kiszka ---- - doc/lxc-wait.sgml.in | 11 +++++++++++ - src/lxc/arguments.h | 1 + - src/lxc/lxc_wait.c | 16 +++++++++++++++- - 3 files changed, 27 insertions(+), 1 deletions(-) - -Index: lxc/doc/lxc-wait.sgml.in -=================================================================== ---- lxc.orig/doc/lxc-wait.sgml.in 2012-07-26 17:51:42.145353005 +0000 -+++ lxc/doc/lxc-wait.sgml.in 2012-07-26 17:51:44.297353675 +0000 -@@ -79,6 +79,17 @@ - - - -+ -+ -+ -+ -+ -+ -+ Wait timeout seconds for desired state to be reached. -+ -+ -+ -+ - - - -Index: lxc/src/lxc/arguments.h -=================================================================== ---- lxc.orig/src/lxc/arguments.h 2012-07-26 17:51:42.145353005 +0000 -+++ lxc/src/lxc/arguments.h 2012-07-26 17:51:44.297353675 +0000 -@@ -57,6 +57,7 @@ - - /* for lxc-wait */ - char *states; -+ long timeout; - - /* close fds from parent? */ - int close_all_fds; -Index: lxc/src/lxc/lxc_wait.c -=================================================================== ---- lxc.orig/src/lxc/lxc_wait.c 2012-07-26 17:51:42.145353005 +0000 -+++ lxc/src/lxc/lxc_wait.c 2012-07-26 17:51:44.301353694 +0000 -@@ -24,6 +24,8 @@ - #include - #include - #include -+#include -+#include - #include - - #include -@@ -46,12 +48,14 @@ - { - switch (c) { - case 's': args->states = optarg; break; -+ case 't': args->timeout = atol(optarg); break; - } - return 0; - } - - static const struct option my_longopts[] = { - {"state", required_argument, 0, 's'}, -+ {"timeout", required_argument, 0, 't'}, - LXC_COMMON_OPTIONS - }; - -@@ -66,7 +70,8 @@ - -n, --name=NAME NAME for name of the container\n\ - -s, --state=STATE ORed states to wait for\n\ - STOPPED, STARTING, RUNNING, STOPPING,\n\ -- ABORTING, FREEZING, FROZEN\n", -+ ABORTING, FREEZING, FROZEN\n\ -+ -t, --timeout=TMO Seconds to wait for state changes\n", - .options = my_longopts, - .parser = my_parser, - .checker = my_checker, -@@ -91,6 +96,11 @@ - return 0; - } - -+static void timeout_handler(int signal) -+{ -+ exit(-1); -+} -+ - int main(int argc, char *argv[]) - { - struct lxc_msg msg; -@@ -124,6 +134,9 @@ - goto out_close; - } - -+ signal(SIGALRM, timeout_handler); -+ alarm(my_args.timeout); -+ - for (;;) { - if (lxc_monitor_read(fd, &msg) < 0) - goto out_close; -@@ -140,6 +153,7 @@ - } - - if (s[msg.value]) { -+ alarm(0); - ret = 0; - goto out_close; - } diff -Nru lxc-0.8.0~rc1/debian/patches/0097-seccomp lxc-1.0.0~alpha1/debian/patches/0097-seccomp --- lxc-0.8.0~rc1/debian/patches/0097-seccomp 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0097-seccomp 1970-01-01 00:00:00.000000000 +0000 @@ -1,546 +0,0 @@ -commit 16049797728edeba06f3d6dce8c21daa7ffdbced -Author: Serge Hallyn -Date: Fri Jul 27 21:13:53 2012 -0500 - - Introduce support for seccomp. - - Hi, - - This patch is so far just a proof of concept. The libseccomp api will be - changing soon so it probably wouldn't be worth pulling this until it is - updated for the new API. - - This patch introduces support for seccomp to lxc. Seccomp lets a program - restrict its own (and its children's) future access to system calls. It - uses a simple whitelist system call policy file. It would probably be - better to switch to something more symbolic (i.e specifying 'open' rather - than the syscall #, especially given container arch flexibility). - - I just wanted to get this out there as a first step. You can also get - source for an ubuntu package based on this patch at - https://code.launchpad.net/~serge-hallyn/ubuntu/quantal/lxc/lxc-seccomp - - Signed-off-by: Serge Hallyn - -Index: lxc-fix-seccomp/README -=================================================================== ---- lxc-fix-seccomp.orig/README 2012-08-16 15:38:00.877173000 -0500 -+++ lxc-fix-seccomp/README 2012-08-16 15:38:00.877173000 -0500 -@@ -52,3 +52,27 @@ - - AUTHOR - Daniel Lezcano -+ -+Seccomp with LXC -+---------------- -+ -+To restrict a container with seccomp, you must specify a profile which is -+basically a whitelist of system calls it may execute. In the container -+config file, add a line like -+ -+lxc.seccomp = /var/lib/lxc/q1/seccomp.full -+ -+I created a usable (but basically worthless) seccomp.full file using -+ -+cat > seccomp.full << EOF -+1 -+whitelist -+EOF -+for i in `seq 0 300`; do -+ echo $i >> secomp.full -+done -+for i in `seq 1024 1079`; do -+ echo $i >> seccomp.full -+done -+ -+ -- Serge Hallyn Fri, 27 Jul 2012 15:47:02 +0600 -Index: lxc-fix-seccomp/configure.ac -=================================================================== ---- lxc-fix-seccomp.orig/configure.ac 2012-08-16 15:38:00.877173000 -0500 -+++ lxc-fix-seccomp/configure.ac 2012-08-16 17:48:05.955917878 -0500 -@@ -18,6 +18,10 @@ - - AM_CONDITIONAL([ENABLE_RPATH], [test "x$enable_rpath" = "xyes"]) - -+AC_ARG_ENABLE([seccomp], -+ [AC_HELP_STRING([--enable-seccomp], [enable seccomp])], -+ [], [enable_seccomp=check]) -+ - AC_ARG_ENABLE([doc], - [AC_HELP_STRING([--enable-doc], [make mans (require docbook2man installed) [default=auto]])], - [], [enable_doc=auto]) -@@ -29,6 +33,18 @@ - AC_MSG_ERROR([docbook2man required by man request, but not found]) - fi - -+if test "$enable_seccomp" = "check" ; then -+ AC_CHECK_LIB([seccomp],[seccomp_init],[enable_seccomp=yes], [enable_seccomp=no]) -+fi -+ -+AM_CONDITIONAL([ENABLE_SECCOMP], [test "x$enable_seccomp" = "xyes"]) -+ -+AM_COND_IF([ENABLE_SECCOMP], -+ [AC_CHECK_HEADER([seccomp.h],[],[AC_MSG_ERROR([You must install the seccomp development package in order to compile lxc])]) -+ AC_CHECK_LIB([seccomp], [seccomp_init],[],[AC_MSG_ERROR([You must install the seccomp development package in order to compile lxc])]) -+ AC_DEFINE_UNQUOTED([ENABLE_SECCOMP], 1, [Seccomp is available]) -+ AC_SUBST([SECCOMP_LIBS], [-lseccomp])]) -+ - AM_CONDITIONAL([ENABLE_DOCBOOK], [test "x$have_docbook" = "xyes"]) - - AC_ARG_ENABLE([examples], -Index: lxc-fix-seccomp/src/lxc/Makefile.am -=================================================================== ---- lxc-fix-seccomp.orig/src/lxc/Makefile.am 2012-08-16 15:38:00.877173000 -0500 -+++ lxc-fix-seccomp/src/lxc/Makefile.am 2012-08-16 17:36:30.547929653 -0500 -@@ -50,6 +50,7 @@ - genl.c genl.h \ - \ - caps.c caps.h \ -+ lxcseccomp.h \ - mainloop.c mainloop.h \ - af_unix.c af_unix.h \ - \ -@@ -60,13 +61,18 @@ - -DLXCPATH=\"$(LXCPATH)\" \ - -DLXCINITDIR=\"$(LXCINITDIR)\" - -+if ENABLE_SECCOMP -+AM_CFLAGS += -DHAVE_SECCOMP -+liblxc_so_SOURCES += seccomp.c -+endif -+ - liblxc_so_CFLAGS = -fPIC -DPIC $(AM_CFLAGS) - - liblxc_so_LDFLAGS = \ - -shared \ - -Wl,-soname,liblxc.so.$(firstword $(subst ., ,$(VERSION))) - --liblxc_so_LDADD = -lutil $(CAP_LIBS) -lapparmor -+liblxc_so_LDADD = -lutil $(CAP_LIBS) -lapparmor $(SECCOMP_LIBS) - - bin_SCRIPTS = \ - lxc-ps \ -@@ -105,7 +111,7 @@ - if ENABLE_RPATH - AM_LDFLAGS += -Wl,-rpath -Wl,$(libdir) - endif --LDADD=liblxc.so @CAP_LIBS@ -lapparmor -+LDADD=liblxc.so @CAP_LIBS@ -lapparmor @SECCOMP_LIBS@ - - lxc_attach_SOURCES = lxc_attach.c - lxc_cgroup_SOURCES = lxc_cgroup.c -Index: lxc-fix-seccomp/src/lxc/conf.h -=================================================================== ---- lxc-fix-seccomp.orig/src/lxc/conf.h 2012-08-16 15:38:00.877173000 -0500 -+++ lxc-fix-seccomp/src/lxc/conf.h 2012-08-16 15:38:00.877173000 -0500 -@@ -223,6 +223,7 @@ - char *aa_profile; - int umount_proc; - struct lxc_list hooks[NUM_LXC_HOOKS]; -+ char *seccomp; // filename with the seccomp rules - }; - - int run_lxc_hooks(const char *name, char *hook, struct lxc_conf *conf); -Index: lxc-fix-seccomp/src/lxc/confile.c -=================================================================== ---- lxc-fix-seccomp.orig/src/lxc/confile.c 2012-08-16 15:38:00.877173000 -0500 -+++ lxc-fix-seccomp/src/lxc/confile.c 2012-08-16 17:48:11.919917776 -0500 -@@ -73,6 +73,7 @@ - static int config_network_ipv6_gateway(const char *, char *, struct lxc_conf *); - static int config_cap_drop(const char *, char *, struct lxc_conf *); - static int config_console(const char *, char *, struct lxc_conf *); -+static int config_seccomp(const char *, char *, struct lxc_conf *); - - typedef int (*config_cb)(const char *, char *, struct lxc_conf *); - -@@ -114,6 +115,7 @@ - { "lxc.network.ipv6", config_network_ipv6 }, - { "lxc.cap.drop", config_cap_drop }, - { "lxc.console", config_console }, -+ { "lxc.seccomp", config_seccomp }, - }; - - static const size_t config_size = sizeof(config)/sizeof(struct config); -@@ -605,6 +607,26 @@ - return 0; - } - -+static int config_seccomp(const char *key, char *value, -+ struct lxc_conf *lxc_conf) -+{ -+ char *path; -+ -+ if (lxc_conf->seccomp) { -+ ERROR("seccomp already defined"); -+ return -1; -+ } -+ path = strdup(value); -+ if (!path) { -+ SYSERROR("failed to strdup '%s': %m", value); -+ return -1; -+ } -+ -+ lxc_conf->seccomp = path; -+ -+ return 0; -+} -+ - static int config_hook(const char *key, char *value, - struct lxc_conf *lxc_conf) - { -Index: lxc-fix-seccomp/src/lxc/lxc-clone.in -=================================================================== ---- lxc-fix-seccomp.orig/src/lxc/lxc-clone.in 2012-08-16 15:38:00.877173000 -0500 -+++ lxc-fix-seccomp/src/lxc/lxc-clone.in 2012-08-16 15:38:00.877173000 -0500 -@@ -180,7 +180,7 @@ - sed -i '/lxc.utsname/d' $lxc_path/$lxc_new/config - echo "lxc.utsname = $hostname" >> $lxc_path/$lxc_new/config - --grep "lxc.mount[ \t]" $lxc_path/$lxc_new/config >/dev/null 2>&1 && { sed -i '/lxc.mount[ \t]/d' $lxc_path/$lxc_new/config; echo "lxc.mount = $lxc_path/$lxc_new/fstab" >> $lxc_path/$lxc_new/config; } -+grep "lxc.mount =" $lxc_path/$lxc_new/config >/dev/null 2>&1 && { sed -i '/lxc.mount =/d' $lxc_path/$lxc_new/config; echo "lxc.mount = $lxc_path/$lxc_new/fstab" >> $lxc_path/$lxc_new/config; } - - if [ -e $lxc_path/$lxc_orig/fstab ];then - cp $lxc_path/$lxc_orig/fstab $lxc_path/$lxc_new/fstab -Index: lxc-fix-seccomp/src/lxc/lxcseccomp.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ lxc-fix-seccomp/src/lxc/lxcseccomp.h 2012-08-16 15:38:00.877173000 -0500 -@@ -0,0 +1,41 @@ -+/* -+ * lxc: linux Container library -+ * -+ * (C) Copyright Canonical, Inc. 2012 -+ * -+ * Authors: -+ * Serge Hallyn -+ * -+ * 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 -+ */ -+ -+#ifndef _lxc_seccomp_h -+ -+#include "conf.h" -+ -+#ifdef HAVE_SECCOMP -+int lxc_seccomp_load(struct lxc_conf *conf); -+int lxc_read_seccomp_config(struct lxc_conf *conf); -+#else -+static inline int lxc_seccomp_load(struct lxc_conf *conf) { -+ return 0; -+} -+ -+static inline int lxc_read_seccomp_config(struct lxc_conf *conf) { -+ return 0; -+} -+#endif -+ -+#endif -Index: lxc-fix-seccomp/src/lxc/seccomp.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ lxc-fix-seccomp/src/lxc/seccomp.c 2012-08-16 15:38:00.877173000 -0500 -@@ -0,0 +1,121 @@ -+/* -+ * lxc: linux Container library -+ * -+ * (C) Copyright Canonical, Inc. 2012 -+ * -+ * Authors: -+ * Serge Hallyn -+ * -+ * 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 -+ */ -+ -+#define _GNU_SOURCE -+#include -+#include -+#include -+#include -+#include -+#include "lxcseccomp.h" -+ -+#include "log.h" -+ -+lxc_log_define(lxc_seccomp, lxc); -+ -+/* -+ * The first line of the config file has a policy language version -+ * the second line has some directives -+ * then comes policy subject to the directives -+ * right now version must be '1' -+ * the directives must include 'whitelist' (only type of policy currently -+ * supported) and can include 'debug' (though debug is not yet supported). -+ */ -+static int parse_config(FILE *f, struct lxc_conf *conf) -+{ -+ char line[1024]; -+ int ret, version; -+ -+ ret = fscanf(f, "%d\n", &version); -+ if (ret != 1 || version != 1) { -+ ERROR("invalid version"); -+ return -1; -+ } -+ if (!fgets(line, 1024, f)) { -+ ERROR("invalid config file"); -+ return -1; -+ } -+ if (!strstr(line, "whitelist")) { -+ ERROR("only whitelist policy is supported"); -+ return -1; -+ } -+ if (strstr(line, "debug")) { -+ ERROR("debug not yet implemented"); -+ return -1; -+ } -+ /* now read in the whitelist entries one per line */ -+ while (fgets(line, 1024, f)) { -+ int nr; -+ ret = sscanf(line, "%d", &nr); -+ if (ret != 1) -+ return -1; -+ ret = seccomp_rule_add(SCMP_ACT_ALLOW, nr, 0); -+ if (ret < 0) { -+ ERROR("failed loading allow rule for %d\n", nr); -+ return ret; -+ } -+ } -+ return 0; -+} -+ -+int lxc_read_seccomp_config(struct lxc_conf *conf) -+{ -+ FILE *f; -+ int ret; -+ -+ if (seccomp_init(SCMP_ACT_ERRNO(31)) < 0) { /* for debug, pass in SCMP_ACT_TRAP */ -+ ERROR("failed initializing seccomp"); -+ return -1; -+ } -+ if (!conf->seccomp) -+ return 0; -+ -+ /* turn of no-new-privs. We don't want it in lxc, and it breaks -+ * with apparmor */ -+ if (seccomp_attr_set(SCMP_FLTATR_CTL_NNP, 0)) { -+ ERROR("failed to turn off n-new-privs\n"); -+ return -1; -+ } -+ -+ f = fopen(conf->seccomp, "r"); -+ if (!f) { -+ SYSERROR("failed to open seccomp policy file %s\n", conf->seccomp); -+ return -1; -+ } -+ ret = parse_config(f, conf); -+ fclose(f); -+ return ret; -+} -+ -+int lxc_seccomp_load(struct lxc_conf *conf) -+{ -+ int ret; -+ if (!conf->seccomp) -+ return 0; -+ ret = seccomp_load(); -+ if (ret < 0) { -+ ERROR("Error loading the seccomp policy"); -+ return -1; -+ } -+ return 0; -+} -Index: lxc-fix-seccomp/src/lxc/start.c -=================================================================== ---- lxc-fix-seccomp.orig/src/lxc/start.c 2012-08-16 15:38:00.877173000 -0500 -+++ lxc-fix-seccomp/src/lxc/start.c 2012-08-16 15:38:00.877173000 -0500 -@@ -129,6 +129,7 @@ - #include "console.h" - #include "sync.h" - #include "namespace.h" -+#include "lxcseccomp.h" - - lxc_log_define(lxc_start, lxc); - -@@ -354,6 +355,11 @@ - goto out_free; - } - -+ if (lxc_read_seccomp_config(conf) != 0) { -+ ERROR("failed loading seccomp policy"); -+ goto out_free_name; -+ } -+ - /* Begin the set the state to STARTING*/ - if (lxc_set_state(name, handler, STARTING)) { - ERROR("failed to set state '%s'", lxc_state2str(STARTING)); -@@ -587,6 +593,9 @@ - if (apparmor_load(handler) < 0) - goto out_warn_father; - -+ if (lxc_seccomp_load(handler->conf) != 0) -+ goto out_warn_father; -+ - close(handler->sigfd); - - HOOK(handler->name, "start", handler->conf); -Index: lxc-fix-seccomp/configure -=================================================================== ---- lxc-fix-seccomp.orig/configure 2012-08-16 15:38:00.877173000 -0500 -+++ lxc-fix-seccomp/configure 2012-08-16 16:23:27.284003869 -0500 -@@ -623,7 +623,10 @@ - ENABLE_EXAMPLES_TRUE - ENABLE_DOCBOOK_FALSE - ENABLE_DOCBOOK_TRUE -+SECCOMP_LIBS - have_docbook -+ENABLE_SECCOMP_FALSE -+ENABLE_SECCOMP_TRUE - ENABLE_RPATH_FALSE - ENABLE_RPATH_TRUE - SETCAP -@@ -720,6 +723,7 @@ - enable_option_checking - enable_dependency_tracking - enable_rpath -+enable_seccomp - enable_doc - enable_examples - with_config_path -@@ -1358,6 +1362,7 @@ - --disable-dependency-tracking speeds up one-time build - --enable-dependency-tracking do not reject slow dependency extractors - --disable-rpath do not set rpath in executables -+ --enable-seccomp enable seccomp - --enable-doc make mans (require docbook2man installed) - [default=auto] - --disable-examples do not install configuration examples -@@ -4340,6 +4345,22 @@ - fi - - -+# Check whether --enable-seccomp was given. -+if test "${enable_seccomp+set}" = set; then : -+ enableval=$enable_seccomp; -+else -+ enable_seccomp=yes -+fi -+ -+ if test "x$enable_seccomp" = "xyes"; then -+ ENABLE_SECCOMP_TRUE= -+ ENABLE_SECCOMP_FALSE='#' -+else -+ ENABLE_SECCOMP_TRUE='#' -+ ENABLE_SECCOMP_FALSE= -+fi -+ -+ - # Check whether --enable-doc was given. - if test "${enable_doc+set}" = set; then : - enableval=$enable_doc; -@@ -4392,6 +4413,71 @@ - as_fn_error $? "docbook2man required by man request, but not found" "$LINENO" 5 - fi - -+if test -z "$ENABLE_SECCOMP_TRUE"; then : -+ ac_fn_c_check_header_mongrel "$LINENO" "seccomp.h" "ac_cv_header_seccomp_h" "$ac_includes_default" -+if test "x$ac_cv_header_seccomp_h" = xyes; then : -+ -+else -+ as_fn_error $? "You must install the seccomp development package in order to compile lxc" "$LINENO" 5 -+fi -+ -+ -+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for seccomp_init in -lseccomp" >&5 -+$as_echo_n "checking for seccomp_init in -lseccomp... " >&6; } -+if ${ac_cv_lib_seccomp_seccomp_init+:} false; then : -+ $as_echo_n "(cached) " >&6 -+else -+ ac_check_lib_save_LIBS=$LIBS -+LIBS="-lseccomp $LIBS" -+cat confdefs.h - <<_ACEOF >conftest.$ac_ext -+/* end confdefs.h. */ -+ -+/* Override any GCC internal prototype to avoid an error. -+ Use char because int might match the return type of a GCC -+ builtin and then its argument prototype would still apply. */ -+#ifdef __cplusplus -+extern "C" -+#endif -+char seccomp_init (); -+int -+main () -+{ -+return seccomp_init (); -+ ; -+ return 0; -+} -+_ACEOF -+if ac_fn_c_try_link "$LINENO"; then : -+ ac_cv_lib_seccomp_seccomp_init=yes -+else -+ ac_cv_lib_seccomp_seccomp_init=no -+fi -+rm -f core conftest.err conftest.$ac_objext \ -+ conftest$ac_exeext conftest.$ac_ext -+LIBS=$ac_check_lib_save_LIBS -+fi -+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_seccomp_seccomp_init" >&5 -+$as_echo "$ac_cv_lib_seccomp_seccomp_init" >&6; } -+if test "x$ac_cv_lib_seccomp_seccomp_init" = xyes; then : -+ cat >>confdefs.h <<_ACEOF -+#define HAVE_LIBSECCOMP 1 -+_ACEOF -+ -+ LIBS="-lseccomp $LIBS" -+ -+else -+ as_fn_error $? "You must install the seccomp development package in order to compile lxc" "$LINENO" 5 -+fi -+ -+ -+cat >>confdefs.h <<_ACEOF -+#define ENABLE_SECCOMP 1 -+_ACEOF -+ -+ SECCOMP_LIBS=-lseccomp -+ -+fi -+ - if test "x$have_docbook" = "xyes"; then - ENABLE_DOCBOOK_TRUE= - ENABLE_DOCBOOK_FALSE='#' -@@ -5103,6 +5189,10 @@ - as_fn_error $? "conditional \"ENABLE_RPATH\" was never defined. - Usually this means the macro was only invoked conditionally." "$LINENO" 5 - fi -+if test -z "${ENABLE_SECCOMP_TRUE}" && test -z "${ENABLE_SECCOMP_FALSE}"; then -+ as_fn_error $? "conditional \"ENABLE_SECCOMP\" was never defined. -+Usually this means the macro was only invoked conditionally." "$LINENO" 5 -+fi - if test -z "${ENABLE_DOCBOOK_TRUE}" && test -z "${ENABLE_DOCBOOK_FALSE}"; then - as_fn_error $? "conditional \"ENABLE_DOCBOOK\" was never defined. - Usually this means the macro was only invoked conditionally." "$LINENO" 5 diff -Nru lxc-0.8.0~rc1/debian/patches/0098-config-file-includes lxc-1.0.0~alpha1/debian/patches/0098-config-file-includes --- lxc-0.8.0~rc1/debian/patches/0098-config-file-includes 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0098-config-file-includes 1970-01-01 00:00:00.000000000 +0000 @@ -1,69 +0,0 @@ -Index: lxc-0.8.0~rc1/src/lxc/confile.c -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/confile.c 2012-08-14 10:25:36.000000000 -0500 -+++ lxc-0.8.0~rc1/src/lxc/confile.c 2012-08-14 10:25:36.000000000 -0500 -@@ -74,6 +74,7 @@ - static int config_cap_drop(const char *, char *, struct lxc_conf *); - static int config_console(const char *, char *, struct lxc_conf *); - static int config_seccomp(const char *, char *, struct lxc_conf *); -+static int config_includefile(const char *, char *, struct lxc_conf *); - - typedef int (*config_cb)(const char *, char *, struct lxc_conf *); - -@@ -116,6 +117,7 @@ - { "lxc.cap.drop", config_cap_drop }, - { "lxc.console", config_console }, - { "lxc.seccomp", config_seccomp }, -+ { "lxc.include", config_includefile }, - }; - - static const size_t config_size = sizeof(config)/sizeof(struct config); -@@ -888,6 +890,12 @@ - return 0; - } - -+static int config_includefile(const char *key, char *value, -+ struct lxc_conf *lxc_conf) -+{ -+ return lxc_config_read(value, lxc_conf); -+} -+ - static int config_rootfs(const char *key, char *value, struct lxc_conf *lxc_conf) - { - if (strlen(value) >= MAXPATHLEN) { -Index: lxc-0.8.0~rc1/doc/lxc.conf.sgml.in -=================================================================== ---- lxc-0.8.0~rc1.orig/doc/lxc.conf.sgml.in 2012-08-14 10:25:36.000000000 -0500 -+++ lxc-0.8.0~rc1/doc/lxc.conf.sgml.in 2012-08-14 10:25:57.681331775 -0500 -@@ -640,6 +640,31 @@ - - - -+ -+ File includes -+ -+ A configuration file can cause other configuration files to -+ be included. In this way common configuration sections can -+ be grouped such that they can be updated in one place, rather -+ than needing to be separately updated in each container -+ configuration. -+ -+ -+ -+ -+ -+ -+ -+ -+ Specify the pathname for another file whose contents -+ should be treated as though they were a part of this -+ file. -+ -+ -+ -+ -+ -+ - - - diff -Nru lxc-0.8.0~rc1/debian/patches/0099-cleanup-after-template-help lxc-1.0.0~alpha1/debian/patches/0099-cleanup-after-template-help --- lxc-0.8.0~rc1/debian/patches/0099-cleanup-after-template-help 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0099-cleanup-after-template-help 1970-01-01 00:00:00.000000000 +0000 @@ -1,32 +0,0 @@ -Description: Cleanup partial container if -h was passed to template - If user calls 'lxc-create -t ubuntu -- -h' (as opposed to - 'lxc-create -t ubuntu -h') then the ubuntu template will print its - help then exit 0. Then lxc-create does not cleanup. So detect this - in lxc-create. -Author: Serge Hallyn -Forwarded: yes -Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/1031043 - -Index: lxc-fix-seccomp/src/lxc/lxc-create.in -=================================================================== ---- lxc-fix-seccomp.orig/src/lxc/lxc-create.in 2012-08-16 17:48:11.867917779 -0500 -+++ lxc-fix-seccomp/src/lxc/lxc-create.in 2012-08-16 18:04:43.735900985 -0500 -@@ -140,6 +140,18 @@ - esac - done - -+# If -h or --help was passed into the container, we'll want to cleanup -+# afterward -+wantedhelp=0 -+for var in "$@" -+do -+if [ "$var" = "-h" -o "$var" = "--help" ]; then -+ help -+ exit 1 -+fi -+done -+ -+ - if [ -z "$lxc_path" ]; then - echo "no configuration path defined !" - exit 1 diff -Nru lxc-0.8.0~rc1/debian/patches/01-lxc-directories.patch lxc-1.0.0~alpha1/debian/patches/01-lxc-directories.patch --- lxc-0.8.0~rc1/debian/patches/01-lxc-directories.patch 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/01-lxc-directories.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,35 +0,0 @@ -Author: Daniel Baumann -Description: - Trimming directories to use: - * /usr/lib/lxc instead of /usr/lib/lxc/lxc - * /usr/share/lxc/templates instead of /usr/lib/lxc/lxc/templates - -diff -Naurp lxc.orig/configure lxc/configure ---- lxc.orig/configure 2012-03-09 12:51:26.713705881 +0100 -+++ lxc/configure 2012-03-09 13:27:14.848357913 +0100 -@@ -4694,9 +4694,9 @@ LXCPATH="${with_config_path}" - - LXCROOTFSMOUNT="${with_rootfs_path}" - --LXCINITDIR='${libexecdir}/lxc' -+LXCINITDIR='${libexecdir}' - --LXCTEMPLATEDIR='${libdir}/lxc/templates' -+LXCTEMPLATEDIR='/usr/share/lxc/templates' - - - for ac_header in linux/netlink.h linux/genetlink.h -diff -Naurp lxc.orig/configure.ac lxc/configure.ac ---- lxc.orig/configure.ac 2012-03-09 12:51:26.713705881 +0100 -+++ lxc/configure.ac 2012-03-09 13:27:35.752463435 +0100 -@@ -62,8 +62,8 @@ AS_AC_EXPAND(LXC_GENERATE_DATE, "$(date) - - AC_SUBST(LXCPATH, "${with_config_path}") - AC_SUBST(LXCROOTFSMOUNT, "${with_rootfs_path}") --AC_SUBST(LXCINITDIR, ['${libexecdir}/lxc']) --AC_SUBST(LXCTEMPLATEDIR, ['${libdir}/lxc/templates']) -+AC_SUBST(LXCINITDIR, ['${libexecdir}']) -+AC_SUBST(LXCTEMPLATEDIR, ['/usr/share/lxc/templates']) - - AC_CHECK_HEADERS([linux/netlink.h linux/genetlink.h], - [], diff -Nru lxc-0.8.0~rc1/debian/patches/0100-template-cleanup-cache lxc-1.0.0~alpha1/debian/patches/0100-template-cleanup-cache --- lxc-0.8.0~rc1/debian/patches/0100-template-cleanup-cache 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0100-template-cleanup-cache 1970-01-01 00:00:00.000000000 +0000 @@ -1,127 +0,0 @@ -Description: Clean up cache if cache build is interrupted -Author: Serge Hallyn -Forwarded: yes -Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/1037331 - -Index: lxc-fixbugs/templates/lxc-ubuntu.in -=================================================================== ---- lxc-fixbugs.orig/templates/lxc-ubuntu.in 2012-08-17 11:15:50.246248000 -0500 -+++ lxc-fixbugs/templates/lxc-ubuntu.in 2012-08-17 13:54:31.873078514 -0500 -@@ -147,6 +147,12 @@ - fi - } - -+cleanup() -+{ -+ rm -rf $cache/partial-$arch -+ rm -rf $cache/rootfs-$arch -+} -+ - download_ubuntu() - { - cache=$1 -@@ -156,6 +162,7 @@ - packages=vim,ssh - echo "installing packages: $packages" - -+ trap cleanup EXIT SIGHUP SIGINT SIGTERM - # check the mini ubuntu was not already downloaded - mkdir -p "$cache/partial-$arch" - if [ $? -ne 0 ]; then -@@ -203,6 +210,10 @@ - fi - - mv "$1/partial-$arch" "$1/rootfs-$arch" -+ trap EXIT -+ trap SIGINT -+ trap SIGTERM -+ trap SIGHUP - echo "Download complete" - return 0 - } -Index: lxc-fixbugs/templates/lxc-ubuntu-cloud.in -=================================================================== ---- lxc-fixbugs.orig/templates/lxc-ubuntu-cloud.in 2012-08-17 11:15:50.246248000 -0500 -+++ lxc-fixbugs/templates/lxc-ubuntu-cloud.in 2012-08-17 13:55:32.297076309 -0500 -@@ -256,6 +256,11 @@ - - filename=`basename $url2` - -+wgetcleanup() -+{ -+ rm -f $filename -+} -+ - buildcleanup() - { - cd $rootfs -@@ -274,7 +279,7 @@ - xdir=`mktemp -d -p .` - tarname=`basename $url` - imgname="$release-*-cloudimg-$arch.img" -- trap buildcleanup EXIT -+ trap buildcleanup EXIT SIGHUP SIGINT SIGTERM - if [ $flushcache -eq 1 -o ! -f $cache/$tarname ]; then - rm -f $tarname - echo "Downloading cloud image from $url" -@@ -289,6 +294,9 @@ - rmdir $xdir - echo "New cloud image cache created" - trap EXIT -+ trap SIGHUP -+ trap SIGINT -+ trap SIGTERM - } - - mkdir -p /var/lock/subsys/ -@@ -301,9 +309,14 @@ - rm -f $filename - fi - -+ trap wgetcleanup EXIT SIGHUP SIGINT SIGTERM - if [ ! -f $filename ]; then - wget $url2 || build_root_tgz $url1 $filename - fi -+ trap EXIT -+ trap SIGHUP -+ trap SIGINT -+ trap SIGTERM - - echo "Extracting container rootfs" - mkdir -p $rootfs -Index: lxc-fixbugs/templates/lxc-debian.in -=================================================================== ---- lxc-fixbugs.orig/templates/lxc-debian.in 2012-08-17 11:15:50.246248000 -0500 -+++ lxc-fixbugs/templates/lxc-debian.in 2012-08-17 13:54:31.065078542 -0500 -@@ -95,6 +95,12 @@ - return 0 - } - -+cleanup() -+{ -+ rm -rf $cache/partial-$SUITE-$arch -+ rm -rf $cache/rootfs-$SUITE-$arch -+} -+ - download_debian() - { - packages=\ -@@ -111,6 +117,7 @@ - cache=$1 - arch=$2 - -+ trap cleanup EXIT SIGHUP SIGINT SIGTERM - # check the mini debian was not already downloaded - mkdir -p "$cache/partial-$SUITE-$arch" - if [ $? -ne 0 ]; then -@@ -130,6 +137,10 @@ - - mv "$1/partial-$SUITE-$arch" "$1/rootfs-$SUITE-$arch" - echo "Download complete." -+ trap EXIT -+ trap SIGINT -+ trap SIGTERM -+ trap SIGHUP - - return 0 - } diff -Nru lxc-0.8.0~rc1/debian/patches/0101-template-empty-apt-cache lxc-1.0.0~alpha1/debian/patches/0101-template-empty-apt-cache --- lxc-0.8.0~rc1/debian/patches/0101-template-empty-apt-cache 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0101-template-empty-apt-cache 1970-01-01 00:00:00.000000000 +0000 @@ -1,18 +0,0 @@ -Description: apt-get clean after debootstrapping a cache -Author: Serge Hallyn -Forwarded: yes -Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/1037626 - -Index: lxc/templates/lxc-ubuntu.in -=================================================================== ---- lxc.orig/templates/lxc-ubuntu.in 2012-08-16 20:59:13.555723709 -0500 -+++ lxc/templates/lxc-ubuntu.in 2012-08-16 21:57:32.959664457 -0500 -@@ -209,6 +209,8 @@ - return 1 - fi - -+ chroot "$1/partial-${arch}" apt-get clean -+ - mv "$1/partial-$arch" "$1/rootfs-$arch" - trap EXIT - trap SIGINT diff -Nru lxc-0.8.0~rc1/debian/patches/0102-lxc-start-d-check-privs lxc-1.0.0~alpha1/debian/patches/0102-lxc-start-d-check-privs --- lxc-0.8.0~rc1/debian/patches/0102-lxc-start-d-check-privs 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0102-lxc-start-d-check-privs 1970-01-01 00:00:00.000000000 +0000 @@ -1,38 +0,0 @@ -Description: exit early out lxc-start if insufficient privs and -d - Starting a container with insufficient privilege (correctly) fails - during lxc_init. However, if starting a daemonized container, we - daemonize before we get to that check. Therefore while the - container will fail to start, and the logfile will show this, the - 'lxc-start -n x -d' command will return success. For ease of - scripting, do a check for the required privilege before we exit. -Author: Serge Hallyn -Forwarded: yes -Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/918327 - -Index: lxc/src/lxc/lxc_start.c -=================================================================== ---- lxc.orig/src/lxc/lxc_start.c 2012-08-16 20:56:28.375771000 -0500 -+++ lxc/src/lxc/lxc_start.c 2012-08-17 11:01:57.738500926 -0500 -@@ -199,9 +199,19 @@ - free(console); - } - -- if (my_args.daemonize && daemon(0, 0)) { -- SYSERROR("failed to daemonize '%s'", my_args.name); -- return err; -+ if (my_args.daemonize) { -+ /* do an early check for needed privs, since otherwise the -+ * user won't see the error */ -+ -+ if (!lxc_caps_check()) { -+ ERROR("Not running with sufficient privilege"); -+ return err; -+ } -+ -+ if (daemon(0, 0)) { -+ SYSERROR("failed to daemonize '%s'", my_args.name); -+ return err; -+ } - } - - if (my_args.close_all_fds) diff -Nru lxc-0.8.0~rc1/debian/patches/0103-make-rootfs-location-optional lxc-1.0.0~alpha1/debian/patches/0103-make-rootfs-location-optional --- lxc-0.8.0~rc1/debian/patches/0103-make-rootfs-location-optional 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0103-make-rootfs-location-optional 1970-01-01 00:00:00.000000000 +0000 @@ -1,444 +0,0 @@ -Description: lxc-create: Make location of container rootfs configurable - Make 'dir' an explicit backing store type, which accepts '--dir rootfs' - as an option to specify a custom location for the container rootfs. Also - update lxc-destroy to now remove the rootfs separately, as removing - @LXCPATH@/$name may not hit it. -Author: Serge Hallyn -Forwarded: yes -Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/1019398 - -Index: lxc-fixbugs/src/lxc/lxc-create.in -=================================================================== ---- lxc-fixbugs.orig/src/lxc/lxc-create.in 2012-08-17 11:15:50.246248000 -0500 -+++ lxc-fixbugs/src/lxc/lxc-create.in 2012-08-17 11:23:01.885410188 -0500 -@@ -23,6 +23,7 @@ - usage() { - echo "usage: lxc-create -n [-f configuration] [-t template] [-h] [fsopts] -- [template_options]" - echo " fsopts: -B none" -+ echo " fsopts: -B dir --dir rootfs_dir" - echo " fsopts: -B lvm [--lvname lvname] [--vgname vgname] [--fstype fstype] [--fssize fssize]" - echo " fsopts: -B btrfs" - echo " flag is not necessary, if possible btrfs support will be used" -@@ -44,6 +45,7 @@ - echo "The container backing store can be altered using '-B'. By default it" - echo "is 'none', which is a simple directory tree under /var/lib/lxc//rootfs" - echo "Otherwise, the following option values may be relevant:" -+ echo "dir : [for dir] path for custom rootfs directory location" - echo "lvname : [for -lvm] name of lv in which to create lv," - echo " container-name by default" - echo "vgname : [for -lvm] name of vg in which to create lv, 'lxc' by default" -@@ -64,7 +66,7 @@ - } - - shortoptions='hn:f:t:B:' --longoptions='help,name:,config:,template:,backingstore:,fstype:,lvname:,vgname:,fssize:' -+longoptions='help,name:,config:,template:,backingstore:,fstype:,dir:,lvname:,vgname:,fssize:' - localstatedir=@LOCALSTATEDIR@ - lxc_path=@LXCPATH@ - bindir=@BINDIR@ -@@ -74,6 +76,7 @@ - fstype=ext4 - fssize=500M - vgname=lxc -+custom_rootfs="" - - getopt=$(getopt -o $shortoptions --longoptions $longoptions -- "$@") - if [ $? != 0 ]; then -@@ -109,6 +112,11 @@ - backingstore=$1 - shift - ;; -+ --dir) -+ shift -+ custom_rootfs=$1 -+ shift -+ ;; - --lvname) - shift - lvname=$1 -@@ -172,9 +180,13 @@ - exit 1 - fi - -+if [ -n "$custom_rootfs" -a "$backingstore" != "dir" ]; then -+ echo "--dir is only valid with -B dir" -+fi -+ - case "$backingstore" in -- lvm|none|btrfs|_unset) :;; -- *) echo "'$backingstore' is not known ('none', 'lvm', 'btrfs')" -+ dir|lvm|none|btrfs|_unset) :;; -+ *) echo "'$backingstore' is not known ('none', 'lvm', 'btrfs', 'dir')" - usage - exit 1 - ;; -@@ -263,6 +275,14 @@ - - cp $lxc_config $lxc_path/$lxc_name/config - -+if [ -n "$custom_rootfs" ]; then -+ if grep -q "lxc.rootfs" $lxc_path/$lxc_name/config ; then -+ echo "configuration file already specifies a lxc.rootfs" -+ exit 1 -+ fi -+ echo "lxc.rootfs = $custom_rootfs" >> $lxc_path/$lxc_name/config -+fi -+ - # Create the fs as needed - if [ $backingstore = "lvm" ]; then - [ -d "$rootfs" ] || mkdir $rootfs -Index: lxc-fixbugs/templates/lxc-ubuntu-cloud.in -=================================================================== ---- lxc-fixbugs.orig/templates/lxc-ubuntu-cloud.in 2012-08-17 11:15:50.246248000 -0500 -+++ lxc-fixbugs/templates/lxc-ubuntu-cloud.in 2012-08-17 12:44:34.405231670 -0500 -@@ -46,12 +46,12 @@ - EOF - fi - -+ grep -q "^lxc.rootfs" $path/config 2>/dev/null || echo "lxc.rootfs = $rootfs" >> $path/config - cat <> $path/config - lxc.utsname = $name - - lxc.tty = 4 - lxc.pts = 1024 --lxc.rootfs = $rootfs - lxc.mount = $path/fstab - lxc.arch = $arch - lxc.cap.drop = sys_module mac_admin -@@ -236,7 +236,13 @@ - exit 1 - fi - --rootfs=$path/rootfs -+# detect rootfs -+config="$path/config" -+if grep -q '^lxc.rootfs' $config 2>/dev/null ; then -+ rootfs=`grep 'lxc.rootfs =' $config | awk -F= '{ print $2 }'` -+else -+ rootfs=$path/rootfs -+fi - - type ubuntu-cloudimg-query - type wget -Index: lxc-fixbugs/templates/lxc-ubuntu.in -=================================================================== ---- lxc-fixbugs.orig/templates/lxc-ubuntu.in 2012-08-17 11:15:50.246248000 -0500 -+++ lxc-fixbugs/templates/lxc-ubuntu.in 2012-08-17 12:39:43.021242302 -0500 -@@ -304,13 +304,13 @@ - EOF - fi - -+ grep -q "^lxc.rootfs" $path/config 2>/dev/null || echo "lxc.rootfs = $rootfs" >> $path/config - cat <> $path/config - lxc.utsname = $name - - lxc.devttydir =$ttydir - lxc.tty = 4 - lxc.pts = 1024 --lxc.rootfs = $rootfs - lxc.mount = $path/fstab - lxc.arch = $arch - lxc.cap.drop = sys_module mac_admin mac_override -@@ -670,7 +670,13 @@ - exit 1 - fi - --rootfs=$path/rootfs -+# detect rootfs -+config="$path/config" -+if grep -q '^lxc.rootfs' $config 2>/dev/null ; then -+ rootfs=`grep 'lxc.rootfs =' $config | awk -F= '{ print $2 }'` -+else -+ rootfs=$path/rootfs -+fi - - install_ubuntu $rootfs $release $flushcache - if [ $? -ne 0 ]; then -Index: lxc-fixbugs/templates/lxc-altlinux.in -=================================================================== ---- lxc-fixbugs.orig/templates/lxc-altlinux.in 2012-08-17 11:15:50.246248000 -0500 -+++ lxc-fixbugs/templates/lxc-altlinux.in 2012-08-17 12:44:53.517230974 -0500 -@@ -239,11 +239,11 @@ - { - - mkdir -p $config_path -+ grep -q "^lxc.rootfs" $config_path/config 2>/dev/null || echo "lxc.rootfs = $rootfs_path" >> $config_path/config - cat <> $config_path/config - lxc.utsname = $name - lxc.tty = 4 - lxc.pts = 1024 --lxc.rootfs = $rootfs_path - lxc.mount = $config_path/fstab - #networking - lxc.network.type = $lxc_network_type -@@ -429,6 +429,11 @@ - exit 1 - fi - -+# check for 'lxc.rootfs' passed in through default config by lxc-create -+if grep -q '^lxc.rootfs' $path/config 2>/dev/null ; then -+ rootfs_path=`grep 'lxc.rootfs =' $path/config | awk -F= '{ print $2 }'` -+fi -+ - install_altlinux - if [ $? -ne 0 ]; then - echo "failed to install altlinux" -Index: lxc-fixbugs/templates/lxc-archlinux.in -=================================================================== ---- lxc-fixbugs.orig/templates/lxc-archlinux.in 2012-08-17 11:15:50.246248000 -0500 -+++ lxc-fixbugs/templates/lxc-archlinux.in 2012-08-17 12:41:11.365239080 -0500 -@@ -218,11 +218,11 @@ - # write container configuration files - function copy_configuration { - mkdir -p "${config_path}" -+ grep -q "^lxc.rootfs" "${config_path}/config" 2>/dev/null || echo "lxc.rootfs=${rootfs_path}" >> "${config_path}/config" - cat > "${config_path}/config" << EOF - lxc.utsname=${name} - lxc.tty=4 - lxc.pts=1024 --lxc.rootfs=${rootfs_path} - lxc.mount=${config_path}/fstab - #networking - lxc.network.type=${lxc_network_type} -@@ -419,6 +419,10 @@ - fi - - rootfs_path="${path}/rootfs" -+# check for 'lxc.rootfs' passed in through default config by lxc-create -+if grep -q '^lxc.rootfs' $path/config 2>/dev/null ; then -+ rootfs_path=`grep 'lxc.rootfs =' $path/config | awk -F= '{ print $2 }'` -+fi - config_path="${default_path}/${name}" - - revert() -Index: lxc-fixbugs/templates/lxc-busybox.in -=================================================================== ---- lxc-fixbugs.orig/templates/lxc-busybox.in 2012-08-17 11:15:50.246248000 -0500 -+++ lxc-fixbugs/templates/lxc-busybox.in 2012-08-17 12:41:56.633237426 -0500 -@@ -228,11 +228,11 @@ - rootfs=$2 - name=$3 - -+grep -q "^lxc.rootfs" $path/config 2>/dev/null || echo "lxc.rootfs = $rootfs" >> $path/config - cat <> $path/config - lxc.utsname = $name - lxc.tty = 1 - lxc.pts = 1 --lxc.rootfs = $rootfs - # uncomment the next line to run the container unconfined: - #lxc.aa_profile = unconfined - EOF -@@ -293,7 +293,13 @@ - exit 1 - fi - --rootfs=$path/rootfs -+# detect rootfs -+config="$path/config" -+if grep -q '^lxc.rootfs' $config 2>/dev/null ; then -+ rootfs=`grep 'lxc.rootfs =' $config | awk -F= '{ print $2 }'` -+else -+ rootfs=$path/rootfs -+fi - - install_busybox $rootfs $name - if [ $? -ne 0 ]; then -Index: lxc-fixbugs/templates/lxc-debian.in -=================================================================== ---- lxc-fixbugs.orig/templates/lxc-debian.in 2012-08-17 11:15:50.246248000 -0500 -+++ lxc-fixbugs/templates/lxc-debian.in 2012-08-17 12:45:52.777228812 -0500 -@@ -200,10 +200,10 @@ - rootfs=$2 - hostname=$3 - -+ grep -q "^lxc.rootfs" $path/config 2>/dev/null || echo "lxc.rootfs = $rootfs" >> $path/config - cat <> $path/config - lxc.tty = 4 - lxc.pts = 1024 --lxc.rootfs = $rootfs - lxc.utsname = $hostname - # uncomment the next line to run the container unconfined: - #lxc.aa_profile = unconfined -@@ -308,7 +308,14 @@ - exit 1 - fi - --rootfs=$path/rootfs -+# detect rootfs -+config="$path/config" -+if grep -q '^lxc.rootfs' $config 2>/dev/null ; then -+ rootfs=`grep 'lxc.rootfs =' $config | awk -F= '{ print $2 }'` -+else -+ rootfs=$path/rootfs -+fi -+ - - install_debian $rootfs - if [ $? -ne 0 ]; then -Index: lxc-fixbugs/templates/lxc-fedora.in -=================================================================== ---- lxc-fixbugs.orig/templates/lxc-fedora.in 2012-08-17 11:15:50.246248000 -0500 -+++ lxc-fixbugs/templates/lxc-fedora.in 2012-08-17 12:43:07.529234840 -0500 -@@ -231,11 +231,11 @@ - { - - mkdir -p $config_path -+ grep -q "^lxc.rootfs" $config_path/config 2>/dev/null || echo "lxc.rootfs = $rootfs_path" >> $config_path/config - cat <> $config_path/config - lxc.utsname = $name - lxc.tty = 4 - lxc.pts = 1024 --lxc.rootfs = $rootfs_path - lxc.mount = $config_path/fstab - - # uncomment the next line to run the container unconfined: -@@ -375,6 +375,10 @@ - - - rootfs_path=$path/rootfs -+# check for 'lxc.rootfs' passed in through default config by lxc-create -+if grep -q '^lxc.rootfs' $path/config 2>/dev/null ; then -+ rootfs_path=`grep 'lxc.rootfs =' $path/config | awk -F= '{ print $2 }'` -+fi - config_path=$default_path/$name - cache=$cache_base/$release - -Index: lxc-fixbugs/templates/lxc-lenny.in -=================================================================== ---- lxc-fixbugs.orig/templates/lxc-lenny.in 2012-08-17 11:15:50.246248000 -0500 -+++ lxc-fixbugs/templates/lxc-lenny.in 2012-08-17 12:46:15.065227998 -0500 -@@ -178,10 +178,10 @@ - rootfs=$2 - name=$3 - -+ grep -q "^lxc.rootfs" $path/config 2>/dev/null || echo "lxc.rootfs = $rootfs" >> $path/config - cat <> $path/config - lxc.tty = 4 - lxc.pts = 1024 --lxc.rootfs = $rootfs - # uncomment the next line to run the container unconfined: - #lxc.aa_profile = unconfined - -@@ -286,7 +286,13 @@ - exit 1 - fi - --rootfs=$path/rootfs -+# detect rootfs -+config="$path/config" -+if grep -q '^lxc.rootfs' $config 2>/dev/null ; then -+ rootfs=`grep 'lxc.rootfs =' $config | awk -F= '{ print $2 }'` -+else -+ rootfs=$path/rootfs -+fi - - install_debian $rootfs - if [ $? -ne 0 ]; then -Index: lxc-fixbugs/templates/lxc-opensuse.in -=================================================================== ---- lxc-fixbugs.orig/templates/lxc-opensuse.in 2012-08-17 11:15:50.246248000 -0500 -+++ lxc-fixbugs/templates/lxc-opensuse.in 2012-08-17 12:43:49.425233313 -0500 -@@ -254,12 +254,12 @@ - rootfs=$2 - name=$3 - -+ grep -q "^lxc.rootfs" $path/config 2>/dev/null || echo "lxc.rootfs = $rootfs" >> $path/config - cat <> $path/config - lxc.utsname = $name - - lxc.tty = 4 - lxc.pts = 1024 --lxc.rootfs = $rootfs - lxc.mount = $path/fstab - # uncomment the next line to run the container unconfined: - #lxc.aa_profile = unconfined -@@ -366,7 +366,13 @@ - exit 1 - fi - --rootfs=$path/rootfs -+# detect rootfs -+config="$path/config" -+if grep -q '^lxc.rootfs' $config 2>/dev/null ; then -+ rootfs=`grep 'lxc.rootfs =' $config | awk -F= '{ print $2 }'` -+else -+ rootfs=$path/rootfs -+fi - - install_opensuse $rootfs - if [ $? -ne 0 ]; then -Index: lxc-fixbugs/templates/lxc-sshd.in -=================================================================== ---- lxc-fixbugs.orig/templates/lxc-sshd.in 2012-08-17 11:15:50.246248000 -0500 -+++ lxc-fixbugs/templates/lxc-sshd.in 2012-08-17 12:44:09.937232563 -0500 -@@ -109,10 +109,10 @@ - rootfs=$2 - name=$3 - -+ grep -q "^lxc.rootfs" $path/config 2>/dev/null || echo "lxc.rootfs = $rootfs" >> $path/config - cat <> $path/config - lxc.utsname = $name - lxc.pts = 1024 --lxc.rootfs = $rootfs - # uncomment the next line to run the container unconfined: - #lxc.aa_profile = unconfined - lxc.mount.entry=/dev dev none ro,bind 0 0 -@@ -206,7 +206,13 @@ - exit 1 - fi - --rootfs=$path/rootfs -+# detect rootfs -+config="$path/config" -+if grep -q '^lxc.rootfs' $config 2>/dev/null ; then -+ rootfs=`grep 'lxc.rootfs =' $config | awk -F= '{ print $2 }'` -+else -+ rootfs=$path/rootfs -+fi - - install_sshd $rootfs - if [ $? -ne 0 ]; then -Index: lxc-fixbugs/doc/lxc-create.sgml.in -=================================================================== ---- lxc-fixbugs.orig/doc/lxc-create.sgml.in 2012-08-17 11:15:50.246248000 -0500 -+++ lxc-fixbugs/doc/lxc-create.sgml.in 2012-08-17 11:49:13.701352838 -0500 -@@ -123,9 +123,13 @@ - - - -- 'backingstore' is one of 'none', 'lvm', or 'btrfs'. The -+ 'backingstore' is one of 'none', 'dir', 'lvm', or 'btrfs'. The - default is 'none', meaning that the container root filesystem - will be a directory under @LXCPATH@/container/rootfs. -+ 'dir' has the same meaning as 'none', but also allows the optional -+ --dir ROOTFS to be specified, meaning -+ that the container rootfs should be placed under the specified path, -+ rather than the default. - The option 'btrfs' need not be specified as it will be used - automatically if the @LXCPATH@ filesystem is found to - be btrfs. If backingstore is 'lvm', then an lvm block device will be -Index: lxc-fixbugs/src/lxc/lxc-destroy.in -=================================================================== ---- lxc-fixbugs.orig/src/lxc/lxc-destroy.in 2012-08-17 11:15:50.246248000 -0500 -+++ lxc-fixbugs/src/lxc/lxc-destroy.in 2012-08-17 12:21:11.493282860 -0500 -@@ -98,15 +98,19 @@ - # If LVM partition, destroy it. If anything else, ignore it. We'll support - # deletion of others later. - rootdev=`grep lxc.rootfs $lxc_path/$lxc_name/config 2>/dev/null | sed -e 's/^[^/]*/\//'` --if [ ! -z "$rootdev" ]; then -+if [ -n "$rootdev" ]; then - if [ -b "$rootdev" -o -h "$rootdev" ]; then - lvdisplay $rootdev > /dev/null 2>&1 - if [ $? -eq 0 ]; then - echo "removing backing store: $rootdev" - lvremove -f $rootdev - fi -+ elif [ -d "$rootdev" ]; then -+ # In case rootfs is not under $lxc_path/$lxc_name, remove it -+ rm -rf --one-file-system --preserve-root $rootdev - fi - fi -+ - # recursively remove the container to remove old container configuration - rm -rf --one-file-system --preserve-root $lxc_path/$lxc_name - diff -Nru lxc-0.8.0~rc1/debian/patches/0104-add-option-to-lxc-attach-to-select-ns lxc-1.0.0~alpha1/debian/patches/0104-add-option-to-lxc-attach-to-select-ns --- lxc-0.8.0~rc1/debian/patches/0104-add-option-to-lxc-attach-to-select-ns 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0104-add-option-to-lxc-attach-to-select-ns 1970-01-01 00:00:00.000000000 +0000 @@ -1,476 +0,0 @@ -This patch adds the -s/--namespaces option to lxc-attach that works -analogously to lxc-unshare, allowing the user to select the namespaces the -process should be attached to. - -User namespaces are supported, under the assumption that the file in -/proc/pid/ns will be called 'usr'. Currently, user namespaces will be -skipped (without having lxc-attach fail, unlike for other namespaces) if the -kernel lacks support. - -Signed-off-by: Christian Seiler -Cc: Stéphane Graber -Cc: Daniel Lezcano -Acked-by: Serge Hallyn ---- - doc/lxc-attach.sgml.in | 99 +++++++++++++++++++++++++++++++++++++++++++++-- - src/lxc/attach.c | 72 ++++++++++++++++++++++++++++++++-- - src/lxc/attach.h | 2 +- - src/lxc/lxc_attach.c | 28 ++++++++++++- - src/lxc/lxc_unshare.c | 46 ---------------------- - src/lxc/namespace.c | 46 ++++++++++++++++++++++ - src/lxc/namespace.h | 3 + - 7 files changed, 236 insertions(+), 60 deletions(-) - -Index: lxc-0.8.0~rc1/doc/lxc-attach.sgml.in -=================================================================== ---- lxc-0.8.0~rc1.orig/doc/lxc-attach.sgml.in 2012-03-01 17:02:37.000000000 -0600 -+++ lxc-0.8.0~rc1/doc/lxc-attach.sgml.in 2012-08-21 16:08:59.384172156 -0500 -@@ -49,7 +49,8 @@ - - lxc-attach -n - name -a -- arch -e -+ arch -e -s -+ namespaces - -- command - - -@@ -122,6 +123,29 @@ - - - -+ -+ -+ -+ -+ -+ -+ Specify the namespaces to attach to, as a pipe-separated liste, -+ e.g. NETWORK|IPC. Allowed values are -+ MOUNT, PID, -+ UTSNAME, IPC, -+ USER and -+ NETWORK. This allows one to change -+ the context of the process to e.g. the network namespace of the -+ container while retaining the other namespaces as those of the -+ host. -+ -+ -+ Important: This option implies -+ . -+ -+ -+ -+ - - - -@@ -144,19 +168,84 @@ - - - To deactivate the network link eth1 of a running container that -- does not have the NET_ADMIN capability, use the -- option to use increased capabilities: -+ does not have the NET_ADMIN capability, use either the -+ option to use increased capabilities, -+ assuming the ip tool is installed: - - lxc-attach -n container -e -- /sbin/ip link delete eth1 - -+ Or, alternatively, use the to use the -+ tools installed on the host outside the container: -+ -+ lxc-attach -n container -s NETWORK -- /sbin/ip link delete eth1 -+ - - - - -+ Compatibility -+ -+ Attaching completely (including the pid and mount namespaces) to a -+ container requires a patched kernel, please see the lxc website for -+ details. lxc-attach will fail in that case if -+ used with an unpatched kernel. -+ -+ -+ Nevertheless, it will succeed on an unpatched kernel of version 3.0 -+ or higher if the option is used to restrict the -+ namespaces that the process is to be attached to to one or more of -+ NETWORK, IPC -+ and UTSNAME. -+ -+ -+ Attaching to user namespaces is currently completely unsupported -+ by the kernel. User namespaces will be skipped (but will not cause -+ lxc-attach to fail) unless used with a future -+ version of the kernel that supports this. -+ -+ -+ -+ -+ Notes -+ -+ The Linux /proc and -+ /sys filesystems contain information -+ about some quantities that are affected by namespaces, such as -+ the directories named after process ids in -+ /proc or the network interface infromation -+ in /sys/class/net. The namespace of the -+ process mounting the pseudo-filesystems determines what information -+ is shown, not the namespace of the process -+ accessing /proc or -+ /sys. -+ -+ -+ If one uses the option to only attach to -+ the pid namespace of a container, but not its mount namespace -+ (which will contain the /proc of the -+ container and not the host), the contents of -+ will reflect that of the host and not the container. Analogously, -+ the same issue occurs when reading the contents of -+ /sys/class/net and attaching to just -+ the network namespace. -+ -+ -+ A workaround is to use lxc-unshare to unshare -+ the mount namespace after using lxc-attach with -+ -s PID and/or -s -+ NETWORK and then unmount and then mount again both -+ pseudo-filesystems within that new mount namespace, before -+ executing a program/script that relies on this information to be -+ correct. -+ -+ -+ -+ - Security - -- The should be used with care, as it may break -- the isolation of the containers if used improperly. -+ The and options should -+ be used with care, as it may break the isolation of the containers -+ if used improperly. - - - -Index: lxc-0.8.0~rc1/src/lxc/attach.c -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/attach.c 2012-03-01 15:42:19.000000000 -0600 -+++ lxc-0.8.0~rc1/src/lxc/attach.c 2012-08-21 16:08:59.384172156 -0500 -@@ -226,13 +226,23 @@ - return 0; - } - --int lxc_attach_to_ns(pid_t pid) -+int lxc_attach_to_ns(pid_t pid, int which) - { - char path[MAXPATHLEN]; -- char *ns[] = { "pid", "mnt", "net", "ipc", "uts" }; -- const int size = sizeof(ns) / sizeof(char *); -+ /* TODO: we assume that the file in /proc for attaching to user -+ * namespaces will be called /proc/$pid/ns/usr, in accordance -+ * with the naming convention of previous namespaces. Once the -+ * kernel really supports setns() on a user namespace, make sure -+ * the array here matches the array in the kernel -+ */ -+ static char *ns[] = { "mnt", "pid", "uts", "ipc", "usr", "net" }; -+ static int flags[] = { -+ CLONE_NEWNS, CLONE_NEWPID, CLONE_NEWUTS, CLONE_NEWIPC, -+ CLONE_NEWUSER, CLONE_NEWNET -+ }; -+ static const int size = sizeof(ns) / sizeof(char *); - int fd[size]; -- int i; -+ int i, j, saved_errno; - - snprintf(path, MAXPATHLEN, "/proc/%d/ns", pid); - if (access(path, X_OK)) { -@@ -241,17 +251,69 @@ - } - - for (i = 0; i < size; i++) { -+ /* ignore if we are not supposed to attach -+ * to that namespace -+ */ -+ if (which != -1 && !(which & flags[i])) { -+ fd[i] = -1; -+ continue; -+ } - snprintf(path, MAXPATHLEN, "/proc/%d/ns/%s", pid, ns[i]); - fd[i] = open(path, O_RDONLY); - if (fd[i] < 0) { -+ /* there is currently no support in the kernel for -+ * attaching to user namespaces - therefore, we -+ * ignore the error, if the file does not exist -+ */ -+ if (flags[i] == CLONE_NEWUSER && errno == ENOENT) { -+ if (which != -1) { -+ /* we don't want the error -+ * message on every full attach, -+ * so we only show it if the -+ * user really requested it -+ * explicitly -+ */ -+ ERROR("Kernel does not support " -+ "attaching to user " -+ "namespaces, skipping."); -+ } else { -+ /* but do show it as a debug -+ * message otherwise, so users -+ * aren't completely left in the -+ * dark -+ */ -+ DEBUG("Kernel does not support " -+ "attaching to user " -+ "namespaces, skipping."); -+ } -+ fd[i] = -1; -+ continue; -+ } -+ -+ saved_errno = errno; -+ -+ /* close all already opened files before we return -+ * an error, so we don't leak file descriptors if -+ * the caller decides to continue nontheless -+ */ -+ for (j = 0; j < i; j++) -+ close(fd[j]); -+ - SYSERROR("failed to open '%s'", path); -+ errno = saved_errno; - return -1; - } - } - - for (i = 0; i < size; i++) { -- if (setns(fd[i], 0)) { -+ if (fd[i] >= 0 && setns(fd[i], 0)) { -+ saved_errno = errno; -+ -+ for (j = i; j < size; j++) -+ close(fd[j]); -+ - SYSERROR("failed to set namespace '%s'", ns[i]); -+ errno = saved_errno; - return -1; - } - -Index: lxc-0.8.0~rc1/src/lxc/attach.h -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/attach.h 2012-03-01 15:42:19.000000000 -0600 -+++ lxc-0.8.0~rc1/src/lxc/attach.h 2012-08-21 16:09:21.224171360 -0500 -@@ -42,7 +42,7 @@ - extern void lxc_proc_free_context_info(struct lxc_proc_context_info *info); - - extern int lxc_attach_proc_to_cgroups(pid_t pid, struct lxc_proc_context_info *ctx); --extern int lxc_attach_to_ns(pid_t other_pid); -+extern int lxc_attach_to_ns(pid_t other_pid, int which); - extern int lxc_attach_drop_privs(struct lxc_proc_context_info *ctx); - - #endif -Index: lxc-0.8.0~rc1/src/lxc/lxc_attach.c -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/lxc_attach.c 2012-03-01 15:42:19.000000000 -0600 -+++ lxc-0.8.0~rc1/src/lxc/lxc_attach.c 2012-08-21 16:08:59.384172156 -0500 -@@ -40,20 +40,24 @@ - #include "start.h" - #include "sync.h" - #include "log.h" -+#include "namespace.h" - - lxc_log_define(lxc_attach_ui, lxc); - - static const struct option my_longopts[] = { - {"elevated-privileges", no_argument, 0, 'e'}, - {"arch", required_argument, 0, 'a'}, -+ {"namespaces", required_argument, 0, 's'}, - LXC_COMMON_OPTIONS - }; - - static int elevated_privileges = 0; - static signed long new_personality = -1; -+static int namespace_flags = -1; - - static int my_parser(struct lxc_arguments* args, int c, char* arg) - { -+ int ret; - switch (c) { - case 'e': elevated_privileges = 1; break; - case 'a': -@@ -63,6 +67,12 @@ - return -1; - } - break; -+ case 's': -+ namespace_flags = 0; -+ ret = lxc_fill_namespace_flags(arg, &namespace_flags); -+ if (ret) -+ return -1; -+ break; - } - - return 0; -@@ -83,7 +93,13 @@ - WARNING: This may leak privleges into the container.\n\ - Use with care.\n\ - -a, --arch=ARCH Use ARCH for program instead of container's own\n\ -- architecture.\n", -+ architecture.\n\ -+ -s, --namespaces=FLAGS\n\ -+ Don't attach to all the namespaces of the container\n\ -+ but just to the following OR'd list of flags:\n\ -+ MOUNT, PID, UTSNAME, IPC, USER or NETWORK\n\ -+ WARNING: Using -s implies -e, it may therefore\n\ -+ leak privileges into the container. Use with care.", - .options = my_longopts, - .parser = my_parser, - .checker = NULL, -@@ -111,7 +127,13 @@ - my_args.progname, my_args.quiet); - if (ret) - return ret; -- -+ -+ /* if we do not attach to all namespaces, we will assume -+ * elevated privileges by default anyway. -+ */ -+ if (namespace_flags != -1) -+ elevated_privileges = 1; -+ - init_pid = get_init_pid(my_args.name); - if (init_pid < 0) { - ERROR("failed to get the init pid"); -@@ -178,7 +200,7 @@ - - curdir = get_current_dir_name(); - -- ret = lxc_attach_to_ns(init_pid); -+ ret = lxc_attach_to_ns(init_pid, namespace_flags); - if (ret < 0) { - ERROR("failed to enter the namespace"); - return -1; -Index: lxc-0.8.0~rc1/src/lxc/lxc_unshare.c -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/lxc_unshare.c 2012-08-21 16:08:28.000000000 -0500 -+++ lxc-0.8.0~rc1/src/lxc/lxc_unshare.c 2012-08-21 16:08:59.384172156 -0500 -@@ -84,52 +84,6 @@ - return uid; - } - --static char *namespaces_list[] = { -- "MOUNT", "PID", "UTSNAME", "IPC", -- "USER", "NETWORK" --}; --static int cloneflags_list[] = { -- CLONE_NEWNS, CLONE_NEWPID, CLONE_NEWUTS, CLONE_NEWIPC, -- CLONE_NEWUSER, CLONE_NEWNET --}; -- --static int lxc_namespace_2_cloneflag(char *namespace) --{ -- int i, len; -- len = sizeof(namespaces_list)/sizeof(namespaces_list[0]); -- for (i = 0; i < len; i++) -- if (!strcmp(namespaces_list[i], namespace)) -- return cloneflags_list[i]; -- -- ERROR("invalid namespace name %s", namespace); -- return -1; --} -- --static int lxc_fill_namespace_flags(char *flaglist, int *flags) --{ -- char *token, *saveptr = NULL; -- int aflag; -- -- if (!flaglist) { -- ERROR("need at least one namespace to unshare"); -- return -1; -- } -- -- token = strtok_r(flaglist, "|", &saveptr); -- while (token) { -- -- aflag = lxc_namespace_2_cloneflag(token); -- if (aflag < 0) -- return -1; -- -- *flags |= aflag; -- -- token = strtok_r(NULL, "|", &saveptr); -- } -- return 0; --} -- -- - struct start_arg { - char ***args; - int *flags; -Index: lxc-0.8.0~rc1/src/lxc/namespace.c -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/namespace.c 2012-03-01 15:42:19.000000000 -0600 -+++ lxc-0.8.0~rc1/src/lxc/namespace.c 2012-08-21 16:08:59.384172156 -0500 -@@ -69,3 +69,49 @@ - - return ret; - } -+ -+static char *namespaces_list[] = { -+ "MOUNT", "PID", "UTSNAME", "IPC", -+ "USER", "NETWORK" -+}; -+static int cloneflags_list[] = { -+ CLONE_NEWNS, CLONE_NEWPID, CLONE_NEWUTS, CLONE_NEWIPC, -+ CLONE_NEWUSER, CLONE_NEWNET -+}; -+ -+int lxc_namespace_2_cloneflag(char *namespace) -+{ -+ int i, len; -+ len = sizeof(namespaces_list)/sizeof(namespaces_list[0]); -+ for (i = 0; i < len; i++) -+ if (!strcmp(namespaces_list[i], namespace)) -+ return cloneflags_list[i]; -+ -+ ERROR("invalid namespace name %s", namespace); -+ return -1; -+} -+ -+int lxc_fill_namespace_flags(char *flaglist, int *flags) -+{ -+ char *token, *saveptr = NULL; -+ int aflag; -+ -+ if (!flaglist) { -+ ERROR("need at least one namespace to unshare/attach"); -+ return -1; -+ } -+ -+ token = strtok_r(flaglist, "|", &saveptr); -+ while (token) { -+ -+ aflag = lxc_namespace_2_cloneflag(token); -+ if (aflag < 0) -+ return -1; -+ -+ *flags |= aflag; -+ -+ token = strtok_r(NULL, "|", &saveptr); -+ } -+ return 0; -+} -+ -Index: lxc-0.8.0~rc1/src/lxc/namespace.h -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/namespace.h 2012-03-01 15:42:19.000000000 -0600 -+++ lxc-0.8.0~rc1/src/lxc/namespace.h 2012-08-21 16:08:59.384172156 -0500 -@@ -50,4 +50,7 @@ - - extern pid_t lxc_clone(int (*fn)(void *), void *arg, int flags); - -+extern int lxc_namespace_2_cloneflag(char *namespace); -+extern int lxc_fill_namespace_flags(char *flaglist, int *flags); -+ - #endif diff -Nru lxc-0.8.0~rc1/debian/patches/0105-lxc-attach-add-R-option lxc-1.0.0~alpha1/debian/patches/0105-lxc-attach-add-R-option --- lxc-0.8.0~rc1/debian/patches/0105-lxc-attach-add-R-option 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0105-lxc-attach-add-R-option 1970-01-01 00:00:00.000000000 +0000 @@ -1,226 +0,0 @@ -When attaching to only some namespaces of the container but not the mount -namespace, the contents of /sys and /proc of the host system do not properly -reflect the context of the container's pid and/or network namespaces, and -possibly others. - -The introduced -R option adds the possibility to additionally unshare the -mount namespace (when it is not being attached) and remount /sys and /proc -in order for those filesystems to properly reflect the container's context -even when only attaching to some of the namespaces. - -Signed-off-by: Christian Seiler -Cc: Stéphane Graber -Cc: Daniel Lezcano -Acked-by: Serge Hallyn ---- - doc/lxc-attach.sgml.in | 42 ++++++++++++++++++++++++++++++++++-------- - src/lxc/attach.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ - src/lxc/attach.h | 1 + - src/lxc/lxc_attach.c | 27 ++++++++++++++++++++++++++- - 4 files changed, 105 insertions(+), 9 deletions(-) - -Index: lxc-0.8.0~rc1/doc/lxc-attach.sgml.in -=================================================================== ---- lxc-0.8.0~rc1.orig/doc/lxc-attach.sgml.in 2012-08-21 16:08:59.000000000 -0500 -+++ lxc-0.8.0~rc1/doc/lxc-attach.sgml.in 2012-08-21 16:09:39.140170707 -0500 -@@ -50,7 +50,7 @@ - lxc-attach -n - name -a - arch -e -s -- namespaces -+ namespaces -R - -- command - - -@@ -146,6 +146,29 @@ - - - -+ -+ -+ -+ -+ -+ -+ When using and the mount namespace is not -+ included, this flag will cause lxc-attach -+ to remount /proc and -+ /sys to reflect the current other -+ namespace contexts. -+ -+ -+ Please see the Notes section for more -+ details. -+ -+ -+ This option will be ignored if one tries to attach to the -+ mount namespace anyway. -+ -+ -+ -+ - - - -@@ -230,13 +253,16 @@ - the network namespace. - - -- A workaround is to use lxc-unshare to unshare -- the mount namespace after using lxc-attach with -- -s PID and/or -s -- NETWORK and then unmount and then mount again both -- pseudo-filesystems within that new mount namespace, before -- executing a program/script that relies on this information to be -- correct. -+ To work around this problem, the flag provides -+ the option to remount /proc and -+ /sys in order for them to reflect the -+ network/pid namespace context of the attached process. In order -+ not to interfere with the host's actual filesystem, the mount -+ namespace will be unshared (like lxc-unshare -+ does) before this is done, esentially giving the process a new -+ mount namespace, which is identical to the hosts's mount namespace -+ except for the /proc and -+ /sys filesystems. - - - -Index: lxc-0.8.0~rc1/src/lxc/attach.c -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/attach.c 2012-08-21 16:08:59.000000000 -0500 -+++ lxc-0.8.0~rc1/src/lxc/attach.c 2012-08-21 16:09:52.908170203 -0500 -@@ -30,6 +30,7 @@ - #include - #include - #include -+#include - - #if !HAVE_DECL_PR_CAPBSET_DROP - #define PR_CAPBSET_DROP 24 -@@ -321,6 +322,49 @@ - } - - return 0; -+} -+ -+int lxc_attach_remount_sys_proc() -+{ -+ int ret; -+ -+ ret = unshare(CLONE_NEWNS); -+ if (ret < 0) { -+ SYSERROR("failed to unshare mount namespace: %s", strerror(errno)); -+ return -1; -+ } -+ -+ /* assume /proc is always mounted, so remount it */ -+ ret = umount2("/proc", MNT_DETACH); -+ if (ret < 0) { -+ SYSERROR("failed to unmount /proc: %s", strerror(errno)); -+ return -1; -+ } -+ -+ ret = mount("none", "/proc", "proc", 0, NULL); -+ if (ret < 0) { -+ SYSERROR("failed to remount /proc: %s", strerror(errno)); -+ return -1; -+ } -+ -+ /* try to umount /sys - if it's not a mount point, -+ * we'll get EINVAL, then we ignore it because it -+ * may not have been mounted in the first place -+ */ -+ ret = umount2("/sys", MNT_DETACH); -+ if (ret < 0 && errno != EINVAL) { -+ SYSERROR("failed to unmount /sys: %s", strerror(errno)); -+ return -1; -+ } else if (ret == 0) { -+ /* remount it */ -+ ret = mount("none", "/sys", "sysfs", 0, NULL); -+ if (ret < 0) { -+ SYSERROR("failed to remount /sys: %s", strerror(errno)); -+ return -1; -+ } -+ } -+ -+ return 0; - } - - int lxc_attach_drop_privs(struct lxc_proc_context_info *ctx) -Index: lxc-0.8.0~rc1/src/lxc/attach.h -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/attach.h 2012-08-21 16:09:21.000000000 -0500 -+++ lxc-0.8.0~rc1/src/lxc/attach.h 2012-08-21 16:09:39.152170705 -0500 -@@ -43,6 +43,7 @@ - - extern int lxc_attach_proc_to_cgroups(pid_t pid, struct lxc_proc_context_info *ctx); - extern int lxc_attach_to_ns(pid_t other_pid, int which); -+extern int lxc_attach_remount_sys_proc(); - extern int lxc_attach_drop_privs(struct lxc_proc_context_info *ctx); - - #endif -Index: lxc-0.8.0~rc1/src/lxc/lxc_attach.c -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/lxc_attach.c 2012-08-21 16:08:59.000000000 -0500 -+++ lxc-0.8.0~rc1/src/lxc/lxc_attach.c 2012-08-21 16:09:39.156170706 -0500 -@@ -48,18 +48,21 @@ - {"elevated-privileges", no_argument, 0, 'e'}, - {"arch", required_argument, 0, 'a'}, - {"namespaces", required_argument, 0, 's'}, -+ {"remount-sys-proc", no_argument, 0, 'R'}, - LXC_COMMON_OPTIONS - }; - - static int elevated_privileges = 0; - static signed long new_personality = -1; - static int namespace_flags = -1; -+static int remount_sys_proc = 0; - - static int my_parser(struct lxc_arguments* args, int c, char* arg) - { - int ret; - switch (c) { - case 'e': elevated_privileges = 1; break; -+ case 'R': remount_sys_proc = 1; break; - case 'a': - new_personality = lxc_config_parse_arch(arg); - if (new_personality < 0) { -@@ -99,7 +102,12 @@ - but just to the following OR'd list of flags:\n\ - MOUNT, PID, UTSNAME, IPC, USER or NETWORK\n\ - WARNING: Using -s implies -e, it may therefore\n\ -- leak privileges into the container. Use with care.", -+ leak privileges into the container. Use with care.\n\ -+ -R, --remount-sys-proc\n\ -+ Remount /sys and /proc if not attaching to the\n\ -+ mount namespace when using -s in order to properly\n\ -+ reflect the correct namespace context. See the\n\ -+ lxc-attach(1) manual page for details.\n", - .options = my_longopts, - .parser = my_parser, - .checker = NULL, -@@ -206,6 +214,23 @@ - return -1; - } - -+ /* if the user wants to attach to namespaces that don't -+ * include the mount namespace, and the -R option was -+ * specified, unshare the mount namespace (but DON'T -+ * attach to that of the container) and remount /sys and -+ * /proc in that new mount namespace so that they -+ * represent the current state of the other namespaces -+ * (i.e. /sys/class/net reflects the current network -+ * namespace and /proc contents reflects the current -+ * pid namespace) -+ */ -+ if (namespace_flags != -1 && !(namespace_flags & CLONE_NEWNS) && remount_sys_proc) { -+ ret = lxc_attach_remount_sys_proc(); -+ if (ret < 0) { -+ return -1; -+ } -+ } -+ - if (curdir && chdir(curdir)) - WARN("could not change directory to '%s'", curdir); - diff -Nru lxc-0.8.0~rc1/debian/patches/02-lxc-distclean.patch lxc-1.0.0~alpha1/debian/patches/02-lxc-distclean.patch --- lxc-0.8.0~rc1/debian/patches/02-lxc-distclean.patch 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/02-lxc-distclean.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ -Author: Daniel Baumann -Description: - Temporarily renaming distclean target until fixed upstream, - it removes too many files and causes FTBFS when build twice - in a row (Closes: #615485). - -diff -Naurp lxc.orig/config/Makefile.am lxc/config/Makefile.am ---- lxc.orig/config/Makefile.am 2011-07-12 17:57:02.445883846 +0200 -+++ lxc/config/Makefile.am 2011-07-12 17:56:17.257659771 +0200 -@@ -1,2 +1,2 @@ --distclean: -+maintainerclean: - @$(RM) -f compile config.guess config.sub depcomp install-sh ltmain.sh missing Makefile.in Makefile -diff -Naurp lxc.orig/config/Makefile.in lxc/config/Makefile.in ---- lxc.orig/config/Makefile.in 2011-07-12 17:57:02.445883846 +0200 -+++ lxc/config/Makefile.in 2011-07-12 17:56:48.241813412 +0200 -@@ -335,7 +335,7 @@ uninstall-am: - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am - --distclean: -+maintainerclean: - @$(RM) -f compile config.guess config.sub depcomp install-sh ltmain.sh missing Makefile.in Makefile - - # Tell versions [3.59,3.63) of GNU make to not export all variables. diff -Nru lxc-0.8.0~rc1/debian/patches/0200-liblxc lxc-1.0.0~alpha1/debian/patches/0200-liblxc --- lxc-0.8.0~rc1/debian/patches/0200-liblxc 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0200-liblxc 1970-01-01 00:00:00.000000000 +0000 @@ -1,4164 +0,0 @@ -Description: liblxc work by Serge Hallyn - -Index: lxc/runapitests.bash -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ lxc/runapitests.bash 2012-08-24 09:23:58.516340000 -0500 -@@ -0,0 +1,32 @@ -+#!/bin/bash -+ -+cleanup() { -+ rm -f /etc/lxc/test-busybox.conf -+ rm -f liblxc.so.0 -+} -+ -+if [ `id -u` -ne 0 ]; then -+ echo "Run as root" -+ exit 1 -+fi -+ -+cat > /etc/lxc/test-busybox.conf << EOF -+lxc.network.type=veth -+lxc.network.link=lxcbr0 -+lxc.network.flags=up -+EOF -+ -+[ -f liblxc.so.0 ] || ln -s src/lxc/liblxc.so ./liblxc.so.0 -+export LD_LIBRARY_PATH=. -+TESTS="containertests locktests startone" -+for curtest in $TESTS; do -+ echo "running $curtest" -+ ./src/tests/$curtest -+ if [ $? -ne 0 ]; then -+ echo "Test $curtest failed. Stopping" -+ cleanup -+ exit 1 -+ fi -+done -+echo "All tests passed" -+cleanup -Index: lxc/configure.ac -=================================================================== ---- lxc.orig/configure.ac 2012-08-24 09:23:58.516340000 -0500 -+++ lxc/configure.ac 2012-08-24 09:23:58.516340000 -0500 -@@ -179,6 +179,8 @@ - src/lxc/lxc-shutdown - src/lxc/lxc-destroy - -+ src/tests/Makefile -+ - ]) - AC_CONFIG_COMMANDS([default],[[]],[[]]) - AC_OUTPUT -Index: lxc/src/Makefile.am -=================================================================== ---- lxc.orig/src/Makefile.am 2012-08-24 09:23:58.516340000 -0500 -+++ lxc/src/Makefile.am 2012-08-24 09:23:58.516340000 -0500 -@@ -1 +1 @@ --SUBDIRS = lxc -+SUBDIRS = lxc tests -Index: lxc/src/tests/Makefile.am -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ lxc/src/tests/Makefile.am 2012-08-24 09:23:58.516340000 -0500 -@@ -0,0 +1,17 @@ -+LDADD = ../lxc/liblxc.so -lrt -+containertests_SOURCES = containertests.c -+locktests_SOURCES = locktests.c -+startone_SOURCES = startone.c -+destroytest_SOURCES = destroytest.c -+saveconfig_SOURCES = saveconfig.c -+createtest_SOURCES = createtest.c -+shutdowntest_SOURCES = shutdowntest.c -+get_item_SOURCES = get_item.c -+getkeys_SOURCES = getkeys.c -+ -+AM_CFLAGS=-I$(top_srcdir)/src \ -+ -DLXCROOTFSMOUNT=\"$(LXCROOTFSMOUNT)\" \ -+ -DLXCPATH=\"$(LXCPATH)\" \ -+ -DLXCINITDIR=\"$(LXCINITDIR)\" -+ -+bin_PROGRAMS = containertests locktests startone destroytest saveconfig createtest shutdowntest get_item getkeys -Index: lxc/src/tests/locktests.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ lxc/src/tests/locktests.c 2012-08-24 09:23:58.516340000 -0500 -@@ -0,0 +1,239 @@ -+/* liblxcapi -+ * -+ * Copyright © 2012 Serge Hallyn . -+ * Copyright © 2012 Canonical Ltd. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2, as -+ * published by the Free Software Foundation. -+ * -+ * 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., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ */ -+#include "../lxc/lxclock.h" -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define mycontainername "lxctest.sem" -+#define TIMEOUT_SECS 3 -+ -+int timedout; -+int pid_to_kill; -+ -+void timeouthandler(int sig) -+{ -+ // timeout received -+ timedout = 1; -+ kill(pid_to_kill, SIGTERM); -+} -+ -+void starttimer(int secs) -+{ -+ timedout = 0; -+ signal(SIGALRM, timeouthandler); -+ alarm(secs); -+} -+void stoptimer(void) -+{ -+ alarm(0); -+ signal(SIGALRM, NULL); -+} -+ -+int test_one_lock(sem_t *lock) -+{ -+ int ret; -+ starttimer(TIMEOUT_SECS); -+ ret = lxclock(lock, TIMEOUT_SECS*2); -+ stoptimer(); -+ if (ret == 0) { -+ lxcunlock(lock); -+ return 0; -+ } -+ if (timedout) -+ fprintf(stderr, "%d: timed out waiting for lock\n", __LINE__); -+ else -+ fprintf(stderr, "%d: failed to get single lock\n", __LINE__); -+ return 1; -+} -+ -+/* -+ * get one lock. Fork a second task to try to get a second lock, -+ * with infinite timeout. If our alarm hits, kill the second -+ * task. If second task does not -+ */ -+int test_two_locks(sem_t *lock) -+{ -+ int status; -+ int ret; -+ -+ ret = lxclock(lock, 1); -+ if (ret) { -+ fprintf(stderr, "%d: Error getting first lock\n", __LINE__); -+ return 2; -+ } -+ -+ pid_to_kill = fork(); -+ if (pid_to_kill < 0) { -+ fprintf(stderr, "%d: Failed to fork\n", __LINE__); -+ lxcunlock(lock); -+ return 3; -+ } -+ -+ if (pid_to_kill == 0) { // child -+ ret = lxclock(lock, TIMEOUT_SECS*2); -+ if (ret == 0) { -+ lxcunlock(lock); -+ exit(0); -+ } -+ fprintf(stderr, "%d: child, was not able to get lock\n", __LINE__); -+ exit(1); -+ } -+ starttimer(TIMEOUT_SECS); -+ waitpid(pid_to_kill, &status, 0); -+ stoptimer(); -+ if (WIFEXITED(status)) { -+ // child exited normally - timeout didn't kill it -+ if (WEXITSTATUS(status) == 0) -+ fprintf(stderr, "%d: child was able to get the lock\n", __LINE__); -+ else -+ fprintf(stderr, "%d: child timed out too early\n", __LINE__); -+ lxcunlock(lock); -+ return 1; -+ } -+ lxcunlock(lock); -+ return 0; -+} -+ -+/* -+ * get one lock. try to get second lock, but asking for timeout. If -+ * should return failure. If our own alarm, set at twice the lock -+ * request's timeout, hits, then lxclock() did not properly time out. -+ */ -+int test_with_timeout(sem_t *lock) -+{ -+ int status; -+ int ret = 0; -+ -+ ret = lxclock(lock, 0); -+ if (ret) { -+ fprintf(stderr, "%d: Error getting first lock\n", __LINE__); -+ return 2; -+ } -+ pid_to_kill = fork(); -+ if (pid_to_kill < 0) { -+ fprintf(stderr, "%d: Error on fork\n", __LINE__); -+ lxcunlock(lock); -+ return 2; -+ } -+ if (pid_to_kill == 0) { -+ ret = lxclock(lock, TIMEOUT_SECS); -+ if (ret == 0) { -+ lxcunlock(lock); -+ exit(0); -+ } -+ exit(1); -+ } -+ starttimer(TIMEOUT_SECS * 2); -+ waitpid(pid_to_kill, &status, 0); -+ stoptimer(); -+ if (!WIFEXITED(status)) { -+ fprintf(stderr, "%d: lxclock did not honor its timeout\n", __LINE__); -+ lxcunlock(lock); -+ return 1; -+ } -+ if (WEXITSTATUS(status) == 0) { -+ fprintf(stderr, "%d: child was able to get lock, should have failed with timeout\n", __LINE__); -+ ret = 1; -+ } -+ lxcunlock(lock); -+ return ret; -+} -+ -+int main(int argc, char *argv[]) -+{ -+ int ret, sval, r; -+ sem_t *lock; -+ -+ lock = lxc_newlock(NULL); -+ if (!lock) { -+ fprintf(stderr, "%d: failed to get unnamed lock\n", __LINE__); -+ exit(1); -+ } -+ ret = lxclock(lock, 0); -+ if (ret) { -+ fprintf(stderr, "%d: failed to take unnamed lock (%d)\n", __LINE__, ret); -+ exit(1); -+ } -+ -+ ret = lxcunlock(lock); -+ if (ret) { -+ fprintf(stderr, "%d: failed to put unnamed lock (%d)\n", __LINE__, ret); -+ exit(1); -+ } -+ -+ sem_destroy(lock); -+ free(lock); -+ -+ lock = lxc_newlock(mycontainername); -+ if (!lock) { -+ fprintf(stderr, "%d: failed to get lock\n", __LINE__); -+ exit(1); -+ } -+ r = sem_getvalue(lock, &sval); -+ if (!r) { -+ fprintf(stderr, "%d: sem value at start is %d\n", __LINE__, sval); -+ } else { -+ fprintf(stderr, "%d: failed to get initial value\n", __LINE__); -+ } -+ -+ ret = test_one_lock(lock); -+ if (ret) { -+ fprintf(stderr, "%d: test failed\n", __LINE__); -+ goto out; -+ } -+ r = sem_getvalue(lock, &sval); -+ if (!r) { -+ fprintf(stderr, "%d: sem value is %d\n", __LINE__, sval); -+ } else { -+ fprintf(stderr, "%d: failed to get sem value\n", __LINE__); -+ } -+ -+ ret = test_two_locks(lock); -+ if (ret) { -+ fprintf(stderr, "%d: test failed\n", __LINE__); -+ goto out; -+ } -+ r = sem_getvalue(lock, &sval); -+ if (!r) { -+ fprintf(stderr, "%d: sem value is %d\n", __LINE__, sval); -+ } else { -+ fprintf(stderr, "%d: failed to get value\n", __LINE__); -+ } -+ -+ ret = test_with_timeout(lock); -+ if (ret) { -+ fprintf(stderr, "%d: test failed\n", __LINE__); -+ goto out; -+ } -+ r = sem_getvalue(lock, &sval); -+ if (!r) { -+ fprintf(stderr, "%d: sem value is %d\n", __LINE__, sval); -+ } else { -+ fprintf(stderr, "%d: failed to get value\n", __LINE__); -+ } -+ -+ fprintf(stderr, "all tests passed\n"); -+ -+out: -+ exit(ret); -+} -Index: lxc/src/tests/containertests.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ lxc/src/tests/containertests.c 2012-08-24 09:23:58.516340000 -0500 -@@ -0,0 +1,257 @@ -+/* liblxcapi -+ * -+ * Copyright © 2012 Serge Hallyn . -+ * Copyright © 2012 Canonical Ltd. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2, as -+ * published by the Free Software Foundation. -+ * -+ * 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., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ */ -+#include "../lxc/lxccontainer.h" -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define MYNAME "lxctest1" -+ -+static int destroy_busybox(void) -+{ -+ int status, ret; -+ pid_t pid = fork(); -+ -+ if (pid < 0) { -+ perror("fork"); -+ return -1; -+ } -+ if (pid == 0) { -+ ret = execlp("lxc-destroy", "lxc-destroy", "-f", "-n", MYNAME, NULL); -+ // Should not return -+ perror("execl"); -+ exit(1); -+ } -+again: -+ ret = waitpid(pid, &status, 0); -+ if (ret == -1) { -+ if (errno == -EINTR) -+ goto again; -+ perror("waitpid"); -+ return -1; -+ } -+ if (ret != pid) -+ goto again; -+ if (!WIFEXITED(status)) { // did not exit normally -+ fprintf(stderr, "%d: lxc-create exited abnormally\n", __LINE__); -+ return -1; -+ } -+ return WEXITSTATUS(status); -+} -+ -+static int create_busybox(void) -+{ -+ int status, ret; -+ pid_t pid = fork(); -+ -+ if (pid < 0) { -+ perror("fork"); -+ return -1; -+ } -+ if (pid == 0) { -+ ret = execlp("lxc-create", "lxc-create", "-t", "busybox", "-f", "/etc/lxc/lxc.conf", "-n", MYNAME, NULL); -+ // Should not return -+ perror("execl"); -+ exit(1); -+ } -+again: -+ ret = waitpid(pid, &status, 0); -+ if (ret == -1) { -+ if (errno == -EINTR) -+ goto again; -+ perror("waitpid"); -+ return -1; -+ } -+ if (ret != pid) -+ goto again; -+ if (!WIFEXITED(status)) { // did not exit normally -+ fprintf(stderr, "%d: lxc-create exited abnormally\n", __LINE__); -+ return -1; -+ } -+ return WEXITSTATUS(status); -+} -+ -+int main(int argc, char *argv[]) -+{ -+ struct lxc_container *c; -+ int ret = 0; -+ const char *s; -+ bool b; -+ char *str; -+ -+ ret = 1; -+ /* test refcounting */ -+ c = lxc_container_new(MYNAME); -+ if (!c) { -+ fprintf(stderr, "%d: error creating lxc_container %s\n", __LINE__, MYNAME); -+ goto out; -+ } -+ if (!lxc_container_get(c)) { -+ fprintf(stderr, "%d: error getting refcount\n", __LINE__); -+ goto out; -+ } -+ /* peek in, inappropriately, make sure refcount is a we'd like */ -+ if (c->numthreads != 2) { -+ fprintf(stderr, "%d: refcount is %d, not %d\n", __LINE__, c->numthreads, 2); -+ goto out; -+ } -+ if (strcmp(c->name, MYNAME) != 0) { -+ fprintf(stderr, "%d: container has wrong name (%s not %s)\n", __LINE__, c->name, MYNAME); -+ goto out; -+ } -+ str = c->config_file_name(c); -+#define CONFIGFNAM "/var/lib/lxc/" MYNAME "/config" -+ if (!str || strcmp(str, CONFIGFNAM)) { -+ fprintf(stderr, "%d: got wrong config file name (%s, not %s)\n", __LINE__, str, CONFIGFNAM); -+ goto out; -+ } -+ free(str); -+ free(c->configfile); -+ c->configfile = NULL; -+ str = c->config_file_name(c); -+ if (str) { -+ fprintf(stderr, "%d: config file name was not NULL as it should have been\n", __LINE__); -+ goto out; -+ } -+ if (lxc_container_put(c) != 0) { -+ fprintf(stderr, "%d: c was freed on non-final put\n", __LINE__); -+ goto out; -+ } -+ if (c->numthreads != 1) { -+ fprintf(stderr, "%d: refcount is %d, not %d\n", __LINE__, c->numthreads, 1); -+ goto out; -+ } -+ if (lxc_container_put(c) != 1) { -+ fprintf(stderr, "%d: c was not freed on final put\n", __LINE__); -+ goto out; -+ } -+ -+ /* test a real container */ -+ c = lxc_container_new(MYNAME); -+ if (!c) { -+ fprintf(stderr, "%d: error creating lxc_container %s\n", __LINE__, MYNAME); -+ ret = 1; -+ goto out; -+ } -+ -+ if (c->lxc_conf != NULL) { -+ fprintf(stderr, "%d: lxc_conf is not NULL as it should be\n", __LINE__); -+ ret = 1; -+ goto out; -+ } -+ b = c->is_defined(c); -+ if (b) { -+ fprintf(stderr, "%d: %s thought it was defined\n", __LINE__, MYNAME); -+ goto out; -+ } -+ -+ s = c->state(c); -+ if (s && strcmp(s, "STOPPED") != 0) { -+ // liblxc says a container is STOPPED if it doesn't exist. That's because -+ // the container may be an application container - it's not wrong, just -+ // sometimes unintuitive. -+ fprintf(stderr, "%d: %s thinks it is in state %s\n", __LINE__, c->name, s); -+ goto out; -+ } -+ -+ // create a container -+ // the liblxc api does not support creation - it probably will eventually, -+ // but not yet. -+ // So we just call out to lxc-create. We'll create a busybox container. -+ ret = create_busybox(); -+ if (ret) { -+ fprintf(stderr, "%d: failed to create a busybox container\n", __LINE__); -+ goto out; -+ } -+ -+ b = c->is_defined(c); -+ if (!b) { -+ fprintf(stderr, "%d: %s thought it was not defined\n", __LINE__, MYNAME); -+ goto out; -+ } -+ -+ s = c->state(c); -+ if (!s || strcmp(s, "STOPPED")) { -+ fprintf(stderr, "%d: %s is in state %s, not in STOPPED.\n", __LINE__, c->name, s ? s : "undefined"); -+ goto out; -+ } -+ -+ b = c->load_config(c, NULL); -+ if (!b) { -+ fprintf(stderr, "%d: %s failed to read its config\n", __LINE__, c->name); -+ goto out; -+ } -+ -+ // test wait states -+ int numstates = lxc_get_wait_states(NULL); -+ if (numstates != MAX_STATE) { -+ fprintf(stderr, "%d: lxc_get_wait_states gave %d not %d\n", __LINE__, numstates, MAX_STATE); -+ goto out; -+ } -+ char **sstr = malloc(numstates * sizeof(char *)); -+ numstates = lxc_get_wait_states(sstr); -+ int i; -+ for (i=0; iwant_daemonize(c); -+ if (!c->startl(c, 0, NULL, NULL)) { -+ fprintf(stderr, "%d: %s failed to start daemonized\n", __LINE__, c->name); -+ goto out; -+ } -+ -+ if (!c->wait(c, "RUNNING", -1)) { -+ fprintf(stderr, "%d: failed waiting for state RUNNING\n", __LINE__); -+ goto out; -+ } -+ -+ sleep(3); -+ s = c->state(c); -+ if (!s || strcmp(s, "RUNNING")) { -+ fprintf(stderr, "%d: %s is in state %s, not in RUNNING.\n", __LINE__, c->name, s ? s : "undefined"); -+ goto out; -+ } -+ -+ printf("hit return to finish"); -+ scanf("%c", &mychar); -+ -+ fprintf(stderr, "all lxc_container tests passed for %s\n", c->name); -+ ret = 0; -+ -+out: -+ if (c) { -+ c->stop(c); -+ destroy_busybox(); -+ } -+ lxc_container_put(c); -+ exit(ret); -+} -Index: lxc/src/tests/startone.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ lxc/src/tests/startone.c 2012-08-24 09:23:58.516340000 -0500 -@@ -0,0 +1,202 @@ -+/* liblxcapi -+ * -+ * Copyright © 2012 Serge Hallyn . -+ * Copyright © 2012 Canonical Ltd. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2, as -+ * published by the Free Software Foundation. -+ * -+ * 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., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ */ -+#include "../lxc/lxccontainer.h" -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define MYNAME "lxctest1" -+ -+static int destroy_ubuntu(void) -+{ -+ int status, ret; -+ pid_t pid = fork(); -+ -+ if (pid < 0) { -+ perror("fork"); -+ return -1; -+ } -+ if (pid == 0) { -+ ret = execlp("lxc-destroy", "lxc-destroy", "-f", "-n", MYNAME, NULL); -+ // Should not return -+ perror("execl"); -+ exit(1); -+ } -+again: -+ ret = waitpid(pid, &status, 0); -+ if (ret == -1) { -+ if (errno == -EINTR) -+ goto again; -+ perror("waitpid"); -+ return -1; -+ } -+ if (ret != pid) -+ goto again; -+ if (!WIFEXITED(status)) { // did not exit normally -+ fprintf(stderr, "%d: lxc-create exited abnormally\n", __LINE__); -+ return -1; -+ } -+ return WEXITSTATUS(status); -+} -+ -+static int create_ubuntu(void) -+{ -+ int status, ret; -+ pid_t pid = fork(); -+ -+ if (pid < 0) { -+ perror("fork"); -+ return -1; -+ } -+ if (pid == 0) { -+ ret = execlp("lxc-create", "lxc-create", "-t", "ubuntu", "-f", "/etc/lxc/lxc.conf", "-n", MYNAME, NULL); -+ // Should not return -+ perror("execl"); -+ exit(1); -+ } -+again: -+ ret = waitpid(pid, &status, 0); -+ if (ret == -1) { -+ if (errno == -EINTR) -+ goto again; -+ perror("waitpid"); -+ return -1; -+ } -+ if (ret != pid) -+ goto again; -+ if (!WIFEXITED(status)) { // did not exit normally -+ fprintf(stderr, "%d: lxc-create exited abnormally\n", __LINE__); -+ return -1; -+ } -+ return WEXITSTATUS(status); -+} -+ -+int main(int argc, char *argv[]) -+{ -+ struct lxc_container *c; -+ int ret = 0; -+ const char *s; -+ bool b; -+ -+ ret = 1; -+ /* test a real container */ -+ c = lxc_container_new(MYNAME); -+ if (!c) { -+ fprintf(stderr, "%d: error creating lxc_container %s\n", __LINE__, MYNAME); -+ ret = 1; -+ goto out; -+ } -+ -+ if (c->is_defined(c)) { -+ fprintf(stderr, "%d: %s thought it was defined\n", __LINE__, MYNAME); -+ goto out; -+ } -+ -+ ret = create_ubuntu(); -+ if (ret) { -+ fprintf(stderr, "%d: failed to create a ubuntu container\n", __LINE__); -+ goto out; -+ } -+ -+ b = c->is_defined(c); -+ if (!b) { -+ fprintf(stderr, "%d: %s thought it was not defined\n", __LINE__, MYNAME); -+ goto out; -+ } -+ -+ s = c->state(c); -+ if (!s || strcmp(s, "STOPPED")) { -+ fprintf(stderr, "%d: %s is in state %s, not in STOPPED.\n", __LINE__, c->name, s ? s : "undefined"); -+ goto out; -+ } -+ -+ b = c->load_config(c, NULL); -+ if (!b) { -+ fprintf(stderr, "%d: %s failed to read its config\n", __LINE__, c->name); -+ goto out; -+ } -+ -+ if (!c->set_config_item(c, "lxc.utsname", "bobo")) { -+ fprintf(stderr, "%d: failed setting lxc.utsname\n", __LINE__); -+ goto out; -+ } -+ -+ printf("hit return to start container"); -+ char mychar; -+ scanf("%c", &mychar); -+ -+ if (!lxc_container_get(c)) { -+ fprintf(stderr, "%d: failed to get extra ref to container\n", __LINE__); -+ exit(1); -+ } -+ pid_t pid = fork(); -+ if (pid < 0) { -+ fprintf(stderr, "%d: fork failed\n", __LINE__); -+ goto out; -+ } -+ if (pid == 0) { -+ b = c->startl(c, 0, NULL); -+ if (!b) -+ fprintf(stderr, "%d: %s failed to start\n", __LINE__, c->name); -+ lxc_container_put(c); -+ exit(!b); -+ } -+ -+ sleep(3); -+ s = c->state(c); -+ if (!s || strcmp(s, "RUNNING")) { -+ fprintf(stderr, "%d: %s is in state %s, not in RUNNING.\n", __LINE__, c->name, s ? s : "undefined"); -+ goto out; -+ } -+ -+ printf("hit return to finish"); -+ scanf("%c", &mychar); -+ c->stop(c); -+ -+ system("mkdir -p /var/lib/lxc/lxctest1/rootfs//usr/local/libexec/lxc"); -+ system("mkdir -p /var/lib/lxc/lxctest1/rootfs/usr/lib/lxc/"); -+ system("cp src/lxc/lxc-init /var/lib/lxc/lxctest1/rootfs//usr/local/libexec/lxc"); -+ system("cp src/lxc/liblxc.so /var/lib/lxc/lxctest1/rootfs/usr/lib/lxc"); -+ system("cp src/lxc/liblxc.so /var/lib/lxc/lxctest1/rootfs/usr/lib/lxc/liblxc.so.0"); -+ system("cp src/lxc/liblxc.so /var/lib/lxc/lxctest1/rootfs/usr/lib"); -+ system("mkdir -p /var/lib/lxc/lxctest1/rootfs/dev/shm"); -+ system("chroot /var/lib/lxc/lxctest1/rootfs apt-get install --no-install-recommends lxc"); -+ // next write out the config file; does it match? -+ if (!c->startl(c, 1, "/bin/hostname", NULL)) { -+ fprintf(stderr, "%d: failed to lxc-execute /bin/hostname", __LINE__); -+ goto out; -+ } -+ // auto-check result? ('bobo' is printed on stdout) -+ -+ fprintf(stderr, "all lxc_container tests passed for %s\n", c->name); -+ ret = 0; -+ -+out: -+ if (c) { -+ c->stop(c); -+ destroy_ubuntu(); -+ } -+ lxc_container_put(c); -+ exit(ret); -+} -Index: lxc/src/lxc/lxc.h -=================================================================== ---- lxc.orig/src/lxc/lxc.h 2012-08-24 09:23:58.516340000 -0500 -+++ lxc/src/lxc/lxc.h 2012-08-24 09:23:58.516340000 -0500 -@@ -84,6 +84,7 @@ - * data was readen, < 0 otherwise - */ - extern int lxc_monitor_read(int fd, struct lxc_msg *msg); -+extern int lxc_monitor_read_timeout(int fd, struct lxc_msg *msg, int timeout); - - /* - * Close the fd associated with the monitoring -@@ -178,6 +179,30 @@ - */ - extern const char const *lxc_version(void); - -+/* -+ * Create and return a new lxccontainer struct. -+ */ -+extern struct lxc_container *lxc_container_new(char *name); -+ -+/* -+ * Returns 1 on success, 0 on failure. -+ */ -+extern int lxc_container_get(struct lxc_container *c); -+ -+/* -+ * Put a lxccontainer struct reference. -+ * Return -1 on error. -+ * Return 0 if this was not the last reference. -+ * If it is the last reference, free the lxccontainer and return 1. -+ */ -+extern int lxc_container_put(struct lxc_container *c); -+ -+/* -+ * Get a list of valid wait states. -+ * If states is NULL, simply return the number of states -+ */ -+extern int lxc_get_wait_states(char **states); -+ - #ifdef __cplusplus - } - #endif -Index: lxc/src/lxc/lxclock.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ lxc/src/lxc/lxclock.h 2012-08-24 09:23:58.516340000 -0500 -@@ -0,0 +1,61 @@ -+/* liblxcapi -+ * -+ * Copyright © 2012 Serge Hallyn . -+ * Copyright © 2012 Canonical Ltd. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2, as -+ * published by the Free Software Foundation. -+ * -+ * 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., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ */ -+ -+#include /* For O_* constants */ -+#include /* For mode constants */ -+#include -+#include -+#include -+ -+/* -+ * lxc_newlock: -+ * if name is not given, create an unnamed semaphore. We use these -+ * to protect against racing threads. -+ * Note that an unnamed sem was malloced by us and needs to be freed. -+ * -+ * If name is given, it is prepended with '/lxcapi.', and used as the -+ * name for a system-wide (well, ipcns-wide) semaphore. We use that -+ * to protect the containers as represented on disk. -+ * A named sem should not be freed. -+ * -+ * XXX TODO -+ * We should probably introduce a lxclock_close() which detecs the type -+ * of lock and calls sem_close() or sem_destroy()+free() not as appropriate. -+ * For now, it is up to the caller to do so. -+ * -+ * sem is initialized to value of 1 -+ * -+ * return NULL on failure, else a sem_t * which can be passed to -+ * lxclock() and lxcunlock(). -+ */ -+extern sem_t *lxc_newlock(char *name); -+ -+/* -+ * lxclock: take an existing lock. If timeout is 0, wait -+ * indefinately. Otherwise use given timeout. -+ * return 0 if we got the lock, -2 on failure to set timeout, or -1 -+ * otherwise in which case errno will be set by sem_wait()). -+ */ -+extern int lxclock(sem_t *sem, int timeout); -+ -+/* -+ * lxcunlock: unlock given sem. Return 0 on success. Otherwise returns -+ * -1 and sem_post will leave errno set. -+ */ -+extern int lxcunlock(sem_t *lock); -Index: lxc/src/lxc/lxc_wait.c -=================================================================== ---- lxc.orig/src/lxc/lxc_wait.c 2012-08-24 09:23:58.516340000 -0500 -+++ lxc/src/lxc/lxc_wait.c 2012-08-24 09:23:58.516340000 -0500 -@@ -77,25 +77,6 @@ - .checker = my_checker, - }; - --static int fillwaitedstates(char *strstates, int *states) --{ -- char *token, *saveptr = NULL; -- int state; -- -- token = strtok_r(strstates, "|", &saveptr); -- while (token) { -- -- state = lxc_str2state(token); -- if (state < 0) -- return -1; -- -- states[state] = 1; -- -- token = strtok_r(NULL, "|", &saveptr); -- } -- return 0; --} -- - static void timeout_handler(int signal) - { - exit(-1); -@@ -114,57 +95,5 @@ - my_args.progname, my_args.quiet)) - return -1; - -- if (fillwaitedstates(my_args.states, s)) -- return -1; -- -- fd = lxc_monitor_open(); -- if (fd < 0) -- return -1; -- -- /* -- * if container present, -- * then check if already in requested state -- */ -- ret = -1; -- state = lxc_getstate(my_args.name); -- if (state < 0) { -- goto out_close; -- } else if ((state >= 0) && (s[state])) { -- ret = 0; -- goto out_close; -- } -- -- signal(SIGALRM, timeout_handler); -- alarm(my_args.timeout); -- -- for (;;) { -- if (lxc_monitor_read(fd, &msg) < 0) -- goto out_close; -- -- if (strcmp(my_args.name, msg.name)) -- continue; -- -- switch (msg.type) { -- case lxc_msg_state: -- if (msg.value < 0 || msg.value >= MAX_STATE) { -- ERROR("Receive an invalid state number '%d'", -- msg.value); -- goto out_close; -- } -- -- if (s[msg.value]) { -- alarm(0); -- ret = 0; -- goto out_close; -- } -- break; -- default: -- /* just ignore garbage */ -- break; -- } -- } -- --out_close: -- lxc_monitor_close(fd); -- return ret; -+ return lxc_wait(my_args.name, my_args.states, my_args.timeout); - } -Index: lxc/src/lxc/Makefile.am -=================================================================== ---- lxc.orig/src/lxc/Makefile.am 2012-08-24 09:23:58.516340000 -0500 -+++ lxc/src/lxc/Makefile.am 2012-08-24 09:23:58.516340000 -0500 -@@ -13,7 +13,9 @@ - list.h \ - log.h \ - state.h \ -- attach.h -+ attach.h \ -+ lxccontainer.h \ -+ lxclock.h - - sodir=$(libdir) - # use PROGRAMS to avoid complains from automake -@@ -54,12 +56,15 @@ - mainloop.c mainloop.h \ - af_unix.c af_unix.h \ - \ -- utmp.c utmp.h -+ utmp.c utmp.h \ -+ lxclock.h lxclock.c \ -+ lxccontainer.c lxccontainer.h - - AM_CFLAGS=-I$(top_srcdir)/src \ - -DLXCROOTFSMOUNT=\"$(LXCROOTFSMOUNT)\" \ - -DLXCPATH=\"$(LXCPATH)\" \ -- -DLXCINITDIR=\"$(LXCINITDIR)\" -+ -DLXCINITDIR=\"$(LXCINITDIR)\" \ -+ -DLXCTEMPLATEDIR=\"$(LXCTEMPLATEDIR)\" - - if ENABLE_SECCOMP - AM_CFLAGS += -DHAVE_SECCOMP -@@ -72,7 +77,7 @@ - -shared \ - -Wl,-soname,liblxc.so.$(firstword $(subst ., ,$(VERSION))) - --liblxc_so_LDADD = -lutil $(CAP_LIBS) -lapparmor $(SECCOMP_LIBS) -+liblxc_so_LDADD = -lutil $(CAP_LIBS) -lapparmor $(SECCOMP_LIBS) -lrt - - bin_SCRIPTS = \ - lxc-ps \ -@@ -111,7 +116,7 @@ - if ENABLE_RPATH - AM_LDFLAGS += -Wl,-rpath -Wl,$(libdir) - endif --LDADD=liblxc.so @CAP_LIBS@ -lapparmor @SECCOMP_LIBS@ -+LDADD=liblxc.so @CAP_LIBS@ -lapparmor @SECCOMP_LIBS@ -lrt - - lxc_attach_SOURCES = lxc_attach.c - lxc_cgroup_SOURCES = lxc_cgroup.c -Index: lxc/src/lxc/state.h -=================================================================== ---- lxc.orig/src/lxc/state.h 2012-08-24 09:23:58.516340000 -0500 -+++ lxc/src/lxc/state.h 2012-08-24 09:23:58.516340000 -0500 -@@ -33,5 +33,6 @@ - - extern lxc_state_t lxc_str2state(const char *state); - extern const char *lxc_state2str(lxc_state_t state); -+extern int lxc_wait(char *lxcname, char *states, int timeout); - - #endif -Index: lxc/src/lxc/lxclock.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ lxc/src/lxc/lxclock.c 2012-08-24 09:23:58.516340000 -0500 -@@ -0,0 +1,105 @@ -+/* liblxcapi -+ * -+ * Copyright © 2012 Serge Hallyn . -+ * Copyright © 2012 Canonical Ltd. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2, as -+ * published by the Free Software Foundation. -+ * -+ * 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., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ */ -+ -+#include "lxclock.h" -+#include -+ -+#define OFLAG (O_CREAT | O_RDWR) -+#define SEMMODE 0660 -+#define SEMVALUE 1 -+#define SEMVALUE_LOCKED 0 -+#define LXCLOCK_PREFIX "/lxcapi." -+ -+ -+static char *lxclock_name(char *container) -+{ -+ int ret; -+ int len = strlen(container) + strlen(LXCLOCK_PREFIX) + 1; -+ char *dest = malloc(len); -+ if (!dest) -+ return NULL; -+ ret = snprintf(dest, len, "%s%s", LXCLOCK_PREFIX, container); -+ if (ret < 0 || ret >= len) { -+ free(dest); -+ return NULL; -+ } -+ return dest; -+} -+ -+static void lxcfree_name(char *name) -+{ -+ if (name) -+ free(name); -+} -+ -+static sem_t *lxc_new_unnamed_sem(void) -+{ -+ sem_t *s; -+ int ret; -+ -+ s = malloc(sizeof(*s)); -+ if (!s) -+ return NULL; -+ ret = sem_init(s, 0, 1); -+ if (ret) -+ return NULL; -+ return s; -+} -+ -+sem_t *lxc_newlock(char *name) -+{ -+ char *lname; -+ sem_t *lock; -+ -+ if (!name) -+ return lxc_new_unnamed_sem(); -+ -+ lname = lxclock_name(name); -+ if (!lname) -+ return NULL; -+ lock = sem_open(lname, OFLAG, SEMMODE, SEMVALUE); -+ lxcfree_name(lname); -+ if (lock == SEM_FAILED) -+ return NULL; -+ return lock; -+} -+ -+int lxclock(sem_t *sem, int timeout) -+{ -+ int ret; -+ -+ if (!timeout) { -+ ret = sem_wait(sem); -+ } else { -+ struct timespec ts; -+ if (clock_gettime(CLOCK_REALTIME, &ts) == -1) -+ return -2; -+ ts.tv_sec += timeout; -+ ret = sem_timedwait(sem, &ts); -+ } -+ -+ return ret; -+} -+ -+int lxcunlock(sem_t *sem) -+{ -+ if (!sem) -+ return -2; -+ return sem_post(sem); -+} -Index: lxc/src/lxc/lxccontainer.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ lxc/src/lxc/lxccontainer.h 2012-08-24 09:23:58.516340000 -0500 -@@ -0,0 +1,71 @@ -+#include "lxclock.h" -+#include -+#include -+ -+#include -+ -+struct lxc_container { -+ // private fields -+ char *name; -+ char *configfile; -+ sem_t *slock; -+ sem_t *privlock; -+ int numthreads; /* protected by privlock. */ -+ struct lxc_conf *lxc_conf; // maybe we'll just want the whole lxc_handler? -+ -+ // public fields -+ char *error_string; -+ int error_num; -+ int daemonize; -+ -+#define LXCDIR "/var/lib/lxc" -+ bool (*is_defined)(struct lxc_container *c); // did /var/lib/lxc/$name/config exist -+ const char *(*state)(struct lxc_container *c); -+ bool (*is_running)(struct lxc_container *c); // true so long as defined and not stopped -+ bool (*freeze)(struct lxc_container *c); -+ bool (*unfreeze)(struct lxc_container *c); -+ pid_t (*init_pid)(struct lxc_container *c); -+ bool (*load_config)(struct lxc_container *c, char *alt_file); -+ /* The '...' is the command line. If provided, it must be ended with a NULL */ -+ bool (*start)(struct lxc_container *c, int useinit, char ** argv); -+ bool (*startl)(struct lxc_container *c, int useinit, ...); -+ bool (*stop)(struct lxc_container *c); -+ void (*want_daemonize)(struct lxc_container *c); -+ // Return current config file name. The result is strdup()d, so free the result. -+ char *(*config_file_name)(struct lxc_container *c); -+ // for wait, timeout == -1 means wait forever, timeout == 0 means don't wait. -+ // otherwise timeout is seconds to wait. -+ bool (*wait)(struct lxc_container *c, char *state, int timeout); -+ bool (*set_config_item)(struct lxc_container *c, char *key, char *value); -+ bool (*destroy)(struct lxc_container *c); -+ bool (*save_config)(struct lxc_container *c, char *alt_file); -+ bool (*create)(struct lxc_container *c, char *t, char **argv); -+ bool (*createl)(struct lxc_container *c, char *t, ...); -+ /* send SIGPWR. if timeout is not 0 or -1, do a hard stop after timeout seconds */ -+ bool (*shutdown)(struct lxc_container *c, int timeout); -+ /* clear all network or capability items in the in-memory configuration */ -+ bool (*clear_config_item)(struct lxc_container *c, char *key); -+ /* print a config item to a in-memory string allocated by the caller. Return -+ * the length which was our would be printed. */ -+ int (*get_config_item)(struct lxc_container *c, char *key, char *retv, int inlen); -+ int (*get_keys)(struct lxc_container *c, char *key, char *retv, int inlen); -+ -+#if 0 -+ bool (*commit_cgroups)(struct lxc_container *c); -+ bool (*reread_cgroups)(struct lxc_container *c); -+ // question with clone: how do we handle non-standard config file in orig? -+ struct lxc_container (*clone)(struct container *c); -+ int (*ns_attach)(struct lxc_container *c, int ns_mask); -+ // we'll need some plumbing to support lxc-console -+#endif -+}; -+ -+struct lxc_container *lxc_container_new(char *name); -+int lxc_container_get(struct lxc_container *c); -+int lxc_container_put(struct lxc_container *c); -+int lxc_get_wait_states(char **states); -+ -+#if 0 -+char ** lxc_get_valid_keys(); -+char ** lxc_get_valid_values(char *key); -+#endif -Index: lxc/src/lxc/confile.h -=================================================================== ---- lxc.orig/src/lxc/confile.h 2012-08-24 09:23:58.516340000 -0500 -+++ lxc/src/lxc/confile.h 2012-08-24 09:23:58.516340000 -0500 -@@ -27,6 +27,15 @@ - struct lxc_conf; - struct lxc_list; - -+typedef int (*config_cb)(const char *, char *, struct lxc_conf *); -+struct lxc_config_t { -+ char *name; -+ config_cb cb; -+}; -+ -+extern struct lxc_config_t *lxc_getconfig(const char *key); -+extern int lxc_list_nicconfigs(struct lxc_conf *c, char *key, char *retv, int inlen); -+extern int lxc_listconfigs(char *retv, int inlen); - extern int lxc_config_read(const char *file, struct lxc_conf *conf); - extern int lxc_config_readline(char *buffer, struct lxc_conf *conf); - -@@ -37,4 +46,7 @@ - /* needed for lxc-attach */ - extern signed long lxc_config_parse_arch(const char *arch); - -+extern int lxc_get_config_item(struct lxc_conf *c, char *key, char *retv, int inlen); -+extern int lxc_clear_config_item(struct lxc_conf *c, char *key); -+extern void write_config(FILE *fout, struct lxc_conf *c); - #endif -Index: lxc/src/lxc/lxccontainer.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ lxc/src/lxc/lxccontainer.c 2012-08-24 09:26:55.474310854 -0500 -@@ -0,0 +1,905 @@ -+/* liblxcapi -+ * -+ * Copyright © 2012 Serge Hallyn . -+ * Copyright © 2012 Canonical Ltd. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2, as -+ * published by the Free Software Foundation. -+ * -+ * 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., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ */ -+ -+#include "lxc.h" -+#include "state.h" -+#include "lxccontainer.h" -+#include "conf.h" -+#include "config.h" -+#include "confile.h" -+#include "cgroup.h" -+#include "commands.h" -+#include "log.h" -+#include -+#include -+#include -+#include -+ -+lxc_log_define(lxc_container, lxc); -+ -+/* LOCKING -+ * c->privlock protects the struct lxc_container from multiple threads. -+ * c->slock protects the on-disk container data -+ * NOTHING mutexes two independent programs with their own struct -+ * lxc_container for the same c->name, between API calls. For instance, -+ * c->config_read(); c->start(); Between those calls, data on disk -+ * could change (which shouldn't bother the caller unless for instance -+ * the rootfs get moved). c->config_read(); update; c->config_write(); -+ * Two such updaters could race. The callers should therefore check their -+ * results. Trying to prevent that would necessarily expose us to deadlocks -+ * due to hung callers. So I prefer to keep the locks only within our own -+ * functions, not across functions. -+ * -+ * If you're going to fork while holding a lxccontainer, increment -+ * c->numthreads (under privlock) before forking. When deleting, -+ * decrement numthreads under privlock, then if it hits 0 you can delete. -+ * Do not ever use a lxccontainer whose numthreads you did not bump. -+ */ -+ -+static void lxc_container_free(struct lxc_container *c) -+{ -+ if (!c) -+ return; -+ -+ if (c->configfile) { -+ free(c->configfile); -+ c->configfile = NULL; -+ } -+ if (c->error_string) { -+ free(c->error_string); -+ c->error_string = NULL; -+ } -+ if (c->privlock) { -+ sem_destroy(c->privlock); -+ free(c->privlock); -+ c->privlock = NULL; -+ } -+ if (c->name) { -+ free(c->name); -+ c->name = NULL; -+ } -+ /* -+ * XXX TODO -+ * note, c->lxc_conf is going to have to be freed, but the fn -+ * to do that hasn't been written yet near as I can tell -+ */ -+ free(c); -+} -+ -+int lxc_container_get(struct lxc_container *c) -+{ -+ if (!c) -+ return 0; -+ -+ if (lxclock(c->privlock, 0)) -+ return 0; -+ if (c->numthreads < 1) { -+ // bail without trying to unlock, bc the privlock is now probably -+ // in freed memory -+ return 0; -+ } -+ c->numthreads++; -+ lxcunlock(c->privlock); -+ return 1; -+} -+ -+int lxc_container_put(struct lxc_container *c) -+{ -+ if (!c) -+ return -1; -+ if (lxclock(c->privlock, 0)) -+ return -1; -+ if (--c->numthreads < 1) { -+ lxcunlock(c->privlock); -+ lxc_container_free(c); -+ return 1; -+ } -+ lxcunlock(c->privlock); -+ return 0; -+} -+ -+static bool file_exists(char *f) -+{ -+ struct stat statbuf; -+ -+ return stat(f, &statbuf) == 0; -+} -+ -+static bool lxcapi_is_defined(struct lxc_container *c) -+{ -+ struct stat statbuf; -+ bool ret = false; -+ int statret; -+ -+ if (!c) -+ return false; -+ -+ if (lxclock(c->privlock, 0)) -+ return false; -+ if (!c->configfile) -+ goto out; -+ statret = stat(c->configfile, &statbuf); -+ if (statret != 0) -+ goto out; -+ ret = true; -+ -+out: -+ lxcunlock(c->privlock); -+ return ret; -+} -+ -+static const char *lxcapi_state(struct lxc_container *c) -+{ -+ const char *ret; -+ lxc_state_t s; -+ -+ if (!c) -+ return NULL; -+ if (lxclock(c->slock, 0)) -+ return NULL; -+ s = lxc_getstate(c->name); -+ ret = lxc_state2str(s); -+ lxcunlock(c->slock); -+ -+ return ret; -+} -+ -+static bool lxcapi_is_running(struct lxc_container *c) -+{ -+ const char *s; -+ -+ if (!c) -+ return false; -+ s = lxcapi_state(c); -+ if (!s || strcmp(s, "STOPPED") == 0) -+ return false; -+ return true; -+} -+ -+static bool lxcapi_freeze(struct lxc_container *c) -+{ -+ int ret; -+ if (!c) -+ return false; -+ -+ if (lxclock(c->slock, 0)) -+ return false; -+ ret = lxc_freeze(c->name); -+ lxcunlock(c->slock); -+ if (ret) -+ return false; -+ return true; -+} -+ -+static bool lxcapi_unfreeze(struct lxc_container *c) -+{ -+ int ret; -+ if (!c) -+ return false; -+ -+ if (lxclock(c->slock, 0)) -+ return false; -+ ret = lxc_unfreeze(c->name); -+ lxcunlock(c->slock); -+ if (ret) -+ return false; -+ return true; -+} -+ -+static pid_t lxcapi_init_pid(struct lxc_container *c) -+{ -+ pid_t ret; -+ if (!c) -+ return -1; -+ -+ if (lxclock(c->slock, 0)) -+ return -1; -+ ret = get_init_pid(c->name); -+ lxcunlock(c->slock); -+ return ret; -+} -+ -+static bool lxcapi_load_config(struct lxc_container *c, char *alt_file) -+{ -+ bool ret = false; -+ char *fname; -+ if (!c) -+ return false; -+ -+ fname = c->configfile; -+ if (alt_file) -+ fname = alt_file; -+ if (!fname) -+ return false; -+ if (lxclock(c->slock, 0)) -+ return false; -+ if (!c->lxc_conf) -+ c->lxc_conf = lxc_conf_init(); -+ if (c->lxc_conf && !lxc_config_read(fname, c->lxc_conf)) -+ ret = true; -+ lxcunlock(c->slock); -+ return ret; -+} -+ -+static void lxcapi_want_daemonize(struct lxc_container *c) -+{ -+ if (!c) -+ return; -+ c->daemonize = 1; -+} -+ -+/* -+ * I can't decide if it'd be more convenient for callers if we accept '...', -+ * or a null-terminated array (i.e. execl vs execv) -+ */ -+static bool lxcapi_start(struct lxc_container *c, int useinit, char ** argv) -+{ -+ int ret; -+ struct lxc_conf *conf; -+ int daemonize = 0; -+ char *default_args[] = { -+ "/sbin/init", -+ '\0', -+ }; -+ -+ /* container exists */ -+ if (!c) -+ return false; -+ /* container has been setup */ -+ if (!c->lxc_conf) -+ return false; -+ -+ /* is this app meant to be run through lxcinit, as in lxc-execute? */ -+ if (useinit && !argv) -+ return false; -+ -+ if (lxclock(c->privlock, 0)) -+ return false; -+ conf = c->lxc_conf; -+ daemonize = c->daemonize; -+ lxcunlock(c->privlock); -+ -+ if (useinit) { -+ ret = lxc_execute(c->name, argv, 1, conf); -+ return ret == 0 ? true : false; -+ } -+ -+ if (!argv) -+ argv = default_args; -+ -+ /* -+ * say, I'm not sure - what locks do we want here? Any? -+ * Is liblxc's locking enough here to protect the on disk -+ * container? We don't want to exclude things like lxc_info -+ * while container is running... -+ */ -+ if (daemonize) { -+ if (!lxc_container_get(c)) -+ return false; -+ pid_t pid = fork(); -+ if (pid < 0) { -+ lxc_container_put(c); -+ return false; -+ } -+ if (pid != 0) -+ return true; -+ /* like daemon(), chdir to / and redirect 0,1,2 to /dev/null */ -+ chdir("/"); -+ close(0); -+ close(1); -+ close(2); -+ open("/dev/null", O_RDONLY); -+ open("/dev/null", O_RDWR); -+ open("/dev/null", O_RDWR); -+ setsid(); -+ } -+ -+ if (putenv("container=lxc")) { -+ fprintf(stderr, "failed to set environment variable"); -+ if (daemonize) { -+ lxc_container_put(c); -+ exit(1); -+ } else { -+ return false; -+ } -+ } -+ -+reboot: -+ conf->reboot = 0; -+ ret = lxc_start(c->name, argv, conf); -+ -+ if (conf->reboot) { -+ INFO("container requested reboot"); -+ conf->reboot = 0; -+ if (conf->maincmd_fd) -+ close(conf->maincmd_fd); -+ conf->maincmd_fd = 0; -+ goto reboot; -+ } -+ -+ if (daemonize) { -+ lxc_container_put(c); -+ exit (ret == 0 ? true : false); -+ } else { -+ return (ret == 0 ? true : false); -+ } -+} -+ -+/* -+ * note there MUST be an ending NULL -+ */ -+static bool lxcapi_startl(struct lxc_container *c, int useinit, ...) -+{ -+ va_list ap; -+ char **inargs = NULL, **temp; -+ int n_inargs = 0; -+ bool bret = false; -+ -+ /* container exists */ -+ if (!c) -+ return false; -+ -+ /* build array of arguments if any */ -+ va_start(ap, useinit); -+ while (1) { -+ char *arg; -+ arg = va_arg(ap, char *); -+ if (!arg) -+ break; -+ n_inargs++; -+ temp = realloc(inargs, n_inargs * sizeof(*inargs)); -+ if (!temp) -+ goto out; -+ inargs = temp; -+ inargs[n_inargs - 1] = strdup(arg); // not sure if it's safe not to copy -+ } -+ va_end(ap); -+ -+ /* add trailing NULL */ -+ if (n_inargs) { -+ n_inargs++; -+ temp = realloc(inargs, n_inargs * sizeof(*inargs)); -+ if (!temp) -+ goto out; -+ inargs = temp; -+ inargs[n_inargs - 1] = NULL; -+ } -+ -+ bret = lxcapi_start(c, useinit, inargs); -+ -+out: -+ if (inargs) { -+ int i; -+ for (i = 0; i < n_inargs; i++) { -+ if (inargs[i]) -+ free(inargs[i]); -+ } -+ free(inargs); -+ } -+ -+ return bret; -+} -+ -+static bool lxcapi_stop(struct lxc_container *c) -+{ -+ int ret; -+ -+ if (!c) -+ return false; -+ -+ ret = lxc_stop(c->name); -+ -+ return ret == 0; -+} -+ -+static bool lxcapi_wait(struct lxc_container *c, char *state, int timeout) -+{ -+ int ret; -+ -+ if (!c) -+ return false; -+ -+ ret = lxc_wait(c->name, state, timeout); -+ return ret == 0; -+} -+ -+static bool valid_template(char *t) -+{ -+ struct stat statbuf; -+ int statret; -+ -+ statret = stat(t, &statbuf); -+ if (statret == 0) -+ return true; -+ return false; -+} -+ -+/* -+ * create the standard expected container dir -+ */ -+static bool create_container_dir(struct lxc_container *c) -+{ -+ char *s; -+ int len, ret; -+ -+ len = strlen(LXCPATH) + strlen(c->name) + 2; -+ s = malloc(len); -+ if (!s) -+ return false; -+ ret = snprintf(s, len, "%s/%s", LXCPATH, c->name); -+ if (ret < 0 || ret >= len) { -+ free(s); -+ return false; -+ } -+ ret = mkdir(s, 0755); -+ if (ret) { -+ if (errno == EEXIST) -+ ret = 0; -+ else -+ SYSERROR("failed to create container path for %s\n", c->name); -+ } -+ free(s); -+ return ret == 0; -+} -+ -+/* -+ * backing stores not (yet) supported -+ * for ->create, argv contains the arguments to pass to the template, -+ * terminated by NULL. If no arguments, you can just pass NULL. -+ */ -+static bool lxcapi_create(struct lxc_container *c, char *t, char **argv) -+{ -+ bool bret = false; -+ pid_t pid; -+ int ret, status; -+ char *tpath = NULL; -+ int len, nargs = 0; -+ char **newargv; -+ -+ if (!c) -+ return false; -+ -+ len = strlen(LXCTEMPLATEDIR) + strlen(t) + strlen("/lxc-") + 1; -+ tpath = malloc(len); -+ if (!tpath) -+ return false; -+ ret = snprintf(tpath, len, "%s/lxc-%s", LXCTEMPLATEDIR, t); -+ if (ret < 0 || ret >= len) -+ goto out; -+ if (!valid_template(tpath)) { -+ ERROR("bad template: %s\n", t); -+ goto out; -+ } -+ -+ if (!create_container_dir(c)) -+ goto out; -+ -+ if (!c->save_config(c, NULL)) { -+ ERROR("failed to save starting configuration for %s\n", c->name); -+ goto out; -+ } -+ -+ /* we're going to fork. but since we'll wait for our child, we -+ don't need to lxc_container_get */ -+ -+ if (lxclock(c->slock, 0)) { -+ ERROR("failed to grab global container lock for %s\n", c->name); -+ goto out; -+ } -+ -+ pid = fork(); -+ if (pid < 0) { -+ SYSERROR("failed to fork task for container creation template\n"); -+ goto out_unlock; -+ } -+ -+ if (pid == 0) { // child -+ char *patharg, *namearg; -+ int i; -+ -+ close(0); -+ close(1); -+ close(2); -+ open("/dev/null", O_RDONLY); -+ open("/dev/null", O_RDWR); -+ open("/dev/null", O_RDWR); -+ -+ /* -+ * create our new array, pre-pend the template name and -+ * base args -+ */ -+ if (argv) -+ for (; argv[nargs]; nargs++) ; -+ nargs += 3; // template, path and name args -+ newargv = malloc(nargs * sizeof(*newargv)); -+ if (!newargv) -+ exit(1); -+ newargv[0] = t; -+ -+ len = strlen(LXCPATH) + strlen(c->name) + strlen("--path=") + 2; -+ patharg = malloc(len); -+ if (!patharg) -+ exit(1); -+ ret = snprintf(patharg, len, "--path=%s/%s", LXCPATH, c->name); -+ if (ret < 0 || ret >= len) -+ exit(1); -+ newargv[1] = patharg; -+ len = strlen("--name=") + strlen(c->name) + 1; -+ namearg = malloc(len); -+ if (!namearg) -+ exit(1); -+ ret = snprintf(namearg, len, "--name=%s", c->name); -+ if (ret < 0 || ret >= len) -+ exit(1); -+ newargv[2] = namearg; -+ -+ /* add passed-in args */ -+ if (argv) -+ for (i = 3; i < nargs; i++) -+ newargv[i] = argv[i-3]; -+ -+ /* add trailing NULL */ -+ nargs++; -+ newargv = realloc(newargv, nargs * sizeof(*newargv)); -+ if (!newargv) -+ exit(1); -+ newargv[nargs - 1] = NULL; -+ -+ /* execute */ -+ ret = execv(tpath, newargv); -+ SYSERROR("failed to execute template %s", tpath); -+ exit(1); -+ } -+ -+again: -+ ret = waitpid(pid, &status, 0); -+ if (ret == -1) { -+ if (errno == -EINTR) -+ goto again; -+ SYSERROR("waitpid failed"); -+ goto out_unlock; -+ } -+ if (ret != pid) -+ goto again; -+ if (!WIFEXITED(status)) { // did not exit normally -+ // we could set an error code and string inside the -+ // container_struct here if we like -+ ERROR("container creation template exited abnormally\n"); -+ goto out_unlock; -+ } -+ -+ if (WEXITSTATUS(status) != 0) -+ ERROR("container creation template for %s exited with %d\n", -+ c->name, WEXITSTATUS(status)); -+ else -+ bret = true; -+ -+out_unlock: -+ lxcunlock(c->slock); -+out: -+ if (tpath) -+ free(tpath); -+ return bret; -+} -+ -+static bool lxcapi_shutdown(struct lxc_container *c, int timeout) -+{ -+ bool retv; -+ pid_t pid; -+ -+ if (!c) -+ return false; -+ -+ if (!timeout) -+ timeout = -1; -+ if (!c->is_running(c)) -+ return true; -+ pid = c->init_pid(c); -+ if (pid <= 0) -+ return true; -+ kill(pid, SIGPWR); -+ retv = c->wait(c, "STOPPED", timeout); -+ if (timeout > 0) { -+ c->stop(c); -+ retv = c->wait(c, "STOPPED", 0); // 0 means don't wait -+ } -+ return retv; -+} -+ -+static bool lxcapi_createl(struct lxc_container *c, char *t, ...) -+{ -+ bool bret = false; -+ char **args = NULL, **temp; -+ va_list ap; -+ int nargs = 0; -+ -+ if (!c) -+ return false; -+ -+ /* -+ * since we're going to wait for create to finish, I don't think we -+ * need to get a copy of the arguments. -+ */ -+ va_start(ap, t); -+ while (1) { -+ char *arg; -+ arg = va_arg(ap, char *); -+ if (!arg) -+ break; -+ nargs++; -+ temp = realloc(args, nargs * sizeof(*args)); -+ if (!temp) -+ goto out; -+ args = temp; -+ args[nargs - 1] = arg; -+ } -+ va_end(ap); -+ -+ bret = c->create(c, t, args); -+ -+out: -+ if (args) -+ free(args); -+ return bret; -+} -+ -+static bool lxcapi_clear_config_item(struct lxc_container *c, char *key) -+{ -+ int ret; -+ -+ if (!c || !c->lxc_conf) -+ return false; -+ if (lxclock(c->privlock, 0)) { -+ return false; -+ } -+ ret = lxc_clear_config_item(c->lxc_conf, key); -+ lxcunlock(c->privlock); -+ return ret == 0; -+} -+ -+static int lxcapi_get_config_item(struct lxc_container *c, char *key, char *retv, int inlen) -+{ -+ int ret; -+ -+ if (!c || !c->lxc_conf) -+ return -1; -+ if (lxclock(c->privlock, 0)) { -+ return -1; -+ } -+ ret = lxc_get_config_item(c->lxc_conf, key, retv, inlen); -+ lxcunlock(c->privlock); -+ return ret; -+} -+ -+static int lxcapi_get_keys(struct lxc_container *c, char *key, char *retv, int inlen) -+{ -+ if (!key) -+ return lxc_listconfigs(retv, inlen); -+ /* -+ * Support 'lxc.network.', i.e. 'lxc.network.0' -+ * This is an intelligent result to show which keys are valid given -+ * the type of nic it is -+ */ -+ if (!c || !c->lxc_conf) -+ return -1; -+ if (lxclock(c->privlock, 0)) -+ return -1; -+ int ret = -1; -+ if (strncmp(key, "lxc.network.", 12) == 0) -+ ret = lxc_list_nicconfigs(c->lxc_conf, key, retv, inlen); -+ lxcunlock(c->privlock); -+ return ret; -+} -+ -+ -+/* default config file - should probably come through autoconf */ -+#define LXC_DEFAULT_CONFIG "/etc/lxc/lxc.conf" -+static bool lxcapi_save_config(struct lxc_container *c, char *alt_file) -+{ -+ if (!alt_file) -+ alt_file = c->configfile; -+ if (!alt_file) -+ return false; // should we write to stdout if no file is specified? -+ if (!c->lxc_conf) -+ if (!c->load_config(c, LXC_DEFAULT_CONFIG)) { -+ ERROR("Error loading default configuration file %s while saving %s\n", LXC_DEFAULT_CONFIG, c->name); -+ return false; -+ } -+ -+ FILE *fout = fopen(alt_file, "w"); -+ if (!fout) -+ return false; -+ if (lxclock(c->privlock, 0)) { -+ fclose(fout); -+ return false; -+ } -+ write_config(fout, c->lxc_conf); -+ fclose(fout); -+ lxcunlock(c->privlock); -+ return true; -+} -+ -+static bool lxcapi_destroy(struct lxc_container *c) -+{ -+ pid_t pid; -+ int ret, status; -+ -+ if (!c) -+ return false; -+ -+ pid = fork(); -+ if (pid < 0) -+ return false; -+ if (pid == 0) { // child -+ ret = execlp("lxc-destroy", "lxc-destroy", "-n", c->name, NULL); -+ perror("execl"); -+ exit(1); -+ } -+ -+again: -+ ret = waitpid(pid, &status, 0); -+ if (ret == -1) { -+ if (errno == -EINTR) -+ goto again; -+ perror("waitpid"); -+ return false; -+ } -+ if (ret != pid) -+ goto again; -+ if (!WIFEXITED(status)) { // did not exit normally -+ // we could set an error code and string inside the -+ // container_struct here if we like -+ return false; -+ } -+ -+ return WEXITSTATUS(status) == 0; -+} -+ -+static bool lxcapi_set_config_item(struct lxc_container *c, char *key, char *v) -+{ -+ int ret; -+ bool b = false; -+ struct lxc_config_t *config; -+ -+ if (!c) -+ return false; -+ -+ if (lxclock(c->privlock, 0)) -+ return false; -+ -+ if (!c->lxc_conf) -+ c->lxc_conf = lxc_conf_init(); -+ if (!c->lxc_conf) -+ goto err; -+ config = lxc_getconfig(key); -+ if (!config) -+ goto err; -+ ret = config->cb(key, v, c->lxc_conf); -+ if (!ret) -+ b = true; -+ -+err: -+ lxcunlock(c->privlock); -+ return b; -+} -+ -+static char *lxcapi_config_file_name(struct lxc_container *c) -+{ -+ if (!c || !c->configfile) -+ return NULL; -+ return strdup(c->configfile); -+} -+ -+struct lxc_container *lxc_container_new(char *name) -+{ -+ struct lxc_container *c; -+ int ret, len; -+ -+ c = malloc(sizeof(*c)); -+ if (!c) { -+ fprintf(stderr, "failed to malloc lxc_container\n"); -+ return NULL; -+ } -+ memset(c, 0, sizeof(*c)); -+ -+ c->name = malloc(strlen(name)+1); -+ if (!c->name) { -+ fprintf(stderr, "Error allocating lxc_container name\n"); -+ goto err; -+ } -+ strcpy(c->name, name); -+ -+ c->numthreads = 1; -+ c->slock = lxc_newlock(name); -+ if (!c->slock) { -+ fprintf(stderr, "failed to create lock\n"); -+ goto err; -+ } -+ -+ c->privlock = lxc_newlock(NULL); -+ if (!c->privlock) { -+ fprintf(stderr, "failed to alloc privlock\n"); -+ goto err; -+ } -+ -+ len = strlen(LXCDIR)+strlen(c->name)+strlen("/config")+2; -+ c->configfile = malloc(len); -+ if (!c->configfile) { -+ fprintf(stderr, "Error allocating config file pathname\n"); -+ goto err; -+ } -+ ret = snprintf(c->configfile, len, "%s/%s/config", LXCDIR, c->name); -+ if (ret < 0 || ret >= len) { -+ fprintf(stderr, "Error printing out config file name\n"); -+ goto err; -+ } -+ -+ if (file_exists(c->configfile)) -+ lxcapi_load_config(c, NULL); -+ -+ // assign the member functions -+ c->is_defined = lxcapi_is_defined; -+ c->state = lxcapi_state; -+ c->is_running = lxcapi_is_running; -+ c->freeze = lxcapi_freeze; -+ c->unfreeze = lxcapi_unfreeze; -+ c->init_pid = lxcapi_init_pid; -+ c->load_config = lxcapi_load_config; -+ c->want_daemonize = lxcapi_want_daemonize; -+ c->start = lxcapi_start; -+ c->startl = lxcapi_startl; -+ c->stop = lxcapi_stop; -+ c->config_file_name = lxcapi_config_file_name; -+ c->wait = lxcapi_wait; -+ c->set_config_item = lxcapi_set_config_item; -+ c->destroy = lxcapi_destroy; -+ c->save_config = lxcapi_save_config; -+ c->get_keys = lxcapi_get_keys; -+ c->create = lxcapi_create; -+ c->createl = lxcapi_createl; -+ c->shutdown = lxcapi_shutdown; -+ c->clear_config_item = lxcapi_clear_config_item; -+ c->get_config_item = lxcapi_get_config_item; -+ -+ /* we'll allow the caller to update these later */ -+ if (lxc_log_init("/var/log/lxccontainer.log", "trace", "lxc_container", 0)) { -+ fprintf(stderr, "failed to open log\n"); -+ goto err; -+ } -+ -+ /* -+ * default configuration file is $LXCDIR/$NAME/config -+ */ -+ -+ return c; -+ -+err: -+ lxc_container_free(c); -+ return NULL; -+} -+ -+int lxc_get_wait_states(char **states) -+{ -+ int i; -+ -+ if (states) -+ for (i=0; i - #include -+#include "network.h" - - lxc_log_define(lxc_confile, lxc); - -@@ -75,15 +76,11 @@ - static int config_console(const char *, char *, struct lxc_conf *); - static int config_seccomp(const char *, char *, struct lxc_conf *); - static int config_includefile(const char *, char *, struct lxc_conf *); -+static int config_network_nic(const char *, char *, struct lxc_conf *); - - typedef int (*config_cb)(const char *, char *, struct lxc_conf *); - --struct config { -- char *name; -- config_cb cb; --}; -- --static struct config config[] = { -+static struct lxc_config_t config[] = { - - { "lxc.arch", config_personality }, - { "lxc.pts", config_pts }, -@@ -114,15 +111,17 @@ - { "lxc.network.ipv4", config_network_ipv4 }, - { "lxc.network.ipv6.gateway", config_network_ipv6_gateway }, - { "lxc.network.ipv6", config_network_ipv6 }, -+ /* config_network_nic must come after all other 'lxc.network.*' entries */ -+ { "lxc.network.", config_network_nic }, - { "lxc.cap.drop", config_cap_drop }, - { "lxc.console", config_console }, - { "lxc.seccomp", config_seccomp }, - { "lxc.include", config_includefile }, - }; - --static const size_t config_size = sizeof(config)/sizeof(struct config); -+static const size_t config_size = sizeof(config)/sizeof(struct lxc_config_t); - --static struct config *getconfig(const char *key) -+extern struct lxc_config_t *lxc_getconfig(const char *key) - { - int i; - -@@ -133,6 +132,76 @@ - return NULL; - } - -+#define strprint(str, inlen, ...) \ -+ do { \ -+ len = snprintf(str, inlen, ##__VA_ARGS__); \ -+ if (len < 0) { SYSERROR("snprintf"); return -1; }; \ -+ fulllen += len; \ -+ if (inlen > 0) { \ -+ if (str) str += len; \ -+ inlen -= len; \ -+ if (inlen < 0) inlen = 0; \ -+ } \ -+ } while (0); -+ -+int lxc_listconfigs(char *retv, int inlen) -+{ -+ int i, fulllen = 0, len; -+ -+ if (!retv) -+ inlen = 0; -+ else -+ memset(retv, 0, inlen); -+ for (i = 0; i < config_size; i++) { -+ char *s = config[i].name; -+ if (s[strlen(s)-1] == '.') -+ continue; -+ strprint(retv, inlen, "%s\n", s); -+ } -+ return fulllen; -+} -+ -+/* -+ * config entry is something like "lxc.network.0.ipv4" -+ * the key 'lxc.network.' was found. So we make sure next -+ * comes an integer, find the right callback (by rewriting -+ * the key), and call it. -+ */ -+static int config_network_nic(const char *key, char *value, -+ struct lxc_conf *lxc_conf) -+{ -+ char *copy = strdup(key), *p; -+ int ret = -1; -+ struct lxc_config_t *config; -+ -+ if (!copy) { -+ SYSERROR("failed to allocate memory"); -+ return -1; -+ } -+ /* -+ * ok we know that to get here we've got "lxc.network." -+ * and it isn't any of the other network entries. So -+ * after the second . should come an integer (# of defined -+ * nic) followed by a valid entry. -+ */ -+ if (*(key+12) < '0' || *(key+12) > '9') -+ goto out; -+ p = index(key+12, '.'); -+ if (!p) -+ goto out; -+ strcpy(copy+12, p+1); -+ config = lxc_getconfig(copy); -+ if (!config) { -+ ERROR("unknown key %s", key); -+ goto out; -+ } -+ ret = config->cb(key, value, lxc_conf); -+ -+out: -+ free(copy); -+ return ret; -+} -+ - static int config_network_type(const char *key, char *value, - struct lxc_conf *lxc_conf) - { -@@ -190,10 +259,89 @@ - return 0; - } - -+/* -+ * if you have p="lxc.network.0.link", pass it p+12 -+ * to get back '0' (the index of the nic) -+ */ -+static int get_network_netdev_idx(const char *key) -+{ -+ int ret, idx; -+ -+ if (*key < '0' || *key > '9') -+ return -1; -+ ret = sscanf(key, "%d", &idx); -+ if (ret != 1) -+ return -1; -+ return idx; -+} -+ -+/* -+ * if you have p="lxc.network.0", pass this p+12 and it will return -+ * the netdev of the first configured nic -+ */ -+static struct lxc_netdev *get_netdev_from_key(const char *key, -+ struct lxc_list *network) -+{ -+ int i = 0, idx = get_network_netdev_idx(key); -+ struct lxc_netdev *netdev = NULL; -+ struct lxc_list *it; -+ if (idx == -1) -+ return NULL; -+ lxc_list_for_each(it, network) { -+ if (idx == i++) { -+ netdev = it->elem; -+ break; -+ } -+ } -+ return netdev; -+} -+ -+extern int lxc_list_nicconfigs(struct lxc_conf *c, char *key, char *retv, int inlen) -+{ -+ struct lxc_netdev *netdev; -+ int fulllen = 0, len; -+ -+ netdev = get_netdev_from_key(key+12, &c->network); -+ if (!netdev) -+ return -1; -+ -+ if (!retv) -+ inlen = 0; -+ else -+ memset(retv, 0, inlen); -+ -+ strprint(retv, inlen, "script.up\n"); -+ if (netdev->type != LXC_NET_EMPTY) { -+ strprint(retv, inlen, "flags\n"); -+ strprint(retv, inlen, "link\n"); -+ strprint(retv, inlen, "name\n"); -+ strprint(retv, inlen, "hwaddr\n"); -+ strprint(retv, inlen, "mtu\n"); -+ strprint(retv, inlen, "ipv6\n"); -+ strprint(retv, inlen, "ipv6_gateway\n"); -+ strprint(retv, inlen, "ipv4\n"); -+ strprint(retv, inlen, "ipv4_gateway\n"); -+ } -+ switch(netdev->type) { -+ case LXC_NET_VETH: -+ strprint(retv, inlen, "veth.pair\n"); -+ break; -+ case LXC_NET_MACVLAN: -+ strprint(retv, inlen, "macvlan.mode\n"); -+ break; -+ case LXC_NET_VLAN: -+ strprint(retv, inlen, "vlan.id\n"); -+ break; -+ case LXC_NET_PHYS: -+ break; -+ } -+ return fulllen; -+} -+ - static struct lxc_netdev *network_netdev(const char *key, const char *value, - struct lxc_list *network) - { -- struct lxc_netdev *netdev; -+ struct lxc_netdev *netdev = NULL; - - if (lxc_list_empty(network)) { - ERROR("network is not created for '%s' = '%s' option", -@@ -201,7 +349,11 @@ - return NULL; - } - -- netdev = lxc_list_last_elem(network); -+ if (get_network_netdev_idx(key+12) == -1) -+ netdev = lxc_list_last_elem(network); -+ else -+ netdev = get_netdev_from_key(key+12, network); -+ - if (!netdev) { - ERROR("no network device defined for '%s' = '%s' option", - key, value); -@@ -586,7 +738,7 @@ - SYSERROR("failed to dup string '%s'", value); - return -1; - } -- if (strcmp(key, "lxc.network.script.up") == 0) { -+ if (strstr(key, "script.up") != NULL) { - netdev->upscript = copy; - return 0; - } -@@ -859,6 +1011,10 @@ - break; - } - -+ /* note - i do believe we're losing memory here, -+ note that token is already pointing into dropcaps -+ which is strdup'd. we never free that bit. -+ */ - droplist->elem = strdup(token); - if (!droplist->elem) { - SYSERROR("failed to dup '%s'", token); -@@ -968,7 +1124,7 @@ - - static int parse_line(char *buffer, void *data) - { -- struct config *config; -+ struct lxc_config_t *config; - char *line, *linep; - char *dot; - char *key; -@@ -1013,7 +1169,7 @@ - value += lxc_char_left_gc(value, strlen(value)); - value[lxc_char_right_gc(value, strlen(value))] = '\0'; - -- config = getconfig(key); -+ config = lxc_getconfig(key); - if (!config) { - ERROR("unknown key %s", key); - goto out; -@@ -1090,3 +1246,425 @@ - - return -1; - } -+ -+static int lxc_get_conf_int(struct lxc_conf *c, char *retv, int inlen, int v) -+{ -+ if (!retv) -+ inlen = 0; -+ else -+ memset(retv, 0, inlen); -+ return snprintf(retv, inlen, "%d", v); -+} -+ -+static int lxc_get_arch_entry(struct lxc_conf *c, char *retv, int inlen) -+{ -+ int len, fulllen = 0; -+ -+ if (!retv) -+ inlen = 0; -+ else -+ memset(retv, 0, inlen); -+ -+ switch(c->personality) { -+ case PER_LINUX32: strprint(retv, inlen, "x86"); break; -+ case PER_LINUX: strprint(retv, inlen, "x86_64"); break; -+ default: break; -+ } -+ -+ return fulllen; -+} -+ -+/* -+ * If you ask for a specific cgroup value, i.e. lxc.cgroup.devices.list, -+ * then just the value(s) will be printed. Since there still could be -+ * more than one, it is newline-separated. -+ * (Maybe that's ambigous, since some values, i.e. devices.list, will -+ * already have newlines?) -+ * If you ask for 'lxc.cgroup", then all cgroup entries will be printed, -+ * in 'lxc.cgroup.subsystem.key = value' format. -+ */ -+static int lxc_get_cgroup_entry(struct lxc_conf *c, char *retv, int inlen, char *key) -+{ -+ int fulllen = 0, len; -+ int all = 0; -+ struct lxc_list *it; -+ -+ if (!retv) -+ inlen = 0; -+ else -+ memset(retv, 0, inlen); -+ -+ if (strcmp(key, "all") == 0) -+ all = 1; -+ -+ lxc_list_for_each(it, &c->cgroup) { -+ struct lxc_cgroup *cg = it->elem; -+ if (all) { -+ strprint(retv, inlen, "lxc.cgroup.%s = %s\n", cg->subsystem, cg->value); -+ } else if (strcmp(cg->subsystem, key) == 0) { -+ strprint(retv, inlen, "%s\n", cg->value); -+ } -+ } -+ return fulllen; -+} -+ -+static int lxc_get_item_hooks(struct lxc_conf *c, char *retv, int inlen, char *key) -+{ -+ char *subkey; -+ int len, fulllen = 0, found = -1; -+ struct lxc_list *it; -+ int i; -+ -+ /* "lxc.hook.mount" */ -+ subkey = index(key, '.'); -+ if (subkey) subkey = index(subkey+1, '.'); -+ if (!subkey) -+ return -1; -+ subkey++; -+ if (!*subkey) -+ return -1; -+ for (i=0; ihooks[found]) { -+ strprint(retv, inlen, "%s\n", (char *)it->elem); -+ } -+ return fulllen; -+} -+ -+static int lxc_get_item_cap_drop(struct lxc_conf *c, char *retv, int inlen) -+{ -+ int len, fulllen = 0; -+ struct lxc_list *it; -+ -+ if (!retv) -+ inlen = 0; -+ else -+ memset(retv, 0, inlen); -+ -+ lxc_list_for_each(it, &c->caps) { -+ strprint(retv, inlen, "%s\n", (char *)it->elem); -+ } -+ return fulllen; -+} -+ -+static int lxc_get_mount_entries(struct lxc_conf *c, char *retv, int inlen) -+{ -+ int len, fulllen = 0; -+ struct lxc_list *it; -+ -+ if (!retv) -+ inlen = 0; -+ else -+ memset(retv, 0, inlen); -+ -+ lxc_list_for_each(it, &c->mount_list) { -+ strprint(retv, inlen, "%s\n", (char *)it->elem); -+ } -+ return fulllen; -+} -+ -+/* -+ * lxc.network.0.XXX, where XXX can be: name, type, link, flags, type, -+ * macvlan.mode, veth.pair, vlan, ipv4, ipv6, upscript, hwaddr, mtu, -+ * ipv4_gateway, ipv6_gateway. ipvX_gateway can return 'auto' instead -+ * of an address. ipv4 and ipv6 return lists (newline-separated). -+ * things like veth.pair return '' if invalid (i.e. if called for vlan -+ * type). -+ */ -+static int lxc_get_item_nic(struct lxc_conf *c, char *retv, int inlen, char *key) -+{ -+ char *p1; -+ int i, len, fulllen = 0; -+ struct lxc_netdev *netdev; -+ -+ if (!retv) -+ inlen = 0; -+ else -+ memset(retv, 0, inlen); -+ -+ p1 = index(key, '.'); -+ if (!p1 || *(p1+1) == '\0') return -1; -+ p1++; -+ -+ netdev = get_netdev_from_key(key, &c->network); -+ if (!netdev) -+ return -1; -+ if (strcmp(p1, "name") == 0) { -+ if (netdev->name) -+ strprint(retv, inlen, "%s", netdev->name); -+ } else if (strcmp(p1, "type") == 0) { -+ strprint(retv, inlen, "%s", lxc_net_type_to_str(netdev->type)); -+ } else if (strcmp(p1, "link") == 0) { -+ if (netdev->link) -+ strprint(retv, inlen, "%s", netdev->link); -+ } else if (strcmp(p1, "flags") == 0) { -+ if (netdev->flags & IFF_UP) -+ strprint(retv, inlen, "up"); -+ } else if (strcmp(p1, "upscript") == 0) { -+ if (netdev->upscript) -+ strprint(retv, inlen, "%s", netdev->upscript); -+ } else if (strcmp(p1, "hwaddr") == 0) { -+ if (netdev->hwaddr) -+ strprint(retv, inlen, "%s", netdev->hwaddr); -+ } else if (strcmp(p1, "mtu") == 0) { -+ if (netdev->mtu) -+ strprint(retv, inlen, "%s", netdev->mtu); -+ } else if (strcmp(p1, "macvlan.mode") == 0) { -+ if (netdev->type == LXC_NET_MACVLAN) { -+ const char *mode; -+ switch (netdev->priv.macvlan_attr.mode) { -+ case MACVLAN_MODE_PRIVATE: mode = "private"; break; -+ case MACVLAN_MODE_VEPA: mode = "vepa"; break; -+ case MACVLAN_MODE_BRIDGE: mode = "bridge"; break; -+ default: mode = "(invalid)"; break; -+ } -+ strprint(retv, inlen, "%s", mode); -+ } -+ } else if (strcmp(p1, "veth.pair") == 0) { -+ if (netdev->type == LXC_NET_VETH && netdev->priv.veth_attr.pair) -+ strprint(retv, inlen, "%s", netdev->priv.veth_attr.pair); -+ } else if (strcmp(p1, "vlan") == 0) { -+ if (netdev->type == LXC_NET_VLAN) { -+ strprint(retv, inlen, "%d", netdev->priv.vlan_attr.vid); -+ } -+ } else if (strcmp(p1, "ipv4_gateway") == 0) { -+ if (netdev->ipv4_gateway_auto) { -+ strprint(retv, inlen, "auto"); -+ } else if (netdev->ipv4_gateway) { -+ char buf[INET_ADDRSTRLEN]; -+ inet_ntop(AF_INET, netdev->ipv4_gateway, buf, sizeof(buf)); -+ strprint(retv, inlen, "%s", buf); -+ } -+ } else if (strcmp(p1, "ipv4") == 0) { -+ struct lxc_list *it2; -+ lxc_list_for_each(it2, &netdev->ipv4) { -+ struct lxc_inetdev *i = it2->elem; -+ char buf[INET_ADDRSTRLEN]; -+ inet_ntop(AF_INET, &i->addr, buf, sizeof(buf)); -+ strprint(retv, inlen, "%s\n", buf); -+ } -+ } else if (strcmp(p1, "ipv6_gateway") == 0) { -+ if (netdev->ipv6_gateway_auto) { -+ strprint(retv, inlen, "auto"); -+ } else if (netdev->ipv6_gateway) { -+ char buf[INET_ADDRSTRLEN]; -+ inet_ntop(AF_INET, netdev->ipv6_gateway, buf, sizeof(buf)); -+ strprint(retv, inlen, "%s", buf); -+ } -+ } else if (strcmp(p1, "ipv6") == 0) { -+ struct lxc_list *it2; -+ lxc_list_for_each(it2, &netdev->ipv6) { -+ struct lxc_inetdev *i = it2->elem; -+ char buf[INET_ADDRSTRLEN]; -+ inet_ntop(AF_INET6, &i->addr, buf, sizeof(buf)); -+ strprint(retv, inlen, "%s\n", buf); -+ } -+ } -+ return fulllen; -+} -+ -+static int lxc_get_item_network(struct lxc_conf *c, char *retv, int inlen) -+{ -+ int len, fulllen = 0; -+ struct lxc_list *it; -+ -+ if (!retv) -+ inlen = 0; -+ else -+ memset(retv, 0, inlen); -+ -+ lxc_list_for_each(it, &c->network) { -+ struct lxc_netdev *n = it->elem; -+ const char *t = lxc_net_type_to_str(n->type); -+ strprint(retv, inlen, "%s\n", t ? t : "(invalid)"); -+ } -+ return fulllen; -+} -+ -+int lxc_get_config_item(struct lxc_conf *c, char *key, char *retv, int inlen) -+{ -+ char *v = NULL; -+ -+ if (strcmp(key, "lxc.mount.entry") == 0) -+ return lxc_get_mount_entries(c, retv, inlen); -+ else if (strcmp(key, "lxc.mount") == 0) -+ v = c->fstab; -+ else if (strcmp(key, "lxc.tty") == 0) -+ return lxc_get_conf_int(c, retv, inlen, c->tty); -+ else if (strcmp(key, "lxc.pts") == 0) -+ return lxc_get_conf_int(c, retv, inlen, c->pts); -+ else if (strcmp(key, "lxc.devttydir") == 0) -+ v = c->ttydir; -+ else if (strcmp(key, "lxc.arch") == 0) -+ return lxc_get_arch_entry(c, retv, inlen); -+ else if (strcmp(key, "lxc.aa_profile") == 0) -+ v = c->aa_profile; -+ else if (strcmp(key, "lxc.cgroup") == 0) // all cgroup info -+ return lxc_get_cgroup_entry(c, retv, inlen, "all"); -+ else if (strncmp(key, "lxc.cgroup.", 11) == 0) // specific cgroup info -+ return lxc_get_cgroup_entry(c, retv, inlen, key + 11); -+ else if (strcmp(key, "lxc.utsname") == 0) -+ v = c->utsname->nodename; -+ else if (strcmp(key, "lxc.console") == 0) -+ v = c->console.path; -+ else if (strcmp(key, "lxc.rootfs.mount") == 0) -+ v = c->rootfs.mount; -+ else if (strcmp(key, "lxc.rootfs") == 0) -+ v = c->rootfs.path; -+ else if (strcmp(key, "lxc.pivotdir") == 0) -+ v = c->rootfs.pivot; -+ else if (strcmp(key, "lxc.cap.drop") == 0) -+ return lxc_get_item_cap_drop(c, retv, inlen); -+ else if (strncmp(key, "lxc.hook", 8) == 0) -+ return lxc_get_item_hooks(c, retv, inlen, key); -+ else if (strcmp(key, "lxc.network") == 0) -+ return lxc_get_item_network(c, retv, inlen); -+ else if (strncmp(key, "lxc.network.", 12) == 0) -+ return lxc_get_item_nic(c, retv, inlen, key + 12); -+ else return -1; -+ -+ if (!v) -+ return 0; -+ if (retv && inlen >= strlen(v) + 1) -+ strncpy(retv, v, strlen(v)+1); -+ return strlen(v); -+} -+ -+int lxc_clear_config_item(struct lxc_conf *c, char *key) -+{ -+ if (strcmp(key, "lxc.network") == 0) -+ return lxc_clear_config_network(c); -+ else if (strncmp(key, "lxc.network.", 12) == 0) -+ return lxc_clear_nic(c, key + 12); -+ else if (strcmp(key, "lxc.cap.drop") == 0) -+ return lxc_clear_config_caps(c); -+ else if (strncmp(key, "lxc.cgroup", 10) == 0) -+ return lxc_clear_cgroups(c, key); -+ else if (strcmp(key, "lxc.mount.entries") == 0) -+ return lxc_clear_mount_entries(c); -+ else if (strcmp(key, "lxc.hook") == 0) -+ return lxc_clear_hooks(c); -+ -+ return -1; -+} -+ -+/* -+ * writing out a confile. -+ */ -+void write_config(FILE *fout, struct lxc_conf *c) -+{ -+ struct lxc_list *it; -+ int i; -+ -+ if (c->fstab) -+ fprintf(fout, "lxc.mount = %s\n", c->fstab); -+ lxc_list_for_each(it, &c->mount_list) { -+ fprintf(fout, "lxc.mount.entry = %s\n", (char *)it->elem); -+ } -+ if (c->tty) -+ fprintf(fout, "lxc.tty = %d\n", c->tty); -+ if (c->pts) -+ fprintf(fout, "lxc.pts = %d\n", c->pts); -+ if (c->ttydir) -+ fprintf(fout, "lxc.devttydir = %s\n", c->ttydir); -+ switch(c->personality) { -+ case PER_LINUX32: fprintf(fout, "lxc.arch = x86\n"); break; -+ case PER_LINUX: fprintf(fout, "lxc.arch = x86_64\n"); break; -+ default: break; -+ } -+ if (c->aa_profile) -+ fprintf(fout, "lxc.aa_profile = %s\n", c->aa_profile); -+ lxc_list_for_each(it, &c->cgroup) { -+ struct lxc_cgroup *cg = it->elem; -+ fprintf(fout, "lxc.cgroup.%s = %s\n", cg->subsystem, cg->value); -+ } -+ if (c->utsname) -+ fprintf(fout, "lxc.utsname = %s\n", c->utsname->nodename); -+ lxc_list_for_each(it, &c->network) { -+ struct lxc_netdev *n = it->elem; -+ const char *t = lxc_net_type_to_str(n->type); -+ struct lxc_list *it2; -+ fprintf(fout, "lxc.network.type = %s\n", t ? t : "(invalid)"); -+ if (n->flags & IFF_UP) -+ fprintf(fout, "lxc.network.flags = up\n"); -+ if (n->link) -+ fprintf(fout, "lxc.network.link = %s\n", n->link); -+ if (n->name) -+ fprintf(fout, "lxc.network.name = %s\n", n->name); -+ if (n->type == LXC_NET_MACVLAN) { -+ const char *mode; -+ switch (n->priv.macvlan_attr.mode) { -+ case MACVLAN_MODE_PRIVATE: mode = "private"; break; -+ case MACVLAN_MODE_VEPA: mode = "vepa"; break; -+ case MACVLAN_MODE_BRIDGE: mode = "bridge"; break; -+ default: mode = "(invalid)"; break; -+ } -+ fprintf(fout, "lxc.network.macvlan.mode = %s\n", mode); -+ } else if (n->type == LXC_NET_VETH) { -+ if (n->priv.veth_attr.pair) -+ fprintf(fout, "lxc.network.veth.pair = %s\n", -+ n->priv.veth_attr.pair); -+ } else if (n->type == LXC_NET_VLAN) { -+ fprintf(fout, "lxc.network.vlan.id = %d\n", n->priv.vlan_attr.vid); -+ } -+ if (n->upscript) -+ fprintf(fout, "lxc.network.script.up = %s\n", n->upscript); -+ if (n->hwaddr) -+ fprintf(fout, "lxc.network.hwaddr = %s\n", n->hwaddr); -+ if (n->mtu) -+ fprintf(fout, "lxc.network.mtu = %s\n", n->mtu); -+ if (n->ipv4_gateway_auto) -+ fprintf(fout, "lxc.network.ipv4.gateway = auto\n"); -+ else if (n->ipv4_gateway) { -+ char buf[INET_ADDRSTRLEN]; -+ inet_ntop(AF_INET, n->ipv4_gateway, buf, sizeof(buf)); -+ fprintf(fout, "lxc.network.ipv4.gateway = %s\n", buf); -+ } -+ lxc_list_for_each(it2, &n->ipv4) { -+ struct lxc_inetdev *i = it2->elem; -+ char buf[INET_ADDRSTRLEN]; -+ inet_ntop(AF_INET, &i->addr, buf, sizeof(buf)); -+ fprintf(fout, "lxc.network.ipv4 = %s\n", buf); -+ } -+ if (n->ipv6_gateway_auto) -+ fprintf(fout, "lxc.network.ipv6.gateway = auto\n"); -+ else if (n->ipv6_gateway) { -+ char buf[INET6_ADDRSTRLEN]; -+ inet_ntop(AF_INET6, n->ipv6_gateway, buf, sizeof(buf)); -+ fprintf(fout, "lxc.network.ipv6.gateway = %s\n", buf); -+ } -+ lxc_list_for_each(it2, &n->ipv6) { -+ struct lxc_inet6dev *i = it2->elem; -+ char buf[INET6_ADDRSTRLEN]; -+ inet_ntop(AF_INET, &i->addr, buf, sizeof(buf)); -+ fprintf(fout, "lxc.network.ipv6 = %s\n", buf); -+ } -+ } -+ lxc_list_for_each(it, &c->caps) -+ fprintf(fout, "lxc.cap.drop = %s\n", (char *)it->elem); -+ for (i=0; ihooks[i]) -+ fprintf(fout, "lxc.hook.%s = %s\n", -+ lxchook_names[i], (char *)it->elem); -+ } -+ if (c->console.path) -+ fprintf(fout, "lxc.console = %s\n", c->console.path); -+ if (c->rootfs.path) -+ fprintf(fout, "lxc.rootfs = %s\n", c->rootfs.path); -+ if (c->rootfs.mount && strcmp(c->rootfs.mount, LXCROOTFSMOUNT) != 0) -+ fprintf(fout, "lxc.rootfs.mount = %s\n", c->rootfs.mount); -+ if (c->rootfs.pivot) -+ fprintf(fout, "lxc.pivotdir = %s\n", c->rootfs.pivot); -+} -Index: lxc/src/lxc/state.c -=================================================================== ---- lxc.orig/src/lxc/state.c 2012-08-24 09:23:58.516340000 -0500 -+++ lxc/src/lxc/state.c 2012-08-24 09:23:58.516340000 -0500 -@@ -31,9 +31,11 @@ - #include - #include - -+#include - #include - #include - #include -+#include - #include "commands.h" - #include "config.h" - -@@ -162,3 +164,108 @@ - return ret; - } - -+static int fillwaitedstates(char *strstates, int *states) -+{ -+ char *token, *saveptr = NULL; -+ int state; -+ -+ token = strtok_r(strstates, "|", &saveptr); -+ while (token) { -+ -+ state = lxc_str2state(token); -+ if (state < 0) -+ return -1; -+ -+ states[state] = 1; -+ -+ token = strtok_r(NULL, "|", &saveptr); -+ } -+ return 0; -+} -+ -+extern int lxc_wait(char *lxcname, char *states, int timeout) -+{ -+ struct lxc_msg msg; -+ int state, ret; -+ int s[MAX_STATE] = { }, fd; -+ -+ if (fillwaitedstates(states, s)) -+ return -1; -+ -+ fd = lxc_monitor_open(); -+ if (fd < 0) -+ return -1; -+ -+ /* -+ * if container present, -+ * then check if already in requested state -+ */ -+ ret = -1; -+ state = lxc_getstate(lxcname); -+ if (state < 0) { -+ goto out_close; -+ } else if ((state >= 0) && (s[state])) { -+ ret = 0; -+ goto out_close; -+ } -+ -+ for (;;) { -+ int elapsed_time, curtime; -+ struct timeval tv; -+ int stop = 0; -+ int retval; -+ -+ if (timeout != -1) { -+ retval = gettimeofday(&tv, NULL); -+ if (retval) -+ goto out_close; -+ curtime = tv.tv_sec; -+ } -+ if (lxc_monitor_read_timeout(fd, &msg, timeout) < 0) -+ goto out_close; -+ -+ if (timeout != -1) { -+ retval = gettimeofday(&tv, NULL); -+ if (retval) -+ goto out_close; -+ elapsed_time = tv.tv_sec - curtime; -+ if (timeout - elapsed_time <= 0) -+ stop = 1; -+ timeout -= elapsed_time; -+ } -+ -+ if (strcmp(lxcname, msg.name)) { -+ if (stop) { -+ ret = -2; -+ goto out_close; -+ } -+ continue; -+ } -+ -+ switch (msg.type) { -+ case lxc_msg_state: -+ if (msg.value < 0 || msg.value >= MAX_STATE) { -+ ERROR("Receive an invalid state number '%d'", -+ msg.value); -+ goto out_close; -+ } -+ -+ if (s[msg.value]) { -+ ret = 0; -+ goto out_close; -+ } -+ break; -+ default: -+ if (stop) { -+ ret = -2; -+ goto out_close; -+ } -+ /* just ignore garbage */ -+ break; -+ } -+ } -+ -+out_close: -+ lxc_monitor_close(fd); -+ return ret; -+} -Index: lxc/src/tests/destroytest.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ lxc/src/tests/destroytest.c 2012-08-24 09:23:58.516340000 -0500 -@@ -0,0 +1,104 @@ -+/* liblxcapi -+ * -+ * Copyright © 2012 Serge Hallyn . -+ * Copyright © 2012 Canonical Ltd. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2, as -+ * published by the Free Software Foundation. -+ * -+ * 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., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ */ -+#include "../lxc/lxccontainer.h" -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define MYNAME "lxctest1" -+ -+static int create_ubuntu(void) -+{ -+ int status, ret; -+ pid_t pid = fork(); -+ -+ if (pid < 0) { -+ perror("fork"); -+ return -1; -+ } -+ if (pid == 0) { -+ ret = execlp("lxc-create", "lxc-create", "-t", "ubuntu", "-f", "/etc/lxc/lxc.conf", "-n", MYNAME, NULL); -+ // Should not return -+ perror("execl"); -+ exit(1); -+ } -+again: -+ ret = waitpid(pid, &status, 0); -+ if (ret == -1) { -+ if (errno == -EINTR) -+ goto again; -+ perror("waitpid"); -+ return -1; -+ } -+ if (ret != pid) -+ goto again; -+ if (!WIFEXITED(status)) { // did not exit normally -+ fprintf(stderr, "%d: lxc-create exited abnormally\n", __LINE__); -+ return -1; -+ } -+ return WEXITSTATUS(status); -+} -+ -+int main(int argc, char *argv[]) -+{ -+ struct lxc_container *c; -+ int ret = 1; -+ -+ if ((c = lxc_container_new(MYNAME)) == NULL) { -+ fprintf(stderr, "%d: error opening lxc_container %s\n", __LINE__, MYNAME); -+ ret = 1; -+ goto out; -+ } -+ -+ if (c->is_defined(c)) { -+ fprintf(stderr, "%d: %s thought it was defined\n", __LINE__, MYNAME); -+ goto out; -+ } -+ -+ if (create_ubuntu()) { -+ fprintf(stderr, "%d: failed to create a ubuntu container\n", __LINE__); -+ goto out; -+ } -+ -+ if (!c->is_defined(c)) { -+ fprintf(stderr, "%d: %s thought it was not defined\n", __LINE__, MYNAME); -+ goto out; -+ } -+ -+ if (!c->destroy(c)) { -+ fprintf(stderr, "%d: error deleting %s\n", __LINE__, MYNAME); -+ goto out; -+ } -+ -+ if (c->is_defined(c)) { -+ fprintf(stderr, "%d: %s thought it was defined\n", __LINE__, MYNAME); -+ goto out; -+ } -+ -+ fprintf(stderr, "all lxc_container tests passed for %s\n", c->name); -+ ret = 0; -+out: -+ lxc_container_put(c); -+ exit(ret); -+} -Index: lxc/src/lxc/conf.c -=================================================================== ---- lxc.orig/src/lxc/conf.c 2012-08-24 09:23:58.516340000 -0500 -+++ lxc/src/lxc/conf.c 2012-08-24 09:23:58.516340000 -0500 -@@ -105,6 +105,9 @@ - #define PR_CAPBSET_DROP 24 - #endif - -+char *lxchook_names[NUM_LXC_HOOKS] = { -+ "pre-start", "mount", "start", "post-stop" }; -+ - extern int pivot_root(const char * new_root, const char * put_old); - - typedef int (*instanciate_cb)(struct lxc_handler *, struct lxc_netdev *); -@@ -1618,7 +1621,7 @@ - ifname, strerror(-err)); - if (netdev->ipv6_gateway_auto) { - char buf[INET6_ADDRSTRLEN]; -- inet_ntop(AF_INET, netdev->ipv6_gateway, buf, sizeof(buf)); -+ inet_ntop(AF_INET6, netdev->ipv6_gateway, buf, sizeof(buf)); - ERROR("tried to set autodetected ipv6 gateway '%s'", buf); - } - return -1; -@@ -2267,3 +2270,195 @@ - } - return 0; - } -+ -+static int lxc_remove_nic(struct lxc_list *it) -+{ -+ struct lxc_netdev *netdev = it->elem; -+ struct lxc_list *it2; -+ -+ lxc_list_del(it); -+ -+ if (netdev->link) -+ free(netdev->link); -+ if (netdev->name) -+ free(netdev->name); -+ if (netdev->upscript) -+ free(netdev->upscript); -+ if (netdev->hwaddr) -+ free(netdev->hwaddr); -+ if (netdev->mtu) -+ free(netdev->mtu); -+ if (netdev->ipv4_gateway) -+ free(netdev->ipv4_gateway); -+ if (netdev->ipv6_gateway) -+ free(netdev->ipv6_gateway); -+ lxc_list_for_each(it2, &netdev->ipv4) { -+ lxc_list_del(it2); -+ free(it2->elem); -+ free(it2); -+ } -+ lxc_list_for_each(it2, &netdev->ipv6) { -+ lxc_list_del(it2); -+ free(it2->elem); -+ free(it2); -+ } -+ free(it); -+} -+ -+/* we get passed in something like '0', '0.ipv4' or '1.ipv6' */ -+int lxc_clear_nic(struct lxc_conf *c, char *key) -+{ -+ char *p1; -+ int ret, idx, i; -+ struct lxc_list *it; -+ struct lxc_netdev *netdev; -+ -+ p1 = index(key, '.'); -+ if (!p1 || *(p1+1) == '\0') -+ p1 = NULL; -+ -+ ret = sscanf(key, "%d", &idx); -+ if (ret != 1) return -1; -+ if (idx < 0) -+ return -1; -+ -+ i = 0; -+ lxc_list_for_each(it, &c->network) { -+ if (i == idx) -+ break; -+ i++; -+ } -+ if (i < idx) // we don't have that many nics defined -+ return -1; -+ -+ if (!it || !it->elem) -+ return -1; -+ -+ netdev = it->elem; -+ -+ if (!p1) { -+ lxc_remove_nic(it); -+ } else if (strcmp(p1, "ipv4") == 0) { -+ struct lxc_list *it2; -+ lxc_list_for_each(it2, &netdev->ipv4) { -+ lxc_list_del(it2); -+ free(it2->elem); -+ free(it2); -+ } -+ } else if (strcmp(p1, "ipv6") == 0) { -+ struct lxc_list *it2; -+ lxc_list_for_each(it2, &netdev->ipv6) { -+ lxc_list_del(it2); -+ free(it2->elem); -+ free(it2); -+ } -+ } else if (strcmp(p1, "link") == 0) { -+ if (netdev->link) { -+ free(netdev->link); -+ netdev->link = NULL; -+ } -+ } else if (strcmp(p1, "name") == 0) { -+ if (netdev->name) { -+ free(netdev->name); -+ netdev->name = NULL; -+ } -+ } else if (strcmp(p1, "script.up") == 0) { -+ if (netdev->upscript) { -+ free(netdev->upscript); -+ netdev->upscript = NULL; -+ } -+ } else if (strcmp(p1, "hwaddr") == 0) { -+ if (netdev->hwaddr) { -+ free(netdev->hwaddr); -+ netdev->hwaddr = NULL; -+ } -+ } else if (strcmp(p1, "mtu") == 0) { -+ if (netdev->mtu) { -+ free(netdev->mtu); -+ netdev->mtu = NULL; -+ } -+ } else if (strcmp(p1, "ipv4_gateway") == 0) { -+ if (netdev->ipv4_gateway) { -+ free(netdev->ipv4_gateway); -+ netdev->ipv4_gateway = NULL; -+ } -+ } else if (strcmp(p1, "ipv6_gateway") == 0) { -+ if (netdev->ipv6_gateway) { -+ free(netdev->ipv6_gateway); -+ netdev->ipv6_gateway = NULL; -+ } -+ } -+ else return -1; -+ -+ return 0; -+} -+ -+int lxc_clear_config_network(struct lxc_conf *c) -+{ -+ struct lxc_list *it; -+ lxc_list_for_each(it, &c->network) { -+ lxc_remove_nic(it); -+ } -+ return 0; -+} -+ -+int lxc_clear_config_caps(struct lxc_conf *c) -+{ -+ struct lxc_list *it; -+ -+ lxc_list_for_each(it, &c->caps) { -+ lxc_list_del(it); -+ free(it->elem); -+ free(it); -+ } -+ return 0; -+} -+ -+int lxc_clear_cgroups(struct lxc_conf *c, char *key) -+{ -+ struct lxc_list *it; -+ bool all = false; -+ char *k = key + 11; -+ -+ if (strcmp(key, "lxc.cgroup") == 0) -+ all = true; -+ -+ lxc_list_for_each(it, &c->cgroup) { -+ struct lxc_cgroup *cg = it->elem; -+ if (!all && strcmp(cg->subsystem, k) != 0) -+ continue; -+ lxc_list_del(it); -+ free(cg->subsystem); -+ free(cg->value); -+ free(cg); -+ free(it); -+ } -+ return 0; -+} -+ -+int lxc_clear_mount_entries(struct lxc_conf *c) -+{ -+ struct lxc_list *it; -+ -+ lxc_list_for_each(it, &c->mount_list) { -+ lxc_list_del(it); -+ free(it->elem); -+ free(it); -+ } -+ return 0; -+} -+ -+int lxc_clear_hooks(struct lxc_conf *c) -+{ -+ struct lxc_list *it; -+ int i; -+ -+ for (i=0; ihooks[i]) { -+ lxc_list_del(it); -+ free(it->elem); -+ free(it); -+ } -+ } -+ return 0; -+} -Index: lxc/src/lxc/network.c -=================================================================== ---- lxc.orig/src/lxc/network.c 2012-08-24 09:23:58.516340000 -0500 -+++ lxc/src/lxc/network.c 2012-08-24 09:23:58.516340000 -0500 -@@ -47,6 +47,7 @@ - - #include "nl.h" - #include "network.h" -+#include "conf.h" - - #ifndef IFLA_LINKMODE - # define IFLA_LINKMODE 17 -@@ -1004,3 +1005,18 @@ - - return err; - } -+ -+static char* lxc_network_types[LXC_NET_MAXCONFTYPE + 1] = { -+ [LXC_NET_VETH] = "veth", -+ [LXC_NET_MACVLAN] = "macvlan", -+ [LXC_NET_VLAN] = "vlan", -+ [LXC_NET_PHYS] = "phys", -+ [LXC_NET_EMPTY] = "empty", -+}; -+ -+const char *lxc_net_type_to_str(int type) -+{ -+ if (type < 0 || type > LXC_NET_MAXCONFTYPE) -+ return NULL; -+ return lxc_network_types[type]; -+} -Index: lxc/src/lxc/network.h -=================================================================== ---- lxc.orig/src/lxc/network.h 2012-08-24 09:23:58.516340000 -0500 -+++ lxc/src/lxc/network.h 2012-08-24 09:23:58.516340000 -0500 -@@ -122,4 +122,5 @@ - */ - extern int lxc_neigh_proxy_off(const char *name, int family); - -+extern const char *lxc_net_type_to_str(int type); - #endif -Index: lxc/src/tests/saveconfig.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ lxc/src/tests/saveconfig.c 2012-08-24 09:23:58.516340000 -0500 -@@ -0,0 +1,106 @@ -+/* liblxcapi -+ * -+ * Copyright © 2012 Serge Hallyn . -+ * Copyright © 2012 Canonical Ltd. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2, as -+ * published by the Free Software Foundation. -+ * -+ * 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., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ */ -+#include "../lxc/lxccontainer.h" -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define MYNAME "lxctest1" -+ -+static int create_ubuntu(void) -+{ -+ int status, ret; -+ pid_t pid = fork(); -+ -+ if (pid < 0) { -+ perror("fork"); -+ return -1; -+ } -+ if (pid == 0) { -+ ret = execlp("lxc-create", "lxc-create", "-t", "ubuntu", "-f", "/etc/lxc/lxc.conf", "-n", MYNAME, NULL); -+ // Should not return -+ perror("execl"); -+ exit(1); -+ } -+again: -+ ret = waitpid(pid, &status, 0); -+ if (ret == -1) { -+ if (errno == -EINTR) -+ goto again; -+ perror("waitpid"); -+ return -1; -+ } -+ if (ret != pid) -+ goto again; -+ if (!WIFEXITED(status)) { // did not exit normally -+ fprintf(stderr, "%d: lxc-create exited abnormally\n", __LINE__); -+ return -1; -+ } -+ return WEXITSTATUS(status); -+} -+ -+int main(int argc, char *argv[]) -+{ -+ struct lxc_container *c; -+ int ret = 1; -+ -+ if ((c = lxc_container_new(MYNAME)) == NULL) { -+ fprintf(stderr, "%d: error opening lxc_container %s\n", __LINE__, MYNAME); -+ ret = 1; -+ goto out; -+ } -+ -+ if (c->is_defined(c)) { -+ fprintf(stderr, "%d: %s thought it was defined\n", __LINE__, MYNAME); -+ goto out; -+ } -+ -+ if (create_ubuntu()) { -+ fprintf(stderr, "%d: failed to create a ubuntu container\n", __LINE__); -+ goto out; -+ } -+ -+ if (!c->is_defined(c)) { -+ fprintf(stderr, "%d: %s thought it was not defined\n", __LINE__, MYNAME); -+ goto out; -+ } -+ -+ c->load_config(c, NULL); -+ unlink("/tmp/lxctest1"); -+ if (!c->save_config(c, "/tmp/lxctest1")) { -+ fprintf(stderr, "%d: failed writing config file /tmp/lxctest1\n", __LINE__); -+ goto out; -+ } -+ rename("/var/lib/lxc/" MYNAME "/config", "/var/lib/lxc/" MYNAME "/config.bak"); -+ if (!c->save_config(c, NULL)) { -+ fprintf(stderr, "%d: failed writing config file\n", __LINE__); -+ goto out; -+ } -+ -+ fprintf(stderr, "all lxc_container tests passed for %s\n", c->name); -+ ret = 0; -+out: -+ lxc_container_put(c); -+ exit(ret); -+} -Index: lxc/src/tests/createtest.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ lxc/src/tests/createtest.c 2012-08-24 09:23:58.516340000 -0500 -@@ -0,0 +1,92 @@ -+/* liblxcapi -+ * -+ * Copyright © 2012 Serge Hallyn . -+ * Copyright © 2012 Canonical Ltd. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2, as -+ * published by the Free Software Foundation. -+ * -+ * 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., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ */ -+#include "../lxc/lxccontainer.h" -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define MYNAME "lxctest1" -+ -+int main(int argc, char *argv[]) -+{ -+ struct lxc_container *c; -+ int ret = 1; -+ -+ if ((c = lxc_container_new(MYNAME)) == NULL) { -+ fprintf(stderr, "%d: error opening lxc_container %s\n", __LINE__, MYNAME); -+ ret = 1; -+ goto out; -+ } -+ -+ if (c->is_defined(c)) { -+ fprintf(stderr, "%d: %s thought it was defined\n", __LINE__, MYNAME); -+ goto out; -+ } -+ -+ if (!c->set_config_item(c, "lxc.network.type", "veth")) { -+ fprintf(stderr, "%d: failed to set network type\n", __LINE__); -+ goto out; -+ } -+ c->set_config_item(c, "lxc.network.link", "lxcbr0"); -+ c->set_config_item(c, "lxc.network.flags", "up"); -+ if (!c->createl(c, "ubuntu", "-r", "lucid", NULL)) { -+ fprintf(stderr, "%d: failed to create a lucid container\n", __LINE__); -+ goto out; -+ } -+ -+ if (!c->is_defined(c)) { -+ fprintf(stderr, "%d: %s thought it was not defined\n", __LINE__, MYNAME); -+ goto out; -+ } -+ -+ c->load_config(c, NULL); -+ c->want_daemonize(c); -+ if (!c->startl(c, 0, NULL)) { -+ fprintf(stderr, "%d: failed to start %s\n", __LINE__, MYNAME); -+ goto out; -+ } -+ fprintf(stderr, "%d: %s started, you have 60 seconds to test a console\n", __LINE__, MYNAME); -+ sleep(60); // wait a minute to let user connect to console -+ -+ if (!c->stop(c)) { -+ fprintf(stderr, "%d: failed to stop %s\n", __LINE__, MYNAME); -+ goto out; -+ } -+ -+ if (!c->destroy(c)) { -+ fprintf(stderr, "%d: error deleting %s\n", __LINE__, MYNAME); -+ goto out; -+ } -+ -+ if (c->is_defined(c)) { -+ fprintf(stderr, "%d: %s thought it was defined\n", __LINE__, MYNAME); -+ goto out; -+ } -+ -+ fprintf(stderr, "all lxc_container tests passed for %s\n", c->name); -+ ret = 0; -+out: -+ lxc_container_put(c); -+ exit(ret); -+} -Index: lxc/src/lxc/monitor.c -=================================================================== ---- lxc.orig/src/lxc/monitor.c 2012-08-24 09:23:58.516340000 -0500 -+++ lxc/src/lxc/monitor.c 2012-08-24 09:23:58.516340000 -0500 -@@ -98,11 +98,28 @@ - return fd; - } - --int lxc_monitor_read(int fd, struct lxc_msg *msg) -+/* timeout of 0 means return immediately; -1 means wait forever */ -+int lxc_monitor_read_timeout(int fd, struct lxc_msg *msg, int timeout) - { - struct sockaddr_un from; - socklen_t len = sizeof(from); - int ret; -+ fd_set rfds; -+ struct timeval tv; -+ -+ if (timeout != -1) { -+ FD_ZERO(&rfds); -+ FD_SET(fd, &rfds); -+ -+ tv.tv_sec = timeout; -+ tv.tv_usec = 0; -+ -+ ret = select(fd+1, &rfds, NULL, NULL, &tv); -+ if (ret == -1) -+ return -1; -+ else if (!ret) -+ return -2; // timed out -+ } - - ret = recvfrom(fd, msg, sizeof(*msg), 0, - (struct sockaddr *)&from, &len); -@@ -114,6 +131,11 @@ - return ret; - } - -+int lxc_monitor_read(int fd, struct lxc_msg *msg) -+{ -+ return lxc_monitor_read_timeout(fd, msg, -1); -+} -+ - int lxc_monitor_close(int fd) - { - return close(fd); -Index: lxc/src/tests/shutdowntest.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ lxc/src/tests/shutdowntest.c 2012-08-24 09:23:58.516340000 -0500 -@@ -0,0 +1,93 @@ -+ -+/* liblxcapi -+ * -+ * Copyright © 2012 Serge Hallyn . -+ * Copyright © 2012 Canonical Ltd. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2, as -+ * published by the Free Software Foundation. -+ * -+ * 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., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ */ -+#include "../lxc/lxccontainer.h" -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define MYNAME "lxctest1" -+ -+int main(int argc, char *argv[]) -+{ -+ struct lxc_container *c; -+ int ret = 1; -+ -+ if ((c = lxc_container_new(MYNAME)) == NULL) { -+ fprintf(stderr, "%d: error opening lxc_container %s\n", __LINE__, MYNAME); -+ ret = 1; -+ goto out; -+ } -+ -+ if (c->is_defined(c)) { -+ fprintf(stderr, "%d: %s thought it was defined\n", __LINE__, MYNAME); -+ goto out; -+ } -+ -+ if (!c->set_config_item(c, "lxc.network.type", "veth")) { -+ fprintf(stderr, "%d: failed to set network type\n", __LINE__); -+ goto out; -+ } -+ c->set_config_item(c, "lxc.network.link", "lxcbr0"); -+ c->set_config_item(c, "lxc.network.flags", "up"); -+ if (!c->createl(c, "ubuntu", "-r", "lucid", NULL)) { -+ fprintf(stderr, "%d: failed to create a lucid container\n", __LINE__); -+ goto out; -+ } -+ -+ if (!c->is_defined(c)) { -+ fprintf(stderr, "%d: %s thought it was not defined\n", __LINE__, MYNAME); -+ goto out; -+ } -+ -+ c->load_config(c, NULL); -+ c->want_daemonize(c); -+ if (!c->startl(c, 0, NULL)) { -+ fprintf(stderr, "%d: failed to start %s\n", __LINE__, MYNAME); -+ goto out; -+ } -+ fprintf(stderr, "%d: %s started, you have 60 seconds to test a console\n", __LINE__, MYNAME); -+ sleep(60); // wait a minute to let user connect to console -+ -+ if (!c->shutdown(c, 60)) { -+ fprintf(stderr, "%d: failed to shut down %s\n", __LINE__, MYNAME); -+ goto out; -+ } -+ -+ if (!c->destroy(c)) { -+ fprintf(stderr, "%d: error deleting %s\n", __LINE__, MYNAME); -+ goto out; -+ } -+ -+ if (c->is_defined(c)) { -+ fprintf(stderr, "%d: %s thought it was defined\n", __LINE__, MYNAME); -+ goto out; -+ } -+ -+ fprintf(stderr, "all lxc_container tests passed for %s\n", c->name); -+ ret = 0; -+out: -+ lxc_container_put(c); -+ exit(ret); -+} -Index: lxc/src/lxc/conf.h -=================================================================== ---- lxc.orig/src/lxc/conf.h 2012-08-24 09:23:58.516340000 -0500 -+++ lxc/src/lxc/conf.h 2012-08-24 09:23:58.516340000 -0500 -@@ -203,6 +203,8 @@ - enum lxchooks { - LXCHOOK_PRESTART, LXCHOOK_MOUNT, LXCHOOK_START, - LXCHOOK_POSTSTOP, NUM_LXC_HOOKS}; -+extern char *lxchook_names[NUM_LXC_HOOKS]; -+ - struct lxc_conf { - char *fstab; - int tty; -@@ -224,6 +226,7 @@ - int umount_proc; - struct lxc_list hooks[NUM_LXC_HOOKS]; - char *seccomp; // filename with the seccomp rules -+ int maincmd_fd; - }; - - int run_lxc_hooks(const char *name, char *hook, struct lxc_conf *conf); -@@ -248,6 +251,13 @@ - extern int lxc_create_tty(const char *name, struct lxc_conf *conf); - extern void lxc_delete_tty(struct lxc_tty_info *tty_info); - -+extern int lxc_clear_config_network(struct lxc_conf *c); -+extern int lxc_clear_nic(struct lxc_conf *c, char *key); -+extern int lxc_clear_config_caps(struct lxc_conf *c); -+extern int lxc_clear_cgroups(struct lxc_conf *c, char *key); -+extern int lxc_clear_mount_entries(struct lxc_conf *c); -+extern int lxc_clear_hooks(struct lxc_conf *c); -+ - /* - * Configure the container from inside - */ -Index: lxc/doc/rootfs/Makefile.am -=================================================================== ---- lxc.orig/doc/rootfs/Makefile.am 2012-08-24 09:23:58.516340000 -0500 -+++ lxc/doc/rootfs/Makefile.am 2012-08-24 09:23:58.516340000 -0500 -@@ -1,3 +1,3 @@ - READMEdir=@LXCROOTFSMOUNT@ - --README_DATA=README -\ No newline at end of file -+README_DATA= -Index: lxc/src/tests/get_item.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ lxc/src/tests/get_item.c 2012-08-24 09:23:58.516340000 -0500 -@@ -0,0 +1,308 @@ -+/* liblxcapi -+ * -+ * Copyright © 2012 Serge Hallyn . -+ * Copyright © 2012 Canonical Ltd. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2, as -+ * published by the Free Software Foundation. -+ * -+ * 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., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ */ -+#include "../lxc/lxccontainer.h" -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define MYNAME "lxctest1" -+ -+int main(int argc, char *argv[]) -+{ -+ struct lxc_container *c; -+ int ret; -+ char v1[2], v2[256], v3[2048]; -+ -+ if ((c = lxc_container_new("testxyz")) == NULL) { -+ fprintf(stderr, "%d: error opening lxc_container %s\n", __LINE__, MYNAME); -+ ret = 1; -+ goto out; -+ } -+ -+ if (!c->set_config_item(c, "lxc.hook.pre-start", "hi there")) { -+ fprintf(stderr, "%d: failed to set hook.pre-start\n", __LINE__); -+ ret = 1; -+ goto out; -+ } -+ ret = c->get_config_item(c, "lxc.hook.pre-start", v2, 255); -+ if (ret < 0) { -+ fprintf(stderr, "%d: get_config_item(lxc.hook.pre-start) returned %d\n", __LINE__, ret); -+ ret = 1; -+ goto out; -+ } -+ fprintf(stderr, "lxc.hook.pre-start returned %d %s\n", ret, v2); -+ -+ ret = c->get_config_item(c, "lxc.network", v2, 255); -+ if (ret < 0) { -+ fprintf(stderr, "%d: get_config_item returned %d\n", __LINE__, ret); -+ ret = 1; -+ goto out; -+ } -+ fprintf(stderr, "%d: get_config_item(lxc.network) returned %d %s\n", __LINE__, ret, v2); -+ if (!c->set_config_item(c, "lxc.tty", "4")) { -+ fprintf(stderr, "%d: failed to set tty\n", __LINE__); -+ ret = 1; -+ goto out; -+ } -+ ret = c->get_config_item(c, "lxc.tty", v2, 255); -+ if (ret < 0) { -+ fprintf(stderr, "%d: get_config_item(lxc.tty) returned %d\n", __LINE__, ret); -+ ret = 1; -+ goto out; -+ } -+ fprintf(stderr, "lxc.tty returned %d %s\n", ret, v2); -+ -+ if (!c->set_config_item(c, "lxc.arch", "x86")) { -+ fprintf(stderr, "%d: failed to set arch\n", __LINE__); -+ ret = 1; -+ goto out; -+ } -+ ret = c->get_config_item(c, "lxc.arch", v2, 255); -+ if (ret < 0) { -+ fprintf(stderr, "%d: get_config_item(lxc.arch) returned %d\n", __LINE__, ret); -+ ret = 1; -+ goto out; -+ } -+ printf("lxc.arch returned %d %s\n", ret, v2); -+ -+#define HNAME "hostname1" -+ // demonstrate proper usage: -+ char *alloced; -+ if (!c->set_config_item(c, "lxc.utsname", HNAME)) { -+ fprintf(stderr, "%d: failed to set utsname\n", __LINE__); -+ ret = 1; -+ goto out; -+ } -+ -+ int len; -+ len = c->get_config_item(c, "lxc.utsname", NULL, 0); // query the size of the string -+ if (len < 0) { -+ fprintf(stderr, "%d: get_config_item(lxc.utsname) returned %d\n", __LINE__, len); -+ ret = 1; -+ goto out; -+ } -+ printf("lxc.utsname returned %d\n", len); -+ -+ // allocate the length of string + 1 for trailing \0 -+ alloced = malloc(len+1); -+ if (!alloced) { -+ fprintf(stderr, "%d: failed to allocate %d bytes for utsname\n", __LINE__, len); -+ ret = 1; -+ goto out; -+ } -+ // now pass in the malloc'd array, and pass in length of string + 1: again -+ // because we need room for the trailing \0 -+ ret = c->get_config_item(c, "lxc.utsname", alloced, len+1); -+ if (ret < 0) { -+ fprintf(stderr, "%d: get_config_item(lxc.utsname) returned %d\n", __LINE__, ret); -+ ret = 1; -+ goto out; -+ } -+ if (strcmp(alloced, HNAME) != 0 || ret != len) { -+ fprintf(stderr, "lxc.utsname returned wrong value: %d %s not %d %s\n", ret, alloced, len, HNAME); -+ ret = 1; -+ goto out; -+ } -+ printf("lxc.utsname returned %d %s\n", len, alloced); -+ free(alloced); -+ -+ if (!c->set_config_item(c, "lxc.mount.entry", "hi there")) { -+ fprintf(stderr, "%d: failed to set mount.entry\n", __LINE__); -+ ret = 1; -+ goto out; -+ } -+ ret = c->get_config_item(c, "lxc.mount.entry", v2, 255); -+ if (ret < 0) { -+ fprintf(stderr, "%d: get_config_item(lxc.mount.entry) returned %d\n", __LINE__, ret); -+ ret = 1; -+ goto out; -+ } -+ printf("lxc.mount.entry returned %d %s\n", ret, v2); -+ -+ if (!c->set_config_item(c, "lxc.aa_profile", "unconfined")) { -+ fprintf(stderr, "%d: failed to set aa_profile\n", __LINE__); -+ ret = 1; -+ goto out; -+ } -+ ret = c->get_config_item(c, "lxc.aa_profile", v2, 255); -+ if (ret < 0) { -+ fprintf(stderr, "%d: get_config_item(lxc.aa_profile) returned %d\n", __LINE__, ret); -+ ret = 1; -+ goto out; -+ } -+ printf("lxc.aa_profile returned %d %s\n", ret, v2); -+ -+ lxc_container_put(c); -+ -+ // new test with real container -+ if ((c = lxc_container_new(MYNAME)) == NULL) { -+ fprintf(stderr, "%d: error opening lxc_container %s\n", __LINE__, MYNAME); -+ ret = 1; -+ goto out; -+ } -+ c->destroy(c); -+ lxc_container_put(c); -+ -+ if ((c = lxc_container_new(MYNAME)) == NULL) { -+ fprintf(stderr, "%d: error opening lxc_container %s\n", __LINE__, MYNAME); -+ ret = 1; -+ goto out; -+ } -+ if (!c->createl(c, "ubuntu", "-r", "lucid", NULL)) { -+ fprintf(stderr, "%d: failed to create a lucid container\n", __LINE__); -+ ret = 1; -+ goto out; -+ } -+ -+ lxc_container_put(c); -+ -+ /* XXX TODO load_config needs to clear out any old config first */ -+ if ((c = lxc_container_new(MYNAME)) == NULL) { -+ fprintf(stderr, "%d: error opening lxc_container %s\n", __LINE__, MYNAME); -+ ret = 1; -+ goto out; -+ } -+ -+ ret = c->get_config_item(c, "lxc.cap.drop", NULL, 300); -+ if (ret < 5 || ret > 255) { -+ fprintf(stderr, "%d: get_config_item(lxc.cap.drop) with NULL returned %d\n", __LINE__, ret); -+ ret = 1; -+ goto out; -+ } -+ ret = c->get_config_item(c, "lxc.cap.drop", v1, 1); -+ if (ret < 5 || ret > 255) { -+ fprintf(stderr, "%d: get_config_item(lxc.cap.drop) returned %d\n", __LINE__, ret); -+ ret = 1; -+ goto out; -+ } -+ ret = c->get_config_item(c, "lxc.cap.drop", v2, 255); -+ if (ret < 0) { -+ fprintf(stderr, "%d: get_config_item(lxc.cap.drop) returned %d %s\n", __LINE__, ret, v2); -+ ret = 1; -+ goto out; -+ } -+ printf("%d: get_config_item(lxc.cap.drop) returned %d %s\n", __LINE__, ret, v2); -+ ret = c->get_config_item(c, "lxc.network", v2, 255); -+ if (ret < 0) { -+ fprintf(stderr, "%d: get_config_item returned %d\n", __LINE__, ret); -+ ret = 1; -+ goto out; -+ } -+ printf("%d: get_config_item(lxc.network) returned %d %s\n", __LINE__, ret, v2); -+ -+ if (!c->set_config_item(c, "lxc.network.ipv4", "10.2.3.4")) { -+ fprintf(stderr, "%d: failed to set ipv4\n", __LINE__); -+ ret = 1; -+ goto out; -+ } -+ -+ ret = c->get_config_item(c, "lxc.network.0.ipv4", v2, 255); -+ if (ret <= 0) { -+ fprintf(stderr, "%d: lxc.network.0.ipv4 returned %d\n", __LINE__, ret); -+ ret = 1; -+ goto out; -+ } -+ if (!c->clear_config_item(c, "lxc.network.0.ipv4")) { -+ fprintf(stderr, "%d: failed clearing all ipv4 entries\n", __LINE__); -+ ret = 1; -+ goto out; -+ } -+ ret = c->get_config_item(c, "lxc.network.0.ipv4", v2, 255); -+ if (ret != 0) { -+ fprintf(stderr, "%d: after clearing ipv4 entries get_item(lxc.network.0.ipv4 returned %d\n", __LINE__, ret); -+ ret = 1; -+ goto out; -+ } -+ -+ ret = c->get_config_item(c, "lxc.network.0.link", v2, 255); -+ if (ret < 0) { -+ fprintf(stderr, "%d: get_config_item returned %d\n", __LINE__, ret); -+ ret = 1; -+ goto out; -+ } -+ printf("%d: get_config_item (link) returned %d %s\n", __LINE__, ret, v2); -+ ret = c->get_config_item(c, "lxc.network.0.name", v2, 255); -+ if (ret < 0) { -+ fprintf(stderr, "%d: get_config_item returned %d\n", __LINE__, ret); -+ ret = 1; -+ goto out; -+ } -+ printf("%d: get_config_item (name) returned %d %s\n", __LINE__, ret, v2); -+ -+ if (!c->clear_config_item(c, "lxc.network")) { -+ fprintf(stderr, "%d: clear_config_item failed\n", __LINE__); -+ ret = 1; -+ goto out; -+ } -+ ret = c->get_config_item(c, "lxc.network", v2, 255); -+ if (ret != 0) { -+ fprintf(stderr, "%d: network was not actually cleared (get_network returned %d)\n", __LINE__, ret); -+ ret = 1; -+ goto out; -+ } -+ -+ ret = c->get_config_item(c, "lxc.cgroup", v3, 2047); -+ if (ret < 0) { -+ fprintf(stderr, "%d: get_config_item(cgroup.devices) returned %d\n", __LINE__, ret); -+ ret = 1; -+ goto out; -+ } -+ printf("%d: get_config_item (cgroup.devices) returned %d %s\n", __LINE__, ret, v3); -+ -+ ret = c->get_config_item(c, "lxc.cgroup.devices.allow", v3, 2047); -+ if (ret < 0) { -+ fprintf(stderr, "%d: get_config_item(cgroup.devices.devices.allow) returned %d\n", __LINE__, ret); -+ ret = 1; -+ goto out; -+ } -+ printf("%d: get_config_item (cgroup.devices.devices.allow) returned %d %s\n", __LINE__, ret, v3); -+ -+ if (!c->clear_config_item(c, "lxc.cgroup")) { -+ fprintf(stderr, "%d: failed clearing lxc.cgroup", __LINE__); -+ ret = 1; -+ goto out; -+ } -+ if (!c->clear_config_item(c, "lxc.cap.drop")) { -+ fprintf(stderr, "%d: failed clearing lxc.cap.drop", __LINE__); -+ ret = 1; -+ goto out; -+ } -+ if (!c->clear_config_item(c, "lxc.mount.entries")) { -+ fprintf(stderr, "%d: failed clearing lxc.mount.entries", __LINE__); -+ ret = 1; -+ goto out; -+ } -+ if (!c->clear_config_item(c, "lxc.hook")) { -+ fprintf(stderr, "%d: failed clearing lxc.hook", __LINE__); -+ ret = 1; -+ goto out; -+ } -+ c->destroy(c); -+ printf("All get_item tests passed\n"); -+ ret = 0; -+out: -+ lxc_container_put(c); -+ exit(ret); -+}; -Index: lxc/src/lxc/commands.c -=================================================================== ---- lxc.orig/src/lxc/commands.c 2012-08-24 09:23:58.516340000 -0500 -+++ lxc/src/lxc/commands.c 2012-08-24 09:23:58.516340000 -0500 -@@ -305,5 +305,6 @@ - close(fd); - } - -+ handler->conf->maincmd_fd = fd; - return ret; - } -Index: lxc/src/tests/getkeys.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ lxc/src/tests/getkeys.c 2012-08-24 09:23:58.516340000 -0500 -@@ -0,0 +1,71 @@ -+/* liblxcapi -+ * -+ * Copyright © 2012 Serge Hallyn . -+ * Copyright © 2012 Canonical Ltd. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2, as -+ * published by the Free Software Foundation. -+ * -+ * 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., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ */ -+#include "../lxc/lxccontainer.h" -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define MYNAME "lxctest1" -+ -+int main(int argc, char *argv[]) -+{ -+ struct lxc_container *c; -+ int len, ret; -+ char v1[2], v2[256], v3[2048]; -+ -+ if ((c = lxc_container_new(MYNAME)) == NULL) { -+ fprintf(stderr, "%d: error opening lxc_container %s\n", __LINE__, MYNAME); -+ ret = 1; -+ goto out; -+ } -+ -+ c->set_config_item(c, "lxc.network.type", "veth"); -+ -+ len = c->get_keys(c, NULL, NULL, 0); -+ if (len < 0) { -+ fprintf(stderr, "%d: failed to get length of all keys (%d)\n", __LINE__, len); -+ ret = 1; -+ goto out; -+ } -+ ret = c->get_keys(c, NULL, v3, len+1); -+ if (ret != len) { -+ fprintf(stderr, "%d: failed to get keys (%d)\n", __LINE__, ret); -+ ret = 1; -+ goto out; -+ } -+ printf("get_keys returned %d\n%s", ret, v3); -+ -+ ret = c->get_keys(c, "lxc.network.0", v3, 2000); -+ if (ret < 0) { -+ fprintf(stderr, "%d: failed to get nic 0 keys(%d)\n", __LINE__, ret); -+ ret = 1; -+ goto out; -+ } -+ printf("get_keys for nic 1 returned %d\n%s", ret, v3); -+ -+out: -+ lxc_container_put(c); -+ exit(ret); -+} diff -Nru lxc-0.8.0~rc1/debian/patches/0201-fix-mkdir-race lxc-1.0.0~alpha1/debian/patches/0201-fix-mkdir-race --- lxc-0.8.0~rc1/debian/patches/0201-fix-mkdir-race 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0201-fix-mkdir-race 1970-01-01 00:00:00.000000000 +0000 @@ -1,24 +0,0 @@ -Description: if mkdir fails with -EEXIST, let it be. -Author: Serge Hallyn -Forwarded: yes - -Index: lxc/src/lxc/cgroup.c -=================================================================== ---- lxc.orig/src/lxc/cgroup.c 2012-08-24 10:51:33.375144000 -0500 -+++ lxc/src/lxc/cgroup.c 2012-08-24 10:59:42.293491913 -0500 -@@ -357,9 +357,12 @@ - } - - /* if /sys/fs/cgroup///lxc does not exist, create it */ -- if (access(cgparent, F_OK) && mkdir(cgparent, 0755)) { -- SYSERROR("failed to create '%s' directory", cgparent); -- return -1; -+ if (access(cgparent, F_OK)) { -+ ret = mkdir(cgparent, 0755); -+ if (ret == -1 && errno == EEXIST) { -+ SYSERROR("failed to create '%s' directory", cgparent); -+ return -1; -+ } - } - - /* diff -Nru lxc-0.8.0~rc1/debian/patches/0202-make-api-start-reliable lxc-1.0.0~alpha1/debian/patches/0202-make-api-start-reliable --- lxc-0.8.0~rc1/debian/patches/0202-make-api-start-reliable 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0202-make-api-start-reliable 1970-01-01 00:00:00.000000000 +0000 @@ -1,58 +0,0 @@ -Index: lxc/src/lxc/lxccontainer.c -=================================================================== ---- lxc.orig/src/lxc/lxccontainer.c 2012-08-24 11:46:43.112003985 -0500 -+++ lxc/src/lxc/lxccontainer.c 2012-08-24 12:22:40.683925258 -0500 -@@ -244,6 +244,26 @@ - c->daemonize = 1; - } - -+static bool lxcapi_wait(struct lxc_container *c, char *state, int timeout) -+{ -+ int ret; -+ -+ if (!c) -+ return false; -+ -+ ret = lxc_wait(c->name, state, timeout); -+ return ret == 0; -+} -+ -+ -+static bool wait_on_daemonized_start(struct lxc_container *c) -+{ -+ /* we'll probably want to make this timeout configurable? */ -+ int timeout = 5; -+ -+ return lxcapi_wait(c, "RUNNING", timeout); -+} -+ - /* - * I can't decide if it'd be more convenient for callers if we accept '...', - * or a null-terminated array (i.e. execl vs execv) -@@ -298,7 +318,7 @@ - return false; - } - if (pid != 0) -- return true; -+ return wait_on_daemonized_start(c); - /* like daemon(), chdir to / and redirect 0,1,2 to /dev/null */ - chdir("/"); - close(0); -@@ -408,17 +428,6 @@ - return ret == 0; - } - --static bool lxcapi_wait(struct lxc_container *c, char *state, int timeout) --{ -- int ret; -- -- if (!c) -- return false; -- -- ret = lxc_wait(c->name, state, timeout); -- return ret == 0; --} -- - static bool valid_template(char *t) - { - struct stat statbuf; diff -Nru lxc-0.8.0~rc1/debian/patches/0203-python-lxc lxc-1.0.0~alpha1/debian/patches/0203-python-lxc --- lxc-0.8.0~rc1/debian/patches/0203-python-lxc 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0203-python-lxc 1970-01-01 00:00:00.000000000 +0000 @@ -1,1086 +0,0 @@ -Description: Initial implementation of python-lxc on top of liblxc - This patch introduces the initial python bindong for liblxc. -Author: Stéphane Graber - -Origin: vendor -Forwarded: no - -Index: lxc/configure.ac -=================================================================== ---- lxc.orig/configure.ac 2012-08-27 17:12:13.000000000 -0400 -+++ lxc/configure.ac 2012-08-27 17:38:07.215872629 -0400 -@@ -12,6 +12,11 @@ - AC_GNU_SOURCE - AC_CHECK_PROG(SETCAP, setcap, yes, no, $PATH$PATH_SEPARATOR/sbin) - -+if test -f /etc/debian_version; then -+ osname="debian" -+fi -+AM_CONDITIONAL([HAVE_DEBIAN], [test x"$osname" == xdebian]) -+ - AC_ARG_ENABLE([rpath], - [AC_HELP_STRING([--disable-rpath], [do not set rpath in executables])], - [], [enable_rpath=yes]) -@@ -53,6 +58,17 @@ - - AM_CONDITIONAL([ENABLE_EXAMPLES], [test "x$enable_examples" = "xyes"]) - -+AC_ARG_ENABLE([python], -+ [AC_HELP_STRING([--enable-python], [enable python binding])], -+ [enable_python=yes], [enable_python=no]) -+ -+AM_CONDITIONAL([ENABLE_PYTHON], [test "x$enable_python" = "xyes"]) -+ -+AM_COND_IF([ENABLE_PYTHON], -+ [AM_PATH_PYTHON([3.2], [], [AC_MSG_ERROR([You must install python3])]) -+ AC_CHECK_HEADER([python$PYTHON_VERSION/Python.h],[],[AC_MSG_ERROR([You must install python3-dev])]) -+ AC_DEFINE_UNQUOTED([ENABLE_PYTHON], 1, [Python3 is available])]) -+ - AS_AC_EXPAND(PREFIX, $prefix) - AS_AC_EXPAND(LIBDIR, $libdir) - AS_AC_EXPAND(BINDIR, $bindir) -@@ -179,6 +195,8 @@ - src/lxc/lxc-shutdown - src/lxc/lxc-destroy - -+ src/python-lxc/Makefile -+ - src/tests/Makefile - - ]) -Index: lxc/src/Makefile.am -=================================================================== ---- lxc.orig/src/Makefile.am 2012-08-27 17:12:13.000000000 -0400 -+++ lxc/src/Makefile.am 2012-08-27 17:12:13.000000000 -0400 -@@ -1 +1 @@ --SUBDIRS = lxc tests -+SUBDIRS = lxc tests python-lxc -Index: lxc/src/python-lxc/test.py -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ lxc/src/python-lxc/test.py 2012-08-27 17:12:13.000000000 -0400 -@@ -0,0 +1,28 @@ -+import lxc -+ -+t1 = lxc.Container("test") -+print("Name set properly: %s" % (t1.name == "test")) -+print("Test config loaded properly: %s" % t1.load_config("/etc/lxc/lxc.conf")) -+print("Real config loaded properly: %s" % t1.load_config()) -+print("Test config path: %s" % (t1.config_file_name == "/var/lib/lxc/test/config")) -+print("Set config item: %s" % t1.set_config_item("lxc.utsname", "blabla")) -+print("Container defined: %s" % (t1.defined)) -+print("Started properly: %s" % t1.start()) -+print("Container running: %s" % t1.wait("RUNNING")) -+print("Container state: %s" % t1.state) -+print("Container running: %s" % t1.running) -+print("Container init process: %s" % t1.init_pid) -+print("Freezing: %s" % t1.freeze()) -+print("Container frozen: %s" % t1.wait("FROZEN")) -+print("Container state: %s" % t1.state) -+print("Unfreezing: %s" % t1.unfreeze()) -+print("Container running: %s" % t1.wait("RUNNING")) -+print("Container state: %s" % t1.state) -+print("Stopped properly: %s" % t1.stop()) -+print("Container state: %s" % t1.state) -+ -+#print("Started properly: %s" % t1.start(useinit=True)) -+#print("Container running: %s" % t1.wait("RUNNING")) -+#print("Container state: %s" % t1.state) -+#print("Stopped properly: %s" % t1.stop()) -+#print("Container state: %s" % t1.state) -Index: lxc/src/python-lxc/Makefile.am -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ lxc/src/python-lxc/Makefile.am 2012-08-27 17:40:12.787876132 -0400 -@@ -0,0 +1,18 @@ -+if ENABLE_PYTHON -+ -+if HAVE_DEBIAN -+ DISTSETUPOPTS=--install-layout=deb -+else -+ DISTSETUPOPTS= -+endif -+ -+all: -+ CFLAGS="$(CFLAGS) -I ../../src -L../../src/lxc/" $(PYTHON) setup.py build -+ -+install: -+ python3 setup.py install --root=$(DESTDIR) --prefix=$(PREFIX) --no-compile $(DISTSETUPOPTS) -+ -+clean: -+ rm -rf build -+ -+endif -Index: lxc/src/python-lxc/lxc.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ lxc/src/python-lxc/lxc.c 2012-08-27 17:12:13.000000000 -0400 -@@ -0,0 +1,576 @@ -+/* -+ * python-lxc: Python bindings for LXC -+ * -+ * (C) Copyright Canonical Ltd. 2012 -+ * -+ * Authors: -+ * Stéphane Graber -+ * -+ * 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 -+ */ -+ -+#include -+#include "structmember.h" -+#include -+#include -+#include -+ -+typedef struct { -+ PyObject_HEAD -+ struct lxc_container *container; -+} Container; -+ -+char** -+convert_tuple_to_char_pointer_array(PyObject *argv) { -+ int argc = PyTuple_Size(argv); -+ int i; -+ -+ char **result = (char**) malloc(sizeof(char*)*argc + 1); -+ -+ for (i = 0; i < argc; i++) { -+ PyObject *pyobj = PyTuple_GetItem(argv, i); -+ -+ char *str = NULL; -+ PyObject *pystr; -+ if (!PyUnicode_Check(pyobj)) { -+ PyErr_SetString(PyExc_ValueError, "Expected a string"); -+ return NULL; -+ } -+ -+ pystr = PyUnicode_AsUTF8String(pyobj); -+ str = PyBytes_AsString(pystr); -+ memcpy((char *) &result[i], (char *) &str, sizeof(str)); -+ } -+ -+ result[argc] = NULL; -+ -+ return result; -+} -+ -+void zombie_handler(int sig) -+{ -+ signal(SIGCHLD,zombie_handler); -+ int status; -+ -+ waitpid(-1, &status, WNOHANG); -+} -+ -+static void -+Container_dealloc(Container* self) -+{ -+ Py_TYPE(self)->tp_free((PyObject*)self); -+} -+ -+static PyObject * -+Container_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -+{ -+ Container *self; -+ -+ self = (Container *)type->tp_alloc(type, 0); -+ -+ return (PyObject *)self; -+} -+ -+static int -+Container_init(Container *self, PyObject *args, PyObject *kwds) -+{ -+ static char *kwlist[] = {"name", NULL}; -+ char *name = NULL; -+ -+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|", kwlist, -+ &name)) -+ return -1; -+ -+ self->container = lxc_container_new(name); -+ if (!self->container) { -+ fprintf(stderr, "%d: error creating lxc_container %s\n", __LINE__, name); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+// Container properties -+static PyObject * -+Container_config_file_name(Container *self, PyObject *args, PyObject *kwds) -+{ -+ return PyUnicode_FromString(self->container->config_file_name(self->container)); -+} -+ -+static PyObject * -+Container_defined(Container *self, PyObject *args, PyObject *kwds) -+{ -+ if (self->container->is_defined(self->container)) { -+ Py_RETURN_TRUE; -+ } -+ -+ Py_RETURN_FALSE; -+} -+ -+static PyObject * -+Container_init_pid(Container *self, PyObject *args, PyObject *kwds) -+{ -+ return Py_BuildValue("i", self->container->init_pid(self->container)); -+} -+ -+static PyObject * -+Container_name(Container *self, PyObject *args, PyObject *kwds) -+{ -+ return PyUnicode_FromString(self->container->name); -+} -+ -+static PyObject * -+Container_running(Container *self, PyObject *args, PyObject *kwds) -+{ -+ if (self->container->is_running(self->container)) { -+ Py_RETURN_TRUE; -+ } -+ -+ Py_RETURN_FALSE; -+} -+ -+static PyObject * -+Container_state(Container *self, PyObject *args, PyObject *kwds) -+{ -+ return PyUnicode_FromString(self->container->state(self->container)); -+} -+ -+// Container Functions -+static PyObject * -+Container_clear_config_item(Container *self, PyObject *args, PyObject *kwds) -+{ -+ static char *kwlist[] = {"key", NULL}; -+ char *key = NULL; -+ -+ if (! PyArg_ParseTupleAndKeywords(args, kwds, "s|", kwlist, -+ &key)) -+ Py_RETURN_FALSE; -+ -+ if (self->container->clear_config_item(self->container, key)) { -+ Py_RETURN_TRUE; -+ } -+ -+ Py_RETURN_FALSE; -+} -+ -+static PyObject * -+Container_create(Container *self, PyObject *args, PyObject *kwds) -+{ -+ char* template_name = NULL; -+ char** create_args = {NULL}; -+ PyObject *vargs = NULL; -+ static char *kwlist[] = {"template", "args", NULL}; -+ -+ if (! PyArg_ParseTupleAndKeywords(args, kwds, "s|O", kwlist, -+ &template_name, &vargs)) -+ Py_RETURN_FALSE; -+ -+ if (vargs && PyTuple_Check(vargs)) { -+ create_args = convert_tuple_to_char_pointer_array(vargs); -+ if (!create_args) { -+ return NULL; -+ } -+ } -+ -+ if (self->container->create(self->container, template_name, create_args)) { -+ Py_RETURN_TRUE; -+ } -+ -+ Py_RETURN_FALSE; -+} -+ -+static PyObject * -+Container_destroy(Container *self, PyObject *args, PyObject *kwds) -+{ -+ if (self->container->destroy(self->container)) { -+ Py_RETURN_TRUE; -+ } -+ -+ Py_RETURN_FALSE; -+} -+ -+static PyObject * -+Container_freeze(Container *self, PyObject *args, PyObject *kwds) -+{ -+ if (self->container->freeze(self->container)) { -+ Py_RETURN_TRUE; -+ } -+ -+ Py_RETURN_FALSE; -+} -+ -+static PyObject * -+Container_get_config_item(Container *self, PyObject *args, PyObject *kwds) -+{ -+ static char *kwlist[] = {"key", NULL}; -+ char* key = NULL; -+ int len = 0; -+ -+ if (! PyArg_ParseTupleAndKeywords(args, kwds, "|s", kwlist, -+ &key)) -+ Py_RETURN_FALSE; -+ -+ len = self->container->get_config_item(self->container, key, NULL, 0); -+ -+ if (len <= 0) { -+ Py_RETURN_FALSE; -+ } -+ -+ char* value = (char*) malloc(sizeof(char)*len + 1); -+ if (self->container->get_config_item(self->container, key, value, len + 1) != len) { -+ Py_RETURN_FALSE; -+ } -+ -+ return PyUnicode_FromString(value); -+} -+ -+static PyObject * -+Container_get_keys(Container *self, PyObject *args, PyObject *kwds) -+{ -+ static char *kwlist[] = {"key", NULL}; -+ char* key = NULL; -+ int len = 0; -+ -+ if (! PyArg_ParseTupleAndKeywords(args, kwds, "|s", kwlist, -+ &key)) -+ Py_RETURN_FALSE; -+ -+ len = self->container->get_keys(self->container, key, NULL, 0); -+ -+ if (len <= 0) { -+ Py_RETURN_FALSE; -+ } -+ -+ char* value = (char*) malloc(sizeof(char)*len + 1); -+ if (self->container->get_keys(self->container, key, value, len + 1) != len) { -+ Py_RETURN_FALSE; -+ } -+ -+ return PyUnicode_FromString(value); -+} -+ -+static PyObject * -+Container_load_config(Container *self, PyObject *args, PyObject *kwds) -+{ -+ static char *kwlist[] = {"path", NULL}; -+ char* path = NULL; -+ -+ if (! PyArg_ParseTupleAndKeywords(args, kwds, "|s", kwlist, -+ &path)) -+ Py_RETURN_FALSE; -+ -+ if (self->container->load_config(self->container, path)) { -+ Py_RETURN_TRUE; -+ } -+ -+ Py_RETURN_FALSE; -+} -+ -+static PyObject * -+Container_save_config(Container *self, PyObject *args, PyObject *kwds) -+{ -+ static char *kwlist[] = {"path", NULL}; -+ char* path = NULL; -+ -+ if (! PyArg_ParseTupleAndKeywords(args, kwds, "|s", kwlist, -+ &path)) -+ Py_RETURN_FALSE; -+ -+ if (self->container->save_config(self->container, path)) { -+ Py_RETURN_TRUE; -+ } -+ -+ Py_RETURN_FALSE; -+} -+ -+static PyObject * -+Container_set_config_item(Container *self, PyObject *args, PyObject *kwds) -+{ -+ static char *kwlist[] = {"key", "value", NULL}; -+ char *key = NULL; -+ char *value = NULL; -+ -+ if (! PyArg_ParseTupleAndKeywords(args, kwds, "ss|", kwlist, -+ &key, &value)) -+ Py_RETURN_FALSE; -+ -+ if (self->container->set_config_item(self->container, key, value)) { -+ Py_RETURN_TRUE; -+ } -+ -+ Py_RETURN_FALSE; -+} -+ -+static PyObject * -+Container_shutdown(Container *self, PyObject *args, PyObject *kwds) -+{ -+ static char *kwlist[] = {"timeout", NULL}; -+ int timeout = -1; -+ -+ if (! PyArg_ParseTupleAndKeywords(args, kwds, "|i", kwlist, -+ &timeout)) -+ Py_RETURN_FALSE; -+ -+ if (self->container->shutdown(self->container, timeout)) { -+ Py_RETURN_TRUE; -+ } -+ -+ Py_RETURN_FALSE; -+} -+ -+static PyObject * -+Container_start(Container *self, PyObject *args, PyObject *kwds) -+{ -+ char** init_args = {NULL}; -+ PyObject *useinit = NULL, *vargs = NULL; -+ int init_useinit = 0; -+ static char *kwlist[] = {"useinit", "cmd", NULL}; -+ -+ if (! PyArg_ParseTupleAndKeywords(args, kwds, "|OO", kwlist, -+ &useinit, &vargs)) -+ Py_RETURN_FALSE; -+ -+ if (useinit && useinit == Py_True) { -+ init_useinit = 1; -+ } -+ -+ if (vargs && PyTuple_Check(vargs)) { -+ init_args = convert_tuple_to_char_pointer_array(vargs); -+ if (!init_args) { -+ return NULL; -+ } -+ } -+ -+ signal(SIGCHLD, zombie_handler); -+ self->container->want_daemonize(self->container); -+ -+ if (self->container->start(self->container, init_useinit, init_args)) { -+ Py_RETURN_TRUE; -+ } -+ -+ Py_RETURN_FALSE; -+} -+ -+static PyObject * -+Container_stop(Container *self, PyObject *args, PyObject *kwds) -+{ -+ if (self->container->stop(self->container)) { -+ Py_RETURN_TRUE; -+ } -+ -+ Py_RETURN_FALSE; -+} -+ -+static PyObject * -+Container_unfreeze(Container *self, PyObject *args, PyObject *kwds) -+{ -+ if (self->container->unfreeze(self->container)) { -+ Py_RETURN_TRUE; -+ } -+ -+ Py_RETURN_FALSE; -+} -+ -+static PyObject * -+Container_wait(Container *self, PyObject *args, PyObject *kwds) -+{ -+ static char *kwlist[] = {"state", "timeout", NULL}; -+ char *state = NULL; -+ int timeout = -1; -+ -+ if (! PyArg_ParseTupleAndKeywords(args, kwds, "s|i", kwlist, -+ &state, &timeout)) -+ Py_RETURN_FALSE; -+ -+ if (self->container->wait(self->container, state, timeout)) { -+ Py_RETURN_TRUE; -+ } -+ -+ Py_RETURN_FALSE; -+} -+ -+static PyGetSetDef Container_getseters[] = { -+ {"config_file_name", -+ (getter)Container_config_file_name, 0, -+ "Path to the container configuration", -+ NULL}, -+ {"defined", -+ (getter)Container_defined, 0, -+ "Boolean indicating whether the container configuration exists", -+ NULL}, -+ {"init_pid", -+ (getter)Container_init_pid, 0, -+ "PID of the container's init process in the host's PID namespace", -+ NULL}, -+ {"name", -+ (getter)Container_name, 0, -+ "Container name", -+ NULL}, -+ {"running", -+ (getter)Container_running, 0, -+ "Boolean indicating whether the container is running or not", -+ NULL}, -+ {"state", -+ (getter)Container_state, 0, -+ "Container state", -+ NULL}, -+}; -+ -+static PyMethodDef Container_methods[] = { -+ {"clear_config_item", (PyCFunction)Container_clear_config_item, METH_VARARGS | METH_KEYWORDS, -+ "clear_config_item(key) -> boolean\n" -+ "\n" -+ "Clear the current value of a config key." -+ }, -+ {"create", (PyCFunction)Container_create, METH_VARARGS | METH_KEYWORDS, -+ "create(template, args = (,)) -> boolean\n" -+ "\n" -+ "Create a new rootfs for the container, using the given template " -+ "and passing some optional arguments to it." -+ }, -+ {"destroy", (PyCFunction)Container_destroy, METH_NOARGS, -+ "destroy() -> boolean\n" -+ "\n" -+ "Destroys the container." -+ }, -+ {"freeze", (PyCFunction)Container_freeze, METH_NOARGS, -+ "freeze() -> boolean\n" -+ "\n" -+ "Freezes the container and returns its return code." -+ }, -+ {"get_config_item", (PyCFunction)Container_get_config_item, METH_VARARGS | METH_KEYWORDS, -+ "get_config_item(key) -> string\n" -+ "\n" -+ "Get the current value of a config key." -+ }, -+ {"get_keys", (PyCFunction)Container_get_keys, METH_VARARGS | METH_KEYWORDS, -+ "get_keys(key) -> string\n" -+ "\n" -+ "Get a list of valid sub-keys for a key." -+ }, -+ {"load_config", (PyCFunction)Container_load_config, METH_VARARGS | METH_KEYWORDS, -+ "load_config(path = DEFAULT) -> boolean\n" -+ "\n" -+ "Read the container configuration from its default " -+ "location or from an alternative location if provided." -+ }, -+ {"save_config", (PyCFunction)Container_save_config, METH_VARARGS | METH_KEYWORDS, -+ "save_config(path = DEFAULT) -> boolean\n" -+ "\n" -+ "Save the container configuration to its default " -+ "location or to an alternative location if provided." -+ }, -+ {"set_config_item", (PyCFunction)Container_set_config_item, METH_VARARGS | METH_KEYWORDS, -+ "set_config_item(key, value) -> boolean\n" -+ "\n" -+ "Set a config key to the provided value." -+ }, -+ {"shutdown", (PyCFunction)Container_shutdown, METH_VARARGS | METH_KEYWORDS, -+ "shutdown(timeout = -1) -> boolean\n" -+ "\n" -+ "Sends SIGPWR to the container and wait for it to shutdown " -+ "unless timeout is set to a positive value, in which case " -+ "the container will be killed when the timeout is reached." -+ }, -+ {"start", (PyCFunction)Container_start, METH_VARARGS | METH_KEYWORDS, -+ "start(useinit = False, cmd = (,)) -> boolean\n" -+ "\n" -+ "Start the container, optionally using lxc-init and" -+ "an alternate init command, then returns its return code." -+ }, -+ {"stop", (PyCFunction)Container_stop, METH_NOARGS, -+ "stop() -> boolean\n" -+ "\n" -+ "Stop the container and returns its return code." -+ }, -+ {"unfreeze", (PyCFunction)Container_unfreeze, METH_NOARGS, -+ "unfreeze() -> boolean\n" -+ "\n" -+ "Unfreezes the container and returns its return code." -+ }, -+ {"wait", (PyCFunction)Container_wait, METH_VARARGS | METH_KEYWORDS, -+ "wait(state, timeout = -1) -> boolean\n" -+ "\n" -+ "Wait for the container to reach a given state or timeout." -+ }, -+ {NULL} /* Sentinel */ -+}; -+ -+static PyTypeObject _lxc_ContainerType = { -+PyVarObject_HEAD_INIT(NULL, 0) -+ "lxc.Container", /* tp_name */ -+ sizeof(Container), /* tp_basicsize */ -+ 0, /* tp_itemsize */ -+ (destructor)Container_dealloc, /* tp_dealloc */ -+ 0, /* tp_print */ -+ 0, /* tp_getattr */ -+ 0, /* tp_setattr */ -+ 0, /* tp_reserved */ -+ 0, /* tp_repr */ -+ 0, /* tp_as_number */ -+ 0, /* tp_as_sequence */ -+ 0, /* tp_as_mapping */ -+ 0, /* tp_hash */ -+ 0, /* tp_call */ -+ 0, /* tp_str */ -+ 0, /* tp_getattro */ -+ 0, /* tp_setattro */ -+ 0, /* tp_as_buffer */ -+ Py_TPFLAGS_DEFAULT | -+ Py_TPFLAGS_BASETYPE, /* tp_flags */ -+ "Container objects", /* tp_doc */ -+ 0, /* tp_traverse */ -+ 0, /* tp_clear */ -+ 0, /* tp_richcompare */ -+ 0, /* tp_weaklistoffset */ -+ 0, /* tp_iter */ -+ 0, /* tp_iternext */ -+ Container_methods, /* tp_methods */ -+ 0, /* tp_members */ -+ Container_getseters, /* tp_getset */ -+ 0, /* tp_base */ -+ 0, /* tp_dict */ -+ 0, /* tp_descr_get */ -+ 0, /* tp_descr_set */ -+ 0, /* tp_dictoffset */ -+ (initproc)Container_init, /* tp_init */ -+ 0, /* tp_alloc */ -+ Container_new, /* tp_new */ -+}; -+ -+static PyModuleDef _lxcmodule = { -+ PyModuleDef_HEAD_INIT, -+ "_lxc", -+ "Binding for liblxc in python", -+ -1, -+ NULL, NULL, NULL, NULL, NULL -+}; -+ -+PyMODINIT_FUNC -+PyInit__lxc(void) -+{ -+ PyObject* m; -+ -+ if (PyType_Ready(&_lxc_ContainerType) < 0) -+ return NULL; -+ -+ m = PyModule_Create(&_lxcmodule); -+ if (m == NULL) -+ return NULL; -+ -+ Py_INCREF(&_lxc_ContainerType); -+ PyModule_AddObject(m, "Container", (PyObject *)&_lxc_ContainerType); -+ return m; -+} -Index: lxc/src/python-lxc/setup.py -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ lxc/src/python-lxc/setup.py 2012-08-27 17:12:13.000000000 -0400 -@@ -0,0 +1,10 @@ -+from distutils.core import setup, Extension -+ -+module = Extension('_lxc', sources = ['lxc.c'], libraries = ['lxc']) -+ -+setup (name = '_lxc', -+ version = '0.1', -+ description = 'LXC', -+ packages = ['lxc'], -+ package_dir = {'lxc':'lxc'}, -+ ext_modules = [module]) -Index: lxc/src/python-lxc/lxc/__init__.py -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ lxc/src/python-lxc/lxc/__init__.py 2012-08-27 17:12:13.000000000 -0400 -@@ -0,0 +1,372 @@ -+# -+# python-lxc: Python bindings for LXC -+# -+# (C) Copyright Canonical Ltd. 2012 -+# -+# Authors: -+# Stéphane Graber -+# -+# 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 -+# -+ -+import _lxc -+import glob -+import os -+import subprocess -+import tempfile -+import time -+import warnings -+ -+warnings.warn("The python-lxc API isn't yet stable " -+ "and may change at any point in the future.", Warning, 2) -+ -+class ContainerNetwork(): -+ props = {} -+ -+ def __init__(self, container, index): -+ self.container = container -+ self.index = index -+ -+ for key in self.container.get_keys("lxc.network.%s" % self.index): -+ if "." in key: -+ self.props[key.replace(".", "_")] = key -+ else: -+ self.props[key] = key -+ -+ if not self.props: -+ return False -+ -+ def __delattr__(self, key): -+ if key in ["container", "index", "props"]: -+ return object.__delattr__(self, key) -+ -+ if key not in self.props: -+ raise AttributeError("'%s' network has no attribute '%s'" % ( -+ self.__get_network_item("type"), key)) -+ -+ return self.__clear_network_item(self.props[key]) -+ -+ def __dir__(self): -+ return sorted(self.props.keys()) -+ -+ def __getattr__(self, key): -+ if key in ["container", "index", "props"]: -+ return object.__getattribute__(self, key) -+ -+ if key not in self.props: -+ raise AttributeError("'%s' network has no attribute '%s'" % ( -+ self.__get_network_item("type"), key)) -+ -+ return self.__get_network_item(self.props[key]) -+ -+ def __hasattr__(self, key): -+ if key in ["container", "index", "props"]: -+ return object.__hasattr__(self, key) -+ -+ if key not in self.props: -+ raise AttributeError("'%s' network has no attribute '%s'" % ( -+ self.__get_network_item("type"), key)) -+ -+ return True -+ -+ def __repr__(self): -+ return "'%s' network at index '%s'" % ( -+ self.__get_network_item("type"), self.index) -+ -+ def __setattr__(self, key, value): -+ if key in ["container", "index", "props"]: -+ return object.__setattr__(self, key, value) -+ -+ if key not in self.props: -+ raise AttributeError("'%s' network has no attribute '%s'" % ( -+ self.__get_network_item("type"), key)) -+ -+ return self.__set_network_item(self.props[key], value) -+ -+ def __clear_network_item(self, key): -+ return self.container.clear_config_item("lxc.network.%s.%s" % ( -+ self.index, key)) -+ -+ def __get_network_item(self, key): -+ return self.container.get_config_item("lxc.network.%s.%s" % ( -+ self.index, key)) -+ -+ def __set_network_item(self, key, value): -+ return self.container.set_config_item("lxc.network.%s.%s" % ( -+ self.index, key), value) -+ -+ -+class ContainerNetworkList(): -+ def __init__(self, container): -+ self.container = container -+ -+ def __getitem__(self, index): -+ count = len(self.container.get_config_item("lxc.network")) -+ if index >= count: -+ raise IndexError("list index out of range") -+ -+ return ContainerNetwork(self.container, index) -+ -+ def __len__(self): -+ return len(self.container.get_config_item("lxc.network")) -+ -+ def add(self, network_type): -+ index = len(self.container.get_config_item("lxc.network")) -+ -+ return self.container.set_config_item("lxc.network.%s.type" % index, -+ network_type) -+ -+ def remove(self, index): -+ count = len(self.container.get_config_item("lxc.network")) -+ if index >= count: -+ raise IndexError("list index out of range") -+ -+ return self.container.clear_config_item("lxc.network.%s" % index) -+ -+ -+class Container(_lxc.Container): -+ def __init__(self, name): -+ """ -+ Creates a new Container instance. -+ """ -+ -+ _lxc.Container.__init__(self, name) -+ self.network = ContainerNetworkList(self) -+ -+ def append_config_item(self, key, value): -+ """ -+ Append 'value' to 'key', assuming 'key' is a list. -+ If 'key' isn't a list, 'value' will be set as the value of 'key'. -+ """ -+ -+ return _lxc.Container.set_config_item(self, key, value) -+ -+ def attach(self, namespace="ALL", *cmd): -+ """ -+ Attach to a running container. -+ """ -+ -+ if not self.running: -+ return False -+ -+ attach = ["lxc-attach", "-n", self.name] -+ if namespace != "ALL": -+ attach += ["-s", namespace] -+ -+ if cmd: -+ attach += ["--"] + list(cmd) -+ -+ if subprocess.call( -+ attach, -+ universal_newlines=True) != 0: -+ return False -+ return True -+ -+ def create(self, template, args={}): -+ """ -+ Create a new rootfs for the container. -+ -+ "template" must be a valid template name. -+ -+ "args" (optional) is a dictionary of parameters and values to pass -+ to the template. -+ """ -+ -+ template_args = [] -+ for item in args.items(): -+ template_args.append("--%s" % item[0]) -+ template_args.append("%s" % item[1]) -+ -+ return _lxc.Container.create(self, template, tuple(template_args)) -+ -+ def clone(self, container): -+ """ -+ Clone an existing container into a new one. -+ """ -+ -+ if self.defined: -+ return False -+ -+ if isinstance(container, Container): -+ source = container -+ else: -+ source = Container(container) -+ -+ if not source.defined: -+ return False -+ -+ if subprocess.call( -+ ["lxc-clone", "-o", source.name, "-n", self.name], -+ universal_newlines=True) != 0: -+ return False -+ -+ self.load_config() -+ return True -+ -+ def console(self, tty="1"): -+ """ -+ Access the console of a container. -+ """ -+ -+ if not self.running: -+ return False -+ -+ if subprocess.call( -+ ["lxc-console", "-n", self.name, "-t", "%s" % tty], -+ universal_newlines=True) != 0: -+ return False -+ return True -+ -+ def get_config_item(self, key): -+ """ -+ Returns the value for a given config key. -+ A list is returned when multiple values are set. -+ """ -+ value = _lxc.Container.get_config_item(self, key) -+ -+ if value is False: -+ return False -+ elif value.endswith("\n"): -+ return value.rstrip("\n").split("\n") -+ else: -+ return value -+ -+ def get_ips(self, timeout=60, interface=None, protocol=None): -+ """ -+ Returns the list of IP addresses for the container. -+ """ -+ -+ if not self.defined or not self.running: -+ return False -+ -+ try: -+ os.makedirs("/run/netns") -+ except: -+ pass -+ -+ path = tempfile.mktemp(dir="/run/netns") -+ -+ os.symlink("/proc/%s/ns/net" % self.init_pid, path) -+ -+ ips = [] -+ -+ count = 0 -+ while count < timeout: -+ if count != 0: -+ time.sleep(1) -+ -+ base_cmd = ["ip", "netns", "exec", path.split("/")[-1], "ip"] -+ -+ # Get IPv6 -+ if protocol in ("ipv6", None): -+ ip6_cmd = base_cmd + ["-6", "addr", "show", "scope", "global"] -+ if interface: -+ ip = subprocess.Popen(ip6_cmd + ["dev", interface], -+ stdout=subprocess.PIPE, universal_newlines=True) -+ else: -+ ip = subprocess.Popen(ip6_cmd, stdout=subprocess.PIPE, -+ universal_newlines=True) -+ -+ ip.wait() -+ for line in ip.stdout.read().split("\n"): -+ fields = line.split() -+ if len(fields) > 2 and fields[0] == "inet6": -+ ips.append(fields[1].split('/')[0]) -+ -+ # Get IPv4 -+ if protocol in ("ipv4", None): -+ ip4_cmd = base_cmd + ["-4", "addr", "show", "scope", "global"] -+ if interface: -+ ip = subprocess.Popen(ip4_cmd + ["dev", interface], -+ stdout=subprocess.PIPE, universal_newlines=True) -+ else: -+ ip = subprocess.Popen(ip4_cmd, stdout=subprocess.PIPE, -+ universal_newlines=True) -+ -+ ip.wait() -+ for line in ip.stdout.read().split("\n"): -+ fields = line.split() -+ if len(fields) > 2 and fields[0] == "inet": -+ ips.append(fields[1].split('/')[0]) -+ -+ if ips: -+ break -+ -+ count += 1 -+ -+ os.remove(path) -+ return ips -+ -+ def get_keys(self, key): -+ """ -+ Returns a list of valid sub-keys. -+ """ -+ value = _lxc.Container.get_keys(self, key) -+ -+ if value is False: -+ return False -+ elif value.endswith("\n"): -+ return value.rstrip("\n").split("\n") -+ else: -+ return value -+ -+ def set_config_item(self, key, value): -+ """ -+ Set a config key to a provided value. -+ The value can be a list for the keys supporting multiple values. -+ """ -+ old_value = self.get_config_item(key) -+ -+ # Check if it's a list -+ def set_key(key, value): -+ self.clear_config_item(key) -+ if isinstance(value, list): -+ for entry in value: -+ if not _lxc.Container.set_config_item(self, key, entry): -+ return False -+ else: -+ _lxc.Container.set_config_item(self, key, value) -+ -+ set_key(key, value) -+ new_value = self.get_config_item(key) -+ -+ if isinstance(value, str) and isinstance(new_value, str) and \ -+ value == new_value: -+ return True -+ elif isinstance(value, list) and isinstance(new_value, list) and \ -+ set(value) == set(new_value): -+ return True -+ elif isinstance(value, str) and isinstance(new_value, list) and \ -+ set([value]) == set(new_value): -+ return True -+ elif old_value: -+ set_key(key, old_value) -+ return False -+ else: -+ self.clear_config_item(key) -+ return False -+ -+ -+def list_containers(as_object=False): -+ """ -+ List the containers on the system. -+ """ -+ containers = [] -+ for entry in glob.glob("/var/lib/lxc/*/config"): -+ if as_object: -+ containers.append(Container(entry.split("/")[-2])) -+ else: -+ containers.append(entry.split("/")[-2]) -+ return containers diff -Nru lxc-0.8.0~rc1/debian/patches/0204-ubuntu-cloud-userdata-path lxc-1.0.0~alpha1/debian/patches/0204-ubuntu-cloud-userdata-path --- lxc-0.8.0~rc1/debian/patches/0204-ubuntu-cloud-userdata-path 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0204-ubuntu-cloud-userdata-path 1970-01-01 00:00:00.000000000 +0000 @@ -1,30 +0,0 @@ -Description: lxc-ubuntu-cloud: get full pathname to userdata file - When passing '--userdata somefile' to the ubuntu-cloud template, a user - may pass a relative pathname. The template uses the filename after - changing current directory, so store the full pathname for the userdata - file instead of a potential relative pathname. -Author: Serge Hallyn -Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/1043582 -Forwarded: yes - -Index: lxc/templates/lxc-ubuntu-cloud.in -=================================================================== ---- lxc.orig/templates/lxc-ubuntu-cloud.in 2012-08-30 09:48:55.396845000 -0500 -+++ lxc/templates/lxc-ubuntu-cloud.in 2012-08-30 09:58:33.047759242 -0500 -@@ -221,9 +221,13 @@ - exit 1 - fi - --if [ -n "$userdata" -a ! -f "$userdata" ]; then -- echo "Userdata does not exist" -- exit 1 -+if [ -n "$userdata" ]; then -+ if [ ! -f "$userdata" ]; then -+ echo "Userdata ($userdata) does not exist" -+ exit 1 -+ else -+ userdata=`readlink -f $userdata` -+ fi - fi - - if [ -z "$path" ]; then diff -Nru lxc-0.8.0~rc1/debian/patches/0205-lxc-ls-manpage-document-two-lines lxc-1.0.0~alpha1/debian/patches/0205-lxc-ls-manpage-document-two-lines --- lxc-0.8.0~rc1/debian/patches/0205-lxc-ls-manpage-document-two-lines 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0205-lxc-ls-manpage-document-two-lines 1970-01-01 00:00:00.000000000 +0000 @@ -1,24 +0,0 @@ -Description: Document the default two-line output in lxc-ls -Author: Serge Hallyn -Forwarded: no - -Index: lxc/doc/lxc-ls.sgml.in -=================================================================== ---- lxc.orig/doc/lxc-ls.sgml.in 2012-08-30 09:48:55.396845000 -0500 -+++ lxc/doc/lxc-ls.sgml.in 2012-08-30 10:04:34.779746043 -0500 -@@ -57,7 +57,14 @@ - Description - - lxc-ls list the containers existing on the -- system. -+ system. By default it lists them in two lines. The first line -+ contains all defined containers, while the second contains all -+ running containers. If additional arguments are given, they are -+ passed to the 'ls' program. This can change the output to be -+ multiple lines. For instance, 'lxc-ls -l' will print a full line -+ for each container. Since lxc-ls will still print first the -+ existing, then the running containers, running containers will -+ appear to be listed twice. - - - diff -Nru lxc-0.8.0~rc1/debian/patches/0206-lxc-wait-initialize-timeout lxc-1.0.0~alpha1/debian/patches/0206-lxc-wait-initialize-timeout --- lxc-0.8.0~rc1/debian/patches/0206-lxc-wait-initialize-timeout 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0206-lxc-wait-initialize-timeout 1970-01-01 00:00:00.000000000 +0000 @@ -1,18 +0,0 @@ -Description: lxc-wait: initialize timeout to -1 - Otherwise it defaults to 0, meaning don't wait. -1 means wait forever, - which is what we want as the default behavior. -Author: Serge Hallyn -Forwarded: yes - -Index: lxc/src/lxc/lxc_wait.c -=================================================================== ---- lxc.orig/src/lxc/lxc_wait.c 2012-08-30 11:30:48.999463000 -0500 -+++ lxc/src/lxc/lxc_wait.c 2012-08-30 11:31:51.491554965 -0500 -@@ -75,6 +75,7 @@ - .options = my_longopts, - .parser = my_parser, - .checker = my_checker, -+ .timeout = -1, - }; - - static void timeout_handler(int signal) diff -Nru lxc-0.8.0~rc1/debian/patches/0207-ubuntu-cloud-fixes.patch lxc-1.0.0~alpha1/debian/patches/0207-ubuntu-cloud-fixes.patch --- lxc-0.8.0~rc1/debian/patches/0207-ubuntu-cloud-fixes.patch 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0207-ubuntu-cloud-fixes.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,165 +0,0 @@ -Description: ubuntu-cloud template cleanups - Fix for quantal images which do not have the user 'ubuntu' present -Author: Scott Moser -Forwarded: yes -Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/1045955 - ---- a/templates/lxc-ubuntu-cloud.in -+++ b/templates/lxc-ubuntu-cloud.in -@@ -230,6 +230,15 @@ if [ -n "$userdata" ]; then - fi - fi - -+if [ -n "$auth_key" ]; then -+ if [ ! -f "$auth_key" ]; then -+ echo "--auth-key=${auth_key} must reference a file" -+ exit 1 -+ fi -+ auth_key=$(readlink -f "${auth_key}") || -+ { echo "failed to get full path for auth_key"; exit 1; } -+fi -+ - if [ -z "$path" ]; then - echo "'path' parameter is required" - exit 1 -@@ -258,17 +267,17 @@ cache="/var/cache/lxc/cloud-$release" - mkdir -p $cache - - if [ -n "$tarball" ]; then -- url2="$tarball" -+ url2="$tarball" - else -- url1=`ubuntu-cloudimg-query $release $stream $arch --format "%{url}\n"` -- url2=`echo $url1 | sed -e 's/.tar.gz/-root\0/'` -+ url1=`ubuntu-cloudimg-query $release $stream $arch --format "%{url}\n"` -+ url2=`echo $url1 | sed -e 's/.tar.gz/-root\0/'` - fi - - filename=`basename $url2` - - wgetcleanup() - { -- rm -f $filename -+ rm -f $filename - } - - buildcleanup() -@@ -321,7 +330,7 @@ mkdir -p /var/lock/subsys/ - - trap wgetcleanup EXIT SIGHUP SIGINT SIGTERM - if [ ! -f $filename ]; then -- wget $url2 || build_root_tgz $url1 $filename -+ wget $url2 || build_root_tgz $url1 $filename - fi - trap EXIT - trap SIGHUP -@@ -335,67 +344,63 @@ mkdir -p /var/lock/subsys/ - - - if [ $cloud -eq 0 ]; then -- echo "Configuring for running outside of a cloud environment" -- echo "If you want to configure for a cloud evironment, please use '-- -C' to create the container" -+ echo "Configuring for running outside of a cloud environment" -+ echo "If you want to configure for a cloud evironment, please use '-- -C' to create the container" - -- seed_d=$rootfs/var/lib/cloud/seed/nocloud-net -- rhostid=$(uuidgen | cut -c -8) -- host_id=${hostid:-$rhostid} -- mkdir -p $seed_d -+ seed_d=$rootfs/var/lib/cloud/seed/nocloud-net -+ rhostid=$(uuidgen | cut -c -8) -+ host_id=${hostid:-$rhostid} -+ mkdir -p $seed_d - -- cat > "$seed_d/meta-data" < "$seed_d/meta-data" <> "$seed_d/meta-data" -+ [ $? -eq 0 ] || -+ { echo "failed to write public keys to metadata"; exit 1; } -+ fi -+ -+ rm $rootfs/etc/hostname -+ -+ if [ $locales -eq 1 ]; then -+ cp /usr/lib/locale/locale-archive $rootfs/usr/lib/locale/locale-archive -+ fi -+ -+ if [ -f "$userdata" ]; then -+ echo "Using custom user-data" -+ cp $userdata $seed_d/user-data -+ else -+ -+ if [ -z "$MIRROR" ]; then -+ MIRROR="http://archive.ubuntu.com/ubuntu" -+ fi - -- rm $rootfs/etc/hostname -- -- if [ $locales -eq 1 ]; then -- cp /usr/lib/locale/locale-archive $rootfs/usr/lib/locale/locale-archive -- fi -- -- -- if [ -n "$auth_key" -a -f "$auth_key" ]; then -- u_path="/home/ubuntu/.ssh" -- root_u_path="$rootfs/$u_path" -- mkdir -p $root_u_path -- cp $auth_key "$root_u_path/authorized_keys" -- chroot $rootfs chown -R ubuntu: "$u_path" -- -- echo "Inserted SSH public key from $auth_key into /home/ubuntu/.ssh/authorized_keys" -- fi -- -- if [ -f "$userdata" ]; then -- echo "Using custom user-data" -- cp $userdata $seed_d/user-data -- else -- -- if [ -z "$MIRROR" ]; then -- MIRROR="http://archive.ubuntu.com/ubuntu" -- fi -- -- cat > "$seed_d/user-data" < "$seed_d/user-data" </var/lock/subsys/lxc-ubucloud - - copy_configuration $path $rootfs $name $arch $release - - echo "Container $name created." - exit 0 -+ -+# vi: ts=4 expandtab diff -Nru lxc-0.8.0~rc1/debian/patches/0208-fix-getitem-utsname-segv lxc-1.0.0~alpha1/debian/patches/0208-fix-getitem-utsname-segv --- lxc-0.8.0~rc1/debian/patches/0208-fix-getitem-utsname-segv 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0208-fix-getitem-utsname-segv 1970-01-01 00:00:00.000000000 +0000 @@ -1,17 +0,0 @@ -Description: get_item(utsname): don't dereference utsname if it is NULL -Author: Serge Hallyn -Forwarded: yes - -Index: lxc/src/lxc/confile.c -=================================================================== ---- lxc.orig/src/lxc/confile.c 2012-09-04 16:23:11.616585000 -0500 -+++ lxc/src/lxc/confile.c 2012-09-04 17:12:59.428180025 -0500 -@@ -1516,7 +1516,7 @@ - else if (strncmp(key, "lxc.cgroup.", 11) == 0) // specific cgroup info - return lxc_get_cgroup_entry(c, retv, inlen, key + 11); - else if (strcmp(key, "lxc.utsname") == 0) -- v = c->utsname->nodename; -+ v = c->utsname ? c->utsname->nodename : NULL; - else if (strcmp(key, "lxc.console") == 0) - v = c->console.path; - else if (strcmp(key, "lxc.rootfs.mount") == 0) diff -Nru lxc-0.8.0~rc1/debian/patches/0209-reload-conf-after-create lxc-1.0.0~alpha1/debian/patches/0209-reload-conf-after-create --- lxc-0.8.0~rc1/debian/patches/0209-reload-conf-after-create 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0209-reload-conf-after-create 1970-01-01 00:00:00.000000000 +0000 @@ -1,92 +0,0 @@ -Index: lxc/src/lxc/conf.c -=================================================================== ---- lxc.orig/src/lxc/conf.c 2012-09-04 16:23:11.616585000 -0500 -+++ lxc/src/lxc/conf.c 2012-09-05 00:30:09.259928864 -0500 -@@ -2465,3 +2465,21 @@ - } - return 0; - } -+ -+void lxc_conf_free(struct lxc_conf *conf) -+{ -+ if (!conf) -+ return; -+ if (conf->console.path) -+ free(conf->console.path); -+ if (conf->rootfs.mount != LXCROOTFSMOUNT) -+ free(conf->rootfs.mount); -+ lxc_clear_config_network(conf); -+ if (conf->aa_profile) -+ free(conf->aa_profile); -+ lxc_clear_config_caps(conf); -+ lxc_clear_cgroups(conf, "lxc.cgroup"); -+ lxc_clear_hooks(conf); -+ lxc_clear_mount_entries(conf); -+ free(conf); -+} -Index: lxc/src/lxc/conf.h -=================================================================== ---- lxc.orig/src/lxc/conf.h 2012-09-04 16:23:11.616585000 -0500 -+++ lxc/src/lxc/conf.h 2012-09-05 00:16:49.583958043 -0500 -@@ -235,6 +235,7 @@ - * Initialize the lxc configuration structure - */ - extern struct lxc_conf *lxc_conf_init(void); -+extern void lxc_conf_free(struct lxc_conf *conf); - - extern int pin_rootfs(const char *rootfs); - -Index: lxc/src/lxc/lxccontainer.c -=================================================================== ---- lxc.orig/src/lxc/lxccontainer.c 2012-09-04 16:23:11.616585000 -0500 -+++ lxc/src/lxc/lxccontainer.c 2012-09-05 00:15:47.991960289 -0500 -@@ -215,6 +215,15 @@ - return ret; - } - -+static bool load_config_locked(struct lxc_container *c, char *fname) -+{ -+ if (!c->lxc_conf) -+ c->lxc_conf = lxc_conf_init(); -+ if (c->lxc_conf && !lxc_config_read(fname, c->lxc_conf)) -+ return true; -+ return false; -+} -+ - static bool lxcapi_load_config(struct lxc_container *c, char *alt_file) - { - bool ret = false; -@@ -229,10 +238,7 @@ - return false; - if (lxclock(c->slock, 0)) - return false; -- if (!c->lxc_conf) -- c->lxc_conf = lxc_conf_init(); -- if (c->lxc_conf && !lxc_config_read(fname, c->lxc_conf)) -- ret = true; -+ ret = load_config_locked(c, fname); - lxcunlock(c->slock); - return ret; - } -@@ -596,11 +602,18 @@ - goto out_unlock; - } - -- if (WEXITSTATUS(status) != 0) -+ if (WEXITSTATUS(status) != 0) { - ERROR("container creation template for %s exited with %d\n", - c->name, WEXITSTATUS(status)); -- else -- bret = true; -+ goto out_unlock; -+ } -+ -+ // now clear out the lxc_conf we have, reload from the created -+ // container -+ if (c->lxc_conf) -+ lxc_conf_free(c->lxc_conf); -+ c->lxc_conf = NULL; -+ bret = load_config_locked(c, c->configfile); - - out_unlock: - lxcunlock(c->slock); diff -Nru lxc-0.8.0~rc1/debian/patches/0210-fix-debian-templates lxc-1.0.0~alpha1/debian/patches/0210-fix-debian-templates --- lxc-0.8.0~rc1/debian/patches/0210-fix-debian-templates 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0210-fix-debian-templates 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +0,0 @@ -Description: Fixes to lxc-debian and lxc-lenny - - - fixed hostname setting in template script. (LP: #1046684) - - fixed lxc-shutdown for debian hosts. (LP: #1046696) - ---- lxc-0.8.0~rc1.orig/templates/lxc-lenny.in -+++ lxc-0.8.0~rc1/templates/lxc-lenny.in -@@ -306,7 +306,7 @@ if [ $? -ne 0 ]; then - exit 1 - fi - --copy_configuration $path $rootfs -+copy_configuration $path $rootfs $name - if [ $? -ne 0 ]; then - echo "failed write configuration file" - exit 1 ---- lxc-0.8.0~rc1.orig/templates/lxc-debian.in -+++ lxc-0.8.0~rc1/templates/lxc-debian.in -@@ -54,6 +54,8 @@ c1:12345:respawn:/sbin/getty 38400 tty1 - c2:12345:respawn:/sbin/getty 38400 tty2 linux - c3:12345:respawn:/sbin/getty 38400 tty3 linux - c4:12345:respawn:/sbin/getty 38400 tty4 linux -+p6::ctrlaltdel:/sbin/init 6 -+p0::powerfail:/sbin/init 0 - EOF - - # disable selinux in debian diff -Nru lxc-0.8.0~rc1/debian/patches/0211-add-hooks-to-manpage lxc-1.0.0~alpha1/debian/patches/0211-add-hooks-to-manpage --- lxc-0.8.0~rc1/debian/patches/0211-add-hooks-to-manpage 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0211-add-hooks-to-manpage 1970-01-01 00:00:00.000000000 +0000 @@ -1,94 +0,0 @@ -Description: document hooks in lxc.conf manpage -Author: Serge Hallyn -Forwarded: yes - -Index: lxc/doc/lxc.conf.sgml.in -=================================================================== ---- lxc.orig/doc/lxc.conf.sgml.in 2012-09-06 11:49:58.300959000 -0500 -+++ lxc/doc/lxc.conf.sgml.in 2012-09-06 12:08:10.688600678 -0500 -@@ -665,6 +665,85 @@ - - - -+ -+ Startup hooks -+ -+ Startup hooks are programs or scripts which can be executed -+ at various times in a container's lifetime. -+ -+ -+ -+ -+ -+ -+ -+ -+ A hook to be run in the host's namespace before the -+ container ttys, consoles, or mounts are up. -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ (Not yet implemented) -+ A hook to be run in the container's fs namespace but before -+ the rootfs has been set up. This allows for manipulation -+ of the rootfs, i.e. to mount an encrypted filesystem. Mounts -+ done in this hook will not be reflected on the host (apart from -+ mounts propagation), so they will be automatically cleaned up -+ when the container shuts down. -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ A hook to be run in the container's namespace after -+ mounting has been done, but before the pivot_root. -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ A hook to be run in the container's namespace immediately -+ before executing the container's init. This requires the -+ program to be available in the container. -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ A hook to be run in the host's namespace after the -+ container has been shut down. -+ -+ -+ -+ -+ -+ - - - diff -Nru lxc-0.8.0~rc1/debian/patches/0212-lxc-destroy-rm-symlink lxc-1.0.0~alpha1/debian/patches/0212-lxc-destroy-rm-symlink --- lxc-0.8.0~rc1/debian/patches/0212-lxc-destroy-rm-symlink 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0212-lxc-destroy-rm-symlink 1970-01-01 00:00:00.000000000 +0000 @@ -1,28 +0,0 @@ -Description: lxc-destroy: Separately rm rootfs if it is a symlink - If rootfs is a symbolic link but not to a block device, then do a separate - rm of its contents. We have to do this because, out of cowardice, we call - rm with --one-filesystem. -Author: Serge Hallyn -Forwarded: yes -Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/1046117 - -Index: lxc/src/lxc/lxc-destroy.in -=================================================================== ---- lxc.orig/src/lxc/lxc-destroy.in 2012-09-05 10:06:17.065918000 -0500 -+++ lxc/src/lxc/lxc-destroy.in 2012-09-05 10:14:35.335461393 -0500 -@@ -99,13 +99,13 @@ - # deletion of others later. - rootdev=`grep lxc.rootfs $lxc_path/$lxc_name/config 2>/dev/null | sed -e 's/^[^/]*/\//'` - if [ -n "$rootdev" ]; then -- if [ -b "$rootdev" -o -h "$rootdev" ]; then -+ if [ -b "$rootdev" ]; then - lvdisplay $rootdev > /dev/null 2>&1 - if [ $? -eq 0 ]; then - echo "removing backing store: $rootdev" - lvremove -f $rootdev - fi -- elif [ -d "$rootdev" ]; then -+ elif [ -h "$rootdev" -o -d "$rootdev" ]; then - # In case rootfs is not under $lxc_path/$lxc_name, remove it - rm -rf --one-file-system --preserve-root $rootdev - fi diff -Nru lxc-0.8.0~rc1/debian/patches/0213-add-premount-hook.patch lxc-1.0.0~alpha1/debian/patches/0213-add-premount-hook.patch --- lxc-0.8.0~rc1/debian/patches/0213-add-premount-hook.patch 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0213-add-premount-hook.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,80 +0,0 @@ -Index: lxc/src/lxc/conf.c -=================================================================== ---- lxc.orig/src/lxc/conf.c 2012-09-06 13:01:55.867556000 -0500 -+++ lxc/src/lxc/conf.c 2012-09-06 13:04:52.090058338 -0500 -@@ -106,7 +106,7 @@ - #endif - - char *lxchook_names[NUM_LXC_HOOKS] = { -- "pre-start", "mount", "start", "post-stop" }; -+ "pre-start", "pre-mount", "mount", "start", "post-stop" }; - - extern int pivot_root(const char * new_root, const char * put_old); - -@@ -2173,6 +2173,11 @@ - return -1; - } - -+ if (run_lxc_hooks(name, "pre-mount", lxc_conf)) { -+ ERROR("failed to run pre-mount hooks for container '%s'.", name); -+ return -1; -+ } -+ - if (setup_rootfs(&lxc_conf->rootfs)) { - ERROR("failed to setup rootfs for '%s'", name); - return -1; -@@ -2256,6 +2261,8 @@ - - if (strcmp(hook, "pre-start") == 0) - which = LXCHOOK_PRESTART; -+ else if (strcmp(hook, "pre-mount") == 0) -+ which = LXCHOOK_PREMOUNT; - else if (strcmp(hook, "mount") == 0) - which = LXCHOOK_MOUNT; - else if (strcmp(hook, "start") == 0) -Index: lxc/src/lxc/conf.h -=================================================================== ---- lxc.orig/src/lxc/conf.h 2012-09-06 13:01:55.867556000 -0500 -+++ lxc/src/lxc/conf.h 2012-09-06 13:03:42.458060880 -0500 -@@ -201,7 +201,7 @@ - * @aa_profile : apparmor profile to switch to - */ - enum lxchooks { -- LXCHOOK_PRESTART, LXCHOOK_MOUNT, LXCHOOK_START, -+ LXCHOOK_PRESTART, LXCHOOK_PREMOUNT, LXCHOOK_MOUNT, LXCHOOK_START, - LXCHOOK_POSTSTOP, NUM_LXC_HOOKS}; - extern char *lxchook_names[NUM_LXC_HOOKS]; - -Index: lxc/src/lxc/confile.c -=================================================================== ---- lxc.orig/src/lxc/confile.c 2012-09-06 13:01:55.867556000 -0500 -+++ lxc/src/lxc/confile.c 2012-09-06 13:04:23.622059377 -0500 -@@ -94,6 +94,7 @@ - { "lxc.pivotdir", config_pivotdir }, - { "lxc.utsname", config_utsname }, - { "lxc.hook.pre-start", config_hook }, -+ { "lxc.hook.pre-mount", config_hook }, - { "lxc.hook.mount", config_hook }, - { "lxc.hook.start", config_hook }, - { "lxc.hook.post-stop", config_hook }, -@@ -791,6 +792,8 @@ - } - if (strcmp(key, "lxc.hook.pre-start") == 0) - return add_hook(lxc_conf, LXCHOOK_PRESTART, copy); -+ else if (strcmp(key, "lxc.hook.pre-mount") == 0) -+ return add_hook(lxc_conf, LXCHOOK_PREMOUNT, copy); - else if (strcmp(key, "lxc.hook.mount") == 0) - return add_hook(lxc_conf, LXCHOOK_MOUNT, copy); - else if (strcmp(key, "lxc.hook.start") == 0) -Index: lxc/doc/lxc.conf.sgml.in -=================================================================== ---- lxc.orig/doc/lxc.conf.sgml.in 2012-09-06 13:01:55.867556000 -0500 -+++ lxc/doc/lxc.conf.sgml.in 2012-09-06 13:05:15.282057493 -0500 -@@ -691,7 +691,6 @@ - - - -- (Not yet implemented) - A hook to be run in the container's fs namespace but before - the rootfs has been set up. This allows for manipulation - of the rootfs, i.e. to mount an encrypted filesystem. Mounts diff -Nru lxc-0.8.0~rc1/debian/patches/0214-give-pclose-errno lxc-1.0.0~alpha1/debian/patches/0214-give-pclose-errno --- lxc-0.8.0~rc1/debian/patches/0214-give-pclose-errno 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0214-give-pclose-errno 1970-01-01 00:00:00.000000000 +0000 @@ -1,19 +0,0 @@ -Description: provide errno when pclose fails, to help debugging -Author: Serge Hallyn -Forwarded: yes - -Index: lxc/src/lxc/conf.c -=================================================================== ---- lxc.orig/src/lxc/conf.c 2012-09-06 22:07:54.632709000 -0500 -+++ lxc/src/lxc/conf.c 2012-09-06 22:09:42.986214961 -0500 -@@ -282,8 +282,8 @@ - - free(output); - -- if (pclose(f)) { -- ERROR("Script exited on error"); -+ if (pclose(f) == -1) { -+ SYSERROR("Script exited on error"); - return -1; - } - diff -Nru lxc-0.8.0~rc1/debian/patches/0215-lxc-clone-name-arg lxc-1.0.0~alpha1/debian/patches/0215-lxc-clone-name-arg --- lxc-0.8.0~rc1/debian/patches/0215-lxc-clone-name-arg 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0215-lxc-clone-name-arg 1970-01-01 00:00:00.000000000 +0000 @@ -1,19 +0,0 @@ -Description: lxc-clone: fix the '--name' parameter - The long opt for --name was being incorrectly compared to --new. -Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/1049914 -Forwarded: yes -Author: Serge Hallyn - -Index: lxc/src/lxc/lxc-clone.in -=================================================================== ---- lxc.orig/src/lxc/lxc-clone.in 2012-09-12 22:32:12.718377000 -0500 -+++ lxc/src/lxc/lxc-clone.in 2012-09-12 22:33:19.206811907 -0500 -@@ -88,7 +88,7 @@ - lxc_vg=$1 - shift - ;; -- -n|--new) -+ -n|--name) - shift - lxc_new=$1 - shift diff -Nru lxc-0.8.0~rc1/debian/patches/0216-hook-kmsg-to-console lxc-1.0.0~alpha1/debian/patches/0216-hook-kmsg-to-console --- lxc-0.8.0~rc1/debian/patches/0216-hook-kmsg-to-console 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0216-hook-kmsg-to-console 1970-01-01 00:00:00.000000000 +0000 @@ -1,55 +0,0 @@ -Description: link /dev/kmsg to /dev/console in the container - This way init log messages can be seen on the console. If containerized - syslog ever comes around, we can get rid of this. -Author: Serge Hallyn -Forwarded: yes -Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/1049926 - -Index: lxc/src/lxc/conf.c -=================================================================== ---- lxc.orig/src/lxc/conf.c 2012-09-12 22:32:12.718377000 -0500 -+++ lxc/src/lxc/conf.c 2012-09-12 22:51:10.238127457 -0500 -@@ -1054,6 +1054,31 @@ - return setup_ttydir_console(rootfs, console, ttydir); - } - -+static int setup_kmsg(const struct lxc_rootfs *rootfs, -+ const struct lxc_console *console) -+{ -+ char kpath[MAXPATHLEN]; -+ int ret; -+ -+ ret = snprintf(kpath, sizeof(kpath), "%s/dev/kmsg", rootfs->mount); -+ if (ret < 0 || ret >= sizeof(kpath)) -+ return -1; -+ -+ ret = unlink(kpath); -+ if (ret && errno != ENOENT) { -+ SYSERROR("error unlinking %s\n", kpath); -+ return -1; -+ } -+ -+ ret = symlink("console", kpath); -+ if (ret) { -+ SYSERROR("failed to create symlink for kmsg"); -+ return -1; -+ } -+ -+ return 0; -+} -+ - static int setup_cgroup(const char *name, struct lxc_list *cgroups) - { - struct lxc_list *iterator; -@@ -2207,6 +2232,11 @@ - return -1; - } - -+ if (setup_kmsg(&lxc_conf->rootfs, &lxc_conf->console)) { -+ ERROR("failed to setup kmsg for '%s'", name); -+ return -1; -+ } -+ - if (setup_tty(&lxc_conf->rootfs, &lxc_conf->tty_info, lxc_conf->ttydir)) { - ERROR("failed to setup the ttys for '%s'", name); - return -1; diff -Nru lxc-0.8.0~rc1/debian/patches/0217-lxc-clone-fix-fstab lxc-1.0.0~alpha1/debian/patches/0217-lxc-clone-fix-fstab --- lxc-0.8.0~rc1/debian/patches/0217-lxc-clone-fix-fstab 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0217-lxc-clone-fix-fstab 1970-01-01 00:00:00.000000000 +0000 @@ -1,18 +0,0 @@ -Description: Fix lxc-clone check for 'lxc.mount =' -Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/1049987 -Author: Serge Hallyn -Forwarded: yes - -Index: lxc/src/lxc/lxc-clone.in -=================================================================== ---- lxc.orig/src/lxc/lxc-clone.in 2012-09-12 22:33:19.206811907 -0500 -+++ lxc/src/lxc/lxc-clone.in 2012-09-13 07:50:23.562096422 -0500 -@@ -180,7 +180,7 @@ - sed -i '/lxc.utsname/d' $lxc_path/$lxc_new/config - echo "lxc.utsname = $hostname" >> $lxc_path/$lxc_new/config - --grep "lxc.mount =" $lxc_path/$lxc_new/config >/dev/null 2>&1 && { sed -i '/lxc.mount =/d' $lxc_path/$lxc_new/config; echo "lxc.mount = $lxc_path/$lxc_new/fstab" >> $lxc_path/$lxc_new/config; } -+grep "lxc.mount" $lxc_path/$lxc_new/config >/dev/null 2>&1 && { sed -i '/lxc.mount/d' $lxc_path/$lxc_new/config; echo "lxc.mount = $lxc_path/$lxc_new/fstab" >> $lxc_path/$lxc_new/config; } - - if [ -e $lxc_path/$lxc_orig/fstab ];then - cp $lxc_path/$lxc_orig/fstab $lxc_path/$lxc_new/fstab diff -Nru lxc-0.8.0~rc1/debian/patches/0218-api-shutdown-fix-doublestop lxc-1.0.0~alpha1/debian/patches/0218-api-shutdown-fix-doublestop --- lxc-0.8.0~rc1/debian/patches/0218-api-shutdown-fix-doublestop 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0218-api-shutdown-fix-doublestop 1970-01-01 00:00:00.000000000 +0000 @@ -1,18 +0,0 @@ -Description: api shutdown: don't c->stop() if already stopped. -Author: Serge E. Hallyn -Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/1050001 -Forwarded: yes - -Index: lxc/src/lxc/lxccontainer.c -=================================================================== ---- lxc.orig/src/lxc/lxccontainer.c 2012-09-12 22:32:12.718377000 -0500 -+++ lxc/src/lxc/lxccontainer.c 2012-09-13 08:57:25.378554968 -0500 -@@ -640,7 +640,7 @@ - return true; - kill(pid, SIGPWR); - retv = c->wait(c, "STOPPED", timeout); -- if (timeout > 0) { -+ if (!retv && timeout > 0) { - c->stop(c); - retv = c->wait(c, "STOPPED", 0); // 0 means don't wait - } diff -Nru lxc-0.8.0~rc1/debian/patches/0219-python-module-improvements lxc-1.0.0~alpha1/debian/patches/0219-python-module-improvements --- lxc-0.8.0~rc1/debian/patches/0219-python-module-improvements 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0219-python-module-improvements 1970-01-01 00:00:00.000000000 +0000 @@ -1,261 +0,0 @@ -Description: Cherry-pick upstream fixes for python module (staging branch) - -Cherry-pick a few fixes from the staging branch: - - PEP-8 syntax fix. - - Raise an exception when getting a Container instance as non-root. - - Make wait() convert any passed state string to its uppercase equivalent. - -Index: ubuntu-lxc-bzr/src/python-lxc/lxc/__init__.py -=================================================================== ---- ubuntu-lxc-bzr.orig/src/python-lxc/lxc/__init__.py 2012-09-13 10:20:15.459137148 -0400 -+++ ubuntu-lxc-bzr/src/python-lxc/lxc/__init__.py 2012-09-13 10:20:15.583137143 -0400 -@@ -32,6 +32,7 @@ - warnings.warn("The python-lxc API isn't yet stable " - "and may change at any point in the future.", Warning, 2) - -+ - class ContainerNetwork(): - props = {} - -@@ -142,6 +143,9 @@ - Creates a new Container instance. - """ - -+ if os.geteuid() != 0: -+ raise Exception("Running as non-root.") -+ - _lxc.Container.__init__(self, name) - self.network = ContainerNetworkList(self) - -@@ -358,6 +362,15 @@ - self.clear_config_item(key) - return False - -+ def wait(self, state, timeout = -1): -+ """ -+ Wait for the container to reach a given state or timeout. -+ """ -+ -+ if isinstance(state, str): -+ state = state.upper() -+ -+ return _lxc.Container.wait(self, state, timeout) - - def list_containers(as_object=False): - """ -Index: ubuntu-lxc-bzr/src/python-lxc/test.py -=================================================================== ---- ubuntu-lxc-bzr.orig/src/python-lxc/test.py 2012-09-13 10:24:54.319126672 -0400 -+++ /dev/null 1970-01-01 00:00:00.000000000 +0000 -@@ -1,28 +0,0 @@ --import lxc -- --t1 = lxc.Container("test") --print("Name set properly: %s" % (t1.name == "test")) --print("Test config loaded properly: %s" % t1.load_config("/etc/lxc/lxc.conf")) --print("Real config loaded properly: %s" % t1.load_config()) --print("Test config path: %s" % (t1.config_file_name == "/var/lib/lxc/test/config")) --print("Set config item: %s" % t1.set_config_item("lxc.utsname", "blabla")) --print("Container defined: %s" % (t1.defined)) --print("Started properly: %s" % t1.start()) --print("Container running: %s" % t1.wait("RUNNING")) --print("Container state: %s" % t1.state) --print("Container running: %s" % t1.running) --print("Container init process: %s" % t1.init_pid) --print("Freezing: %s" % t1.freeze()) --print("Container frozen: %s" % t1.wait("FROZEN")) --print("Container state: %s" % t1.state) --print("Unfreezing: %s" % t1.unfreeze()) --print("Container running: %s" % t1.wait("RUNNING")) --print("Container state: %s" % t1.state) --print("Stopped properly: %s" % t1.stop()) --print("Container state: %s" % t1.state) -- --#print("Started properly: %s" % t1.start(useinit=True)) --#print("Container running: %s" % t1.wait("RUNNING")) --#print("Container state: %s" % t1.state) --#print("Stopped properly: %s" % t1.stop()) --#print("Container state: %s" % t1.state) -Index: ubuntu-lxc-bzr/src/python-lxc/examples/api_test.py -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ ubuntu-lxc-bzr/src/python-lxc/examples/api_test.py 2012-09-13 10:35:10.649816049 -0400 -@@ -0,0 +1,151 @@ -+#!/usr/bin/python3 -+# -+# api_test.py: Test/demo of the python3-lxc API -+# -+# (C) Copyright Canonical Ltd. 2012 -+# -+# Authors: -+# Stéphane Graber -+# -+# 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 -+# -+ -+import warnings -+warnings.filterwarnings("ignore", "The python-lxc API isn't yet stable") -+ -+import lxc -+import uuid -+import sys -+ -+# Some constants -+LXC_PATH_LIB = "/var/lib/lxc" -+LXC_TEMPLATE = "ubuntu" -+ -+# Let's pick a random name, avoiding clashes -+CONTAINER_NAME = str(uuid.uuid1()) -+CLONE_NAME = str(uuid.uuid1()) -+ -+## Instantiate the container instance -+print("Getting instance for '%s'" % CONTAINER_NAME) -+container = lxc.Container(CONTAINER_NAME) -+ -+# A few basic checks of the current state -+assert(container.config_file_name == "%s/%s/config" % -+ (LXC_PATH_LIB, CONTAINER_NAME)) -+assert(container.defined == False) -+assert(container.init_pid == -1) -+assert(container.name == CONTAINER_NAME) -+assert(container.running == False) -+assert(container.state == "STOPPED") -+ -+## Create a rootfs -+print("Creating rootfs using '%s'" % LXC_TEMPLATE) -+container.create(LXC_TEMPLATE) -+ -+assert(container.defined == True) -+assert(container.name == CONTAINER_NAME -+ == container.get_config_item("lxc.utsname")) -+assert(container.name in lxc.list_containers()) -+ -+## Test the config -+print("Testing the configuration") -+capdrop = container.get_config_item("lxc.cap.drop") -+container.clear_config_item("lxc.cap.drop") -+container.set_config_item("lxc.cap.drop", capdrop[:-1]) -+container.append_config_item("lxc.cap.drop", capdrop[-1]) -+container.save_config() -+ -+# A few basic checks of the current state -+assert(isinstance(capdrop, list)) -+assert(capdrop == container.get_config_item("lxc.cap.drop")) -+ -+## Test the networking -+print("Testing the networking") -+ -+# A few basic checks of the current state -+assert("name" in container.get_keys("lxc.network.0")) -+assert(len(container.network) == 1) -+assert(container.network[0].hwaddr.startswith("00:16:3e")) -+ -+## Starting the container -+print("Starting the container") -+container.start() -+container.wait("RUNNING", 3) -+ -+# A few basic checks of the current state -+assert(container.init_pid > 1) -+assert(container.running == True) -+assert(container.state == "RUNNING") -+ -+## Checking IP address -+print("Getting the IP addresses") -+ips = container.get_ips(timeout=10) -+container.attach("NETWORK|UTSNAME", "/sbin/ifconfig", "eth0") -+ -+# A few basic checks of the current state -+assert(len(ips) > 0) -+ -+## Freezing the container -+print("Freezing the container") -+container.freeze() -+container.wait("FROZEN", 3) -+ -+# A few basic checks of the current state -+assert(container.init_pid > 1) -+assert(container.running == True) -+assert(container.state == "FROZEN") -+ -+## Unfreezing the container -+print("Unfreezing the container") -+container.unfreeze() -+container.wait("RUNNING", 3) -+ -+# A few basic checks of the current state -+assert(container.init_pid > 1) -+assert(container.running == True) -+assert(container.state == "RUNNING") -+ -+if len(sys.argv) > 1 and sys.argv[1] == "--with-console": -+ ## Attaching to tty1 -+ print("Attaching to tty1") -+ container.console(tty=1) -+ -+## Shutting down the container -+print("Shutting down the container") -+container.shutdown(3) -+ -+if container.running: -+ print("Stopping the container") -+ container.stop() -+ container.wait("STOPPED", 3) -+ -+# A few basic checks of the current state -+assert(container.init_pid == -1) -+assert(container.running == False) -+assert(container.state == "STOPPED") -+ -+## Cloning the container -+print("Cloning the container") -+clone = lxc.Container(CLONE_NAME) -+clone.clone(container) -+clone.start() -+clone.stop() -+clone.destroy() -+ -+## Destroy the container -+print("Destroying the container") -+container.destroy() -+ -+assert(container.defined == False) -Index: ubuntu-lxc-bzr/src/python-lxc/lxc.c -=================================================================== ---- ubuntu-lxc-bzr.orig/src/python-lxc/lxc.c 2012-09-13 10:42:11.970961000 -0400 -+++ ubuntu-lxc-bzr/src/python-lxc/lxc.c 2012-09-13 10:42:19.957799924 -0400 -@@ -59,14 +59,6 @@ - return result; - } - --void zombie_handler(int sig) --{ -- signal(SIGCHLD,zombie_handler); -- int status; -- -- waitpid(-1, &status, WNOHANG); --} -- - static void - Container_dealloc(Container* self) - { -@@ -353,7 +345,6 @@ - } - } - -- signal(SIGCHLD, zombie_handler); - self->container->want_daemonize(self->container); - - if (self->container->start(self->container, init_useinit, init_args)) { diff -Nru lxc-0.8.0~rc1/debian/patches/0220-getitem-per-hook-type lxc-1.0.0~alpha1/debian/patches/0220-getitem-per-hook-type --- lxc-0.8.0~rc1/debian/patches/0220-getitem-per-hook-type 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0220-getitem-per-hook-type 1970-01-01 00:00:00.000000000 +0000 @@ -1,84 +0,0 @@ -Description: Support individual hook types in clear_config_item - Without this patch, only clear_config_item("lxc.hook") works. -Forwarded: yes -Author: Serge Hallyn -Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/1050719 - -Index: lxc/src/lxc/conf.c -=================================================================== ---- lxc.orig/src/lxc/conf.c 2012-09-14 11:34:25.616537000 -0500 -+++ lxc/src/lxc/conf.c 2012-09-14 12:07:18.149733532 -0500 -@@ -2488,18 +2488,31 @@ - return 0; - } - --int lxc_clear_hooks(struct lxc_conf *c) -+int lxc_clear_hooks(struct lxc_conf *c, char *key) - { - struct lxc_list *it; -+ bool all = false, done = false; -+ char *k = key + 9; - int i; - -+ if (strcmp(key, "lxc.hook") == 0) -+ all = true; -+ - for (i=0; ihooks[i]) { -- lxc_list_del(it); -- free(it->elem); -- free(it); -+ if (all || strcmp(k, lxchook_names[i]) == 0) { -+ lxc_list_for_each(it, &c->hooks[i]) { -+ lxc_list_del(it); -+ free(it->elem); -+ free(it); -+ } -+ done = true; - } - } -+ -+ if (!done) { -+ ERROR("Invalid hook key: %s", key); -+ return -1; -+ } - return 0; - } - -@@ -2516,7 +2529,7 @@ - free(conf->aa_profile); - lxc_clear_config_caps(conf); - lxc_clear_cgroups(conf, "lxc.cgroup"); -- lxc_clear_hooks(conf); -+ lxc_clear_hooks(conf, "lxc.hook"); - lxc_clear_mount_entries(conf); - free(conf); - } -Index: lxc/src/lxc/conf.h -=================================================================== ---- lxc.orig/src/lxc/conf.h 2012-09-14 11:34:25.616537000 -0500 -+++ lxc/src/lxc/conf.h 2012-09-14 11:37:06.507461581 -0500 -@@ -252,7 +252,7 @@ - extern int lxc_clear_config_caps(struct lxc_conf *c); - extern int lxc_clear_cgroups(struct lxc_conf *c, char *key); - extern int lxc_clear_mount_entries(struct lxc_conf *c); --extern int lxc_clear_hooks(struct lxc_conf *c); -+extern int lxc_clear_hooks(struct lxc_conf *c, char *key); - - /* - * Configure the container from inside -Index: lxc/src/lxc/confile.c -=================================================================== ---- lxc.orig/src/lxc/confile.c 2012-09-14 11:34:25.616537000 -0500 -+++ lxc/src/lxc/confile.c 2012-09-14 11:36:55.171461993 -0500 -@@ -1557,8 +1557,8 @@ - return lxc_clear_cgroups(c, key); - else if (strcmp(key, "lxc.mount.entries") == 0) - return lxc_clear_mount_entries(c); -- else if (strcmp(key, "lxc.hook") == 0) -- return lxc_clear_hooks(c); -+ else if (strncmp(key, "lxc.hook", 8) == 0) -+ return lxc_clear_hooks(c, key); - - return -1; - } diff -Nru lxc-0.8.0~rc1/debian/patches/0221-make-nonflush-upgrades-robust lxc-1.0.0~alpha1/debian/patches/0221-make-nonflush-upgrades-robust --- lxc-0.8.0~rc1/debian/patches/0221-make-nonflush-upgrades-robust 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0221-make-nonflush-upgrades-robust 1970-01-01 00:00:00.000000000 +0000 @@ -1,51 +0,0 @@ -Description: try to better handle out of date container caches. - For a lucid container, apt-get update before installing the source package for - add-apt-repository, so that apt-get does not fail. - . - If apt-get dist-upgrade fails, suggest running lxc-create with -F. -Author: Serge Hallyn -Forwarded: yes -Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/942862 - -Index: lxc/templates/lxc-ubuntu.in -=================================================================== ---- lxc.orig/templates/lxc-ubuntu.in 2012-09-14 11:34:25.616537000 -0500 -+++ lxc/templates/lxc-ubuntu.in 2012-09-14 13:04:45.657607740 -0500 -@@ -153,6 +153,12 @@ - rm -rf $cache/rootfs-$arch - } - -+suggest_flush() -+{ -+ echo "Container upgrade failed. The container cache may be out of date," -+ echo "in which case flushing the case (see -F in the hep output) may help." -+} -+ - download_ubuntu() - { - cache=$1 -@@ -200,15 +206,9 @@ - EOF - chmod +x "$1/partial-${arch}"/usr/sbin/policy-rc.d - -- lxc-unshare -s MOUNT -- chroot "$1/partial-${arch}" apt-get dist-upgrade -y -- ret=$? -+ lxc-unshare -s MOUNT -- chroot "$1/partial-${arch}" apt-get dist-upgrade -y || { suggest_flush; false; } - rm -f "$1/partial-${arch}"/usr/sbin/policy-rc.d - -- if [ $ret -ne 0 ]; then -- echo "Failed to upgrade the cache" -- return 1 -- fi -- - chroot "$1/partial-${arch}" apt-get clean - - mv "$1/partial-$arch" "$1/rootfs-$arch" -@@ -473,6 +473,7 @@ - # for lucid, if not trimming, then add the ubuntu-virt - # ppa and install lxcguest - if [ $release = "lucid" ]; then -+ chroot $rootfs apt-get update - chroot $rootfs apt-get install --force-yes -y python-software-properties - chroot $rootfs add-apt-repository ppa:ubuntu-virt/ppa - fi diff -Nru lxc-0.8.0~rc1/debian/patches/0222-debian-dhcp3-package lxc-1.0.0~alpha1/debian/patches/0222-debian-dhcp3-package --- lxc-0.8.0~rc1/debian/patches/0222-debian-dhcp3-package 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0222-debian-dhcp3-package 1970-01-01 00:00:00.000000000 +0000 @@ -1,19 +0,0 @@ -Description: lxc-debian: specify isc-dhcp-server in package list - dhcp3-client does not exist in testing. -Author: Serge Hallyn -Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/1052972 -Forwarded: yes - -Index: lxc/templates/lxc-debian.in -=================================================================== ---- lxc.orig/templates/lxc-debian.in 2012-09-21 13:34:12.247622000 -0500 -+++ lxc/templates/lxc-debian.in 2012-09-21 13:34:45.480764561 -0500 -@@ -110,7 +110,7 @@ - locales,\ - libui-dialog-perl,\ - dialog,\ --dhcp3-client,\ -+isc-dhcp-client,\ - netbase,\ - net-tools,\ - iproute,\ diff -Nru lxc-0.8.0~rc1/debian/patches/0223-ubuntu-template-user-msg lxc-1.0.0~alpha1/debian/patches/0223-ubuntu-template-user-msg --- lxc-0.8.0~rc1/debian/patches/0223-ubuntu-template-user-msg 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0223-ubuntu-template-user-msg 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ -Description: lxc-ubuntu: fix printing of default user - If a user is bound into the container, don't claim the default user is - ubuntu. -Author: Serge Hallyn -Forwarded: yes -Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/1052315 - -Index: lxc/templates/lxc-ubuntu.in -=================================================================== ---- lxc.orig/templates/lxc-ubuntu.in 2012-09-19 11:54:39.942250000 -0500 -+++ lxc/templates/lxc-ubuntu.in 2012-09-19 11:56:48.377032378 -0500 -@@ -708,7 +708,11 @@ - - echo "" - echo "##" --echo "# The default user is 'ubuntu' with password 'ubuntu'!" --echo "# Use the 'sudo' command to run tasks as root in the container." -+if [ -n "$bindhome" ]; then -+ echo "# Log in as user $bindhome" -+else -+ echo "# The default user is 'ubuntu' with password 'ubuntu'!" -+ echo "# Use the 'sudo' command to run tasks as root in the container." -+fi - echo "##" - echo "" diff -Nru lxc-0.8.0~rc1/debian/patches/0225-ubuntu-cloud-numeric-owner lxc-1.0.0~alpha1/debian/patches/0225-ubuntu-cloud-numeric-owner --- lxc-0.8.0~rc1/debian/patches/0225-ubuntu-cloud-numeric-owner 2012-10-24 16:12:37.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0225-ubuntu-cloud-numeric-owner 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ -Description: ubuntu-cloud template: extract root tar with --numeric-owner - when extracting the tarball of the filesystem it must be done with - --numeric-owner. Without this argument, ownership is potentially - broken because tar converts the username/groupname to uid/gid. - this does not necessarily match the entries in /etc/passwd or group - inside the extracted root. -Author: Scott Moser -Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/1066084 -Forwarded: no -Index: lxc/templates/lxc-ubuntu-cloud.in -=================================================================== ---- lxc.orig/templates/lxc-ubuntu-cloud.in 2012-10-24 11:12:20.663545281 -0500 -+++ lxc/templates/lxc-ubuntu-cloud.in 2012-10-24 11:12:34.807545042 -0500 -@@ -340,7 +340,7 @@ - echo "Extracting container rootfs" - mkdir -p $rootfs - cd $rootfs -- tar -zxf $cache/$filename -+ tar --numeric-owner -zxf $cache/$filename - - - if [ $cloud -eq 0 ]; then diff -Nru lxc-0.8.0~rc1/debian/patches/0227-ubuntu-cloud-parsing lxc-1.0.0~alpha1/debian/patches/0227-ubuntu-cloud-parsing --- lxc-0.8.0~rc1/debian/patches/0227-ubuntu-cloud-parsing 2012-11-29 18:45:02.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0227-ubuntu-cloud-parsing 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ -Description: fix lxc-ubuntu-cloud option parsing bugs - the -u shortopt matching --userdata was not specified, and when -L - is found, there is no optarg so shift 1 not 2. -Author: Serge Hallyn -Ubuntu-bug: https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/1076031 -Forwarded: yes - -Index: lxc/templates/lxc-ubuntu-cloud.in -=================================================================== ---- lxc.orig/templates/lxc-ubuntu-cloud.in 2012-11-26 10:12:13.063703856 -0600 -+++ lxc/templates/lxc-ubuntu-cloud.in 2012-11-26 10:23:17.435679618 -0600 -@@ -131,7 +131,7 @@ - return 0 - } - --options=$(getopt -o a:hp:r:n:Fi:CLS:T:ds: -l arch:,help,path:,release:,name:,flush-cache,hostid:,auth-key:,cloud,no_locales,tarball:,debug,stream:,userdata: -- "$@") -+options=$(getopt -o a:hp:r:n:Fi:CLS:T:ds:u: -l arch:,help,path:,release:,name:,flush-cache,hostid:,auth-key:,cloud,no_locales,tarball:,debug,stream:,userdata: -- "$@") - if [ $? -ne 0 ]; then - usage $(basename $0) - exit 1 -@@ -189,7 +189,7 @@ - -u|--userdata) userdata=$2; shift 2;; - -C|--cloud) cloud=1; shift 1;; - -S|--auth-key) auth_key=$2; shift 2;; -- -L|--no_locales) locales=0; shift 2;; -+ -L|--no_locales) locales=0; shift 1;; - -T|--tarball) tarball=$2; shift 2;; - -d|--debug) debug=1; shift 1;; - -s|--stream) stream=$2; shift 2;; diff -Nru lxc-0.8.0~rc1/debian/patches/0228-ignore-kmsg-setup-failure lxc-1.0.0~alpha1/debian/patches/0228-ignore-kmsg-setup-failure --- lxc-0.8.0~rc1/debian/patches/0228-ignore-kmsg-setup-failure 2013-01-08 16:25:37.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0228-ignore-kmsg-setup-failure 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -Description: don't fail if /dev/kmsg isn't set up - It's not crucial, and containers can be set up with ro root which will - prevent it from working anywa. - Note - this is already in the github staging tree. -Author: Serge Hallyn -Forwarded: no - -Index: lxc-0.8.0~rc1/src/lxc/conf.c -=================================================================== ---- lxc-0.8.0~rc1.orig/src/lxc/conf.c 2013-01-08 10:25:34.376389708 -0600 -+++ lxc-0.8.0~rc1/src/lxc/conf.c 2013-01-08 10:25:34.368389710 -0600 -@@ -2232,10 +2232,8 @@ - return -1; - } - -- if (setup_kmsg(&lxc_conf->rootfs, &lxc_conf->console)) { -+ if (setup_kmsg(&lxc_conf->rootfs, &lxc_conf->console)) // don't fail - ERROR("failed to setup kmsg for '%s'", name); -- return -1; -- } - - if (setup_tty(&lxc_conf->rootfs, &lxc_conf->tty_info, lxc_conf->ttydir)) { - ERROR("failed to setup the ttys for '%s'", name); diff -Nru lxc-0.8.0~rc1/debian/patches/0229-lxc-clone-mount-fix lxc-1.0.0~alpha1/debian/patches/0229-lxc-clone-mount-fix --- lxc-0.8.0~rc1/debian/patches/0229-lxc-clone-mount-fix 2012-11-29 18:45:06.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/0229-lxc-clone-mount-fix 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ -Description: lxc-clone: fix wrong handling of lxc.mount - We can't simply search on and remove 'lxc.mount' entries, as those will - also hit lxc.mount.entry entries. Look for 'lxc.mount[ \t]' instead. - This cherrypicks an upstream fix for lxc-clone, so does not need to be - forwarded upstream. -Author: Serge Hallyn -Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/1084089 -Forwarded: no - -Index: lxc/src/lxc/lxc-clone.in -=================================================================== ---- lxc.orig/src/lxc/lxc-clone.in 2012-11-26 16:52:52.161010000 -0600 -+++ lxc/src/lxc/lxc-clone.in 2012-11-28 10:47:07.365481892 -0600 -@@ -180,7 +180,7 @@ - sed -i '/lxc.utsname/d' $lxc_path/$lxc_new/config - echo "lxc.utsname = $hostname" >> $lxc_path/$lxc_new/config - --grep "lxc.mount" $lxc_path/$lxc_new/config >/dev/null 2>&1 && { sed -i '/lxc.mount/d' $lxc_path/$lxc_new/config; echo "lxc.mount = $lxc_path/$lxc_new/fstab" >> $lxc_path/$lxc_new/config; } -+grep "lxc.mount[ \t]" $lxc_path/$lxc_new/config >/dev/null 2>&1 && { sed -i '/lxc.mount[ \t]/d' $lxc_path/$lxc_new/config; echo "lxc.mount = $lxc_path/$lxc_new/fstab" >> $lxc_path/$lxc_new/config; } - - if [ -e $lxc_path/$lxc_orig/fstab ];then - cp $lxc_path/$lxc_orig/fstab $lxc_path/$lxc_new/fstab diff -Nru lxc-0.8.0~rc1/debian/patches/03-lxc-configuration-path.patch lxc-1.0.0~alpha1/debian/patches/03-lxc-configuration-path.patch --- lxc-0.8.0~rc1/debian/patches/03-lxc-configuration-path.patch 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/03-lxc-configuration-path.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,18 +0,0 @@ -Author: Daniel Baumann -Description: Removing double check for configuration path in lxc-create (Closes: #633996). - -diff -Naurp lxc.orig/src/lxc/lxc-create.in lxc/src/lxc/lxc-create.in ---- lxc.orig/src/lxc/lxc-create.in 2012-03-02 13:20:15.859239022 +0100 -+++ lxc/src/lxc/lxc-create.in 2012-03-09 12:38:50.401955584 +0100 -@@ -145,11 +145,6 @@ if [ -z "$lxc_path" ]; then - exit 1 - fi - --if [ ! -r $lxc_path ]; then -- echo "configuration path '$lxc_path' not found" -- exit 1 --fi -- - if [ -z "$lxc_name" ]; then - echo "no container name specified" - usage diff -Nru lxc-0.8.0~rc1/debian/patches/04-lxc-create-template-name.patch lxc-1.0.0~alpha1/debian/patches/04-lxc-create-template-name.patch --- lxc-0.8.0~rc1/debian/patches/04-lxc-create-template-name.patch 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/04-lxc-create-template-name.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,39 +0,0 @@ -Author: Daniel Baumann -Description: - Keeping creation of new containers without previously existing configuration - non-interactive and trimm the warning message. - -diff -Naurp lxc.orig/src/lxc/lxc-create.in lxc/src/lxc/lxc-create.in ---- lxc.orig/src/lxc/lxc-create.in 2011-11-10 11:48:17.145423030 +0100 -+++ lxc/src/lxc/lxc-create.in 2011-11-10 20:09:37.670570553 +0100 -@@ -148,29 +148,10 @@ if [ ! -z $lxc_template ]; then - fi - - if [ -z "$lxc_config" ]; then -- echo -- echo "Warning:" -- echo "-------" -- echo "Usually the template option is called with a configuration" -+ echo "Note: Usually the template option is called with a configuration" - echo "file option too, mostly to configure the network." -- echo "eg. lxc-create -n foo -f lxc.conf -t debian" -- echo "The configuration file is often:" -- echo -- echo "lxc.network.type=macvlan" -- echo "lxc.network.link=eth0" -- echo "lxc.network.flags=up" -- echo -- echo "or alternatively:" -- echo -- echo "lxc.network.type=veth" -- echo "lxc.network.link=br0" -- echo "lxc.network.flags=up" -- echo - echo "For more information look at lxc.conf (5)" - echo -- echo "At this point, I assume you know what you do." -- echo "Press to continue ..." -- read dummy - fi - - ${templatedir}/lxc-$lxc_template --path=$lxc_path/$lxc_name --name=$lxc_name $* diff -Nru lxc-0.8.0~rc1/debian/patches/05-doc-ip-address.patch lxc-1.0.0~alpha1/debian/patches/05-doc-ip-address.patch --- lxc-0.8.0~rc1/debian/patches/05-doc-ip-address.patch 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/05-doc-ip-address.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,173 +0,0 @@ -Author: Daniel Baumann -Description: - Use non-routed, private IPv4 address in documentation examples (Closes: #571525). - -diff -Naurp lxc.orig/doc/examples/lxc-complex.conf lxc/doc/examples/lxc-complex.conf ---- lxc.orig/doc/examples/lxc-complex.conf 2011-09-09 16:32:11.821390993 +0200 -+++ lxc/doc/examples/lxc-complex.conf 2011-09-20 23:56:27.777134985 +0200 -@@ -5,19 +5,19 @@ lxc.network.type = veth - lxc.network.flags = up - lxc.network.link = br0 - lxc.network.hwaddr = 4a:49:43:49:79:bf --lxc.network.ipv4 = 1.2.3.5/24 -+lxc.network.ipv4 = 10.2.3.5/24 - lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3597 - - lxc.network.type = macvlan - lxc.network.flags = up - lxc.network.link = eth0 - lxc.network.hwaddr = 4a:49:43:49:79:bd --lxc.network.ipv4 = 1.2.3.4/24 -+lxc.network.ipv4 = 10.2.3.4/24 - lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3596 - - lxc.network.type = phys - lxc.network.flags = up - lxc.network.link = dummy0 - lxc.network.hwaddr = 4a:49:43:49:79:ff --lxc.network.ipv4 = 1.2.3.6/24 -+lxc.network.ipv4 = 10.2.3.6/24 - lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3297 -diff -Naurp lxc.orig/doc/examples/lxc-complex.conf.in lxc/doc/examples/lxc-complex.conf.in ---- lxc.orig/doc/examples/lxc-complex.conf.in 2011-09-09 16:32:11.821390993 +0200 -+++ lxc/doc/examples/lxc-complex.conf.in 2011-09-20 23:56:41.425201779 +0200 -@@ -5,19 +5,19 @@ lxc.network.type = veth - lxc.network.flags = up - lxc.network.link = br0 - lxc.network.hwaddr = 4a:49:43:49:79:bf --lxc.network.ipv4 = 1.2.3.5/24 -+lxc.network.ipv4 = 10.2.3.5/24 - lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3597 - - lxc.network.type = macvlan - lxc.network.flags = up - lxc.network.link = eth0 - lxc.network.hwaddr = 4a:49:43:49:79:bd --lxc.network.ipv4 = 1.2.3.4/24 -+lxc.network.ipv4 = 10.2.3.4/24 - lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3596 - - lxc.network.type = phys - lxc.network.flags = up - lxc.network.link = dummy0 - lxc.network.hwaddr = 4a:49:43:49:79:ff --lxc.network.ipv4 = 1.2.3.6/24 -+lxc.network.ipv4 = 10.2.3.6/24 - lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3297 -diff -Naurp lxc.orig/doc/examples/lxc-macvlan.conf lxc/doc/examples/lxc-macvlan.conf ---- lxc.orig/doc/examples/lxc-macvlan.conf 2011-09-09 16:32:11.821390993 +0200 -+++ lxc/doc/examples/lxc-macvlan.conf 2011-09-20 23:57:25.901425757 +0200 -@@ -4,5 +4,5 @@ lxc.network.type = macvlan - lxc.network.flags = up - lxc.network.link = eth0 - lxc.network.hwaddr = 4a:49:43:49:79:bd --lxc.network.ipv4 = 1.2.3.4/24 -+lxc.network.ipv4 = 10.2.3.4/24 - lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3596 -diff -Naurp lxc.orig/doc/examples/lxc-macvlan.conf.in lxc/doc/examples/lxc-macvlan.conf.in ---- lxc.orig/doc/examples/lxc-macvlan.conf.in 2011-09-09 16:32:11.821390993 +0200 -+++ lxc/doc/examples/lxc-macvlan.conf.in 2011-09-20 23:57:23.845415375 +0200 -@@ -4,5 +4,5 @@ lxc.network.type = macvlan - lxc.network.flags = up - lxc.network.link = eth0 - lxc.network.hwaddr = 4a:49:43:49:79:bd --lxc.network.ipv4 = 1.2.3.4/24 -+lxc.network.ipv4 = 10.2.3.4/24 - lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3596 -diff -Naurp lxc.orig/doc/examples/lxc-phys.conf lxc/doc/examples/lxc-phys.conf ---- lxc.orig/doc/examples/lxc-phys.conf 2011-09-09 16:32:11.821390993 +0200 -+++ lxc/doc/examples/lxc-phys.conf 2011-09-20 23:57:28.117436890 +0200 -@@ -5,5 +5,5 @@ lxc.network.type = phys - lxc.network.flags = up - lxc.network.link = eth0 - lxc.network.hwaddr = 4a:49:43:49:79:ff --lxc.network.ipv4 = 1.2.3.6/24 -+lxc.network.ipv4 = 10.2.3.6/24 - lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3297 -diff -Naurp lxc.orig/doc/examples/lxc-phys.conf.in lxc/doc/examples/lxc-phys.conf.in ---- lxc.orig/doc/examples/lxc-phys.conf.in 2011-09-09 16:32:11.821390993 +0200 -+++ lxc/doc/examples/lxc-phys.conf.in 2011-09-20 23:57:19.497394305 +0200 -@@ -5,5 +5,5 @@ lxc.network.type = phys - lxc.network.flags = up - lxc.network.link = eth0 - lxc.network.hwaddr = 4a:49:43:49:79:ff --lxc.network.ipv4 = 1.2.3.6/24 -+lxc.network.ipv4 = 10.2.3.6/24 - lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3297 -diff -Naurp lxc.orig/doc/examples/lxc-veth.conf lxc/doc/examples/lxc-veth.conf ---- lxc.orig/doc/examples/lxc-veth.conf 2011-09-09 16:32:11.821390993 +0200 -+++ lxc/doc/examples/lxc-veth.conf 2011-09-20 23:56:46.513226093 +0200 -@@ -5,5 +5,5 @@ lxc.network.type = veth - lxc.network.flags = up - lxc.network.link = br0 - lxc.network.hwaddr = 4a:49:43:49:79:bf --lxc.network.ipv4 = 1.2.3.5/24 -+lxc.network.ipv4 = 10.2.3.5/24 - lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3597 -diff -Naurp lxc.orig/doc/examples/lxc-veth.conf.in lxc/doc/examples/lxc-veth.conf.in ---- lxc.orig/doc/examples/lxc-veth.conf.in 2011-09-09 16:32:11.821390993 +0200 -+++ lxc/doc/examples/lxc-veth.conf.in 2011-09-20 23:56:17.505087055 +0200 -@@ -5,5 +5,5 @@ lxc.network.type = veth - lxc.network.flags = up - lxc.network.link = br0 - lxc.network.hwaddr = 4a:49:43:49:79:bf --lxc.network.ipv4 = 1.2.3.5/24 -+lxc.network.ipv4 = 10.2.3.5/24 - lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3597 -diff -Naurp lxc.orig/doc/examples/lxc-vlan.conf lxc/doc/examples/lxc-vlan.conf ---- lxc.orig/doc/examples/lxc-vlan.conf 2011-09-09 16:32:11.821390993 +0200 -+++ lxc/doc/examples/lxc-vlan.conf 2011-09-20 23:57:31.533454612 +0200 -@@ -5,5 +5,5 @@ lxc.network.vlan.id = 1234 - lxc.network.flags = up - lxc.network.link = eth0 - lxc.network.hwaddr = 4a:49:43:49:79:bd --lxc.network.ipv4 = 1.2.3.4/24 -+lxc.network.ipv4 = 10.2.3.4/24 - lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3596 -diff -Naurp lxc.orig/doc/examples/lxc-vlan.conf.in lxc/doc/examples/lxc-vlan.conf.in ---- lxc.orig/doc/examples/lxc-vlan.conf.in 2011-09-09 16:32:11.821390993 +0200 -+++ lxc/doc/examples/lxc-vlan.conf.in 2011-09-20 23:57:21.629404927 +0200 -@@ -5,5 +5,5 @@ lxc.network.vlan.id = 1234 - lxc.network.flags = up - lxc.network.link = eth0 - lxc.network.hwaddr = 4a:49:43:49:79:bd --lxc.network.ipv4 = 1.2.3.4/24 -+lxc.network.ipv4 = 10.2.3.4/24 - lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3596 -diff -Naurp lxc.orig/doc/lxc.conf.sgml.in lxc/doc/lxc.conf.sgml.in ---- lxc.orig/doc/lxc.conf.sgml.in 2011-09-15 11:01:01.165397074 +0200 -+++ lxc/doc/lxc.conf.sgml.in 2011-09-20 23:56:57.261283643 +0200 -@@ -590,7 +590,7 @@ Foundation, Inc., 59 Temple Place, Suite - lxc.network.link = br0 - lxc.network.name = eth0 - lxc.network.hwaddr = 4a:49:43:49:79:bf -- lxc.network.ipv4 = 1.2.3.5/24 1.2.3.255 -+ lxc.network.ipv4 = 10.2.3.5/24 10.2.3.255 - lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3597 - - -@@ -621,21 +621,21 @@ Foundation, Inc., 59 Temple Place, Suite - lxc.network.flags = up - lxc.network.link = br0 - lxc.network.hwaddr = 4a:49:43:49:79:bf -- lxc.network.ipv4 = 1.2.3.5/24 1.2.3.255 -+ lxc.network.ipv4 = 10.2.3.5/24 10.2.3.255 - lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3597 - lxc.network.ipv6 = 2003:db8:1:0:214:5432:feab:3588 - lxc.network.type = macvlan - lxc.network.flags = up - lxc.network.link = eth0 - lxc.network.hwaddr = 4a:49:43:49:79:bd -- lxc.network.ipv4 = 1.2.3.4/24 -+ lxc.network.ipv4 = 10.2.3.4/24 - lxc.network.ipv4 = 192.168.10.125/24 - lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3596 - lxc.network.type = phys - lxc.network.flags = up - lxc.network.link = dummy0 - lxc.network.hwaddr = 4a:49:43:49:79:ff -- lxc.network.ipv4 = 1.2.3.6/24 -+ lxc.network.ipv4 = 10.2.3.6/24 - lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3297 - lxc.cgroup.cpuset.cpus = 0,1 - lxc.cgroup.cpu.shares = 1234 diff -Nru lxc-0.8.0~rc1/debian/patches/06-bash.patch lxc-1.0.0~alpha1/debian/patches/06-bash.patch --- lxc-0.8.0~rc1/debian/patches/06-bash.patch 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/06-bash.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,230 +0,0 @@ -Author: Daniel Baumann -Description: Avoid using bashisms in lxc commands. - -diff -Naurp lxc.orig/src/lxc/lxc-checkconfig.in lxc/src/lxc/lxc-checkconfig.in ---- lxc.orig/src/lxc/lxc-checkconfig.in 2012-03-02 13:20:15.859239022 +0100 -+++ lxc/src/lxc/lxc-checkconfig.in 2012-03-09 12:50:18.485367724 +0100 -@@ -1,37 +1,40 @@ --#!/bin/bash -+#!/bin/sh - - # Allow environment variables to override grep and config - : ${CONFIG:=/proc/config.gz} - : ${GREP:=zgrep} - --SETCOLOR_SUCCESS="echo -en \\033[1;32m" --SETCOLOR_FAILURE="echo -en \\033[1;31m" --SETCOLOR_WARNING="echo -en \\033[1;33m" --SETCOLOR_NORMAL="echo -en \\033[0;39m" -+SETCOLOR_SUCCESS () { printf '\033[1;32m'; } -+SETCOLOR_FAILURE () { printf '\033[1;31m'; } -+SETCOLOR_WARNING () { printf '\033[1;33m'; } -+SETCOLOR_NORMAL () { printf '\033[0;39m'; } - - is_set() { -- $GREP -q "$1=[y|m]" $CONFIG -+ $GREP -q "$1=[y|m]" "$CONFIG" - return $? - } - - is_enabled() { -- mandatory=$2 -+ prefix=$1 -+ option=$2 -+ mandatory=$3 - -- is_set $1 -+ is_set "$option" - RES=$? - -+ echo -n "$prefix" - if [ $RES -eq 0 ]; then -- $SETCOLOR_SUCCESS && echo -e "enabled" && $SETCOLOR_NORMAL -+ SETCOLOR_SUCCESS && echo "enabled" && SETCOLOR_NORMAL - else -- if [ ! -z "$mandatory" -a "$mandatory" = yes ]; then -- $SETCOLOR_FAILURE && echo -e "required" && $SETCOLOR_NORMAL -+ if [ ! -z "$mandatory" ] && [ "$mandatory" = yes ]; then -+ SETCOLOR_FAILURE && echo "required" && SETCOLOR_NORMAL - else -- $SETCOLOR_WARNING && echo -e "missing" && $SETCOLOR_NORMAL -+ SETCOLOR_WARNING && echo "missing" && SETCOLOR_NORMAL - fi - fi - } - --if [ ! -f $CONFIG ]; then -+if [ ! -f "$CONFIG" ]; then - echo "Kernel config $CONFIG not found, looking in other places..." - KVER="`uname -r`" - HEADERS_CONFIG="/lib/modules/$KVER/build/.config" -@@ -53,13 +56,13 @@ if [ ! -f $CONFIG ]; then - fi - - echo "--- Namespaces ---" --echo -n "Namespaces: " && is_enabled CONFIG_NAMESPACES yes --echo -n "Utsname namespace: " && is_enabled CONFIG_UTS_NS --echo -n "Ipc namespace: " && is_enabled CONFIG_IPC_NS yes --echo -n "Pid namespace: " && is_enabled CONFIG_PID_NS yes --echo -n "User namespace: " && is_enabled CONFIG_USER_NS --echo -n "Network namespace: " && is_enabled CONFIG_NET_NS --echo -n "Multiple /dev/pts instances: " && is_enabled DEVPTS_MULTIPLE_INSTANCES -+is_enabled "Namespaces: " CONFIG_NAMESPACES yes -+is_enabled "Utsname namespace: " CONFIG_UTS_NS -+is_enabled "Ipc namespace: " CONFIG_IPC_NS yes -+is_enabled "Pid namespace: " CONFIG_PID_NS yes -+is_enabled "User namespace: " CONFIG_USER_NS -+is_enabled "Network namespace: " CONFIG_NET_NS -+is_enabled "Multiple /dev/pts instances: " DEVPTS_MULTIPLE_INSTANCES - echo - echo "--- Control groups ---" - -@@ -70,42 +73,34 @@ print_cgroups() { - - CGROUP_MNT_PATH=`print_cgroups cgroup /proc/self/mounts | head -1` - --echo -n "Cgroup: " && is_enabled CONFIG_CGROUPS yes -+is_enabled "Cgroup: " CONFIG_CGROUPS yes - --if [ -f $CGROUP_MNT_PATH/cgroup.clone_children ]; then -+if [ -f "$CGROUP_MNT_PATH/cgroup.clone_children" ]; then - echo -n "Cgroup clone_children flag: " && -- $SETCOLOR_SUCCESS && echo -e "enabled" && $SETCOLOR_NORMAL -+ SETCOLOR_SUCCESS && echo "enabled" && SETCOLOR_NORMAL - else - echo -n "Cgroup namespace: " && is_enabled CONFIG_CGROUP_NS yes - fi --echo -n "Cgroup device: " && is_enabled CONFIG_CGROUP_DEVICE --echo -n "Cgroup sched: " && is_enabled CONFIG_CGROUP_SCHED --echo -n "Cgroup cpu account: " && is_enabled CONFIG_CGROUP_CPUACCT --echo -n "Cgroup memory controller: " && is_enabled CONFIG_CGROUP_MEM_RES_CTLR --is_set CONFIG_SMP && echo -n "Cgroup cpuset: " && is_enabled CONFIG_CPUSETS -+is_enabled "Cgroup device: " CONFIG_CGROUP_DEVICE -+is_enabled "Cgroup sched: " CONFIG_CGROUP_SCHED -+is_enabled "Cgroup cpu account: " CONFIG_CGROUP_CPUACCT -+is_enabled "Cgroup memory controller: " CONFIG_CGROUP_MEM_RES_CTLR -+is_set CONFIG_SMP && is_enabled "Cgroup cpuset: " CONFIG_CPUSETS - echo - echo "--- Misc ---" --echo -n "Veth pair device: " && is_enabled CONFIG_VETH --echo -n "Macvlan: " && is_enabled CONFIG_MACVLAN --echo -n "Vlan: " && is_enabled CONFIG_VLAN_8021Q --KVER_MAJOR=$($GREP '^# Linux' $CONFIG | \ -- sed -r 's/.* ([0-9])\.[0-9]{1,2}\.[0-9]{1,3}.*/\1/') --if [[ $KVER_MAJOR == 2 ]]; then --KVER_MINOR=$($GREP '^# Linux' $CONFIG | \ -- sed -r 's/.* 2.6.([0-9]{2}).*/\1/') -+is_enabled "Veth pair device: " CONFIG_VETH -+is_enabled "Macvlan: " CONFIG_MACVLAN -+is_enabled "Vlan: " CONFIG_VLAN_8021Q -+KVER=$($GREP "^# Linux" "$CONFIG" | sed -r "s/.*([23])\.([0-9])+\.([0-9]+).*/\1 \2 \3/") -+kernel_version () { echo $(( ( $1 << 16 ) + ( $2 << 8 ) + $3)); } -+echo -n "File capabilities: " -+if [ $(kernel_version $KVER) -le $(kernel_version 2 6 32) ]; then -+ is_enabled CONFIG_SECURITY_FILE_CAPABILITIES - else --KVER_MINOR=$($GREP '^# Linux' $CONFIG | \ -- sed -r 's/.* [0-9]\.([0-9]{1,3})\.[0-9]{1,3}.*/\1/') -+ SETCOLOR_SUCCESS && echo "enabled" && SETCOLOR_NORMAL - fi --echo -n "File capabilities: " && -- ( [[ ${KVER_MAJOR} == 2 && ${KVER_MINOR} < 33 ]] && -- is_enabled CONFIG_SECURITY_FILE_CAPABILITIES ) || -- ( [[ ( ${KVER_MAJOR} == 2 && ${KVER_MINOR} > 32 ) || -- ${KVER_MAJOR} > 2 ]] && $SETCOLOR_SUCCESS && -- echo -e "enabled" && $SETCOLOR_NORMAL ) - - echo - echo "Note : Before booting a new kernel, you can check its configuration" - echo "usage : CONFIG=/path/to/config $0" - echo -- -diff -Naurp lxc.orig/src/lxc/lxc-clone.in lxc/src/lxc/lxc-clone.in ---- lxc.orig/src/lxc/lxc-clone.in 2012-03-02 13:20:15.859239022 +0100 -+++ lxc/src/lxc/lxc-clone.in 2012-03-09 12:43:15.615270353 +0100 -@@ -1,4 +1,4 @@ --#!/bin/bash -+#!/bin/sh - - # - # lxc: linux Container library -diff -Naurp lxc.orig/src/lxc/lxc-create.in lxc/src/lxc/lxc-create.in ---- lxc.orig/src/lxc/lxc-create.in 2012-03-09 12:39:58.430294287 +0100 -+++ lxc/src/lxc/lxc-create.in 2012-03-09 12:41:35.350756130 +0100 -@@ -1,4 +1,4 @@ --#!/bin/bash -+#!/bin/sh - - # - # lxc: linux Container library -diff -Naurp lxc.orig/src/lxc/lxc-destroy.in lxc/src/lxc/lxc-destroy.in ---- lxc.orig/src/lxc/lxc-destroy.in 2012-03-02 13:20:15.859239022 +0100 -+++ lxc/src/lxc/lxc-destroy.in 2012-03-09 12:42:48.359136155 +0100 -@@ -1,4 +1,4 @@ --#!/bin/bash -+#!/bin/sh - - # - # lxc: linux Container library -@@ -98,7 +98,7 @@ fi - # deletion of others later. - rootdev=`grep lxc.rootfs $lxc_path/$lxc_name/config 2>/dev/null | sed -e 's/^[^/]*/\//'` - if [ ! -z "$rootdev" ]; then -- if [ -b "$rootdev" -o -h "$rootdev" ]; then -+ if [ -b "$rootdev" ] || [ -h "$rootdev" ]; then - lvdisplay $rootdev > /dev/null 2>&1 - if [ $? -eq 0 ]; then - echo "removing backing store: $rootdev" -diff -Naurp lxc.orig/src/lxc/lxc-ls.in lxc/src/lxc/lxc-ls.in ---- lxc.orig/src/lxc/lxc-ls.in 2012-03-02 13:20:15.859239022 +0100 -+++ lxc/src/lxc/lxc-ls.in 2012-03-09 12:41:35.350756130 +0100 -@@ -1,4 +1,4 @@ --#!/bin/bash -+#!/bin/sh - - localstatedir=@LOCALSTATEDIR@ - lxcpath=@LXCPATH@ -diff -Naurp lxc.orig/src/lxc/lxc-netstat.in lxc/src/lxc/lxc-netstat.in ---- lxc.orig/src/lxc/lxc-netstat.in 2012-03-02 13:20:15.859239022 +0100 -+++ lxc/src/lxc/lxc-netstat.in 2012-03-09 12:41:35.354756455 +0100 -@@ -1,4 +1,4 @@ --#!/bin/bash -+#!/bin/sh - # set -ex - - usage() { -@@ -59,7 +59,7 @@ for i in "$cgroups"; do - cgroup_name=$(echo $i | awk ' { print $1 } ') - cgroup_path=$(echo $i | awk ' { print $3 } ') - -- if [ "$cgroup_name" == "lxc" ]; then -+ if [ "$cgroup_name" = "lxc" ]; then - break; - fi - -diff -Naurp lxc.orig/src/lxc/lxc-setcap.in lxc/src/lxc/lxc-setcap.in ---- lxc.orig/src/lxc/lxc-setcap.in 2012-03-02 13:20:15.863239028 +0100 -+++ lxc/src/lxc/lxc-setcap.in 2012-03-09 12:41:35.354756455 +0100 -@@ -1,4 +1,4 @@ --#!/bin/bash -+#!/bin/sh - - # - # lxc: linux Container library -diff -Naurp lxc.orig/src/lxc/lxc-setuid.in lxc/src/lxc/lxc-setuid.in ---- lxc.orig/src/lxc/lxc-setuid.in 2012-03-02 13:20:15.863239028 +0100 -+++ lxc/src/lxc/lxc-setuid.in 2012-03-09 12:41:35.354756455 +0100 -@@ -1,4 +1,4 @@ --#!/bin/bash -+#!/bin/sh - - # - # lxc: linux Container library -diff -Naurp lxc.orig/src/lxc/lxc-version.in lxc/src/lxc/lxc-version.in ---- lxc.orig/src/lxc/lxc-version.in 2011-10-25 14:02:11.000000000 +0200 -+++ lxc/src/lxc/lxc-version.in 2012-03-09 12:41:35.354756455 +0100 -@@ -1,3 +1,3 @@ --#!/bin/bash -+#!/bin/sh - - echo "lxc version: @PACKAGE_VERSION@" diff -Nru lxc-0.8.0~rc1/debian/patches/07-lxc-netstat.patch lxc-1.0.0~alpha1/debian/patches/07-lxc-netstat.patch --- lxc-0.8.0~rc1/debian/patches/07-lxc-netstat.patch 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/07-lxc-netstat.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,74 +0,0 @@ -Author: Daniel Baumann -Description: - Allow to use -- as seperator in lxc-netstat, otherwise -n from - lxc-netstat collides with netstats -n option (Closes: #641251). - -diff -Naurp lxc.orig/src/lxc/lxc-netstat.in lxc/src/lxc/lxc-netstat.in ---- lxc.orig/src/lxc/lxc-netstat.in 2011-12-15 12:01:30.450940512 +0100 -+++ lxc/src/lxc/lxc-netstat.in 2011-12-15 12:12:26.890189809 +0100 -@@ -2,7 +2,7 @@ - # set -ex - - usage() { -- echo "usage: $(basename $0) --name [netstat options]" -+ echo "usage: $(basename $0) -n|--name -- [netstat_options]" - } - - help() { -@@ -18,22 +18,43 @@ help() { - echo "to be executed as root." - } - --exec="" -+shortoptions='hn:' -+longoptions='help,name:,exec:' - --if [ $# -eq 0 ]; then -- usage -- exit 1 -+getopt=$(getopt -o $shortoptions --longoptions $longoptions -- "$@") -+if [ $? != 0 ]; then -+ usage -+ exit 1; - fi - --for i in "$@"; do -- case $i in -- -h|--help) -- help; exit 1;; -- -n|--name) -- name=$2; shift 2;; -- --exec) -- exec="exec"; shift;; -- esac -+exec="" -+ -+eval set -- "$getopt" -+ -+while true; do -+ case "$1" in -+ -h|--help) -+ help -+ exit 1 -+ ;; -+ -n|--name) -+ shift -+ lxc_name=$1 -+ shift -+ ;; -+ --exec) -+ shift -+ exec="exec" -+ ;; -+ --) -+ shift -+ break;; -+ *) -+ echo $1 -+ usage -+ exit 1 -+ ;; -+ esac - done - - if [ -z "$exec" ]; then diff -Nru lxc-0.8.0~rc1/debian/patches/08-lxc-debconf.patch lxc-1.0.0~alpha1/debian/patches/08-lxc-debconf.patch --- lxc-0.8.0~rc1/debian/patches/08-lxc-debconf.patch 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/08-lxc-debconf.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,15 +0,0 @@ -Author: Daniel Baumann -Description: Don't list vendor specific example template. - -diff -Naurp lxc/src/lxc/lxc-create.in lxc.orig/src/lxc/lxc-create.in ---- lxc/src/lxc/lxc-create.in 2012-03-09 13:21:01.354510931 +0100 -+++ lxc.orig/src/lxc/lxc-create.in 2012-03-09 13:20:39.210396083 +0100 -@@ -52,7 +52,7 @@ help() { - echo - if [ -z $lxc_template ]; then - echo "for template-specific help, specify a template, for instance:" -- echo "lxc-create -t ubuntu -h" -+ echo "lxc-create -t debconf -h" - exit 0 - fi - type ${templatedir}/lxc-$lxc_template >/dev/null diff -Nru lxc-0.8.0~rc1/debian/patches/09-lxc-create-trap-name.patch lxc-1.0.0~alpha1/debian/patches/09-lxc-create-trap-name.patch --- lxc-0.8.0~rc1/debian/patches/09-lxc-create-trap-name.patch 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/09-lxc-create-trap-name.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,16 +0,0 @@ -Author: Daniel Baumann -Description: - Adding patch to correct signal names in lxc-create trap (Closes: #655173). - -diff -Naurp lxc.orig/src/lxc/lxc-create.in lxc/src/lxc/lxc-create.in ---- lxc.orig/src/lxc/lxc-create.in 2012-03-09 12:56:37.247241547 +0100 -+++ lxc/src/lxc/lxc-create.in 2012-03-09 12:58:41.571862228 +0100 -@@ -234,7 +234,7 @@ cleanup() { - exit 1 - } - --trap cleanup SIGHUP SIGINT SIGTERM -+trap cleanup HUP INT TERM - - mkdir -p $lxc_path/$lxc_name - diff -Nru lxc-0.8.0~rc1/debian/patches/10-lxc-clone-trap-name.patch lxc-1.0.0~alpha1/debian/patches/10-lxc-clone-trap-name.patch --- lxc-0.8.0~rc1/debian/patches/10-lxc-clone-trap-name.patch 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/10-lxc-clone-trap-name.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,16 +0,0 @@ -Author: Daniel Baumann -Description: - Adding patch to correct signal names in lxc-clone trap. - -diff -Naurp lxc.orig/src/lxc/lxc-clone.in lxc/src/lxc/lxc-clone.in ---- lxc.orig/src/lxc/lxc-clone.in 2012-03-09 12:51:26.729705970 +0100 -+++ lxc/src/lxc/lxc-clone.in 2012-03-09 13:02:43.913060803 +0100 -@@ -169,7 +169,7 @@ cleanup() { - echo aborted - exit 1 - } --trap cleanup SIGHUP SIGINT SIGTERM -+trap cleanup HUP INT TERM - - mkdir -p $lxc_path/$lxc_new - hostname=$lxc_new diff -Nru lxc-0.8.0~rc1/debian/patches/11-lxc-console-escape.patch lxc-1.0.0~alpha1/debian/patches/11-lxc-console-escape.patch --- lxc-0.8.0~rc1/debian/patches/11-lxc-console-escape.patch 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/11-lxc-console-escape.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -Author: Ivan Vilata i Balaguer -Description: Allow escape prefix to escape itself (Closes: #659011). - -diff -Naurp lxc.orig/src/lxc/lxc_console.c lxc/src/lxc/lxc_console.c ---- lxc.orig/src/lxc/lxc_console.c 2012-02-04 01:15:47.427960171 +0100 -+++ lxc/src/lxc/lxc_console.c 2012-02-07 13:39:41.186587873 +0100 -@@ -144,7 +144,7 @@ static int stdin_handler(int fd, void *d - } - - /* we want to exit the console with Ctrl+a q */ -- if (c == my_args.escape) { -+ if (c == my_args.escape && !wait4q) { - wait4q = !wait4q; - return 0; - } -@@ -202,7 +202,9 @@ int main(int argc, char *argv[]) - if (err) - goto out; - -- fprintf(stderr, "\nType to exit the console\n", -+ fprintf(stderr, "\n\ -+Type to exit the console, \ -+ to enter Ctrl+%1$c itself\n", - 'a' + my_args.escape - 1); - - err = setsid(); diff -Nru lxc-0.8.0~rc1/debian/patches/12-lxc-create-rootfs.patch lxc-1.0.0~alpha1/debian/patches/12-lxc-create-rootfs.patch --- lxc-0.8.0~rc1/debian/patches/12-lxc-create-rootfs.patch 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/12-lxc-create-rootfs.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,19 +0,0 @@ -Author: Daniel Baumann -Description: - Only create rootfs directory where required. In general, lxc-create - should not mess with this and leave it entirely up to the templates - to create it. - -diff -Naurp lxc.orig/src/lxc/lxc-create.in lxc/src/lxc/lxc-create.in ---- lxc.orig/src/lxc/lxc-create.in 2012-03-15 16:58:33.069832600 +0100 -+++ lxc/src/lxc/lxc-create.in 2012-04-10 15:31:32.575773434 +0200 -@@ -255,8 +255,8 @@ else - fi - - # Create the fs as needed --[ -d "$rootfs" ] || mkdir $rootfs - if [ $backingstore = "lvm" ]; then -+ [ -d "$rootfs" ] || mkdir $rootfs - lvcreate -L $fssize -n $lvname $vgname || exit 1 - udevadm settle - mkfs -t $fstype $rootdev || exit 1 diff -Nru lxc-0.8.0~rc1/debian/patches/compilecleanups/0001-replace-HOOK-define-with-proper-code.patch lxc-1.0.0~alpha1/debian/patches/compilecleanups/0001-replace-HOOK-define-with-proper-code.patch --- lxc-0.8.0~rc1/debian/patches/compilecleanups/0001-replace-HOOK-define-with-proper-code.patch 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/compilecleanups/0001-replace-HOOK-define-with-proper-code.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,85 +0,0 @@ -From c7e82333008330ae9edceac6b37676f3b79c8766 Mon Sep 17 00:00:00 2001 -From: Serge Hallyn -Date: Tue, 4 Sep 2012 13:57:39 -0500 -Subject: [PATCH 1/4] replace HOOK define with proper code. - -Signed-off-by: Serge Hallyn ---- - src/lxc/conf.c | 11 +++++++++-- - src/lxc/conf.h | 6 ------ - src/lxc/start.c | 15 +++++++++++---- - 3 files changed, 20 insertions(+), 12 deletions(-) - -Index: lxc/src/lxc/conf.c -=================================================================== ---- lxc.orig/src/lxc/conf.c 2012-09-04 14:53:59.000000000 -0500 -+++ lxc/src/lxc/conf.c 2012-09-04 15:08:16.372453068 -0500 -@@ -2192,7 +2192,10 @@ - ERROR("failed to setup the cgroups for '%s'", name); - return -1; - } -- HOOK(name, "mount", lxc_conf); -+ if (run_lxc_hooks(name, "mount", lxc_conf)) { -+ ERROR("failed to run mount hooks for container '%s'.", name); -+ return -1; -+ } - - if (setup_console(&lxc_conf->rootfs, &lxc_conf->console, lxc_conf->ttydir)) { - ERROR("failed to setup the console for '%s'", name); -Index: lxc/src/lxc/conf.h -=================================================================== ---- lxc.orig/src/lxc/conf.h 2012-09-04 14:53:59.000000000 -0500 -+++ lxc/src/lxc/conf.h 2012-09-04 14:57:15.180477191 -0500 -@@ -230,11 +230,6 @@ - }; - - int run_lxc_hooks(const char *name, char *hook, struct lxc_conf *conf); --#define HOOK(name, which, conf) \ -- do { \ -- int hookret = run_lxc_hooks(name, which, conf); \ -- if (hookret) return -1; \ -- } while (0); - - /* - * Initialize the lxc configuration structure -Index: lxc/src/lxc/start.c -=================================================================== ---- lxc.orig/src/lxc/start.c 2012-09-04 14:53:59.000000000 -0500 -+++ lxc/src/lxc/start.c 2012-09-04 14:56:24.304479050 -0500 -@@ -366,7 +366,10 @@ - goto out_free_name; - } - -- HOOK(name, "pre-start", conf); -+ if (run_lxc_hooks(name, "pre-start", conf)) { -+ ERROR("failed to run pre-start hooks for container '%s'.", name); -+ goto out_aborting; -+ } - - if (lxc_create_tty(name, conf)) { - ERROR("failed to create the ttys"); -@@ -412,7 +415,8 @@ - lxc_set_state(name, handler, STOPPING); - lxc_set_state(name, handler, STOPPED); - -- HOOK(name, "post-stop", handler->conf); -+ if (run_lxc_hooks(name, "post-stop", handler->conf)) -+ ERROR("failed to run post-stop hooks for container '%s'.", name); - - /* reset mask set by setup_signal_fd */ - if (sigprocmask(SIG_SETMASK, &handler->oldmask, NULL)) -@@ -596,9 +600,12 @@ - if (lxc_seccomp_load(handler->conf) != 0) - goto out_warn_father; - -- close(handler->sigfd); -+ if (run_lxc_hooks(handler->name, "start", handler->conf)) { -+ ERROR("failed to run start hooks for container '%s'.", handler->name); -+ goto out_warn_father; -+ } - -- HOOK(handler->name, "start", handler->conf); -+ close(handler->sigfd); - - /* after this call, we are in error because this - * ops should not return as it execs */ diff -Nru lxc-0.8.0~rc1/debian/patches/compilecleanups/0002-add-prototype-for-clone-2-as-per-manpage.patch lxc-1.0.0~alpha1/debian/patches/compilecleanups/0002-add-prototype-for-clone-2-as-per-manpage.patch --- lxc-0.8.0~rc1/debian/patches/compilecleanups/0002-add-prototype-for-clone-2-as-per-manpage.patch 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/compilecleanups/0002-add-prototype-for-clone-2-as-per-manpage.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,28 +0,0 @@ -From 8c9bd229bdc0dc8b3643d5ab0ee2ae04cd8e64bd Mon Sep 17 00:00:00 2001 -From: Serge Hallyn -Date: Tue, 4 Sep 2012 14:06:29 -0500 -Subject: [PATCH 2/4] add prototype for clone(2) as per manpage - -Signed-off-by: Serge Hallyn ---- - src/lxc/namespace.h | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/src/lxc/namespace.h b/src/lxc/namespace.h -index 04e81bb..715dffa 100644 ---- a/src/lxc/namespace.h -+++ b/src/lxc/namespace.h -@@ -47,6 +47,10 @@ - #ifndef CLONE_NEWNET - # define CLONE_NEWNET 0x40000000 - #endif -+int clone(int (*fn)(void *), void *child_stack, -+ int flags, void *arg, ... -+ /* pid_t *ptid, struct user_desc *tls, pid_t *ctid */ ); -+ - - extern pid_t lxc_clone(int (*fn)(void *), void *arg, int flags); - --- -1.7.10.4 - diff -Nru lxc-0.8.0~rc1/debian/patches/compilecleanups/0003-check-chdir-return-value.patch lxc-1.0.0~alpha1/debian/patches/compilecleanups/0003-check-chdir-return-value.patch --- lxc-0.8.0~rc1/debian/patches/compilecleanups/0003-check-chdir-return-value.patch 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/compilecleanups/0003-check-chdir-return-value.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ -From 9c56dfa4ed80933eb8779d1161f6ebf2f33cb7d5 Mon Sep 17 00:00:00 2001 -From: Serge Hallyn -Date: Tue, 4 Sep 2012 14:10:40 -0500 -Subject: [PATCH 3/4] check chdir(/) return value - -Signed-off-by: Serge Hallyn ---- - src/lxc/lxccontainer.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c -index e88460b..840679b 100644 ---- a/src/lxc/lxccontainer.c -+++ b/src/lxc/lxccontainer.c -@@ -320,7 +320,10 @@ static bool lxcapi_start(struct lxc_container *c, int useinit, char ** argv) - if (pid != 0) - return wait_on_daemonized_start(c); - /* like daemon(), chdir to / and redirect 0,1,2 to /dev/null */ -- chdir("/"); -+ if (chdir("/")) { -+ SYSERROR("Error chdir()ing to /."); -+ return false; -+ } - close(0); - close(1); - close(2); --- -1.7.10.4 - diff -Nru lxc-0.8.0~rc1/debian/patches/compilecleanups/0004-Fix-passing-non-const-char-in-for-const-char.patch lxc-1.0.0~alpha1/debian/patches/compilecleanups/0004-Fix-passing-non-const-char-in-for-const-char.patch --- lxc-0.8.0~rc1/debian/patches/compilecleanups/0004-Fix-passing-non-const-char-in-for-const-char.patch 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/compilecleanups/0004-Fix-passing-non-const-char-in-for-const-char.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,77 +0,0 @@ -From 98f9a6f40d02ac4c3cd51c3aadcefa2f943d92bb Mon Sep 17 00:00:00 2001 -From: Serge Hallyn -Date: Tue, 4 Sep 2012 14:18:03 -0500 -Subject: [PATCH 4/4] Fix passing non-const char* in for const char* - -Signed-off-by: Serge Hallyn ---- - src/lxc/lxc.h | 2 +- - src/lxc/lxc_wait.c | 2 +- - src/lxc/lxccontainer.c | 2 +- - src/lxc/lxccontainer.h | 2 +- - src/tests/containertests.c | 2 +- - 5 files changed, 5 insertions(+), 5 deletions(-) - -Index: lxc/src/lxc/lxc.h -=================================================================== ---- lxc.orig/src/lxc/lxc.h 2012-09-04 14:53:59.855772000 -0500 -+++ lxc/src/lxc/lxc.h 2012-09-04 14:57:56.172475697 -0500 -@@ -201,7 +201,7 @@ - * Get a list of valid wait states. - * If states is NULL, simply return the number of states - */ --extern int lxc_get_wait_states(char **states); -+extern int lxc_get_wait_states(const char **states); - - #ifdef __cplusplus - } -Index: lxc/src/lxc/lxc_wait.c -=================================================================== ---- lxc.orig/src/lxc/lxc_wait.c 2012-09-04 14:53:59.855772000 -0500 -+++ lxc/src/lxc/lxc_wait.c 2012-09-04 14:57:56.176475696 -0500 -@@ -96,5 +96,5 @@ - my_args.progname, my_args.quiet)) - return -1; - -- return lxc_wait(my_args.name, my_args.states, my_args.timeout); -+ return lxc_wait(strdup(my_args.name), my_args.states, my_args.timeout); - } -Index: lxc/src/lxc/lxccontainer.c -=================================================================== ---- lxc.orig/src/lxc/lxccontainer.c 2012-09-04 14:57:55.320475729 -0500 -+++ lxc/src/lxc/lxccontainer.c 2012-09-04 14:57:56.176475696 -0500 -@@ -906,7 +906,7 @@ - return NULL; - } - --int lxc_get_wait_states(char **states) -+int lxc_get_wait_states(const char **states) - { - int i; - -Index: lxc/src/lxc/lxccontainer.h -=================================================================== ---- lxc.orig/src/lxc/lxccontainer.h 2012-09-04 14:53:59.855772000 -0500 -+++ lxc/src/lxc/lxccontainer.h 2012-09-04 14:57:56.176475696 -0500 -@@ -63,7 +63,7 @@ - struct lxc_container *lxc_container_new(char *name); - int lxc_container_get(struct lxc_container *c); - int lxc_container_put(struct lxc_container *c); --int lxc_get_wait_states(char **states); -+int lxc_get_wait_states(const char **states); - - #if 0 - char ** lxc_get_valid_keys(); -Index: lxc/src/tests/containertests.c -=================================================================== ---- lxc.orig/src/tests/containertests.c 2012-09-04 14:53:59.855772000 -0500 -+++ lxc/src/tests/containertests.c 2012-09-04 14:57:56.176475696 -0500 -@@ -210,7 +210,7 @@ - fprintf(stderr, "%d: lxc_get_wait_states gave %d not %d\n", __LINE__, numstates, MAX_STATE); - goto out; - } -- char **sstr = malloc(numstates * sizeof(char *)); -+ const char **sstr = malloc(numstates * sizeof(const char *)); - numstates = lxc_get_wait_states(sstr); - int i; - for (i=0; ielem; - struct lxc_list *it2; diff -Nru lxc-0.8.0~rc1/debian/patches/compilecleanups/0006-unused-var lxc-1.0.0~alpha1/debian/patches/compilecleanups/0006-unused-var --- lxc-0.8.0~rc1/debian/patches/compilecleanups/0006-unused-var 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/compilecleanups/0006-unused-var 1970-01-01 00:00:00.000000000 +0000 @@ -1,48 +0,0 @@ -Index: lxc/src/lxc/confile.c -=================================================================== ---- lxc.orig/src/lxc/confile.c 2012-09-04 15:16:36.960434802 -0500 -+++ lxc/src/lxc/confile.c 2012-09-04 15:16:54.040434179 -0500 -@@ -1386,7 +1386,7 @@ - static int lxc_get_item_nic(struct lxc_conf *c, char *retv, int inlen, char *key) - { - char *p1; -- int i, len, fulllen = 0; -+ int len, fulllen = 0; - struct lxc_netdev *netdev; - - if (!retv) -Index: lxc/src/lxc/lxc_wait.c -=================================================================== ---- lxc.orig/src/lxc/lxc_wait.c 2012-09-04 15:08:21.252452889 -0500 -+++ lxc/src/lxc/lxc_wait.c 2012-09-04 15:19:07.028429327 -0500 -@@ -78,17 +78,8 @@ - .timeout = -1, - }; - --static void timeout_handler(int signal) --{ -- exit(-1); --} -- - int main(int argc, char *argv[]) - { -- struct lxc_msg msg; -- int s[MAX_STATE] = { }, fd; -- int state, ret; -- - if (lxc_arguments_parse(&my_args, argc, argv)) - return -1; - -Index: lxc/src/tests/getkeys.c -=================================================================== ---- lxc.orig/src/tests/getkeys.c 2012-09-04 14:53:59.855772000 -0500 -+++ lxc/src/tests/getkeys.c 2012-09-04 15:19:37.192428226 -0500 -@@ -33,7 +33,7 @@ - { - struct lxc_container *c; - int len, ret; -- char v1[2], v2[256], v3[2048]; -+ char v3[2048]; - - if ((c = lxc_container_new(MYNAME)) == NULL) { - fprintf(stderr, "%d: error opening lxc_container %s\n", __LINE__, MYNAME); diff -Nru lxc-0.8.0~rc1/debian/patches/compilecleanups/0007-tests-check-return-values lxc-1.0.0~alpha1/debian/patches/compilecleanups/0007-tests-check-return-values --- lxc-0.8.0~rc1/debian/patches/compilecleanups/0007-tests-check-return-values 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/compilecleanups/0007-tests-check-return-values 1970-01-01 00:00:00.000000000 +0000 @@ -1,80 +0,0 @@ -Index: lxc/src/tests/containertests.c -=================================================================== ---- lxc.orig/src/tests/containertests.c 2012-09-04 15:08:21.252452889 -0500 -+++ lxc/src/tests/containertests.c 2012-09-04 15:22:19.260422311 -0500 -@@ -220,7 +220,9 @@ - - printf("hit return to start container"); - char mychar; -- scanf("%c", &mychar); -+ ret = scanf("%c", &mychar); -+ if (!ret) -+ goto out; - - /* non-daemonized is tested in 'startone' */ - c->want_daemonize(c); -@@ -242,7 +244,9 @@ - } - - printf("hit return to finish"); -- scanf("%c", &mychar); -+ ret = scanf("%c", &mychar); -+ if (!ret) -+ goto out; - - fprintf(stderr, "all lxc_container tests passed for %s\n", c->name); - ret = 0; -Index: lxc/src/tests/startone.c -=================================================================== ---- lxc.orig/src/tests/startone.c 2012-09-04 14:53:59.855772000 -0500 -+++ lxc/src/tests/startone.c 2012-09-04 15:24:48.676416859 -0500 -@@ -144,7 +144,8 @@ - - printf("hit return to start container"); - char mychar; -- scanf("%c", &mychar); -+ if (!scanf("%c", &mychar)) -+ goto out; - - if (!lxc_container_get(c)) { - fprintf(stderr, "%d: failed to get extra ref to container\n", __LINE__); -@@ -171,17 +172,30 @@ - } - - printf("hit return to finish"); -- scanf("%c", &mychar); -+ if (scanf("%c", &mychar)) -+ goto out; - c->stop(c); - -- system("mkdir -p /var/lib/lxc/lxctest1/rootfs//usr/local/libexec/lxc"); -- system("mkdir -p /var/lib/lxc/lxctest1/rootfs/usr/lib/lxc/"); -- system("cp src/lxc/lxc-init /var/lib/lxc/lxctest1/rootfs//usr/local/libexec/lxc"); -- system("cp src/lxc/liblxc.so /var/lib/lxc/lxctest1/rootfs/usr/lib/lxc"); -- system("cp src/lxc/liblxc.so /var/lib/lxc/lxctest1/rootfs/usr/lib/lxc/liblxc.so.0"); -- system("cp src/lxc/liblxc.so /var/lib/lxc/lxctest1/rootfs/usr/lib"); -- system("mkdir -p /var/lib/lxc/lxctest1/rootfs/dev/shm"); -- system("chroot /var/lib/lxc/lxctest1/rootfs apt-get install --no-install-recommends lxc"); -+ ret = system("mkdir -p /var/lib/lxc/lxctest1/rootfs//usr/local/libexec/lxc"); -+ if (ret != -1) -+ ret = system("mkdir -p /var/lib/lxc/lxctest1/rootfs/usr/lib/lxc/"); -+ if (ret != -1) -+ ret = system("cp src/lxc/lxc-init /var/lib/lxc/lxctest1/rootfs//usr/local/libexec/lxc"); -+ if (ret != -1) -+ ret = system("cp src/lxc/liblxc.so /var/lib/lxc/lxctest1/rootfs/usr/lib/lxc"); -+ if (ret != -1) -+ ret = system("cp src/lxc/liblxc.so /var/lib/lxc/lxctest1/rootfs/usr/lib/lxc/liblxc.so.0"); -+ if (ret != -1) -+ ret = system("cp src/lxc/liblxc.so /var/lib/lxc/lxctest1/rootfs/usr/lib"); -+ if (ret != -1) -+ ret = system("mkdir -p /var/lib/lxc/lxctest1/rootfs/dev/shm"); -+ if (ret != -1) -+ ret = system("chroot /var/lib/lxc/lxctest1/rootfs apt-get install --no-install-recommends lxc"); -+ if (ret == -1) { -+ fprintf(stderr, "%d: failed to install lxc-init in container", __LINE__); -+ goto out; -+ } -+ - // next write out the config file; does it match? - if (!c->startl(c, 1, "/bin/hostname", NULL)) { - fprintf(stderr, "%d: failed to lxc-execute /bin/hostname", __LINE__); diff -Nru lxc-0.8.0~rc1/debian/patches/series lxc-1.0.0~alpha1/debian/patches/series --- lxc-0.8.0~rc1/debian/patches/series 2013-01-08 16:25:33.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/series 2013-10-25 20:44:24.000000000 +0000 @@ -1,110 +1,15 @@ -01-lxc-directories.patch -02-lxc-distclean.patch -03-lxc-configuration-path.patch -04-lxc-create-template-name.patch -05-doc-ip-address.patch -#06-bash.patch -07-lxc-netstat.patch -08-lxc-debconf.patch -09-lxc-create-trap-name.patch -10-lxc-clone-trap-name.patch -11-lxc-console-escape.patch -12-lxc-create-rootfs.patch -0013-lxc-create-use-default-config.patch -0030-ubuntu-template-fail.patch -0031-ubuntu-template-resolvconf.patch -0044-lxc-destroy-rm-autos -0045-fix-other-templates -0046-lxc-clone-change-hwaddr -0047-bindhome-check-shell -0049-ubuntu-template-sudo-and-cleanup -0050-clone-lvm-sizes -0052-ubuntu-bind-user-conflict -0053-lxc-start-pin-rootfs -0054-ubuntu-debug -0055-ubuntu-handle-badgrp -0056-dont-watch-utmp -0057-update-manpages -0058-fixup-ubuntu-cloud -0059-reenable-daily-cloudimg -0060-lxc-shutdown -0061-lxc-start-apparmor -0062-templates-relative-paths -0063-check-apparmor-enabled -0064-apparmor-mount-proc -0065-fix-bindhome-relpath -0066-confile-typo -0067-templates-lxc-profile -0068-fix-lxc-config-layout -0069-ubuntu-cloud-fix -0070-templates-rmdir-dev-shm -0071-ubuntu-cloud-fix-image-extraction -0072-lxc-shutdown-help -0073-lxc-destroy-waits-before-destroy -0074-lxc-execute-find-init -#0075-lxc-ls-bash -0076-fix-sprintfs -0077-execute-without-rootfs -0078-lxc-clone-quote-line -0079-quantal-support -0080-drop-maverick -0081-fix-multiarch-install -0082-umount-old-proc -0083-ubuntu-simplify-template -0084-lxc-ubuntu-drop-duplicate-code.patch -0085-pivot-dir -0086-lxc-unshare-zero-args -0087-lxc-ls-dash -0088-ubuntu-template-flock -0089-lxc-netstat-exec -0090-lxc-ubuntu-use-dpkg-add-architecture -0091-introduce-container-hooks.patch -0092-clone-no-dhclient.conf-update-when-not-hardcoded -0093-lxc-clone-copy-fstab -0094-fix-dev-shm-check -0095-lxc-clone-change-uuid-on-xfs.patch -0096-lxc-wait-add-timeout.patch -0097-seccomp -0098-config-file-includes -0099-cleanup-after-template-help -0100-template-cleanup-cache -0101-template-empty-apt-cache -0102-lxc-start-d-check-privs -0103-make-rootfs-location-optional -0104-add-option-to-lxc-attach-to-select-ns -0105-lxc-attach-add-R-option -0200-liblxc -0201-fix-mkdir-race -0202-make-api-start-reliable -0203-python-lxc -0204-ubuntu-cloud-userdata-path -0205-lxc-ls-manpage-document-two-lines -0206-lxc-wait-initialize-timeout -compilecleanups/0001-replace-HOOK-define-with-proper-code.patch -compilecleanups/0002-add-prototype-for-clone-2-as-per-manpage.patch -compilecleanups/0003-check-chdir-return-value.patch -compilecleanups/0004-Fix-passing-non-const-char-in-for-const-char.patch -compilecleanups/0005-return-nonvoid -compilecleanups/0006-unused-var -compilecleanups/0007-tests-check-return-values -0207-ubuntu-cloud-fixes.patch -0208-fix-getitem-utsname-segv -0209-reload-conf-after-create -0210-fix-debian-templates -0211-add-hooks-to-manpage -0212-lxc-destroy-rm-symlink -0213-add-premount-hook.patch -0214-give-pclose-errno -0215-lxc-clone-name-arg -0216-hook-kmsg-to-console -0217-lxc-clone-fix-fstab -0218-api-shutdown-fix-doublestop -0219-python-module-improvements -0220-getitem-per-hook-type -0221-make-nonflush-upgrades-robust -0222-debian-dhcp3-package -0223-ubuntu-template-user-msg -0225-ubuntu-cloud-numeric-owner -0227-ubuntu-cloud-parsing -0228-ignore-kmsg-setup-failure -0229-lxc-clone-mount-fix +transition/00-redirect-lxc-list.patch +0000-add-autostart.patch +0001-debian-template-set-hwaddr +0002-pin_rootfs-be-quiet-and-don-t-fail-container-start.patch +0003-move-monitor-fifo-and-monitor-sock-to-run.patch +0004-hash-lxcname-for-use-in-monitor-unix-socket-sun_path.patch +0005-ignore-ability-to-init-lxc-monitord.log.patch +0006-add-pstore-to-container-fstab.patch +0007-apparmor.c-drop-newline-when-reading-current-profile.patch +0008-Fix-crasher-in-get_ips.patch +0009-lxc-ubuntu-cloud-pass-numeric-owner-and-p-to-untar.patch +0010-lxc-ubuntu-cloud-Cope-with-spaces-in-paths.patch +0011-ubuntu-cloud-prep-hook-fix-debug-helper-to-not-inapp.patch +0012-ubuntu-Improper-pty-permissions.patch +0013-get-rid-of-lxcpath_anon-idea.patch diff -Nru lxc-0.8.0~rc1/debian/patches/transition/00-redirect-lxc-list.patch lxc-1.0.0~alpha1/debian/patches/transition/00-redirect-lxc-list.patch --- lxc-0.8.0~rc1/debian/patches/transition/00-redirect-lxc-list.patch 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/patches/transition/00-redirect-lxc-list.patch 2013-10-07 21:32:53.000000000 +0000 @@ -0,0 +1,26 @@ +Description: Redirection for lxc-list + lxc-list will be deprecated in 1.0, this patch adds a warning when + lxc-ls is called as lxc-list (through the temporary symlink) and changes + the default rendering to list similar options. +Author: Stéphane Graber +Origin: vendor +Forwarded: not-needed + +Index: stgraber-lxc-git/src/lxc/lxc-ls +=================================================================== +--- stgraber-lxc-git.orig/src/lxc/lxc-ls 2013-05-27 14:37:35.988415931 -0400 ++++ stgraber-lxc-git/src/lxc/lxc-ls 2013-05-27 14:37:35.984415931 -0400 +@@ -143,6 +143,13 @@ + + args = parser.parse_args() + ++# lxc-list is an alias for --fancy ++if sys.argv[0].endswith("lxc-list"): ++ args.fancy = True ++ print("WARNING: lxc-list is deprecated, please use lxc-ls --fancy.") ++ print(" This symlink will be dropped in LXC 1.0.") ++ print("") ++ + # --active is the same as --running --frozen + if args.active: + if not args.state: diff -Nru lxc-0.8.0~rc1/debian/po/POTFILES.in lxc-1.0.0~alpha1/debian/po/POTFILES.in --- lxc-0.8.0~rc1/debian/po/POTFILES.in 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/po/POTFILES.in 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -[type: gettext/rfc822deb] lxc.templates diff -Nru lxc-0.8.0~rc1/debian/po/cs.po lxc-1.0.0~alpha1/debian/po/cs.po --- lxc-0.8.0~rc1/debian/po/cs.po 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/po/cs.po 1970-01-01 00:00:00.000000000 +0000 @@ -1,105 +0,0 @@ -# Czech translation of lxc debconf templates. -# Copyright (C) 2011 Michal Simunek -# This file is distributed under the same license as the lxc package. -# -msgid "" -msgstr "" -"Project-Id-Version: lxc 0.7.5-9\n" -"Report-Msgid-Bugs-To: lxc@packages.debian.org\n" -"POT-Creation-Date: 2012-02-09 13:08+0100\n" -"PO-Revision-Date: 2011-11-17 17:31+0100\n" -"Last-Translator: Michal Simunek \n" -"Language-Team: Czech \n" -"Language: cs\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#. Type: title -#. Description -#: ../lxc.templates:1001 -msgid "Linux Containers: LXC setup" -msgstr "Nastavení Linux Containers (LXC)" - -#. Type: boolean -#. Description -#: ../lxc.templates:2001 -msgid "Automatically start Linux Containers on boot?" -msgstr "Spouštět automaticky Linuxové kontejnery při zavádění systému?" - -#. Type: boolean -#. Description -#: ../lxc.templates:2001 -msgid "" -"Linux Containers that have their configuration files copied or symlinked to " -"the /etc/lxc/auto directory can be automatically started during system boot, " -"and shut down on reboot or halt." -msgstr "" -"Linuxové kontejnery, které mají své konfigurační soubory nakopírované, nebo " -"mají symbolické odkazy na adresář /etc/lxc/auto, lze automaticky spouštět " -"při zavádění systému a ukončovat při restartu či uspání." - -#. Type: boolean -#. Description -#: ../lxc.templates:2001 -msgid "If unsure, choose yes (default)." -msgstr "Nejste-li si jistí, zvolte ano (výchozí)." - -#. Type: select -#. Description -#: ../lxc.templates:3001 -#, fuzzy -#| msgid "Linux Container: Stop method" -msgid "Linux Container: Shutdown method" -msgstr "Linuxový kontejner: Způsob zastavení" - -#. Type: select -#. Description -#: ../lxc.templates:3001 -#, fuzzy -#| msgid "" -#| "Linux Containers can be stopped in different ways. The stop method kills " -#| "all processes inside the container. The halt method initiates a shutdown, " -#| "which takes longer and can have problems with containers that don't " -#| "shutdown themselves properly." -msgid "" -"Linux Containers can be shutdown in different ways. The stop method " -"terminates all processes inside the container. The halt method initiates a " -"shutdown, which takes longer and can have problems with containers that " -"don't shutdown themselves properly." -msgstr "" -"Linuxové kontejnery lze zastavit různými způsoby. Způsob stop zabije všechny " -"procesy uvnitř kontejneru. Způsob halt zinicializuje vypnutí, které trvá " -"delší dobu a může mít problémy s kontejnery, které se sami správně nevypnou." - -#. Type: select -#. Description -#: ../lxc.templates:3001 -msgid "" -"Unless you know that your containers don't shutdown properly, choose halt " -"(default)." -msgstr "" - -#. Type: string -#. Description -#: ../lxc.templates:4001 -msgid "LXC directory:" -msgstr "Adresář pro LXC:" - -#. Type: string -#. Description -#: ../lxc.templates:4001 -msgid "" -"Please specify the directory that will be used to store the Linux Containers." -msgstr "" -"Zadejte prosím adresář, který se bude používat k ukládání Linuxových " -"kontejnerů." - -#. Type: string -#. Description -#: ../lxc.templates:4001 -msgid "If unsure, use /var/lib/lxc (default)." -msgstr "Nejste-li si jistí, použijte /var/lib/lxc (výchozí)." - -#~ msgid "If unsure, choose stop (default)." -#~ msgstr "Nejste-li si jistí, zvolte stop (výchozí)." diff -Nru lxc-0.8.0~rc1/debian/po/da.po lxc-1.0.0~alpha1/debian/po/da.po --- lxc-0.8.0~rc1/debian/po/da.po 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/po/da.po 1970-01-01 00:00:00.000000000 +0000 @@ -1,96 +0,0 @@ -# Danish translation of lxc debconf templates. -# Copyright (C) 2011 Joe Hansen -# This file is distributed under the same license as the lxc package. -# -msgid "" -msgstr "" -"Project-Id-Version: lxc\n" -"Report-Msgid-Bugs-To: lxc@packages.debian.org\n" -"POT-Creation-Date: 2012-02-09 13:08+0100\n" -"PO-Revision-Date: 2011-10-23 17:30+01:00\n" -"Last-Translator: Joe Hansen \n" -"Language-Team: Danish \n" -"Language: da\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#. Type: title -#. Description -#: ../lxc.templates:1001 -#, fuzzy -#| msgid "Linux Containers (LXC) setup" -msgid "Linux Containers: LXC setup" -msgstr "Opsætning af Linuxcontainere (LXC)" - -#. Type: boolean -#. Description -#: ../lxc.templates:2001 -msgid "Automatically start Linux Containers on boot?" -msgstr "Igangsæt automatisk Linuxcontainere ved opstart?" - -#. Type: boolean -#. Description -#: ../lxc.templates:2001 -#, fuzzy -#| msgid "" -#| "Linux Containers can be automatically started during system boot and shut " -#| "down on reboot or halt." -msgid "" -"Linux Containers that have their configuration files copied or symlinked to " -"the /etc/lxc/auto directory can be automatically started during system boot, " -"and shut down on reboot or halt." -msgstr "" -"Linuxcontainere kan automatisk igangsættes ved systemopstart og lukke ned " -"ved genstart eller stop." - -#. Type: boolean -#. Description -#: ../lxc.templates:2001 -msgid "If unsure, choose yes (default)." -msgstr "" - -#. Type: select -#. Description -#: ../lxc.templates:3001 -#, fuzzy -#| msgid "Linux Containers (LXC) setup" -msgid "Linux Container: Shutdown method" -msgstr "Opsætning af Linuxcontainere (LXC)" - -#. Type: select -#. Description -#: ../lxc.templates:3001 -msgid "" -"Linux Containers can be shutdown in different ways. The stop method " -"terminates all processes inside the container. The halt method initiates a " -"shutdown, which takes longer and can have problems with containers that " -"don't shutdown themselves properly." -msgstr "" - -#. Type: select -#. Description -#: ../lxc.templates:3001 -msgid "" -"Unless you know that your containers don't shutdown properly, choose halt " -"(default)." -msgstr "" - -#. Type: string -#. Description -#: ../lxc.templates:4001 -msgid "LXC directory:" -msgstr "" - -#. Type: string -#. Description -#: ../lxc.templates:4001 -msgid "" -"Please specify the directory that will be used to store the Linux Containers." -msgstr "" - -#. Type: string -#. Description -#: ../lxc.templates:4001 -msgid "If unsure, use /var/lib/lxc (default)." -msgstr "" diff -Nru lxc-0.8.0~rc1/debian/po/de.po lxc-1.0.0~alpha1/debian/po/de.po --- lxc-0.8.0~rc1/debian/po/de.po 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/po/de.po 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -# German translation of lxc debconf templates. -# Copyright (C) 2011 Daniel Baumann -# This file is distributed under the same license as the lxc package. -# -msgid "" -msgstr "" -"Project-Id-Version: lxc 0.7.5-2\n" -"Report-Msgid-Bugs-To: lxc@packages.debian.org\n" -"POT-Creation-Date: 2012-02-09 13:08+0100\n" -"PO-Revision-Date: 2010-07-20 05:54+0200\n" -"Last-Translator: Daniel Baumann \n" -"Language-Team: none\n" -"Language: de\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#. Type: title -#. Description -#: ../lxc.templates:1001 -msgid "Linux Containers: LXC setup" -msgstr "Linux Containers: LXC setup" - -#. Type: boolean -#. Description -#: ../lxc.templates:2001 -msgid "Automatically start Linux Containers on boot?" -msgstr "Linux Container automatisch beim Hochfahren starten?" - -#. Type: boolean -#. Description -#: ../lxc.templates:2001 -msgid "" -"Linux Containers that have their configuration files copied or symlinked to " -"the /etc/lxc/auto directory can be automatically started during system boot, " -"and shut down on reboot or halt." -msgstr "" -"Linux Container welche ihre Konfigurationsdateien in das /etc/lxc/auto " -"Verzeichnis kopiert oder gelinkt haben, können während des Hochfahrens " -"automatisch gestartet und während des Herunterfahrens oder Neustarts " -"automatisch beendet werden." - -#. Type: boolean -#. Description -#: ../lxc.templates:2001 -msgid "If unsure, choose yes (default)." -msgstr "Wenn Sie unsicher sind, wählen sie ja (Standard)." - -#. Type: select -#. Description -#: ../lxc.templates:3001 -msgid "Linux Container: Shutdown method" -msgstr "Linux Container Shutdown Methode" - -#. Type: select -#. Description -#: ../lxc.templates:3001 -msgid "" -"Linux Containers can be shutdown in different ways. The stop method " -"terminates all processes inside the container. The halt method initiates a " -"shutdown, which takes longer and can have problems with containers that " -"don't shutdown themselves properly." -msgstr "" -"Linux Container können auf unterschiedliche Weise gestoppt werden. Die Stopp " -"Methode terminiert alle Prozesse innerhalb des Containers. Die Halt Methode " -"initiiert ein Herunterfahren welches länger dauert und Probleme bereiten " -"kann mit Container, die sich nicht selbst korrekt herunterfahren können." - -#. Type: select -#. Description -#: ../lxc.templates:3001 -msgid "" -"Unless you know that your containers don't shutdown properly, choose halt " -"(default)." -msgstr "" -"Sofern Sie nicht wissen dass Ihre Container nicht korrekt herunterfahren, " -"wählen Sie halt (Standard)." - -#. Type: string -#. Description -#: ../lxc.templates:4001 -msgid "LXC directory:" -msgstr "LXC Verzeichnis:" - -#. Type: string -#. Description -#: ../lxc.templates:4001 -msgid "" -"Please specify the directory that will be used to store the Linux Containers." -msgstr "" -"Bitte geben Sie das Verzeichnis an, welches für die Container verwendet " -"werden soll." - -#. Type: string -#. Description -#: ../lxc.templates:4001 -msgid "If unsure, use /var/lib/lxc (default)." -msgstr "Wenn Sie unsicher sind, benutzen sie /var/lib/lxc (Standard)." - -#~ msgid "If unsure, choose stop (default)." -#~ msgstr "Wenn Sie unsicher sind, wählen sie stop (Standard)." diff -Nru lxc-0.8.0~rc1/debian/po/es.po lxc-1.0.0~alpha1/debian/po/es.po --- lxc-0.8.0~rc1/debian/po/es.po 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/po/es.po 1970-01-01 00:00:00.000000000 +0000 @@ -1,97 +0,0 @@ -# lxc po-debconf translation to Spanish -# Copyright (C) 2011-2012 Camaleón -# This file is distributed under the same license as the lxc package. -# -msgid "" -msgstr "" -"Project-Id-Version: lxc 0.8.0~rc1-3\n" -"Report-Msgid-Bugs-To: lxc@packages.debian.org\n" -"POT-Creation-Date: 2012-02-09 13:08+0100\n" -"PO-Revision-Date: 2012-03-12 18:24+0100\n" -"Last-Translator: Camaleón \n" -"Language-Team: Debian Spanish \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit" - -#. Type: title -#. Description -#: ../lxc.templates:1001 -msgid "Linux Containers: LXC setup" -msgstr "Contenedores Linux: Configuración de LXC" - -#. Type: boolean -#. Description -#: ../lxc.templates:2001 -msgid "Automatically start Linux Containers on boot?" -msgstr "¿Desea iniciar los Contenedores Linux al arrancar?" - -#. Type: boolean -#. Description -#: ../lxc.templates:2001 -msgid "" -"Linux Containers that have their configuration files copied or symlinked to " -"the /etc/lxc/auto directory can be automatically started during system boot, " -"and shut down on reboot or halt." -msgstr "" -"Los Contenedores Linux cuyos archivos de configuración han sido copiados o " -"vinculados mediante un enlace simbólico en el directorio «/etc/lxc/auto» se " -"pueden iniciar automáticamente al arrancar el sistema y se pueden cerrar al " -"reiniciar o apagar el equipo." - -#. Type: boolean -#. Description -#: ../lxc.templates:2001 -msgid "If unsure, choose yes (default)." -msgstr "Si no está seguro, seleccione «sí» (opción predeterminada)." - -#. Type: select -#. Description -#: ../lxc.templates:3001 -#| msgid "Linux Container: Stop method" -msgid "Linux Container: Shutdown method" -msgstr "Contenedores Linux: Método de detención" - -#. Type: select -#. Description -#: ../lxc.templates:3001 -msgid "" -"Linux Containers can be shutdown in different ways. The stop method " -"terminates all processes inside the container. The halt method initiates a " -"shutdown, which takes longer and can have problems with containers that " -"don't shutdown themselfs properly." -msgstr "" -"Los Contenedores Linux se pueden detener de diferentes formas. El método " -"«detener» finaliza todos los procesos dentro del contenedor. El método " -"«interrumpir» inicia una secuencia de cierre que lleva más tiempo y puede " -"tener problemas con los contenedores que no se cierran correctamente por sí " -"mismos." - -#. Type: select -#. Description -#: ../lxc.templates:3001 -msgid "" -"Unless you know that your containers don't shutdown properly, choose halt " -"(default)." -msgstr "Seleccione «interrumpir» (opción predeterminada) excepto si sabe que sus contenedores no se van a cerrar correctamente." - -#. Type: string -#. Description -#: ../lxc.templates:4001 -msgid "LXC directory:" -msgstr "Directorio de LXC:" - -#. Type: string -#. Description -#: ../lxc.templates:4001 -msgid "" -"Please specify the directory that will be used to store the Linux Containers." -msgstr "" -"Por favor, especifique el directorio que se utilizará para almacenar los " -"Contenedores Linux." - -#. Type: string -#. Description -#: ../lxc.templates:4001 -msgid "If unsure, use /var/lib/lxc (default)." -msgstr "Si no está seguro, utilice «/var/lib/lxc» (opción predeterminada)." diff -Nru lxc-0.8.0~rc1/debian/po/fr.po lxc-1.0.0~alpha1/debian/po/fr.po --- lxc-0.8.0~rc1/debian/po/fr.po 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/po/fr.po 1970-01-01 00:00:00.000000000 +0000 @@ -1,102 +0,0 @@ -# French translation of lxc debconf templates. -# Copyright (C) 2011 Julien Patriarca -# Copyright (C) 2011-2012 Christian Perrier -# This file is distributed under the same license as the lxc package. -# -msgid "" -msgstr "" -"Project-Id-Version: lxc\n" -"Report-Msgid-Bugs-To: lxc@packages.debian.org\n" -"POT-Creation-Date: 2012-02-09 13:08+0100\n" -"PO-Revision-Date: 2012-03-12 07:52+0100\n" -"Last-Translator: Christian Perrier \n" -"Language-Team: French \n" -"Language: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n > 1);\n" - -#. Type: title -#. Description -#: ../lxc.templates:1001 -msgid "Linux Containers: LXC setup" -msgstr "Conteneurs Linux : configuration de LXC" - -#. Type: boolean -#. Description -#: ../lxc.templates:2001 -msgid "Automatically start Linux Containers on boot?" -msgstr "Lancer automatiquement les conteneurs Linux à l'amorçage du système ?" - -#. Type: boolean -#. Description -#: ../lxc.templates:2001 -msgid "" -"Linux Containers that have their configuration files copied or symlinked to " -"the /etc/lxc/auto directory can be automatically started during system boot, " -"and shut down on reboot or halt." -msgstr "" -"Les conteneurs Linux (« Linux Containers ») dont les fichiers de " -"configuration sont copiés ou liés dans /etc/lxc/auto peuvent être " -"automatiquement démarrés durant l'amorçage du système et éteints au moment " -"du redémarrage ou de l'arrêt." - -#. Type: boolean -#. Description -#: ../lxc.templates:2001 -msgid "If unsure, choose yes (default)." -msgstr "Dans le doute, vous pouvez choisir cette option." - -#. Type: select -#. Description -#: ../lxc.templates:3001 -msgid "Linux Container: Shutdown method" -msgstr "Conteneurs Linux : méthode d'arrêt" - -#. Type: select -#. Description -#: ../lxc.templates:3001 -msgid "" -"Linux Containers can be shutdown in different ways. The stop method " -"terminates all processes inside the container. The halt method initiates a " -"shutdown, which takes longer and can have problems with containers that " -"don't shutdown themselves properly." -msgstr "" -"Les conteneurs Linux peuvent être arrêtés de différents manières. La méthode " -"« stop » interrompt tous les processus au sein du conteneur. La méthode " -"« halt » initie une extinction, ce qui prend plus de temps et peut causer " -"des problèmes si les conteneurs ne s'arrêtent pas correctement." - -#. Type: select -#. Description -#: ../lxc.templates:3001 -msgid "" -"Unless you know that your containers don't shutdown properly, choose halt " -"(default)." -msgstr "" -"Il est conseillé de choisir la méthode « halt » sauf si les conteneurs ne " -"s'arrêtent pas correctement." - -#. Type: string -#. Description -#: ../lxc.templates:4001 -msgid "LXC directory:" -msgstr "Répertoire de LXC :" - -#. Type: string -#. Description -#: ../lxc.templates:4001 -msgid "" -"Please specify the directory that will be used to store the Linux Containers." -msgstr "" -"Veuillez indiquer le répertoire à utiliser pour stocker les conteneurs Linux." - -#. Type: string -#. Description -#: ../lxc.templates:4001 -msgid "If unsure, use /var/lib/lxc (default)." -msgstr "Il est recommandé de choisir /var/lib/lxc." - -#~ msgid "If unsure, choose stop (default)." -#~ msgstr "Dans le doute, la méthode « stop » est recommandée." diff -Nru lxc-0.8.0~rc1/debian/po/nl.po lxc-1.0.0~alpha1/debian/po/nl.po --- lxc-0.8.0~rc1/debian/po/nl.po 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/po/nl.po 1970-01-01 00:00:00.000000000 +0000 @@ -1,104 +0,0 @@ -# Dutch translation of lxc debconf templates. -# Copyright (C) 2012 Jeroen Schot -# This file is distributed under the same license as the lxc package. -# -msgid "" -msgstr "" -"Project-Id-Version: lxc 0.7.5-24\n" -"Report-Msgid-Bugs-To: lxc@packages.debian.org\n" -"POT-Creation-Date: 2012-02-09 13:08+0100\n" -"PO-Revision-Date: 2012-02-09 17:01+0100\n" -"Last-Translator: Jeroen Schot \n" -"Language-Team: Debian l10n Dutch \n" -"Language: nl\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#. Type: title -#. Description -#: ../lxc.templates:1001 -msgid "Linux Containers: LXC setup" -msgstr "Linux Containers: LXC-instellingen" - -#. Type: boolean -#. Description -#: ../lxc.templates:2001 -msgid "Automatically start Linux Containers on boot?" -msgstr "Linux Containers automatisch opstarten bij de systeemstart?" - -#. Type: boolean -#. Description -#: ../lxc.templates:2001 -msgid "" -"Linux Containers that have their configuration files copied or symlinked to " -"the /etc/lxc/auto directory can be automatically started during system boot, " -"and shut down on reboot or halt." -msgstr "" -"Linux Containers waarvan de configuratiebestanden zijn gekopieerd of " -"gekoppeld naar de map /etc/lxc/auto kunnen automatisch worden gestart bij de " -"systeemstart en afgesloten bij het herstarten of uitschakelen." - -#. Type: boolean -#. Description -#: ../lxc.templates:2001 -msgid "If unsure, choose yes (default)." -msgstr "Als u twijfelt, kies dan ja (standaard)." - -#. Type: select -#. Description -#: ../lxc.templates:3001 -#, fuzzy -#| msgid "Linux Container: Stop method" -msgid "Linux Container: Shutdown method" -msgstr "Linux Container: Stop-methode" - -#. Type: select -#. Description -#: ../lxc.templates:3001 -#, fuzzy -#| msgid "" -#| "Linux Containers can be stopped in different ways. The stop method kills " -#| "all processes inside the container. The halt method initiates a shutdown, " -#| "which takes longer and can have problems with containers that don't " -#| "shutdown themselves properly." -msgid "" -"Linux Containers can be shutdown in different ways. The stop method " -"terminates all processes inside the container. The halt method initiates a " -"shutdown, which takes longer and can have problems with containers that " -"don't shutdown themselves properly." -msgstr "" -"Linux Containers kunnen op verschillende manieren worden gestopt. De stop-" -"methode termineert alle processen in de container. De halt-methode doet " -"alsof het systeem wordt uitgeschakeld, dit duurt langer en kan problemen " -"geven met containers die zich niet netjes uitschakelen." - -#. Type: select -#. Description -#: ../lxc.templates:3001 -msgid "" -"Unless you know that your containers don't shutdown properly, choose halt " -"(default)." -msgstr "" - -#. Type: string -#. Description -#: ../lxc.templates:4001 -msgid "LXC directory:" -msgstr "LXC-map:" - -#. Type: string -#. Description -#: ../lxc.templates:4001 -msgid "" -"Please specify the directory that will be used to store the Linux Containers." -msgstr "In welke map moeten de Linux Containers worden bewaard?" - -#. Type: string -#. Description -#: ../lxc.templates:4001 -msgid "If unsure, use /var/lib/lxc (default)." -msgstr "Als u twijfelt, gebruik dan /var/lib/lxc (standaard)" - -#~ msgid "If unsure, choose stop (default)." -#~ msgstr "Als u twijfelt, kies dan stop (standaard)." diff -Nru lxc-0.8.0~rc1/debian/po/pt.po lxc-1.0.0~alpha1/debian/po/pt.po --- lxc-0.8.0~rc1/debian/po/pt.po 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/po/pt.po 1970-01-01 00:00:00.000000000 +0000 @@ -1,111 +0,0 @@ -# Portuguese translation of lxc debconf templates. -# Copyright (C) 2011 Miguel Figueiredo -# This file is distributed under the same license as the lxc package. -# -msgid "" -msgstr "" -"Project-Id-Version: lxc\n" -"Report-Msgid-Bugs-To: lxc@packages.debian.org\n" -"POT-Creation-Date: 2012-02-09 13:08+0100\n" -"PO-Revision-Date: 2011-11-08 21:40+0000\n" -"Last-Translator: Miguel Figueiredo \n" -"Language-Team: Portuguese \n" -"Language: Portuguese\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#. Type: title -#. Description -#: ../lxc.templates:1001 -#, fuzzy -#| msgid "Linux Containers (LXC) setup" -msgid "Linux Containers: LXC setup" -msgstr "Configuração de Linux Containers (LXC)" - -#. Type: boolean -#. Description -#: ../lxc.templates:2001 -msgid "Automatically start Linux Containers on boot?" -msgstr "Iniciar automaticamente Linux Containers no arranque?" - -#. Type: boolean -#. Description -#: ../lxc.templates:2001 -#, fuzzy -#| msgid "" -#| "Linux Containers can be automatically started during system boot and shut " -#| "down on reboot or halt." -msgid "" -"Linux Containers that have their configuration files copied or symlinked to " -"the /etc/lxc/auto directory can be automatically started during system boot, " -"and shut down on reboot or halt." -msgstr "" -"Os Linux Containers podem ser automaticamente iniciados durante o arranque " -"do sistema e parados durante ao reiniciar ou desligar." - -#. Type: boolean -#. Description -#: ../lxc.templates:2001 -msgid "If unsure, choose yes (default)." -msgstr "Em caso de dúvida, escolha sim (pré-definido)." - -#. Type: select -#. Description -#: ../lxc.templates:3001 -#, fuzzy -#| msgid "Linux Container: Stop method" -msgid "Linux Container: Shutdown method" -msgstr "Linux Container: Método de paragem" - -#. Type: select -#. Description -#: ../lxc.templates:3001 -#, fuzzy -#| msgid "" -#| "Linux Containers can be stopped in different ways. The stop method kills " -#| "all processes inside the container. The halt method initiates a shutdown, " -#| "which takes longer and can have problems with containers that don't " -#| "shutdown themselves properly." -msgid "" -"Linux Containers can be shutdown in different ways. The stop method " -"terminates all processes inside the container. The halt method initiates a " -"shutdown, which takes longer and can have problems with containers that " -"don't shutdown themselves properly." -msgstr "" -"Os Linux Containers podem ser parados de várias formas. O método stop mata " -"todos os processos dentro do container. O método halt inicia uma paragem, " -"que demora mais e pode ter problemas com containers que não se desligam a " -"eles próprios correctamente." - -#. Type: select -#. Description -#: ../lxc.templates:3001 -msgid "" -"Unless you know that your containers don't shutdown properly, choose halt " -"(default)." -msgstr "" - -#. Type: string -#. Description -#: ../lxc.templates:4001 -msgid "LXC directory:" -msgstr "Directório do LXC:" - -#. Type: string -#. Description -#: ../lxc.templates:4001 -msgid "" -"Please specify the directory that will be used to store the Linux Containers." -msgstr "" -"Por favor especique o directório que pode ser utilizado para guardar os " -"Linux Containers." - -#. Type: string -#. Description -#: ../lxc.templates:4001 -msgid "If unsure, use /var/lib/lxc (default)." -msgstr "Em caso de dúvida, utilize /var/lib/lxc (pré-definido)." - -#~ msgid "If unsure, choose stop (default)." -#~ msgstr "Em caso de dúvida, escolha stop (pré-definido)." diff -Nru lxc-0.8.0~rc1/debian/po/ru.po lxc-1.0.0~alpha1/debian/po/ru.po --- lxc-0.8.0~rc1/debian/po/ru.po 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/po/ru.po 1970-01-01 00:00:00.000000000 +0000 @@ -1,109 +0,0 @@ -# Russian translation of lxc debconf templates. -# Copyright (C) 2011-2012 Yuri Kozlov -# This file is distributed under the same license as the lxc package. -# -msgid "" -msgstr "" -"Project-Id-Version: lxc 0.8.0~rc1-3\n" -"Report-Msgid-Bugs-To: lxc@packages.debian.org\n" -"POT-Creation-Date: 2012-02-09 13:08+0100\n" -"PO-Revision-Date: 2012-03-23 18:58+0400\n" -"Last-Translator: Yuri Kozlov \n" -"Language-Team: Russian \n" -"Language: ru\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " -"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" - -#. Type: title -#. Description -#: ../lxc.templates:1001 -msgid "Linux Containers: LXC setup" -msgstr "Linux Containers: настройка LXC" - -#. Type: boolean -#. Description -#: ../lxc.templates:2001 -msgid "Automatically start Linux Containers on boot?" -msgstr "Запускать Linux Containers при загрузке автоматически?" - -#. Type: boolean -#. Description -#: ../lxc.templates:2001 -msgid "" -"Linux Containers that have their configuration files copied or symlinked to " -"the /etc/lxc/auto directory can be automatically started during system boot, " -"and shut down on reboot or halt." -msgstr "" -"Linux Containers, у которых файлы настройки скопированы из или являются " -"символьными ссылками на каталог /etc/lxc/auto, могут запускаться " -"автоматически при включении машины и выключаться при перезагрузке или " -"остановке." - -#. Type: boolean -#. Description -#: ../lxc.templates:2001 -msgid "If unsure, choose yes (default)." -msgstr "Если не уверены, ответьте утвердительно (по умолчанию)." - -#. Type: select -#. Description -#: ../lxc.templates:3001 -#| msgid "Linux Container: Stop method" -msgid "Linux Container: Shutdown method" -msgstr "Linux Container: метод выключения" - -#. Type: select -#. Description -#: ../lxc.templates:3001 -#| msgid "" -#| "Linux Containers can be stopped in different ways. The stop method kills " -#| "all processes inside the container. The halt method initiates a shutdown, " -#| "which takes longer and can have problems with containers that don't " -#| "shutdown themselfs properly." -msgid "" -"Linux Containers can be shutdown in different ways. The stop method " -"terminates all processes inside the container. The halt method initiates a " -"shutdown, which takes longer and can have problems with containers that " -"don't shutdown themselfs properly." -msgstr "" -"Работу Linux Containers можно выключать разными способами. Метод stop " -"завершает все процессы внутри контейнера. Метод halt запускает процесс " -"выключения, который выполняется дольше и может привести к проблеме с " -"контейнерами, которые не могут самостоятельно выключиться правильно." - -#. Type: select -#. Description -#: ../lxc.templates:3001 -msgid "" -"Unless you know that your containers don't shutdown properly, choose halt " -"(default)." -msgstr "" -"Если вы знаете, что ваши контейнеры не выключаются правильным образом, " -"выберите " -"остановку (halt, по умолчанию)." - -#. Type: string -#. Description -#: ../lxc.templates:4001 -msgid "LXC directory:" -msgstr "Каталог LXC:" - -#. Type: string -#. Description -#: ../lxc.templates:4001 -msgid "" -"Please specify the directory that will be used to store the Linux Containers." -msgstr "" -"Укажите каталог, который будет использован для хранения Linux Containers." - -#. Type: string -#. Description -#: ../lxc.templates:4001 -msgid "If unsure, use /var/lib/lxc (default)." -msgstr "Если не уверены, используйте /var/lib/lxc (по умолчанию)." - -#~ msgid "If unsure, choose stop (default)." -#~ msgstr "Если не уверены, выберите stop (по умолчанию)." diff -Nru lxc-0.8.0~rc1/debian/po/sv.po lxc-1.0.0~alpha1/debian/po/sv.po --- lxc-0.8.0~rc1/debian/po/sv.po 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/po/sv.po 1970-01-01 00:00:00.000000000 +0000 @@ -1,106 +0,0 @@ -# Swedish translation of lxc debconf templates. -# Copyright (C) 2011 Martin Bagge -# This file is distributed under the same license as the lxc package. -# -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: lxc@packages.debian.org\n" -"POT-Creation-Date: 2012-02-09 13:08+0100\n" -"PO-Revision-Date: 2011-12-06 21:02+0100\n" -"Last-Translator: Martin Bagge / brother \n" -"Language-Team: Swedish \n" -"Language: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Poedit-Language: Swedish\n" -"X-Poedit-Country: Sweden\n" - -#. Type: title -#. Description -#: ../lxc.templates:1001 -msgid "Linux Containers: LXC setup" -msgstr " Linux Containers: Inställningar för LXC" - -#. Type: boolean -#. Description -#: ../lxc.templates:2001 -msgid "Automatically start Linux Containers on boot?" -msgstr "Ska Linux Containers starta automatiskt vid systemets uppstart?" - -#. Type: boolean -#. Description -#: ../lxc.templates:2001 -msgid "" -"Linux Containers that have their configuration files copied or symlinked to " -"the /etc/lxc/auto directory can be automatically started during system boot, " -"and shut down on reboot or halt." -msgstr "" -"Linux Containers som har inställningsfilerna kopierade eller länkade till " -"katalogen /etc/lxc/auto kan automatiskt startas vid systemets uppstart eller " -"stängas av vid omstart eller nedstängning av systemet." - -#. Type: boolean -#. Description -#: ../lxc.templates:2001 -msgid "If unsure, choose yes (default)." -msgstr "Om du är osäker välj ja (standard)" - -#. Type: select -#. Description -#: ../lxc.templates:3001 -#, fuzzy -#| msgid "Linux Container: Stop method" -msgid "Linux Container: Shutdown method" -msgstr " Linux Container: Metdo för avstängning" - -#. Type: select -#. Description -#: ../lxc.templates:3001 -#, fuzzy -#| msgid "" -#| "Linux Containers can be stopped in different ways. The stop method kills " -#| "all processes inside the container. The halt method initiates a shutdown, " -#| "which takes longer and can have problems with containers that don't " -#| "shutdown themselves properly." -msgid "" -"Linux Containers can be shutdown in different ways. The stop method " -"terminates all processes inside the container. The halt method initiates a " -"shutdown, which takes longer and can have problems with containers that " -"don't shutdown themselves properly." -msgstr "" -"Linux Containers kan stängas av på olika sätt. Metoden avstäning kommer att " -"döda alla processer inuti containern. Halt-metoden påbörjar en nedstängning, " -"detta tar längre tid och kan innebära problem med containers som inte " -"stänger av sig korrekt själva." - -#. Type: select -#. Description -#: ../lxc.templates:3001 -msgid "" -"Unless you know that your containers don't shutdown properly, choose halt " -"(default)." -msgstr "" - -#. Type: string -#. Description -#: ../lxc.templates:4001 -msgid "LXC directory:" -msgstr "Katalog för LXC:" - -#. Type: string -#. Description -#: ../lxc.templates:4001 -msgid "" -"Please specify the directory that will be used to store the Linux Containers." -msgstr "Ange katalogen som ska användas för att lagra Linux Containers." - -#. Type: string -#. Description -#: ../lxc.templates:4001 -msgid "If unsure, use /var/lib/lxc (default)." -msgstr "Om du är osäker använd /var/lib/lxc (standard)." - -#~ msgid "If unsure, choose stop (default)." -#~ msgstr "Om du är osäker välj stopp (standard)" diff -Nru lxc-0.8.0~rc1/debian/po/templates.pot lxc-1.0.0~alpha1/debian/po/templates.pot --- lxc-0.8.0~rc1/debian/po/templates.pot 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/po/templates.pot 1970-01-01 00:00:00.000000000 +0000 @@ -1,88 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: lxc@packages.debian.org\n" -"POT-Creation-Date: 2012-02-09 13:08+0100\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"Language: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=CHARSET\n" -"Content-Transfer-Encoding: 8bit\n" - -#. Type: title -#. Description -#: ../lxc.templates:1001 -msgid "Linux Containers: LXC setup" -msgstr "" - -#. Type: boolean -#. Description -#: ../lxc.templates:2001 -msgid "Automatically start Linux Containers on boot?" -msgstr "" - -#. Type: boolean -#. Description -#: ../lxc.templates:2001 -msgid "" -"Linux Containers that have their configuration files copied or symlinked to " -"the /etc/lxc/auto directory can be automatically started during system boot, " -"and shut down on reboot or halt." -msgstr "" - -#. Type: boolean -#. Description -#: ../lxc.templates:2001 -msgid "If unsure, choose yes (default)." -msgstr "" - -#. Type: select -#. Description -#: ../lxc.templates:3001 -msgid "Linux Container: Shutdown method" -msgstr "" - -#. Type: select -#. Description -#: ../lxc.templates:3001 -msgid "" -"Linux Containers can be shutdown in different ways. The stop method " -"terminates all processes inside the container. The halt method initiates a " -"shutdown, which takes longer and can have problems with containers that " -"don't shutdown themselves properly." -msgstr "" - -#. Type: select -#. Description -#: ../lxc.templates:3001 -msgid "" -"Unless you know that your containers don't shutdown properly, choose halt " -"(default)." -msgstr "" - -#. Type: string -#. Description -#: ../lxc.templates:4001 -msgid "LXC directory:" -msgstr "" - -#. Type: string -#. Description -#: ../lxc.templates:4001 -msgid "" -"Please specify the directory that will be used to store the Linux Containers." -msgstr "" - -#. Type: string -#. Description -#: ../lxc.templates:4001 -msgid "If unsure, use /var/lib/lxc (default)." -msgstr "" diff -Nru lxc-0.8.0~rc1/debian/po/zh_CN.po lxc-1.0.0~alpha1/debian/po/zh_CN.po --- lxc-0.8.0~rc1/debian/po/zh_CN.po 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/po/zh_CN.po 1970-01-01 00:00:00.000000000 +0000 @@ -1,94 +0,0 @@ -# Chinese (simplified) translation of lxc debconf templates. -# Copyright (C) 2011 syq -# This file is distributed under the same license as the lxc package. -# -msgid "" -msgstr "" -"Project-Id-Version: lxc-deconf VERSION\n" -"Report-Msgid-Bugs-To: lxc@packages.debian.org\n" -"POT-Creation-Date: 2012-02-09 13:08+0100\n" -"PO-Revision-Date: 2011-11-07 16:15+0800\n" -"Last-Translator: YunQiang Su \n" -"Language-Team: Chinese (simplified)\n" -"Language: zh_CN\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#. Type: title -#. Description -#: ../lxc.templates:1001 -#, fuzzy -#| msgid "Linux Containers (LXC) setup" -msgid "Linux Containers: LXC setup" -msgstr "Linux Containers (LXC) 设置" - -#. Type: boolean -#. Description -#: ../lxc.templates:2001 -msgid "Automatically start Linux Containers on boot?" -msgstr "引导时自动启动 Linux Containers" - -#. Type: boolean -#. Description -#: ../lxc.templates:2001 -#, fuzzy -#| msgid "" -#| "Linux Containers can be automatically started during system boot and shut " -#| "down on reboot or halt." -msgid "" -"Linux Containers that have their configuration files copied or symlinked to " -"the /etc/lxc/auto directory can be automatically started during system boot, " -"and shut down on reboot or halt." -msgstr "Linux Containers 可以在系统引导时自动启动,在重新引导或者关机时关闭。" - -#. Type: boolean -#. Description -#: ../lxc.templates:2001 -msgid "If unsure, choose yes (default)." -msgstr "" - -#. Type: select -#. Description -#: ../lxc.templates:3001 -#, fuzzy -#| msgid "Linux Containers (LXC) setup" -msgid "Linux Container: Shutdown method" -msgstr "Linux Containers (LXC) 设置" - -#. Type: select -#. Description -#: ../lxc.templates:3001 -msgid "" -"Linux Containers can be shutdown in different ways. The stop method " -"terminates all processes inside the container. The halt method initiates a " -"shutdown, which takes longer and can have problems with containers that " -"don't shutdown themselves properly." -msgstr "" - -#. Type: select -#. Description -#: ../lxc.templates:3001 -msgid "" -"Unless you know that your containers don't shutdown properly, choose halt " -"(default)." -msgstr "" - -#. Type: string -#. Description -#: ../lxc.templates:4001 -msgid "LXC directory:" -msgstr "" - -#. Type: string -#. Description -#: ../lxc.templates:4001 -msgid "" -"Please specify the directory that will be used to store the Linux Containers." -msgstr "" - -#. Type: string -#. Description -#: ../lxc.templates:4001 -msgid "If unsure, use /var/lib/lxc (default)." -msgstr "" diff -Nru lxc-0.8.0~rc1/debian/rules lxc-1.0.0~alpha1/debian/rules --- lxc-0.8.0~rc1/debian/rules 2013-02-07 19:28:36.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/rules 2013-11-04 14:11:04.000000000 +0000 @@ -1,4 +1,5 @@ #!/usr/bin/make -f +export DEB_BUILD_HARDENING = 1 DEB_DH_INSTALLINIT_ARGS = --upstart-only @@ -9,44 +10,12 @@ %: dh ${@} --with autotools_dev --with autoreconf -override_dh_auto_clean: - dh_auto_clean - - for _FILE in debian/*.install.in; \ - do \ - rm -f debian/$$(basename $${_FILE} .in); \ - sed -e 's|@DEB_HOST_MULTIARCH@|$(DEB_HOST_MULTIARCH)|g' \ - $${_FILE} > debian/$$(basename $${_FILE} .in); \ - done - override_dh_auto_configure: - dh_auto_configure -- --libdir=\$${prefix}/lib/$(DEB_HOST_MULTIARCH) --libexecdir=\$${prefix}/lib/$(DEB_HOST_MULTIARCH) --with-rootfs-path=\$${prefix}/lib/$(DEB_HOST_MULTIARCH)/lxc --enable-doc --disable-rpath --enable-seccomp=check --enable-python - -override_dh_auto_install: - dh_auto_install - - # creating lxc directories - mkdir -p debian/tmp/etc/lxc/auto - mkdir -p debian/tmp/etc/lxc/debconf - mkdir -p debian/tmp/usr/share/lxc/cache - mkdir -p debian/tmp/usr/share/lxc/packages - mkdir -p debian/tmp/var/log/lxc - - # removing useless files - rm -f debian/tmp/usr/share/lxc/templates/lxc-lenny - -override_dh_builddeb: - dh_builddeb -- -Zgzip -z9 - -override_dh_compress: - dh_compress -X.cfg - -override_dh_gencontrol: -ifeq ($(DEB_HOST_MULTIARCH),) - dh_gencontrol -else - dh_gencontrol -- -Vmultiarch:Pre-Depends="multiarch-support" -endif + dh_auto_configure -- --libdir=\$${prefix}/lib/$(DEB_HOST_MULTIARCH) \ + --libexecdir=\$${prefix}/lib/$(DEB_HOST_MULTIARCH) \ + --with-rootfs-path=\$${prefix}/lib/$(DEB_HOST_MULTIARCH)/lxc \ + --enable-python $(shell DEB_CFLAGS_MAINT_APPEND="$$(python3-config --includes)" dpkg-buildflags --export=configure) \ + --enable-doc --disable-rpath --enable-apparmor --with-distro=ubuntu override_dh_install: # copy apparmor profiles @@ -58,16 +27,16 @@ cp debian/apparmor/lxc-default-with-nesting debian/lxc/etc/apparmor.d/lxc/lxc-default-with-nesting cp debian/apparmor/abstractions-lxc-container-base debian/lxc/etc/apparmor.d/abstractions/lxc/container-base cp debian/apparmor/abstractions-lxc-start-container debian/lxc/etc/apparmor.d/abstractions/lxc/start-container + if dpkg --compare-versions "$(shell grep DISTRIB_RELEASE /etc/lsb-release | cut -d= -f2)" ge "13.10"; then \ + sed -i "/umount,$$/a\ \ dbus," debian/lxc/etc/apparmor.d/abstractions/lxc/container-base; \ + fi if [ -x /usr/bin/dh_apparmor ]; then \ dh_apparmor -p lxc --profile-name=usr.bin.lxc-start; \ fi + # copy apport hook mkdir -p debian/lxc/usr/share/apport/package-hooks cp debian/lxc.apport debian/lxc/usr/share/apport/package-hooks/source_lxc.py - # copy example hooks - mkdir -p debian/lxc/usr/share/lxc - cp -r debian/hooks debian/lxc/usr/share/lxc/ - chmod ugo+x debian/lxc/usr/share/lxc/hooks/* # copy dnsmasq configuration mkdir -p debian/lxc/etc/dnsmasq.d-available @@ -75,23 +44,18 @@ dh_install --fail-missing - # replace upstream lxc-wait which can only run one-at-a-time - cp -f debian/local/lxc-wait debian/lxc/usr/bin/ - - # move the tests to their separate namespace - mv debian/lxc/usr/bin/startone debian/lxc/usr/bin/lxc-test-startone - mv debian/lxc/usr/bin/containertests debian/lxc/usr/bin/lxc-test-containertests - mv debian/lxc/usr/bin/destroytest debian/lxc/usr/bin/lxc-test-destroytest - mv debian/lxc/usr/bin/saveconfig debian/lxc/usr/bin/lxc-test-saveconfig - mv debian/lxc/usr/bin/createtest debian/lxc/usr/bin/lxc-test-createtest - mv debian/lxc/usr/bin/shutdowntest debian/lxc/usr/bin/lxc-test-shutdowntest - mv debian/lxc/usr/bin/locktests debian/lxc/usr/bin/lxc-test-locktests - mv debian/lxc/usr/bin/get_item debian/lxc/usr/bin/lxc-test-get-item - mv debian/lxc/usr/bin/getkeys debian/lxc/usr/bin/lxc-test-getkeys - override_dh_installinit: dh_installinit --no-restart-on-upgrade --name=lxc dh_installinit --no-restart-on-upgrade --name=lxc-net + dh_installinit --no-restart-on-upgrade --name=lxc-instance + +override_dh_builddeb: + # prevent system users from using setuid-root binaries under /var/lib/lxc + mkdir -p debian/lxc/var/lib/lxc + chmod 700 debian/lxc/var/lib/lxc + mkdir -p debian/lxc/var/cache/lxc + chmod 700 debian/lxc/var/cache/lxc + dh_builddeb override_dh_strip: dh_strip --dbg-package=lxc-dbg diff -Nru lxc-0.8.0~rc1/debian/source/options lxc-1.0.0~alpha1/debian/source/options --- lxc-0.8.0~rc1/debian/source/options 2012-10-24 16:10:12.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/source/options 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -compression = gzip -compression-level = 9 diff -Nru lxc-0.8.0~rc1/debian/tests/control lxc-1.0.0~alpha1/debian/tests/control --- lxc-0.8.0~rc1/debian/tests/control 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/tests/control 2013-10-07 21:32:53.000000000 +0000 @@ -0,0 +1,3 @@ +Tests: exercise +Depends: @, cgroup-lite +Restrictions: needs-root allow-stderr diff -Nru lxc-0.8.0~rc1/debian/tests/exercise lxc-1.0.0~alpha1/debian/tests/exercise --- lxc-0.8.0~rc1/debian/tests/exercise 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/debian/tests/exercise 2013-10-07 21:32:53.000000000 +0000 @@ -0,0 +1,83 @@ +#!/bin/sh +#--------------------------------------------------------------------- +# Some very basic tests to run in a DEP-8 environment. +#--------------------------------------------------------------------- + +template_dir=/usr/share/lxc/templates + +# Exit with error message. +# +# @msg: message to display. +die() +{ + msg="$*" + echo "ERROR: $msg" >&2 + exit 1 +} + +# seconds to wait for container to be running/stopped +boot_secs=10 +shutdown_secs=10 + +distro=$(lsb_release --id|cut -d: -f2-|awk '{print $1}'|tr '[A-Z]' '[a-z]') +[ -z "$distro" ] && die "failed to determine distro" + +[ ! -d "$template_dir" ] && die "template directory does not exist" + +file=$(ls "${template_dir}/lxc-${distro}" 2>/dev/null) +[ -z "$file" ] && die "template does not exist for distro '$distro'" +template="$distro" + +release=$(lsb_release -c|awk '{print $2}') +[ -z "$release" ] && die "failed to establish release" + +orig_name="${release}-dep8" +new_name="${orig_name}-clone" + +name="$orig_name" + +# adt sets TMPDIR, this confuses debootstrap/apt-get when creating a container +unset TMPDIR + +# flush cache to ensure we always get the latest bootstrap image +lxc-create -n "$name" -t "$template" -- -r "$release" --flush-cache || \ + die "failed to create container '$name' using template '$template' for release '$release'" + +lxc-ls -1 | grep -q "^${name}$" || \ + die "container not known" + +lxc-start -n "$name" --daemon || die "failed to initiate container start" + +lxc-wait -n "$name" -s RUNNING -t $boot_secs || \ + die "container $name: did not start after $boot_secs seconds" + +lxc-stop -n "$name" || die "container $name: failed to initiate shutdown" + +lxc-wait -n "$name" -s STOPPED -t $shutdown_secs || \ + die "container $name: did not stop within $shutdown_secs seconds" + +lxc-clone -o "$orig_name" -n "$new_name" || \ + die "failed to clone container '$orig_name' to '$new_name'" + +# switch attention to the clone +name="$new_name" + +lxc-start -n "$name" --daemon || die "container $name: failed to initiate start" + +lxc-wait -n "$name" -s RUNNING -t $boot_secs || \ + die "container $name: did not start after $boot_secs seconds" + +lxc-stop -n "$name" || die "container $new_nam: failed to initiate shutdown" + +lxc-wait -n "$name" -s STOPPED -t $shutdown_secs || \ + die "container $name: did not stop within $shutdown_secs seconds" + +# clean up +for name in "$orig_name" "$new_name" +do + lxc-destroy -n "$name" || die "container: $name: cannot delete" +done + +echo SUCCESS + +exit 0 diff -Nru lxc-0.8.0~rc1/doc/FAQ.txt lxc-1.0.0~alpha1/doc/FAQ.txt --- lxc-0.8.0~rc1/doc/FAQ.txt 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/FAQ.txt 2013-07-08 15:50:40.000000000 +0000 @@ -32,8 +32,8 @@ "[syserr] lxc_start:96: Invalid argument - failed to fork into a new namespace" -Answer: -------- +Answer: +------- read the lxc man page about kernel version prereq :) most probably your kernel is not configured to support the container options you diff -Nru lxc-0.8.0~rc1/doc/Makefile.am lxc-1.0.0~alpha1/doc/Makefile.am --- lxc-0.8.0~rc1/doc/Makefile.am 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/Makefile.am 2013-09-10 22:22:00.000000000 +0000 @@ -2,45 +2,63 @@ DIST_SUBDIRS = examples rootfs EXTRA_DIST = \ - FAQ.txt \ - $(man_MANS) + FAQ.txt if ENABLE_DOCBOOK man_MANS = \ + lxc-attach.1 \ + lxc-cgroup.1 \ + lxc-checkconfig.1 \ + lxc-checkpoint.1 \ + lxc-clone.1 \ + lxc-console.1 \ lxc-create.1 \ lxc-destroy.1 \ lxc-execute.1 \ + lxc-freeze.1 \ + lxc-info.1 \ + lxc-kill.1 \ + lxc-monitor.1 \ + lxc-netstat.1 \ + lxc-ps.1 \ + lxc-restart.1 \ lxc-start.1 \ lxc-stop.1 \ - lxc-checkpoint.1 \ - lxc-restart.1 \ - lxc-console.1 \ - lxc-freeze.1 \ lxc-unfreeze.1 \ - lxc-monitor.1 \ + lxc-unshare.1 \ + lxc-version.1 \ lxc-wait.1 \ - lxc-ls.1 \ - lxc-ps.1 \ - lxc-cgroup.1 \ - lxc-kill.1 \ - lxc-attach.1 \ \ lxc.conf.5 \ \ lxc.7 +if ENABLE_PYTHON + man_MANS += lxc-device.1 + man_MANS += lxc-ls.1 + man_MANS += lxc-start-ephemeral.1 +else + man_MANS += legacy/lxc-ls.1 +endif -%.1 : %.sgml - docbook2man -w all $< - -%.5 : %.sgml - docbook2man -w all $< +if ENABLE_LUA + man_MANS += lxc-top.1 +endif -%.7 : %.sgml - docbook2man -w all $< +%.1 : %.sgml + $(db2xman) $< + test "$(shell basename $@)" != "$@" && mv $(shell basename $@) $@ || true + +%.5 : %.sgml + $(db2xman) $< + test "$(shell basename $@)" != "$@" && mv $(shell basename $@) $@ || true + +%.7 : %.sgml + $(db2xman) $< + test "$(shell basename $@)" != "$@" && mv $(shell basename $@) $@ || true lxc-%.sgml : common_options.sgml see_also.sgml -maintainer-clean-local: +clean-local: $(RM) manpage.* *.7 *.5 *.1 $(man_MANS) endif diff -Nru lxc-0.8.0~rc1/doc/Makefile.in lxc-1.0.0~alpha1/doc/Makefile.in --- lxc-0.8.0~rc1/doc/Makefile.in 2012-03-01 23:04:43.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/Makefile.in 2013-09-10 22:30:08.000000000 +0000 @@ -1,9 +1,8 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. +# Makefile.in generated by automake 1.13.3 from Makefile.am. # @configure_input@ -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -15,6 +14,51 @@ @SET_MAKE@ VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -33,42 +77,74 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ +@ENABLE_DOCBOOK_TRUE@@ENABLE_PYTHON_TRUE@am__append_1 = lxc-device.1 \ +@ENABLE_DOCBOOK_TRUE@@ENABLE_PYTHON_TRUE@ lxc-ls.1 \ +@ENABLE_DOCBOOK_TRUE@@ENABLE_PYTHON_TRUE@ lxc-start-ephemeral.1 +@ENABLE_DOCBOOK_TRUE@@ENABLE_PYTHON_FALSE@am__append_2 = legacy/lxc-ls.1 +@ENABLE_DOCBOOK_TRUE@@ENABLE_LUA_TRUE@am__append_3 = lxc-top.1 subdir = doc -DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ - $(srcdir)/common_options.sgml.in $(srcdir)/lxc-attach.sgml.in \ - $(srcdir)/lxc-cgroup.sgml.in $(srcdir)/lxc-checkpoint.sgml.in \ +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(srcdir)/lxc-attach.sgml.in $(srcdir)/lxc-cgroup.sgml.in \ + $(srcdir)/lxc-checkconfig.sgml.in \ + $(srcdir)/lxc-checkpoint.sgml.in $(srcdir)/lxc-clone.sgml.in \ $(srcdir)/lxc-console.sgml.in $(srcdir)/lxc-create.sgml.in \ - $(srcdir)/lxc-destroy.sgml.in $(srcdir)/lxc-execute.sgml.in \ - $(srcdir)/lxc-freeze.sgml.in $(srcdir)/lxc-kill.sgml.in \ + $(srcdir)/lxc-destroy.sgml.in $(srcdir)/lxc-device.sgml.in \ + $(srcdir)/lxc-execute.sgml.in $(srcdir)/lxc-freeze.sgml.in \ + $(srcdir)/lxc-info.sgml.in $(srcdir)/lxc-kill.sgml.in \ $(srcdir)/lxc-ls.sgml.in $(srcdir)/lxc-monitor.sgml.in \ - $(srcdir)/lxc-ps.sgml.in $(srcdir)/lxc-restart.sgml.in \ + $(srcdir)/lxc-netstat.sgml.in $(srcdir)/lxc-ps.sgml.in \ + $(srcdir)/lxc-restart.sgml.in \ + $(srcdir)/lxc-start-ephemeral.sgml.in \ $(srcdir)/lxc-start.sgml.in $(srcdir)/lxc-stop.sgml.in \ - $(srcdir)/lxc-unfreeze.sgml.in $(srcdir)/lxc-wait.sgml.in \ - $(srcdir)/lxc.conf.sgml.in $(srcdir)/lxc.sgml.in \ + $(srcdir)/lxc-top.sgml.in $(srcdir)/lxc-unfreeze.sgml.in \ + $(srcdir)/lxc-unshare.sgml.in $(srcdir)/lxc-version.sgml.in \ + $(srcdir)/lxc-wait.sgml.in $(srcdir)/lxc.conf.sgml.in \ + $(srcdir)/lxc.sgml.in $(srcdir)/common_options.sgml.in \ $(srcdir)/see_also.sgml.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/config/acinclude.m4 \ - $(top_srcdir)/config/linux.m4 $(top_srcdir)/configure.ac + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/src/config.h -CONFIG_CLEAN_FILES = lxc-create.sgml lxc-destroy.sgml lxc-execute.sgml \ - lxc-start.sgml lxc-checkpoint.sgml lxc-restart.sgml \ - lxc-stop.sgml lxc-console.sgml lxc-freeze.sgml \ - lxc-unfreeze.sgml lxc-monitor.sgml lxc-wait.sgml lxc-ls.sgml \ - lxc-ps.sgml lxc-cgroup.sgml lxc-kill.sgml lxc-attach.sgml \ - lxc.conf.sgml lxc.sgml common_options.sgml see_also.sgml +CONFIG_CLEAN_FILES = lxc-attach.sgml lxc-cgroup.sgml \ + lxc-checkconfig.sgml lxc-checkpoint.sgml lxc-clone.sgml \ + lxc-console.sgml lxc-create.sgml lxc-destroy.sgml \ + lxc-device.sgml lxc-execute.sgml lxc-freeze.sgml lxc-info.sgml \ + lxc-kill.sgml lxc-ls.sgml lxc-monitor.sgml lxc-netstat.sgml \ + lxc-ps.sgml lxc-restart.sgml lxc-start-ephemeral.sgml \ + lxc-start.sgml lxc-stop.sgml lxc-top.sgml lxc-unfreeze.sgml \ + lxc-unshare.sgml lxc-version.sgml lxc-wait.sgml lxc.conf.sgml \ + lxc.sgml common_options.sgml see_also.sgml CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = SOURCES = DIST_SOURCES = -RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ - html-recursive info-recursive install-data-recursive \ - install-dvi-recursive install-exec-recursive \ - install-html-recursive install-info-recursive \ - install-pdf-recursive install-ps-recursive install-recursive \ - installcheck-recursive installdirs-recursive pdf-recursive \ - ps-recursive uninstall-recursive +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ @@ -90,6 +166,12 @@ am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } man1dir = $(mandir)/man1 am__installdirs = "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man5dir)" \ "$(DESTDIR)$(man7dir)" @@ -99,9 +181,29 @@ MANS = $(man_MANS) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive -AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ - $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) @@ -132,6 +234,8 @@ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +APPARMOR_LIBS = @APPARMOR_LIBS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ @@ -162,19 +266,31 @@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBDIR = @LIBDIR@ +LIBEXECDIR = @LIBEXECDIR@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ -LINUX_DIR = @LINUX_DIR@ -LINUX_SRCARCH = @LINUX_SRCARCH@ LOCALSTATEDIR = @LOCALSTATEDIR@ +LOGPATH = @LOGPATH@ LTLIBOBJS = @LTLIBOBJS@ +LUA_CFLAGS = @LUA_CFLAGS@ +LUA_INSTALL_CMOD = @LUA_INSTALL_CMOD@ +LUA_INSTALL_LMOD = @LUA_INSTALL_LMOD@ +LUA_LIBS = @LUA_LIBS@ +LUA_VERSION = @LUA_VERSION@ +LXCHOOKDIR = @LXCHOOKDIR@ LXCINITDIR = @LXCINITDIR@ LXCPATH = @LXCPATH@ LXCROOTFSMOUNT = @LXCROOTFSMOUNT@ LXCTEMPLATEDIR = @LXCTEMPLATEDIR@ +LXC_DEFAULT_CONFIG = @LXC_DEFAULT_CONFIG@ +LXC_DISTRO_CONF = @LXC_DISTRO_CONF@ LXC_GENERATE_DATE = @LXC_GENERATE_DATE@ +LXC_GLOBAL_CONF = @LXC_GLOBAL_CONF@ +LXC_USERNIC_CONF = @LXC_USERNIC_CONF@ +LXC_USERNIC_DB = @LXC_USERNIC_DB@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +NEWUIDMAP = @NEWUIDMAP@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ @@ -184,8 +300,19 @@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PREFIX = @PREFIX@ -SETCAP = @SETCAP@ +PYTHON = @PYTHON@ +PYTHONDEV_CFLAGS = @PYTHONDEV_CFLAGS@ +PYTHONDEV_LIBS = @PYTHONDEV_LIBS@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +SECCOMP_LIBS = @SECCOMP_LIBS@ +SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ @@ -210,10 +337,11 @@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ +db2xman = @db2xman@ docdir = @docdir@ +docdtd = @docdtd@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ -have_docbook = @have_docbook@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ @@ -231,9 +359,13 @@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ @@ -245,32 +377,18 @@ SUBDIRS = examples rootfs DIST_SUBDIRS = examples rootfs EXTRA_DIST = \ - FAQ.txt \ - $(man_MANS) - -@ENABLE_DOCBOOK_TRUE@man_MANS = \ -@ENABLE_DOCBOOK_TRUE@ lxc-create.1 \ -@ENABLE_DOCBOOK_TRUE@ lxc-destroy.1 \ -@ENABLE_DOCBOOK_TRUE@ lxc-execute.1 \ -@ENABLE_DOCBOOK_TRUE@ lxc-start.1 \ -@ENABLE_DOCBOOK_TRUE@ lxc-stop.1 \ -@ENABLE_DOCBOOK_TRUE@ lxc-checkpoint.1 \ -@ENABLE_DOCBOOK_TRUE@ lxc-restart.1 \ -@ENABLE_DOCBOOK_TRUE@ lxc-console.1 \ -@ENABLE_DOCBOOK_TRUE@ lxc-freeze.1 \ -@ENABLE_DOCBOOK_TRUE@ lxc-unfreeze.1 \ -@ENABLE_DOCBOOK_TRUE@ lxc-monitor.1 \ -@ENABLE_DOCBOOK_TRUE@ lxc-wait.1 \ -@ENABLE_DOCBOOK_TRUE@ lxc-ls.1 \ -@ENABLE_DOCBOOK_TRUE@ lxc-ps.1 \ -@ENABLE_DOCBOOK_TRUE@ lxc-cgroup.1 \ -@ENABLE_DOCBOOK_TRUE@ lxc-kill.1 \ -@ENABLE_DOCBOOK_TRUE@ lxc-attach.1 \ -@ENABLE_DOCBOOK_TRUE@ \ -@ENABLE_DOCBOOK_TRUE@ lxc.conf.5 \ -@ENABLE_DOCBOOK_TRUE@ \ -@ENABLE_DOCBOOK_TRUE@ lxc.7 + FAQ.txt +@ENABLE_DOCBOOK_TRUE@man_MANS = lxc-attach.1 lxc-cgroup.1 \ +@ENABLE_DOCBOOK_TRUE@ lxc-checkconfig.1 lxc-checkpoint.1 \ +@ENABLE_DOCBOOK_TRUE@ lxc-clone.1 lxc-console.1 lxc-create.1 \ +@ENABLE_DOCBOOK_TRUE@ lxc-destroy.1 lxc-execute.1 lxc-freeze.1 \ +@ENABLE_DOCBOOK_TRUE@ lxc-info.1 lxc-kill.1 lxc-monitor.1 \ +@ENABLE_DOCBOOK_TRUE@ lxc-netstat.1 lxc-ps.1 lxc-restart.1 \ +@ENABLE_DOCBOOK_TRUE@ lxc-start.1 lxc-stop.1 lxc-unfreeze.1 \ +@ENABLE_DOCBOOK_TRUE@ lxc-unshare.1 lxc-version.1 lxc-wait.1 \ +@ENABLE_DOCBOOK_TRUE@ lxc.conf.5 lxc.7 $(am__append_1) \ +@ENABLE_DOCBOOK_TRUE@ $(am__append_2) $(am__append_3) all: all-recursive .SUFFIXES: @@ -304,39 +422,57 @@ $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): +lxc-attach.sgml: $(top_builddir)/config.status $(srcdir)/lxc-attach.sgml.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ +lxc-cgroup.sgml: $(top_builddir)/config.status $(srcdir)/lxc-cgroup.sgml.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ +lxc-checkconfig.sgml: $(top_builddir)/config.status $(srcdir)/lxc-checkconfig.sgml.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ +lxc-checkpoint.sgml: $(top_builddir)/config.status $(srcdir)/lxc-checkpoint.sgml.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ +lxc-clone.sgml: $(top_builddir)/config.status $(srcdir)/lxc-clone.sgml.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ +lxc-console.sgml: $(top_builddir)/config.status $(srcdir)/lxc-console.sgml.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ lxc-create.sgml: $(top_builddir)/config.status $(srcdir)/lxc-create.sgml.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ lxc-destroy.sgml: $(top_builddir)/config.status $(srcdir)/lxc-destroy.sgml.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ +lxc-device.sgml: $(top_builddir)/config.status $(srcdir)/lxc-device.sgml.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ lxc-execute.sgml: $(top_builddir)/config.status $(srcdir)/lxc-execute.sgml.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ -lxc-start.sgml: $(top_builddir)/config.status $(srcdir)/lxc-start.sgml.in +lxc-freeze.sgml: $(top_builddir)/config.status $(srcdir)/lxc-freeze.sgml.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ -lxc-checkpoint.sgml: $(top_builddir)/config.status $(srcdir)/lxc-checkpoint.sgml.in +lxc-info.sgml: $(top_builddir)/config.status $(srcdir)/lxc-info.sgml.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ -lxc-restart.sgml: $(top_builddir)/config.status $(srcdir)/lxc-restart.sgml.in +lxc-kill.sgml: $(top_builddir)/config.status $(srcdir)/lxc-kill.sgml.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ -lxc-stop.sgml: $(top_builddir)/config.status $(srcdir)/lxc-stop.sgml.in +lxc-ls.sgml: $(top_builddir)/config.status $(srcdir)/lxc-ls.sgml.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ -lxc-console.sgml: $(top_builddir)/config.status $(srcdir)/lxc-console.sgml.in +lxc-monitor.sgml: $(top_builddir)/config.status $(srcdir)/lxc-monitor.sgml.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ -lxc-freeze.sgml: $(top_builddir)/config.status $(srcdir)/lxc-freeze.sgml.in +lxc-netstat.sgml: $(top_builddir)/config.status $(srcdir)/lxc-netstat.sgml.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ -lxc-unfreeze.sgml: $(top_builddir)/config.status $(srcdir)/lxc-unfreeze.sgml.in +lxc-ps.sgml: $(top_builddir)/config.status $(srcdir)/lxc-ps.sgml.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ -lxc-monitor.sgml: $(top_builddir)/config.status $(srcdir)/lxc-monitor.sgml.in +lxc-restart.sgml: $(top_builddir)/config.status $(srcdir)/lxc-restart.sgml.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ -lxc-wait.sgml: $(top_builddir)/config.status $(srcdir)/lxc-wait.sgml.in +lxc-start-ephemeral.sgml: $(top_builddir)/config.status $(srcdir)/lxc-start-ephemeral.sgml.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ -lxc-ls.sgml: $(top_builddir)/config.status $(srcdir)/lxc-ls.sgml.in +lxc-start.sgml: $(top_builddir)/config.status $(srcdir)/lxc-start.sgml.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ -lxc-ps.sgml: $(top_builddir)/config.status $(srcdir)/lxc-ps.sgml.in +lxc-stop.sgml: $(top_builddir)/config.status $(srcdir)/lxc-stop.sgml.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ -lxc-cgroup.sgml: $(top_builddir)/config.status $(srcdir)/lxc-cgroup.sgml.in +lxc-top.sgml: $(top_builddir)/config.status $(srcdir)/lxc-top.sgml.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ -lxc-kill.sgml: $(top_builddir)/config.status $(srcdir)/lxc-kill.sgml.in +lxc-unfreeze.sgml: $(top_builddir)/config.status $(srcdir)/lxc-unfreeze.sgml.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ -lxc-attach.sgml: $(top_builddir)/config.status $(srcdir)/lxc-attach.sgml.in +lxc-unshare.sgml: $(top_builddir)/config.status $(srcdir)/lxc-unshare.sgml.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ +lxc-version.sgml: $(top_builddir)/config.status $(srcdir)/lxc-version.sgml.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ +lxc-wait.sgml: $(top_builddir)/config.status $(srcdir)/lxc-wait.sgml.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ lxc.conf.sgml: $(top_builddir)/config.status $(srcdir)/lxc.conf.sgml.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ @@ -348,11 +484,18 @@ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ install-man1: $(man_MANS) @$(NORMAL_INSTALL) - test -z "$(man1dir)" || $(MKDIR_P) "$(DESTDIR)$(man1dir)" - @list=''; test -n "$(man1dir)" || exit 0; \ - { for i in $$list; do echo "$$i"; done; \ - l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ - sed -n '/\.1[a-z]*$$/p'; \ + @list1=''; \ + list2='$(man_MANS)'; \ + test -n "$(man1dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.1[a-z]*$$/p'; \ + fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ @@ -381,16 +524,21 @@ sed -n '/\.1[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ - test -z "$$files" || { \ - echo " ( cd '$(DESTDIR)$(man1dir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(man1dir)" && rm -f $$files; } + dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) install-man5: $(man_MANS) @$(NORMAL_INSTALL) - test -z "$(man5dir)" || $(MKDIR_P) "$(DESTDIR)$(man5dir)" - @list=''; test -n "$(man5dir)" || exit 0; \ - { for i in $$list; do echo "$$i"; done; \ - l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ - sed -n '/\.5[a-z]*$$/p'; \ + @list1=''; \ + list2='$(man_MANS)'; \ + test -n "$(man5dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man5dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man5dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.5[a-z]*$$/p'; \ + fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ @@ -419,16 +567,21 @@ sed -n '/\.5[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ - test -z "$$files" || { \ - echo " ( cd '$(DESTDIR)$(man5dir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(man5dir)" && rm -f $$files; } + dir='$(DESTDIR)$(man5dir)'; $(am__uninstall_files_from_dir) install-man7: $(man_MANS) @$(NORMAL_INSTALL) - test -z "$(man7dir)" || $(MKDIR_P) "$(DESTDIR)$(man7dir)" - @list=''; test -n "$(man7dir)" || exit 0; \ - { for i in $$list; do echo "$$i"; done; \ - l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ - sed -n '/\.7[a-z]*$$/p'; \ + @list1=''; \ + list2='$(man_MANS)'; \ + test -n "$(man7dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man7dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man7dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.7[a-z]*$$/p'; \ + fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ @@ -457,27 +610,28 @@ sed -n '/\.7[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^7][0-9a-z]*$$,7,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ - test -z "$$files" || { \ - echo " ( cd '$(DESTDIR)$(man7dir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(man7dir)" && rm -f $$files; } + dir='$(DESTDIR)$(man7dir)'; $(am__uninstall_files_from_dir) # This directory's subdirectories are mostly independent; you can cd -# into them and run `make' without going through this Makefile. -# To change the values of `make' variables: instead of editing Makefiles, -# (1) if the variable is set in `config.status', edit `config.status' -# (which will cause the Makefiles to be regenerated when you run `make'); -# (2) otherwise, pass the desired values on the `make' command line. -$(RECURSIVE_TARGETS): - @fail= failcom='exit 1'; \ - for f in x $$MAKEFLAGS; do \ - case $$f in \ - *=* | --[!k]*);; \ - *k*) failcom='fail=yes';; \ - esac; \ - done; \ +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ @@ -492,57 +646,12 @@ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" -$(RECURSIVE_CLEAN_TARGETS): - @fail= failcom='exit 1'; \ - for f in x $$MAKEFLAGS; do \ - case $$f in \ - *=* | --[!k]*);; \ - *k*) failcom='fail=yes';; \ - esac; \ - done; \ - dot_seen=no; \ - case "$@" in \ - distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ - *) list='$(SUBDIRS)' ;; \ - esac; \ - rev=''; for subdir in $$list; do \ - if test "$$subdir" = "."; then :; else \ - rev="$$subdir $$rev"; \ - fi; \ - done; \ - rev="$$rev ."; \ - target=`echo $@ | sed s/-recursive//`; \ - for subdir in $$rev; do \ - echo "Making $$target in $$subdir"; \ - if test "$$subdir" = "."; then \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || eval $$failcom; \ - done && test -z "$$fail" -tags-recursive: - list='$(SUBDIRS)'; for subdir in $$list; do \ - test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ - done -ctags-recursive: - list='$(SUBDIRS)'; for subdir in $$list; do \ - test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ - done - -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags -TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ @@ -558,12 +667,7 @@ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ + $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ @@ -575,15 +679,11 @@ $$unique; \ fi; \ fi -ctags: CTAGS -CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique @@ -592,24 +692,26 @@ here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) - @list='$(MANS)'; if test -n "$$list"; then \ - list=`for p in $$list; do \ - if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ - if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \ - if test -n "$$list" && \ - grep 'ab help2man is required to generate this page' $$list >/dev/null; then \ - echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \ - grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \ - echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \ - echo " typically \`make maintainer-clean' will remove them" >&2; \ - exit 1; \ - else :; fi; \ - else :; fi @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ @@ -641,13 +743,10 @@ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ - test -d "$(distdir)/$$subdir" \ - || $(MKDIR_P) "$(distdir)/$$subdir" \ - || exit 1; \ - fi; \ - done - @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ @@ -685,10 +784,15 @@ installcheck: installcheck-recursive install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi mostlyclean-generic: clean-generic: @@ -700,10 +804,10 @@ maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -@ENABLE_DOCBOOK_FALSE@maintainer-clean-local: +@ENABLE_DOCBOOK_FALSE@clean-local: clean: clean-recursive -clean-am: clean-generic mostlyclean-am +clean-am: clean-generic clean-local mostlyclean-am distclean: distclean-recursive -rm -f Makefile @@ -751,8 +855,7 @@ maintainer-clean: maintainer-clean-recursive -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic \ - maintainer-clean-local +maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive @@ -770,37 +873,38 @@ uninstall-man: uninstall-man1 uninstall-man5 uninstall-man7 -.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ - install-am install-strip tags-recursive +.MAKE: $(am__recursive_targets) install-am install-strip -.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ - all all-am check check-am clean clean-generic ctags \ - ctags-recursive distclean distclean-generic distclean-tags \ - distdir dvi dvi-am html html-am info info-am install \ - install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-man1 install-man5 install-man7 install-pdf \ - install-pdf-am install-ps install-ps-am install-strip \ - installcheck installcheck-am installdirs installdirs-am \ - maintainer-clean maintainer-clean-generic \ - maintainer-clean-local mostlyclean mostlyclean-generic pdf \ - pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \ +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ + check-am clean clean-generic clean-local cscopelist-am ctags \ + ctags-am distclean distclean-generic distclean-tags distdir \ + dvi dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-man1 \ + install-man5 install-man7 install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ + pdf-am ps ps-am tags tags-am uninstall uninstall-am \ uninstall-man uninstall-man1 uninstall-man5 uninstall-man7 -@ENABLE_DOCBOOK_TRUE@%.1 : %.sgml -@ENABLE_DOCBOOK_TRUE@ docbook2man -w all $< - -@ENABLE_DOCBOOK_TRUE@%.5 : %.sgml -@ENABLE_DOCBOOK_TRUE@ docbook2man -w all $< - -@ENABLE_DOCBOOK_TRUE@%.7 : %.sgml -@ENABLE_DOCBOOK_TRUE@ docbook2man -w all $< +@ENABLE_DOCBOOK_TRUE@%.1 : %.sgml +@ENABLE_DOCBOOK_TRUE@ $(db2xman) $< +@ENABLE_DOCBOOK_TRUE@ test "$(shell basename $@)" != "$@" && mv $(shell basename $@) $@ || true + +@ENABLE_DOCBOOK_TRUE@%.5 : %.sgml +@ENABLE_DOCBOOK_TRUE@ $(db2xman) $< +@ENABLE_DOCBOOK_TRUE@ test "$(shell basename $@)" != "$@" && mv $(shell basename $@) $@ || true + +@ENABLE_DOCBOOK_TRUE@%.7 : %.sgml +@ENABLE_DOCBOOK_TRUE@ $(db2xman) $< +@ENABLE_DOCBOOK_TRUE@ test "$(shell basename $@)" != "$@" && mv $(shell basename $@) $@ || true @ENABLE_DOCBOOK_TRUE@lxc-%.sgml : common_options.sgml see_also.sgml -@ENABLE_DOCBOOK_TRUE@maintainer-clean-local: +@ENABLE_DOCBOOK_TRUE@clean-local: @ENABLE_DOCBOOK_TRUE@ $(RM) manpage.* *.7 *.5 *.1 $(man_MANS) # Tell versions [3.59,3.63) of GNU make to not export all variables. diff -Nru lxc-0.8.0~rc1/doc/common_options.sgml.in lxc-1.0.0~alpha1/doc/common_options.sgml.in --- lxc-0.8.0~rc1/doc/common_options.sgml.in 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/common_options.sgml.in 2013-09-10 22:22:00.000000000 +0000 @@ -5,7 +5,7 @@ (C) Copyright IBM Corp. 2007, 2008 Authors: -Daniel Lezcano +Daniel Lezcano This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -19,7 +19,7 @@ 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 +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA --> @@ -58,6 +58,15 @@ + + + + Use an alternate container path. The default is @LXCPATH@. + + + + + diff -Nru lxc-0.8.0~rc1/doc/examples/Makefile.am lxc-1.0.0~alpha1/doc/examples/Makefile.am --- lxc-0.8.0~rc1/doc/examples/Makefile.am 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/examples/Makefile.am 2013-09-10 22:22:00.000000000 +0000 @@ -1,5 +1,3 @@ -EXTRA_DIST = $(pkgexamples_DATA) - if ENABLE_EXAMPLES pkgexamplesdir=$(docdir)/examples diff -Nru lxc-0.8.0~rc1/doc/examples/Makefile.in lxc-1.0.0~alpha1/doc/examples/Makefile.in --- lxc-0.8.0~rc1/doc/examples/Makefile.in 2012-03-01 23:04:43.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/examples/Makefile.in 2013-09-10 22:30:09.000000000 +0000 @@ -1,9 +1,8 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. +# Makefile.in generated by automake 1.13.3 from Makefile.am. # @configure_input@ -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -16,6 +15,51 @@ @SET_MAKE@ VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -35,15 +79,14 @@ build_triplet = @build@ host_triplet = @host@ subdir = doc/examples -DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ - $(srcdir)/lxc-complex.conf.in \ - $(srcdir)/lxc-empty-netns.conf.in \ - $(srcdir)/lxc-macvlan.conf.in $(srcdir)/lxc-no-netns.conf.in \ - $(srcdir)/lxc-phys.conf.in $(srcdir)/lxc-veth.conf.in \ - $(srcdir)/lxc-vlan.conf.in +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(srcdir)/lxc-macvlan.conf.in $(srcdir)/lxc-vlan.conf.in \ + $(srcdir)/lxc-no-netns.conf.in \ + $(srcdir)/lxc-empty-netns.conf.in $(srcdir)/lxc-phys.conf.in \ + $(srcdir)/lxc-veth.conf.in $(srcdir)/lxc-complex.conf.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/config/acinclude.m4 \ - $(top_srcdir)/config/linux.m4 $(top_srcdir)/configure.ac + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d @@ -52,8 +95,25 @@ lxc-empty-netns.conf lxc-phys.conf lxc-veth.conf \ lxc-complex.conf CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = SOURCES = DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ @@ -75,11 +135,20 @@ am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } am__installdirs = "$(DESTDIR)$(pkgexamplesdir)" DATA = $(noinst_DATA) $(pkgexamples_DATA) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +APPARMOR_LIBS = @APPARMOR_LIBS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ @@ -110,19 +179,31 @@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBDIR = @LIBDIR@ +LIBEXECDIR = @LIBEXECDIR@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ -LINUX_DIR = @LINUX_DIR@ -LINUX_SRCARCH = @LINUX_SRCARCH@ LOCALSTATEDIR = @LOCALSTATEDIR@ +LOGPATH = @LOGPATH@ LTLIBOBJS = @LTLIBOBJS@ +LUA_CFLAGS = @LUA_CFLAGS@ +LUA_INSTALL_CMOD = @LUA_INSTALL_CMOD@ +LUA_INSTALL_LMOD = @LUA_INSTALL_LMOD@ +LUA_LIBS = @LUA_LIBS@ +LUA_VERSION = @LUA_VERSION@ +LXCHOOKDIR = @LXCHOOKDIR@ LXCINITDIR = @LXCINITDIR@ LXCPATH = @LXCPATH@ LXCROOTFSMOUNT = @LXCROOTFSMOUNT@ LXCTEMPLATEDIR = @LXCTEMPLATEDIR@ +LXC_DEFAULT_CONFIG = @LXC_DEFAULT_CONFIG@ +LXC_DISTRO_CONF = @LXC_DISTRO_CONF@ LXC_GENERATE_DATE = @LXC_GENERATE_DATE@ +LXC_GLOBAL_CONF = @LXC_GLOBAL_CONF@ +LXC_USERNIC_CONF = @LXC_USERNIC_CONF@ +LXC_USERNIC_DB = @LXC_USERNIC_DB@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +NEWUIDMAP = @NEWUIDMAP@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ @@ -132,8 +213,19 @@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PREFIX = @PREFIX@ -SETCAP = @SETCAP@ +PYTHON = @PYTHON@ +PYTHONDEV_CFLAGS = @PYTHONDEV_CFLAGS@ +PYTHONDEV_LIBS = @PYTHONDEV_LIBS@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +SECCOMP_LIBS = @SECCOMP_LIBS@ +SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ @@ -158,10 +250,11 @@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ +db2xman = @db2xman@ docdir = @docdir@ +docdtd = @docdtd@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ -have_docbook = @have_docbook@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ @@ -179,9 +272,13 @@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ @@ -190,7 +287,6 @@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -EXTRA_DIST = $(pkgexamples_DATA) @ENABLE_EXAMPLES_TRUE@pkgexamplesdir = $(docdir)/examples @ENABLE_EXAMPLES_TRUE@pkgexamples_DATA = \ @ENABLE_EXAMPLES_TRUE@ lxc-macvlan.conf \ @@ -259,8 +355,11 @@ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ install-pkgexamplesDATA: $(pkgexamples_DATA) @$(NORMAL_INSTALL) - test -z "$(pkgexamplesdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgexamplesdir)" @list='$(pkgexamples_DATA)'; test -n "$(pkgexamplesdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkgexamplesdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkgexamplesdir)" || exit 1; \ + fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ @@ -274,14 +373,12 @@ @$(NORMAL_UNINSTALL) @list='$(pkgexamples_DATA)'; test -n "$(pkgexamplesdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - test -n "$$files" || exit 0; \ - echo " ( cd '$(DESTDIR)$(pkgexamplesdir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(pkgexamplesdir)" && rm -f $$files -tags: TAGS -TAGS: + dir='$(DESTDIR)$(pkgexamplesdir)'; $(am__uninstall_files_from_dir) +tags TAGS: + +ctags CTAGS: -ctags: CTAGS -CTAGS: +cscope cscopelist: distdir: $(DISTFILES) @@ -331,10 +428,15 @@ installcheck: installcheck-am install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi mostlyclean-generic: clean-generic: @@ -414,16 +516,17 @@ .MAKE: install-am install-strip -.PHONY: all all-am check check-am clean clean-generic distclean \ - distclean-generic distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-pkgexamplesDATA install-ps \ - install-ps-am install-strip installcheck installcheck-am \ - installdirs maintainer-clean maintainer-clean-generic \ - mostlyclean mostlyclean-generic pdf pdf-am ps ps-am uninstall \ - uninstall-am uninstall-pkgexamplesDATA +.PHONY: all all-am check check-am clean clean-generic cscopelist-am \ + ctags-am distclean distclean-generic distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-pkgexamplesDATA install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ + pdf-am ps ps-am tags-am uninstall uninstall-am \ + uninstall-pkgexamplesDATA # Tell versions [3.59,3.63) of GNU make to not export all variables. diff -Nru lxc-0.8.0~rc1/doc/examples/lxc-complex.conf lxc-1.0.0~alpha1/doc/examples/lxc-complex.conf --- lxc-0.8.0~rc1/doc/examples/lxc-complex.conf 2012-03-01 23:04:48.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/examples/lxc-complex.conf 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# Container with network a complex network mixing macvlan, veth and -# physical network devices -lxc.utsname = complex -lxc.network.type = veth -lxc.network.flags = up -lxc.network.link = br0 -lxc.network.hwaddr = 4a:49:43:49:79:bf -lxc.network.ipv4 = 1.2.3.5/24 -lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3597 - -lxc.network.type = macvlan -lxc.network.flags = up -lxc.network.link = eth0 -lxc.network.hwaddr = 4a:49:43:49:79:bd -lxc.network.ipv4 = 1.2.3.4/24 -lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3596 - -lxc.network.type = phys -lxc.network.flags = up -lxc.network.link = dummy0 -lxc.network.hwaddr = 4a:49:43:49:79:ff -lxc.network.ipv4 = 1.2.3.6/24 -lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3297 diff -Nru lxc-0.8.0~rc1/doc/examples/lxc-complex.conf.in lxc-1.0.0~alpha1/doc/examples/lxc-complex.conf.in --- lxc-0.8.0~rc1/doc/examples/lxc-complex.conf.in 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/examples/lxc-complex.conf.in 2013-07-08 15:50:40.000000000 +0000 @@ -5,19 +5,19 @@ lxc.network.flags = up lxc.network.link = br0 lxc.network.hwaddr = 4a:49:43:49:79:bf -lxc.network.ipv4 = 1.2.3.5/24 +lxc.network.ipv4 = 10.2.3.5/24 lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3597 lxc.network.type = macvlan lxc.network.flags = up lxc.network.link = eth0 lxc.network.hwaddr = 4a:49:43:49:79:bd -lxc.network.ipv4 = 1.2.3.4/24 +lxc.network.ipv4 = 10.2.3.4/24 lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3596 lxc.network.type = phys lxc.network.flags = up lxc.network.link = dummy0 lxc.network.hwaddr = 4a:49:43:49:79:ff -lxc.network.ipv4 = 1.2.3.6/24 +lxc.network.ipv4 = 10.2.3.6/24 lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3297 diff -Nru lxc-0.8.0~rc1/doc/examples/lxc-empty-netns.conf lxc-1.0.0~alpha1/doc/examples/lxc-empty-netns.conf --- lxc-0.8.0~rc1/doc/examples/lxc-empty-netns.conf 2012-03-01 23:04:48.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/examples/lxc-empty-netns.conf 1970-01-01 00:00:00.000000000 +0000 @@ -1,4 +0,0 @@ -# Container with new network withtout network devices -lxc.utsname = omega -lxc.network.type = empty -lxc.network.flags = up diff -Nru lxc-0.8.0~rc1/doc/examples/lxc-macvlan.conf lxc-1.0.0~alpha1/doc/examples/lxc-macvlan.conf --- lxc-0.8.0~rc1/doc/examples/lxc-macvlan.conf 2012-03-01 23:04:48.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/examples/lxc-macvlan.conf 1970-01-01 00:00:00.000000000 +0000 @@ -1,8 +0,0 @@ -# Container with network virtualized using the macvlan device driver -lxc.utsname = alpha -lxc.network.type = macvlan -lxc.network.flags = up -lxc.network.link = eth0 -lxc.network.hwaddr = 4a:49:43:49:79:bd -lxc.network.ipv4 = 1.2.3.4/24 -lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3596 diff -Nru lxc-0.8.0~rc1/doc/examples/lxc-macvlan.conf.in lxc-1.0.0~alpha1/doc/examples/lxc-macvlan.conf.in --- lxc-0.8.0~rc1/doc/examples/lxc-macvlan.conf.in 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/examples/lxc-macvlan.conf.in 2013-07-08 15:50:40.000000000 +0000 @@ -4,5 +4,5 @@ lxc.network.flags = up lxc.network.link = eth0 lxc.network.hwaddr = 4a:49:43:49:79:bd -lxc.network.ipv4 = 1.2.3.4/24 +lxc.network.ipv4 = 10.2.3.4/24 lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3596 diff -Nru lxc-0.8.0~rc1/doc/examples/lxc-no-netns.conf lxc-1.0.0~alpha1/doc/examples/lxc-no-netns.conf --- lxc-0.8.0~rc1/doc/examples/lxc-no-netns.conf 2012-03-01 23:04:48.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/examples/lxc-no-netns.conf 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -# Container with non-virtualized network -lxc.utsname = delta diff -Nru lxc-0.8.0~rc1/doc/examples/lxc-phys.conf lxc-1.0.0~alpha1/doc/examples/lxc-phys.conf --- lxc-0.8.0~rc1/doc/examples/lxc-phys.conf 2012-03-01 23:04:48.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/examples/lxc-phys.conf 1970-01-01 00:00:00.000000000 +0000 @@ -1,9 +0,0 @@ -# Container with network virtualized using a physical network device with name -# 'eth0' -lxc.utsname = gamma -lxc.network.type = phys -lxc.network.flags = up -lxc.network.link = eth0 -lxc.network.hwaddr = 4a:49:43:49:79:ff -lxc.network.ipv4 = 1.2.3.6/24 -lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3297 diff -Nru lxc-0.8.0~rc1/doc/examples/lxc-phys.conf.in lxc-1.0.0~alpha1/doc/examples/lxc-phys.conf.in --- lxc-0.8.0~rc1/doc/examples/lxc-phys.conf.in 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/examples/lxc-phys.conf.in 2013-07-08 15:50:40.000000000 +0000 @@ -5,5 +5,5 @@ lxc.network.flags = up lxc.network.link = eth0 lxc.network.hwaddr = 4a:49:43:49:79:ff -lxc.network.ipv4 = 1.2.3.6/24 +lxc.network.ipv4 = 10.2.3.6/24 lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3297 diff -Nru lxc-0.8.0~rc1/doc/examples/lxc-veth.conf lxc-1.0.0~alpha1/doc/examples/lxc-veth.conf --- lxc-0.8.0~rc1/doc/examples/lxc-veth.conf 2012-03-01 23:04:48.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/examples/lxc-veth.conf 1970-01-01 00:00:00.000000000 +0000 @@ -1,9 +0,0 @@ -# Container with network virtualized using a pre-configured bridge named br0 and -# veth pair virtual network devices -lxc.utsname = beta -lxc.network.type = veth -lxc.network.flags = up -lxc.network.link = br0 -lxc.network.hwaddr = 4a:49:43:49:79:bf -lxc.network.ipv4 = 1.2.3.5/24 -lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3597 diff -Nru lxc-0.8.0~rc1/doc/examples/lxc-veth.conf.in lxc-1.0.0~alpha1/doc/examples/lxc-veth.conf.in --- lxc-0.8.0~rc1/doc/examples/lxc-veth.conf.in 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/examples/lxc-veth.conf.in 2013-07-08 15:50:40.000000000 +0000 @@ -5,5 +5,5 @@ lxc.network.flags = up lxc.network.link = br0 lxc.network.hwaddr = 4a:49:43:49:79:bf -lxc.network.ipv4 = 1.2.3.5/24 +lxc.network.ipv4 = 10.2.3.5/24 lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3597 diff -Nru lxc-0.8.0~rc1/doc/examples/lxc-vlan.conf lxc-1.0.0~alpha1/doc/examples/lxc-vlan.conf --- lxc-0.8.0~rc1/doc/examples/lxc-vlan.conf 2012-03-01 23:04:48.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/examples/lxc-vlan.conf 1970-01-01 00:00:00.000000000 +0000 @@ -1,9 +0,0 @@ -# Container with network virtualized using the vlan device driver -lxc.utsname = alpha -lxc.network.type = vlan -lxc.network.vlan.id = 1234 -lxc.network.flags = up -lxc.network.link = eth0 -lxc.network.hwaddr = 4a:49:43:49:79:bd -lxc.network.ipv4 = 1.2.3.4/24 -lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3596 diff -Nru lxc-0.8.0~rc1/doc/examples/lxc-vlan.conf.in lxc-1.0.0~alpha1/doc/examples/lxc-vlan.conf.in --- lxc-0.8.0~rc1/doc/examples/lxc-vlan.conf.in 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/examples/lxc-vlan.conf.in 2013-07-08 15:50:40.000000000 +0000 @@ -5,5 +5,5 @@ lxc.network.flags = up lxc.network.link = eth0 lxc.network.hwaddr = 4a:49:43:49:79:bd -lxc.network.ipv4 = 1.2.3.4/24 +lxc.network.ipv4 = 10.2.3.4/24 lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3596 diff -Nru lxc-0.8.0~rc1/doc/legacy/lxc-ls.sgml.in lxc-1.0.0~alpha1/doc/legacy/lxc-ls.sgml.in --- lxc-0.8.0~rc1/doc/legacy/lxc-ls.sgml.in 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/legacy/lxc-ls.sgml.in 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,156 @@ + + + + +]> + + + + @LXC_GENERATE_DATE@ + + + lxc-ls + 1 + + + + lxc-ls + + + list the containers existing on the system + + + + + + lxc-ls + --active + ls options + + + + + Description + + lxc-ls list the containers existing on the + system. + + + + + Options + + + + + + + + + List active containers. + + + + + + + + + + + The option passed to lxc-ls are the + same as the ls command. + + + + + + + + + + Examples + + + lxc-ls -l + + + list all the container and their permissions. + + + + + + lxc-ls --active -1 + + + list active containers and display the list in one column. + + + + + + + + + See Also + + + + ls + 1 + , + + + + + &seealso; + + + Author + Daniel Lezcano daniel.lezcano@free.fr + + + + + diff -Nru lxc-0.8.0~rc1/doc/lxc-attach.1 lxc-1.0.0~alpha1/doc/lxc-attach.1 --- lxc-0.8.0~rc1/doc/lxc-attach.1 2012-03-01 23:04:54.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/lxc-attach.1 1970-01-01 00:00:00.000000000 +0000 @@ -1,137 +0,0 @@ -.\" This manpage has been automatically generated by docbook2man -.\" from a DocBook document. This tool can be found at: -.\" -.\" Please send any bug reports, improvements, comments, patches, -.\" etc. to Steve Cheng . -.TH "LXC-ATTACH" "1" "02 March 2012" "" "" - -.SH NAME -lxc-attach \- start a process inside a running container. -.SH SYNOPSIS - -\fBlxc-attach \fI-n -name\fB [-a -arch] [-e] -[-- command]\fR - -.SH "DESCRIPTION" -.PP -\fBlxc-attach\fR runs the specified -\fIcommand\fR inside the container -specified by \fIname\fR\&. The container -has to be running already. -.PP -If no \fIcommand\fR is specified, the -current default shell of the user running -\fBlxc-attach\fR will be looked up inside the -container and executed. This will fail if no such user exists -inside the container or the container does not have a working -nsswitch mechanism. -.SH "OPTIONS" -.TP -\fB -a, --arch \fIarch\fB \fR -Specify the architecture which the kernel should appear to be -running as to the command executed. This option will accept the -same settings as the \fBlxc.arch\fR option in -container configuration files, see -\fB\fIlxc.conf\fB\fR(5)\&. By default, the current archictecture of the -running container will be used. -.TP -\fB -e, --elevated-privileges \fR -Do not drop privileges when running -\fIcommand\fR inside the container. If -this option is specified, the new process will -\fBnot\fR be added to the container's cgroup(s) -and it will not drop its capabilities before executing. - -\fBWarning:\fR This may leak privileges into the -container if the command starts subprocesses that remain active -after the main process that was attached is terminated. The -(re-)starting of daemons inside the container is problematic, -especially if the daemon starts a lot of subprocesses such as -\fBcron\fR or \fBsshd\fR\&. -\fBUse with great care.\fR -.SH "COMMON OPTIONS" -.PP -These options are common to most of lxc commands. -.TP -\fB-?, -h, --help\fR -Print a longer usage message than normal. -.TP -\fB--usage\fR -Give the usage message -.TP -\fB-q, --quiet\fR -mute on -.TP -\fB-o, --logfile=\fIFILE\fB\fR -Output to an alternate log -\fIFILE\fR\&. The default is no log. -.TP -\fB-l, --logpriority=\fILEVEL\fB\fR -Set log priority to -\fILEVEL\fR\&. The default log -priority is ERROR\&. Possible values are : -FATAL, CRIT, -WARN, ERROR, -NOTICE, INFO, -DEBUG\&. - -Note that this option is setting the priority of the events -log in the alternate log file. It do not have effect on the -ERROR events log on stderr. -.TP -\fB-n, --name=\fINAME\fB\fR -Use container identifier \fINAME\fR\&. -The container identifier format is an alphanumeric string. -.SH "EXAMPLES" -.PP -To spawn a new shell running inside an existing container, use - -.nf - lxc-attach -n container - -.fi -.PP -To restart the cron service of a running Debian container, use - -.nf - lxc-attach -n container -- /etc/init.d/cron restart - -.fi -.PP -To deactivate the network link eth1 of a running container that -does not have the NET_ADMIN capability, use the \fB-e\fR -option to use increased capabilities: - -.nf - lxc-attach -n container -e -- /sbin/ip link delete eth1 - -.fi -.SH "SECURITY" -.PP -The \fB-e\fR should be used with care, as it may break -the isolation of the containers if used improperly. -.SH "SEE ALSO" -.PP -\fBlxc\fR(1), -\fBlxc-create\fR(1), -\fBlxc-destroy\fR(1), -\fBlxc-start\fR(1), -\fBlxc-stop\fR(1), -\fBlxc-execute\fR(1), -\fBlxc-kill\fR(1), -\fBlxc-console\fR(1), -\fBlxc-monitor\fR(1), -\fBlxc-wait\fR(1), -\fBlxc-cgroup\fR(1), -\fBlxc-ls\fR(1), -\fBlxc-ps\fR(1), -\fBlxc-info\fR(1), -\fBlxc-freeze\fR(1), -\fBlxc-unfreeze\fR(1), -\fBlxc-attach\fR(1), -\fBlxc.conf\fR(5) -.SH "AUTHOR" -.PP -Daniel Lezcano diff -Nru lxc-0.8.0~rc1/doc/lxc-attach.sgml.in lxc-1.0.0~alpha1/doc/lxc-attach.sgml.in --- lxc-0.8.0~rc1/doc/lxc-attach.sgml.in 2012-03-01 23:02:37.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/lxc-attach.sgml.in 2013-09-10 22:22:00.000000000 +0000 @@ -5,7 +5,7 @@ (C) Copyright IBM Corp. 2007, 2008 Authors: -Daniel Lezcano +Daniel Lezcano This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -19,11 +19,11 @@ 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 +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA --> - @@ -47,10 +47,17 @@ - lxc-attach -n - name -a - arch -e - -- command + + lxc-attach + -n name + -a arch + -e + -s namespaces + -R + --keep-env + --clear-env + -- command + @@ -122,7 +129,84 @@ - + + + + + + + Specify the namespaces to attach to, as a pipe-separated list, + e.g. NETWORK|IPC. Allowed values are + MOUNT, PID, + UTSNAME, IPC, + USER and + NETWORK. This allows one to change + the context of the process to e.g. the network namespace of the + container while retaining the other namespaces as those of the + host. + + + Important: This option implies + . + + + + + + + + + + + When using and the mount namespace is not + included, this flag will cause lxc-attach + to remount /proc and + /sys to reflect the current other + namespace contexts. + + + Please see the Notes section for more + details. + + + This option will be ignored if one tries to attach to the + mount namespace anyway. + + + + + + + + + + + Keep the current environment for attached programs. This is + the current default behaviour (as of version 0.9), but is + is likely to change in the future, since this may leak + undesirable information into the container. If you rely on + the environment being available for the attached program, + please use this option to be future-proof. In addition to + current environment variables, container=lxc will be set. + + + + + + + + + + + Clear the environment before attaching, so no undesired + environment variables leak into the container. The variable + container=lxc will be the only environment with which the + attached program starts. + + + + + @@ -144,19 +228,86 @@ To deactivate the network link eth1 of a running container that - does not have the NET_ADMIN capability, use the - option to use increased capabilities: + does not have the NET_ADMIN capability, use either the + option to use increased capabilities, + assuming the ip tool is installed: lxc-attach -n container -e -- /sbin/ip link delete eth1 + Or, alternatively, use the to use the + tools installed on the host outside the container: + + lxc-attach -n container -s NETWORK -- /sbin/ip link delete eth1 + + Compatibility + + Attaching completely (including the pid and mount namespaces) to a + container requires a patched kernel, please see the lxc website for + details. lxc-attach will fail in that case if + used with an unpatched kernel. + + + Nevertheless, it will succeed on an unpatched kernel of version 3.0 + or higher if the option is used to restrict the + namespaces that the process is to be attached to to one or more of + NETWORK, IPC + and UTSNAME. + + + Attaching to user namespaces is currently completely unsupported + by the kernel. lxc-attach should however be able + to do this once once future kernel versions implement this. + + + + + Notes + + The Linux /proc and + /sys filesystems contain information + about some quantities that are affected by namespaces, such as + the directories named after process ids in + /proc or the network interface infromation + in /sys/class/net. The namespace of the + process mounting the pseudo-filesystems determines what information + is shown, not the namespace of the process + accessing /proc or + /sys. + + + If one uses the option to only attach to + the pid namespace of a container, but not its mount namespace + (which will contain the /proc of the + container and not the host), the contents of + will reflect that of the host and not the container. Analogously, + the same issue occurs when reading the contents of + /sys/class/net and attaching to just + the network namespace. + + + To work around this problem, the flag provides + the option to remount /proc and + /sys in order for them to reflect the + network/pid namespace context of the attached process. In order + not to interfere with the host's actual filesystem, the mount + namespace will be unshared (like lxc-unshare + does) before this is done, esentially giving the process a new + mount namespace, which is identical to the hosts's mount namespace + except for the /proc and + /sys filesystems. + + + + Security - The should be used with care, as it may break - the isolation of the containers if used improperly. + The and options should + be used with care, as it may break the isolation of the containers + if used improperly. diff -Nru lxc-0.8.0~rc1/doc/lxc-cgroup.1 lxc-1.0.0~alpha1/doc/lxc-cgroup.1 --- lxc-0.8.0~rc1/doc/lxc-cgroup.1 2012-03-01 23:04:54.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/lxc-cgroup.1 1970-01-01 00:00:00.000000000 +0000 @@ -1,100 +0,0 @@ -.\" This manpage has been automatically generated by docbook2man -.\" from a DocBook document. This tool can be found at: -.\" -.\" Please send any bug reports, improvements, comments, patches, -.\" etc. to Steve Cheng . -.TH "LXC-CGROUP" "1" "02 March 2012" "" "" - -.SH NAME -lxc-cgroup \- manage the control group associated with a container -.SH SYNOPSIS - -\fBlxc-start \fI-n name\fB -\fIsubsystem\fB [value] -\fR - -.SH "DESCRIPTION" -.PP -\fBlxc-cgroup\fR get or set value from the control -group associated with the -container \fIname\fR\&. If -no [value] is specified, the value of -the \fIsubsystem\fR is displayed, otherwise -it is set. The \fBlxc-cgroup\fR does not assume the -correctness of the \fIsubsystem\fR name, it -is up to the user to specify the -right \fIsubsystem\fR name. -.SH "OPTIONS" -.TP -\fB \fIsubsystem\fB \fR -Specify the subsystem control group name. -.TP -\fB [value] \fR -Specify the subsystem control group value to be set. -.SH "COMMON OPTIONS" -.PP -These options are common to most of lxc commands. -.TP -\fB-?, -h, --help\fR -Print a longer usage message than normal. -.TP -\fB--usage\fR -Give the usage message -.TP -\fB-q, --quiet\fR -mute on -.TP -\fB-o, --logfile=\fIFILE\fB\fR -Output to an alternate log -\fIFILE\fR\&. The default is no log. -.TP -\fB-l, --logpriority=\fILEVEL\fB\fR -Set log priority to -\fILEVEL\fR\&. The default log -priority is ERROR\&. Possible values are : -FATAL, CRIT, -WARN, ERROR, -NOTICE, INFO, -DEBUG\&. - -Note that this option is setting the priority of the events -log in the alternate log file. It do not have effect on the -ERROR events log on stderr. -.TP -\fB-n, --name=\fINAME\fB\fR -Use container identifier \fINAME\fR\&. -The container identifier format is an alphanumeric string. -.SH "EXAMPLES" -.TP -\fBlxc-cgroup -n foo devices.list\fR -display the allowed devices to be used. -.TP -\fBlxc-cgroup -n foo cpuset.cpus "0,3"\fR -assign the processors 0 and 3 to the container. -.SH "DIAGNOSTIC" -.TP -\fBThe container was not found\fR -The container is not running. -.SH "SEE ALSO" -.PP -\fBlxc\fR(1), -\fBlxc-create\fR(1), -\fBlxc-destroy\fR(1), -\fBlxc-start\fR(1), -\fBlxc-stop\fR(1), -\fBlxc-execute\fR(1), -\fBlxc-kill\fR(1), -\fBlxc-console\fR(1), -\fBlxc-monitor\fR(1), -\fBlxc-wait\fR(1), -\fBlxc-cgroup\fR(1), -\fBlxc-ls\fR(1), -\fBlxc-ps\fR(1), -\fBlxc-info\fR(1), -\fBlxc-freeze\fR(1), -\fBlxc-unfreeze\fR(1), -\fBlxc-attach\fR(1), -\fBlxc.conf\fR(5) -.SH "AUTHOR" -.PP -Daniel Lezcano diff -Nru lxc-0.8.0~rc1/doc/lxc-cgroup.sgml.in lxc-1.0.0~alpha1/doc/lxc-cgroup.sgml.in --- lxc-0.8.0~rc1/doc/lxc-cgroup.sgml.in 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/lxc-cgroup.sgml.in 2013-09-10 22:22:00.000000000 +0000 @@ -1,11 +1,11 @@ - - @@ -48,9 +48,10 @@ - lxc-start -n name - subsystem value - + lxc-cgroup + -n name + state-object + value @@ -58,17 +59,20 @@ Description - lxc-cgroup get or set value from the control - group associated with the - container name. If - no value is specified, the value of - the subsystem is displayed, otherwise - it is set. The lxc-cgroup does not assume the - correctness of the subsystem name, it - is up to the user to specify the - right subsystem name. + lxc-cgroup gets or sets the value of a + state-object (e.g., 'cpuset.cpus') + in the container's cgroup for the corresponding subsystem (e.g., + 'cpuset'). If no value is specified, the + current value of the state-object is + displayed; otherwise it is set. + + Note that lxc-cgroup does not check that the + state-object is valid for the running + kernel, or that the corresponding subsystem is contained in any + mounted cgroup hierarchy. + @@ -77,11 +81,11 @@ - + - Specify the subsystem control group name. + Specify the state object name. @@ -92,7 +96,7 @@ - Specify the subsystem control group value to be set. + Specify the value to assign to the state object. @@ -139,7 +143,7 @@ The container is not running. - + diff -Nru lxc-0.8.0~rc1/doc/lxc-checkconfig.sgml.in lxc-1.0.0~alpha1/doc/lxc-checkconfig.sgml.in --- lxc-0.8.0~rc1/doc/lxc-checkconfig.sgml.in 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/lxc-checkconfig.sgml.in 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,98 @@ + + + +]> + + + + @LXC_GENERATE_DATE@ + + + lxc-checkconfig + 1 + + + + lxc-checkconfig + + + check the current kernel for lxc support + + + + + + lxc-checkconfig + + + + + Description + + lxc-checkconfig check the current kernel for + lxc support + + + + + Examples + + + lxc-checkconfig + + + check the current kernel. + CONFIG can be set in the environment to an alternate location. + + + + + + + &seealso; + + + Author + Stéphane Graber stgraber@ubuntu.com + + + + diff -Nru lxc-0.8.0~rc1/doc/lxc-checkpoint.1 lxc-1.0.0~alpha1/doc/lxc-checkpoint.1 --- lxc-0.8.0~rc1/doc/lxc-checkpoint.1 2012-03-01 23:04:52.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/lxc-checkpoint.1 1970-01-01 00:00:00.000000000 +0000 @@ -1,140 +0,0 @@ -.\" This manpage has been automatically generated by docbook2man -.\" from a DocBook document. This tool can be found at: -.\" -.\" Please send any bug reports, improvements, comments, patches, -.\" etc. to Steve Cheng . -.TH "LXC-CHECKPOINT" "1" "02 March 2012" "IBM" "" - -.SH NAME -lxc-checkpoint \- checkpoint a running container (not implemented yet) -.SH SYNOPSIS - -\fBlxc-checkpoint ---statefile=\fIFILE\fB ---statefd=\fIFD\fB ---name=\fINAME\fB \fR [ \fB-k|-p\fR ] - -.SH "DESCRIPTION" -.PP -\fBlxc-checkpoint\fR is a command -to checkpoint the specified container -\fINAME\fR and dumps its state into the file -\fIFILE\fR\&. If the -option \fB--kill\fR is specified, the application -running in the container will terminate after the checkpoint -just before resuming its execution. If the -option \fB--pause\fR is specified, the application -will be stopped after the checkpoint just before resuming -execution. The command \fBlxc-unfreeze\fR will -resume its execution. -.SH "CHECKPOINT OPTIONS" -.TP -\fB-S, --statefile=\fIFILE\fB\fR -write the state of the container in this -\fIFILE\fR\&. -This option is exclusive with \fB--statefd\fR below. -.TP -\fB-d, --statefd=\fIFD\fB\fR -write the state of the container in this -\fIFD\fR file descriptor. -This option is exclusive with above \fB--statefile\fR\&. -.TP -\fB-k,--kill\fR -Kill container processes after checkpoint. the processes are sent -a SIGKILL signal. - -This option is mutually exclusive with the following -\fB--pause\fR option. -.TP -\fB-p,--pause\fR -Pause container processes after checkpoint. The container -will be stopped until you resume it. This option is -mutually exclusive with previously mentionned -\fB--kill\fR option. -.SH "COMMON OPTIONS" -.PP -These options are common to most of lxc commands. -.TP -\fB-?, -h, --help\fR -Print a longer usage message than normal. -.TP -\fB--usage\fR -Give the usage message -.TP -\fB-q, --quiet\fR -mute on -.TP -\fB-o, --logfile=\fIFILE\fB\fR -Output to an alternate log -\fIFILE\fR\&. The default is no log. -.TP -\fB-l, --logpriority=\fILEVEL\fB\fR -Set log priority to -\fILEVEL\fR\&. The default log -priority is ERROR\&. Possible values are : -FATAL, CRIT, -WARN, ERROR, -NOTICE, INFO, -DEBUG\&. - -Note that this option is setting the priority of the events -log in the alternate log file. It do not have effect on the -ERROR events log on stderr. -.TP -\fB-n, --name=\fINAME\fB\fR -Use container identifier \fINAME\fR\&. -The container identifier format is an alphanumeric string. -.SH "EXAMPLES" -.PP -To start a new container 123 computing decimals of pi - -.nf - lxc-execute -n 123 -- pi1 -d 500000 - lxc-execute --name=123 -- pi1 -d 500000 - -.fi -.PP -to checkpoint the same container in \fBdump-death\fR -mode - -.nf - lxc-checkpoint -n 123 -S /share/123/chkpt1 -k - lxc-checkpoint --name=123 -S /share/123/chkpt1 -k - -.fi -.PP -to checkpoint the same container and \fBpause\fR it - -.nf - lxc-checkpoint -n 123 -S /share/123/chkpt1 -p - lxc-checkpoint --name=123 -S /share/123/chkpt1 -p - -.fi -.SH "NOTES" -.PP -Actually, this command does not operate. Its description -helps to define a CLI api for future Checkpoint / Restart -solution -.SH "SEE ALSO" -.PP -\fBlxc\fR(1), -\fBlxc-create\fR(1), -\fBlxc-destroy\fR(1), -\fBlxc-start\fR(1), -\fBlxc-stop\fR(1), -\fBlxc-execute\fR(1), -\fBlxc-kill\fR(1), -\fBlxc-console\fR(1), -\fBlxc-monitor\fR(1), -\fBlxc-wait\fR(1), -\fBlxc-cgroup\fR(1), -\fBlxc-ls\fR(1), -\fBlxc-ps\fR(1), -\fBlxc-info\fR(1), -\fBlxc-freeze\fR(1), -\fBlxc-unfreeze\fR(1), -\fBlxc-attach\fR(1), -\fBlxc.conf\fR(5) -.SH "AUTHOR" -.PP -Daniel Lezcano diff -Nru lxc-0.8.0~rc1/doc/lxc-checkpoint.sgml.in lxc-1.0.0~alpha1/doc/lxc-checkpoint.sgml.in --- lxc-0.8.0~rc1/doc/lxc-checkpoint.sgml.in 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/lxc-checkpoint.sgml.in 2013-09-10 22:22:00.000000000 +0000 @@ -5,7 +5,7 @@ (C) Copyright IBM Corp. 2007, 2008 Authors: -Daniel Lezcano +Daniel Lezcano This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -19,11 +19,11 @@ 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 +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA --> - @@ -49,10 +49,10 @@ - lxc-checkpoint - --statefile=FILE - --statefd=FD - --name=NAME + lxc-checkpoint + --statefile=FILE + --statefd=FD + --name=NAME | diff -Nru lxc-0.8.0~rc1/doc/lxc-clone.sgml.in lxc-1.0.0~alpha1/doc/lxc-clone.sgml.in --- lxc-0.8.0~rc1/doc/lxc-clone.sgml.in 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/lxc-clone.sgml.in 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,288 @@ + + + + +]> + + + + @LXC_GENERATE_DATE@ + + + lxc-clone + 1 + + + + lxc-clone + + + clone a new container from an existing one. + + + + + + lxc-clone + -s + -K + -M + -H + -B backingstore + -L fssize + -p lxcpath + -P newlxcpath + -o orig + -n new + -- hook arguments + + + lxc-clone + -s + -K + -M + -H + -B backingstore + -L fssize + -p lxcpath + -P newlxcpath + orig + new + -- hook arguments + + + + + Description + + + lxc-clone Creates a new container as a clone of an existing + container. Two types of clones are supported: copy and snapshot. A copy + clone copies the root filessytem from the original container to the new. A + snapshot filesystem uses the backing store's snapshot functionality to create + a very small copy-on-write snapshot of the original container. Snapshot + clones require the new container backing store to support snapshotting. Currently + this includes only btrfs, lvm, overlayfs and zfs. LVM devices do not support + snapshots fo snapshots. + + + + The backing store of the new container will be the same type as the + original container, + with one exception: overlayfs snapshots can be created of directory backed + containers. This can be requested by using the -B overlayfs + arguments. + + + + The names of the original and new container can be given (in that order) + after all options, or can be specified with the + -o and -n options, + respectively. + + + + + + + Options + + + + + + + + + + The new container's rootfs should be a LVM or btrfs snapshot of the original. + + + + + + + + + + + Do not change the hostname of the container (in the root + filesystem). + + + + + + + + + + + Use the same MAC address as the original container, rather tahn + generating a new random one. + + + + + + + + + + + Copy all mount hooks into the new container's directory, and + update any lxcpaths and container names as needed. + + + + + + + + + + + In the case of a block device backed container, a size for the new + block device. By default, the new device will be made the + same size as the original. + + + + + + + + + + + The lxcpath of the original container. By default, the system + wide configured lxcpath will be used. + + + + + + + + + + + The lxcpath for the new container. By default the same lxcpath + as the original will be used. Note that with btrfs snapshots, + changing lxcpaths may not be possible, as subvolume snapshots + must be in the same btrfs filesystem. + + + + + + + + + + + Select a different backing store for the new container. By + default the same as the original container's is used. Note that + currently changing the backingstore is only supported for + overlayfs snapshots of directory backed containers. Valid + backing stores include dir (directory), btrfs, lvm, zfs, loop + and overlayfs. + + + + + + + + + + + The name of the original container to clone. + + + + + + + + + + + The name of the new container to create. + + + + + + + + + + + Clone hook + + If the container being cloned has one or more lxc.hook.clone + specified, then the specified hooks will be called for the new container. The + first 3 arguments passed to the clone hook will be the container name, a section + ('lxc'), and the hook type ('clone'). Extra arguments passed + lxc-clone will be passed to the hook program starting at + argument 4. The LXC_ROOTFS_MOUNT environment variable gives + the path under which the container's root filesystem is mounted. The + configuration file pathname is stored in LXC_CONFIG_FILE, the + new container name in LXC_NAME, the old container name in + LXC_SRC_NAME, and the path or device on which + the rootfs is located is in LXC_ROOTFS_PATH. + + + + &seealso; + + + Author + Serge Hallyn serge.hallyn@ubuntu.com + + + + + diff -Nru lxc-0.8.0~rc1/doc/lxc-console.1 lxc-1.0.0~alpha1/doc/lxc-console.1 --- lxc-0.8.0~rc1/doc/lxc-console.1 2012-03-01 23:04:53.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/lxc-console.1 1970-01-01 00:00:00.000000000 +0000 @@ -1,96 +0,0 @@ -.\" This manpage has been automatically generated by docbook2man -.\" from a DocBook document. This tool can be found at: -.\" -.\" Please send any bug reports, improvements, comments, patches, -.\" etc. to Steve Cheng . -.TH "LXC-CONSOLE" "1" "02 March 2012" "" "" - -.SH NAME -lxc-console \- Launch a console for the specified container -.SH SYNOPSIS - -\fBlxc-console \fI-n name\fB -[-t ttynum] -\fR - -.SH "DESCRIPTION" -.PP -If the tty service has been configured and is available for the -container specified as parameter, this command will launch a -console allowing to log on the container. -.PP -The available tty are free slots taken by this command. That -means if the container has four ttys available and the command -has been launched four times taking the different tty, the fifth -command will fail because no console will be available. -.PP -The command will connect to a tty. If the connection is lost or -broken, the command can be launched again and regain the tty at -the state it was before the disconnection. -.SH "OPTIONS" -.TP -\fB -t [ttynum] \fR -Specify the tty number to connect, if not specified a tty -number will be automatically choosen by the container. -.SH "COMMON OPTIONS" -.PP -These options are common to most of lxc commands. -.TP -\fB-?, -h, --help\fR -Print a longer usage message than normal. -.TP -\fB--usage\fR -Give the usage message -.TP -\fB-q, --quiet\fR -mute on -.TP -\fB-o, --logfile=\fIFILE\fB\fR -Output to an alternate log -\fIFILE\fR\&. The default is no log. -.TP -\fB-l, --logpriority=\fILEVEL\fB\fR -Set log priority to -\fILEVEL\fR\&. The default log -priority is ERROR\&. Possible values are : -FATAL, CRIT, -WARN, ERROR, -NOTICE, INFO, -DEBUG\&. - -Note that this option is setting the priority of the events -log in the alternate log file. It do not have effect on the -ERROR events log on stderr. -.TP -\fB-n, --name=\fINAME\fB\fR -Use container identifier \fINAME\fR\&. -The container identifier format is an alphanumeric string. -.SH "DIAGNOSTIC" -.TP -\fBtty service denied\fR -No tty is available or there is not enough privilege to -use the console. For example, the container belongs to -user "foo" and "bar" is trying to open a console to it. -.SH "SEE ALSO" -.PP -\fBlxc\fR(1), -\fBlxc-create\fR(1), -\fBlxc-destroy\fR(1), -\fBlxc-start\fR(1), -\fBlxc-stop\fR(1), -\fBlxc-execute\fR(1), -\fBlxc-kill\fR(1), -\fBlxc-console\fR(1), -\fBlxc-monitor\fR(1), -\fBlxc-wait\fR(1), -\fBlxc-cgroup\fR(1), -\fBlxc-ls\fR(1), -\fBlxc-ps\fR(1), -\fBlxc-info\fR(1), -\fBlxc-freeze\fR(1), -\fBlxc-unfreeze\fR(1), -\fBlxc-attach\fR(1), -\fBlxc.conf\fR(5) -.SH "AUTHOR" -.PP -Daniel Lezcano diff -Nru lxc-0.8.0~rc1/doc/lxc-console.sgml.in lxc-1.0.0~alpha1/doc/lxc-console.sgml.in --- lxc-0.8.0~rc1/doc/lxc-console.sgml.in 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/lxc-console.sgml.in 2013-09-10 22:22:00.000000000 +0000 @@ -1,11 +1,11 @@ - - @@ -48,9 +48,10 @@ - lxc-console -n name - -t ttynum - + lxc-console + -n name + -e escape character + -t ttynum @@ -66,8 +67,8 @@ The available tty are free slots taken by this command. That means if the container has four ttys available and the command - has been launched four times taking the different tty, the fifth - command will fail because no console will be available. + has been launched four times each taking a different tty, the + fifth command will fail because no console will be available. @@ -76,6 +77,17 @@ the state it was before the disconnection. + + A ttynum of 0 may be given to attach + to the container's /dev/console instead of its + dev/tty<ttynum>. + + + + A keyboard escape sequence may be used to disconnect from the tty + and quit lxc-console. The default escape sequence is <Ctrl+a q>. + + @@ -84,12 +96,26 @@ - + - Specify the tty number to connect, if not specified a tty - number will be automatically choosen by the container. + Specify the escape sequence prefix to use instead of + <Ctrl a>. + This may be given as '^letter' or just 'letter'. For example + to use <Ctrl+b q> as the escape sequence use -e '^b'. + + + + + + + + + + Specify the tty number to connect to or 0 for the console. If not + specified the next available tty number will be automatically + choosen by the container. @@ -114,7 +140,7 @@ user "foo" and "bar" is trying to open a console to it. - + diff -Nru lxc-0.8.0~rc1/doc/lxc-create.1 lxc-1.0.0~alpha1/doc/lxc-create.1 --- lxc-0.8.0~rc1/doc/lxc-create.1 2012-03-01 23:04:51.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/lxc-create.1 1970-01-01 00:00:00.000000000 +0000 @@ -1,76 +0,0 @@ -.\" This manpage has been automatically generated by docbook2man -.\" from a DocBook document. This tool can be found at: -.\" -.\" Please send any bug reports, improvements, comments, patches, -.\" etc. to Steve Cheng . -.TH "LXC-CREATE" "1" "02 March 2012" "" "" - -.SH NAME -lxc-create \- creates a container -.SH SYNOPSIS - -\fBlxc-create \fI-n name\fB -[-f config_file] -[-t template]\fR - -.SH "DESCRIPTION" -.PP -\fBlxc-create\fR creates a system object where is -stored the configuration informations and where can be stored -user information. The identifier \fIname\fR -is used to specify the container to be used with the different -lxc commands. -.PP -The object is a directory created in \fI${localstatedir}/lib/lxc\fR -and identified by its name. -.PP -The object is the definition of the different resources an -application can use or can see. The more the configuration file -contains informations, the more the container is isolated and -the more the application is jailed. -.PP -If the configuration file \fIconfig_file\fR -is not specified, the container will be created with the default -isolation: processes, sysv ipc and mount points. -.SH "OPTIONS" -.TP -\fB -f \fIconfig_file\fB \fR -Specify the configuration file to configure the virtualization -and isolation functionalities for the container. -.TP -\fB -t \fItemplate\fB \fR -\&'template' is the short name of an existing 'lxc-template' -script that is called by lxc-create, -eg. busybox, debian, fedora, ubuntu or sshd. -Refer to the examples in \fI${libdir}/lxc/templates\fR -for details of the expected script structure. -.SH "DIAGNOSTIC" -.TP -\fBThe container already exists\fR -As the message mention it, you try to create a container -but there is a container with the same name. You can use -the \fBlxc-ls -l\fR command to list the -available containers on the system. -.SH "SEE ALSO" -.PP -\fBlxc\fR(1), -\fBlxc-create\fR(1), -\fBlxc-destroy\fR(1), -\fBlxc-start\fR(1), -\fBlxc-stop\fR(1), -\fBlxc-execute\fR(1), -\fBlxc-kill\fR(1), -\fBlxc-console\fR(1), -\fBlxc-monitor\fR(1), -\fBlxc-wait\fR(1), -\fBlxc-cgroup\fR(1), -\fBlxc-ls\fR(1), -\fBlxc-ps\fR(1), -\fBlxc-info\fR(1), -\fBlxc-freeze\fR(1), -\fBlxc-unfreeze\fR(1), -\fBlxc-attach\fR(1), -\fBlxc.conf\fR(5) -.SH "AUTHOR" -.PP -Daniel Lezcano diff -Nru lxc-0.8.0~rc1/doc/lxc-create.sgml.in lxc-1.0.0~alpha1/doc/lxc-create.sgml.in --- lxc-0.8.0~rc1/doc/lxc-create.sgml.in 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/lxc-create.sgml.in 2013-09-10 22:22:00.000000000 +0000 @@ -1,11 +1,11 @@ - - @@ -48,9 +48,12 @@ - lxc-create -n name - -f config_file - -t template + lxc-create + -n name + -f config_file + -t template + -B backingstore + -- template-options @@ -110,6 +113,54 @@ eg. busybox, debian, fedora, ubuntu or sshd. Refer to the examples in @LXCTEMPLATEDIR@ for details of the expected script structure. + Alternatively, the full path to an executable template script + can also be passed as a parameter. + + + + + + + + + + + 'backingstore' is one of 'none', 'dir', 'lvm', 'loop', or 'btrfs'. The + default is 'none', meaning that the container root filesystem + will be a directory under @LXCPATH@/container/rootfs. + 'dir' has the same meaning as 'none', but also allows the optional + --dir ROOTFS to be specified, meaning + that the container rootfs should be placed under the specified path, + rather than the default. If 'btrfs' is specified, then the + target filesystem must be btrfs, and the container rootfs will be + created as a new subvolume. This allows snapshotted clones to be + created, but also causes rsync --one-filesystem to treat it as a + separate filesystem. + If backingstore is 'lvm', then an lvm block device will be + used and the following further options are available: + --lvname lvname1 will create an LV + named lvname1 rather than the default, which + is the container name. --vgname vgname1 + will create the LV in volume group vgname1 + rather than the default, lxc. + --fstype FSTYPE will create an FSTYPE + filesystem on the LV, rather than the default, which is ext4. + --fssize SIZE will create a LV (and + filesystem) of size SIZE rather than the default, which is 1G. + + + + + + + + + + + This will pass template-options to the + template as arguments. To see the list of options supported by + the template, you can run + lxc-create -t TEMPLATE -h. @@ -133,7 +184,7 @@ available containers on the system. - + diff -Nru lxc-0.8.0~rc1/doc/lxc-destroy.1 lxc-1.0.0~alpha1/doc/lxc-destroy.1 --- lxc-0.8.0~rc1/doc/lxc-destroy.1 2012-03-01 23:04:52.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/lxc-destroy.1 1970-01-01 00:00:00.000000000 +0000 @@ -1,48 +0,0 @@ -.\" This manpage has been automatically generated by docbook2man -.\" from a DocBook document. This tool can be found at: -.\" -.\" Please send any bug reports, improvements, comments, patches, -.\" etc. to Steve Cheng . -.TH "LXC-DESTROY" "1" "02 March 2012" "" "" - -.SH NAME -lxc-destroy \- destroy a container. -.SH SYNOPSIS - -\fBlxc-destroy \fI-n -name\fB\fR - -.SH "DESCRIPTION" -.PP -\fBlxc-destroy\fR destroys the system object -previously created by the \fBlxc-create\fR command. -.SH "DIAGNOSTIC" -.TP -\fBThe container was not found\fR -The specified container for destruction was not found. It -is probable it does not exists and was already -destroyed.You can use the \fBlxc-ls -l\fR -command to list the available containers on the system. -.SH "SEE ALSO" -.PP -\fBlxc\fR(1), -\fBlxc-create\fR(1), -\fBlxc-destroy\fR(1), -\fBlxc-start\fR(1), -\fBlxc-stop\fR(1), -\fBlxc-execute\fR(1), -\fBlxc-kill\fR(1), -\fBlxc-console\fR(1), -\fBlxc-monitor\fR(1), -\fBlxc-wait\fR(1), -\fBlxc-cgroup\fR(1), -\fBlxc-ls\fR(1), -\fBlxc-ps\fR(1), -\fBlxc-info\fR(1), -\fBlxc-freeze\fR(1), -\fBlxc-unfreeze\fR(1), -\fBlxc-attach\fR(1), -\fBlxc.conf\fR(5) -.SH "AUTHOR" -.PP -Daniel Lezcano diff -Nru lxc-0.8.0~rc1/doc/lxc-destroy.sgml.in lxc-1.0.0~alpha1/doc/lxc-destroy.sgml.in --- lxc-0.8.0~rc1/doc/lxc-destroy.sgml.in 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/lxc-destroy.sgml.in 2013-09-10 22:22:00.000000000 +0000 @@ -1,11 +1,11 @@ - - @@ -48,8 +48,9 @@ - lxc-destroy -n - name + lxc-destroy + -n name + -f @@ -64,6 +65,35 @@ + + Options + + + + + + + + + If a container is running, stop it first. If this option is + not specified and the container is running, then + lxc-destroy will be aborted. + + + + + + + + Use an alternate container path. The default is @LXCPATH@. + + + + + + + + Diagnostic @@ -78,7 +108,7 @@ command to list the available containers on the system. - + diff -Nru lxc-0.8.0~rc1/doc/lxc-device.sgml.in lxc-1.0.0~alpha1/doc/lxc-device.sgml.in --- lxc-0.8.0~rc1/doc/lxc-device.sgml.in 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/lxc-device.sgml.in 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,174 @@ + + + + +]> + + + + @LXC_GENERATE_DATE@ + + + lxc-device + 1 + + + + lxc-device + + + manage deices of running containers + + + + + + lxc-device + -h + -n name + add + DEVICE + NAME + + + + + Description + + lxc-device manages devices in running container. + + + + + Options + + + + + + + + The full command help message. + + + + + + + + + + + The name of the target container. + + + + + + + + + + + What action to perform. Only 'add' is supported at this point. + + + + + + + + + + + The device to add to the container. + It can either be the path to a device under /dev or a network + interface name. + + + + + + + + + + + Name for the device within the container. + + + + + + + + Examples + + + lxc-device -n p1 add /dev/video0 + + + Creates a /dev/video0 device in container p1 based on the matching + device on the host. + + + + + + lxc-device -n p1 add eth0 eth1 + + + Moves eth0 from the host as eth1 in p1. + + + + + + + &seealso; + + + Author + Stéphane Graber stgraber@ubuntu.com + + + + diff -Nru lxc-0.8.0~rc1/doc/lxc-execute.1 lxc-1.0.0~alpha1/doc/lxc-execute.1 --- lxc-0.8.0~rc1/doc/lxc-execute.1 2012-03-01 23:04:52.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/lxc-execute.1 1970-01-01 00:00:00.000000000 +0000 @@ -1,131 +0,0 @@ -.\" This manpage has been automatically generated by docbook2man -.\" from a DocBook document. This tool can be found at: -.\" -.\" Please send any bug reports, improvements, comments, patches, -.\" etc. to Steve Cheng . -.TH "LXC-EXECUTE" "1" "02 March 2012" "" "" - -.SH NAME -lxc-execute \- run an application inside a container. -.SH SYNOPSIS - -\fBlxc-execute \fI-n name\fB -[-f config_file] [-s KEY=VAL -] -[--] -\fIcommand\fB\fR - -.SH "DESCRIPTION" -.PP -\fBlxc-execute\fR runs the specified -\fIcommand\fR inside the container -specified by \fIname\fR\&. -.PP -It will setup the container -according to the configuration previously defined with the -lxc-create command or with the configuration file parameter. -If no configuration is -defined, the default isolation is used. -.PP -This command is mainly used when you want to quickly launch an -application in an isolated environment. -.PP -\fBlxc-execute\fR command will run the -specified command into the container via an intermediate -process, \fBlxc-init\fR\&. -This lxc-init after launching the specified command, -will wait for its end and all other reparented processes. -(that allows to support daemons in the container). -In other words, in the -container, \fBlxc-init\fR has the pid 1 and the -first process of the application has the pid 2. -.PP -The above \fBlxc-init\fR is designed to forward received -signals to the started command. -So \fBlxc-kill\fR (1) sent signal is received -by the user specified command (pid 2 in the container). -.SH "OPTIONS" -.TP -\fB -f, --rcfile \fIconfig_file\fB \fR -Specify the configuration file to configure the virtualization -and isolation functionalities for the container. - -This configuration file if present will be used even if there is -already a configuration file present in the previously created -container (via lxc-create). -.TP -\fB -s, --define \fIKEY=VAL\fB \fR -Assign value \fIVAL\fR to configuration -variable \fIKEY\fR\&. This overrides any -assignment done in \fIconfig_file\fR\&. -.TP -\fB--\fR -Signal the end of options and disables further option -processing. Any arguments after the -- are treated as -arguments. - -This option is useful when you want to execute, with the -command \fBlxc-execute\fR, a command line -with its own options. -.SH "COMMON OPTIONS" -.PP -These options are common to most of lxc commands. -.TP -\fB-?, -h, --help\fR -Print a longer usage message than normal. -.TP -\fB--usage\fR -Give the usage message -.TP -\fB-q, --quiet\fR -mute on -.TP -\fB-o, --logfile=\fIFILE\fB\fR -Output to an alternate log -\fIFILE\fR\&. The default is no log. -.TP -\fB-l, --logpriority=\fILEVEL\fB\fR -Set log priority to -\fILEVEL\fR\&. The default log -priority is ERROR\&. Possible values are : -FATAL, CRIT, -WARN, ERROR, -NOTICE, INFO, -DEBUG\&. - -Note that this option is setting the priority of the events -log in the alternate log file. It do not have effect on the -ERROR events log on stderr. -.TP -\fB-n, --name=\fINAME\fB\fR -Use container identifier \fINAME\fR\&. -The container identifier format is an alphanumeric string. -.SH "DIAGNOSTIC" -.TP -\fBThe container is busy\fR -The specified container is already running an -application. You should stop it before reuse this -container or create a new one. -.SH "SEE ALSO" -.PP -\fBlxc\fR(1), -\fBlxc-create\fR(1), -\fBlxc-destroy\fR(1), -\fBlxc-start\fR(1), -\fBlxc-stop\fR(1), -\fBlxc-execute\fR(1), -\fBlxc-kill\fR(1), -\fBlxc-console\fR(1), -\fBlxc-monitor\fR(1), -\fBlxc-wait\fR(1), -\fBlxc-cgroup\fR(1), -\fBlxc-ls\fR(1), -\fBlxc-ps\fR(1), -\fBlxc-info\fR(1), -\fBlxc-freeze\fR(1), -\fBlxc-unfreeze\fR(1), -\fBlxc-attach\fR(1), -\fBlxc.conf\fR(5) -.SH "AUTHOR" -.PP -Daniel Lezcano diff -Nru lxc-0.8.0~rc1/doc/lxc-execute.sgml.in lxc-1.0.0~alpha1/doc/lxc-execute.sgml.in --- lxc-0.8.0~rc1/doc/lxc-execute.sgml.in 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/lxc-execute.sgml.in 2013-09-10 22:22:00.000000000 +0000 @@ -1,11 +1,11 @@ - - @@ -48,11 +48,11 @@ - lxc-execute -n name - -f config_file -s KEY=VAL - - -- - command + lxc-execute + -n name + -f config_file + -s KEY=VAL + -- command @@ -132,12 +132,12 @@ Signal the end of options and disables further option processing. Any arguments after the -- are treated as - arguments. + arguments to command. - This option is useful when you want to execute, with the - command lxc-execute, a command line - with its own options. + This option is useful when you want specify options + to command and don't want + lxc-execute to interpret them. @@ -162,7 +162,7 @@ container or create a new one. - + diff -Nru lxc-0.8.0~rc1/doc/lxc-freeze.1 lxc-1.0.0~alpha1/doc/lxc-freeze.1 --- lxc-0.8.0~rc1/doc/lxc-freeze.1 2012-03-01 23:04:53.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/lxc-freeze.1 1970-01-01 00:00:00.000000000 +0000 @@ -1,82 +0,0 @@ -.\" This manpage has been automatically generated by docbook2man -.\" from a DocBook document. This tool can be found at: -.\" -.\" Please send any bug reports, improvements, comments, patches, -.\" etc. to Steve Cheng . -.TH "LXC-FREEZE" "1" "02 March 2012" "" "" - -.SH NAME -lxc-freeze \- freeze all the container's processes -.SH SYNOPSIS - -\fBlxc-freeze \fI-n name\fB -\fR - -.SH "DESCRIPTION" -.PP -\fBlxc-freeze\fR freezes all the processes running -inside the container. The processes will be blocked until they -are explicitly thawed by the \fBlxc-unfreeze\fR -command. This command is useful for batch managers to schedule a -group of processes. -.SH "COMMON OPTIONS" -.PP -These options are common to most of lxc commands. -.TP -\fB-?, -h, --help\fR -Print a longer usage message than normal. -.TP -\fB--usage\fR -Give the usage message -.TP -\fB-q, --quiet\fR -mute on -.TP -\fB-o, --logfile=\fIFILE\fB\fR -Output to an alternate log -\fIFILE\fR\&. The default is no log. -.TP -\fB-l, --logpriority=\fILEVEL\fB\fR -Set log priority to -\fILEVEL\fR\&. The default log -priority is ERROR\&. Possible values are : -FATAL, CRIT, -WARN, ERROR, -NOTICE, INFO, -DEBUG\&. - -Note that this option is setting the priority of the events -log in the alternate log file. It do not have effect on the -ERROR events log on stderr. -.TP -\fB-n, --name=\fINAME\fB\fR -Use container identifier \fINAME\fR\&. -The container identifier format is an alphanumeric string. -.SH "DIAGNOSTIC" -.TP -\fBThe container was not found\fR -The specified container was not created before with -the \fBlxc-create\fR command. -.SH "SEE ALSO" -.PP -\fBlxc\fR(1), -\fBlxc-create\fR(1), -\fBlxc-destroy\fR(1), -\fBlxc-start\fR(1), -\fBlxc-stop\fR(1), -\fBlxc-execute\fR(1), -\fBlxc-kill\fR(1), -\fBlxc-console\fR(1), -\fBlxc-monitor\fR(1), -\fBlxc-wait\fR(1), -\fBlxc-cgroup\fR(1), -\fBlxc-ls\fR(1), -\fBlxc-ps\fR(1), -\fBlxc-info\fR(1), -\fBlxc-freeze\fR(1), -\fBlxc-unfreeze\fR(1), -\fBlxc-attach\fR(1), -\fBlxc.conf\fR(5) -.SH "AUTHOR" -.PP -Daniel Lezcano diff -Nru lxc-0.8.0~rc1/doc/lxc-freeze.sgml.in lxc-1.0.0~alpha1/doc/lxc-freeze.sgml.in --- lxc-0.8.0~rc1/doc/lxc-freeze.sgml.in 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/lxc-freeze.sgml.in 2013-09-10 22:22:00.000000000 +0000 @@ -1,11 +1,11 @@ - - @@ -48,8 +48,8 @@ - lxc-freeze -n name - + lxc-freeze + -n name @@ -81,7 +81,7 @@ the lxc-create command. - + diff -Nru lxc-0.8.0~rc1/doc/lxc-info.sgml.in lxc-1.0.0~alpha1/doc/lxc-info.sgml.in --- lxc-0.8.0~rc1/doc/lxc-info.sgml.in 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/lxc-info.sgml.in 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,186 @@ + + + + +]> + + + + @LXC_GENERATE_DATE@ + + + lxc-info + 1 + + + + lxc-info + + + query information about a container + + + + + + lxc-info + -n name + -c KEY + -s + -p + -t state + + + + + Description + + lxc-info queries and shows information about a + container. + + + + + Options + + + + + + + + + The container name. + + + + + + + + + + + Print a configuration key from the running container. This option + may be given mulitple times to print out multiple key = value pairs. + + + + + + + + + + + Just print the container's state. + + + + + + + + + + + Just print the container's pid. + + + + + + + + + + + Check whether the container is in the provided state. + + + + + + + &commonoptions; + + + Examples + + + lxc-info -n foo + + + Show information for foo. + + + + + + lxc-info -n foo -t RUNNING + + + exits 0 if foo is RUNNING, 1 otherwise. + + + + + + lxc-info -n foo -c lxc.network.0.veth.pair + + + prints the veth pair name of foo. + + + + + + + + &seealso; + + + Author + Stéphane Graber stgraber@ubuntu.com + + + + diff -Nru lxc-0.8.0~rc1/doc/lxc-kill.1 lxc-1.0.0~alpha1/doc/lxc-kill.1 --- lxc-0.8.0~rc1/doc/lxc-kill.1 2012-03-01 23:04:54.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/lxc-kill.1 1970-01-01 00:00:00.000000000 +0000 @@ -1,93 +0,0 @@ -.\" This manpage has been automatically generated by docbook2man -.\" from a DocBook document. This tool can be found at: -.\" -.\" Please send any bug reports, improvements, comments, patches, -.\" etc. to Steve Cheng . -.TH "LXC-KILL" "1" "02 March 2012" "IBM" "" - -.SH NAME -lxc-kill \- Send a signal to the process 1 of the container. -.SH SYNOPSIS - -\fBlxc-kill --name=\fINAME\fB \fISIGNUM\fB\fR - -.SH "DESCRIPTION" -.PP -\fBlxc-kill\fR send -the \fISIGNUM\fR signal to the first process of the container. -.PP -The \fISIGNUM\fR is a numeric value, -the signal name is not supported. -.PP -If this command is used on an application container ran by -lxc-execute, the lxc-init will receive the signal and will forward it to -the process 2 which is the command specified in the command line. See -lxc-execute (1). -Obviously the SIGKILL and SIGSTOP signals are not able to be forwarded, -(as per the signal(7) man page). -.SH "COMMON OPTIONS" -.PP -These options are common to most of lxc commands. -.TP -\fB-?, -h, --help\fR -Print a longer usage message than normal. -.TP -\fB--usage\fR -Give the usage message -.TP -\fB-q, --quiet\fR -mute on -.TP -\fB-o, --logfile=\fIFILE\fB\fR -Output to an alternate log -\fIFILE\fR\&. The default is no log. -.TP -\fB-l, --logpriority=\fILEVEL\fB\fR -Set log priority to -\fILEVEL\fR\&. The default log -priority is ERROR\&. Possible values are : -FATAL, CRIT, -WARN, ERROR, -NOTICE, INFO, -DEBUG\&. - -Note that this option is setting the priority of the events -log in the alternate log file. It do not have effect on the -ERROR events log on stderr. -.TP -\fB-n, --name=\fINAME\fB\fR -Use container identifier \fINAME\fR\&. -The container identifier format is an alphanumeric string. -.SH "EXAMPLES" -.PP -To send the signal 26 to the process pi1 running in container -123 : - -.nf - lxc-execute -n 123 -- pi1 -d 500000 - lxc-kill --name=123 26 - -.fi -.SH "SEE ALSO" -.PP -\fBlxc\fR(1), -\fBlxc-create\fR(1), -\fBlxc-destroy\fR(1), -\fBlxc-start\fR(1), -\fBlxc-stop\fR(1), -\fBlxc-execute\fR(1), -\fBlxc-kill\fR(1), -\fBlxc-console\fR(1), -\fBlxc-monitor\fR(1), -\fBlxc-wait\fR(1), -\fBlxc-cgroup\fR(1), -\fBlxc-ls\fR(1), -\fBlxc-ps\fR(1), -\fBlxc-info\fR(1), -\fBlxc-freeze\fR(1), -\fBlxc-unfreeze\fR(1), -\fBlxc-attach\fR(1), -\fBlxc.conf\fR(5) -.SH "AUTHOR" -.PP -Daniel Lezcano diff -Nru lxc-0.8.0~rc1/doc/lxc-kill.sgml.in lxc-1.0.0~alpha1/doc/lxc-kill.sgml.in --- lxc-0.8.0~rc1/doc/lxc-kill.sgml.in 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/lxc-kill.sgml.in 2013-09-10 22:22:00.000000000 +0000 @@ -5,7 +5,7 @@ (C) Copyright IBM Corp. 2007, 2008 Authors: -Daniel Lezcano +Daniel Lezcano This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -19,11 +19,11 @@ 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 +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA --> - @@ -49,7 +49,9 @@ - lxc-kill --name=NAME SIGNUM + lxc-kill + --name=NAME + SIGNUM diff -Nru lxc-0.8.0~rc1/doc/lxc-ls.1 lxc-1.0.0~alpha1/doc/lxc-ls.1 --- lxc-0.8.0~rc1/doc/lxc-ls.1 2012-03-01 23:04:54.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/lxc-ls.1 1970-01-01 00:00:00.000000000 +0000 @@ -1,56 +0,0 @@ -.\" This manpage has been automatically generated by docbook2man -.\" from a DocBook document. This tool can be found at: -.\" -.\" Please send any bug reports, improvements, comments, patches, -.\" etc. to Steve Cheng . -.TH "LXC-LS" "1" "02 March 2012" "" "" - -.SH NAME -lxc-ls \- list the containers existing on the system -.SH SYNOPSIS - -\fBlxc-ls [ls option] -\fR - -.SH "DESCRIPTION" -.PP -\fBlxc-ls\fR list the containers existing on the -system. -.SH "OPTIONS" -.TP -\fB [ls options] \fR -The option passed to \fBlxc-ls\fR are the -same as the \fBls\fR command. -.SH "EXAMPLES" -.TP -\fBlxc-ls -l\fR -list all the container and their permissions. -.TP -\fBlxc-ls -1\fR -list all the containers and display the list in one column. -.SH "SEE ALSO" -.PP -\fBls\fR(1), -.SH "SEE ALSO" -.PP -\fBlxc\fR(1), -\fBlxc-create\fR(1), -\fBlxc-destroy\fR(1), -\fBlxc-start\fR(1), -\fBlxc-stop\fR(1), -\fBlxc-execute\fR(1), -\fBlxc-kill\fR(1), -\fBlxc-console\fR(1), -\fBlxc-monitor\fR(1), -\fBlxc-wait\fR(1), -\fBlxc-cgroup\fR(1), -\fBlxc-ls\fR(1), -\fBlxc-ps\fR(1), -\fBlxc-info\fR(1), -\fBlxc-freeze\fR(1), -\fBlxc-unfreeze\fR(1), -\fBlxc-attach\fR(1), -\fBlxc.conf\fR(5) -.SH "AUTHOR" -.PP -Daniel Lezcano diff -Nru lxc-0.8.0~rc1/doc/lxc-ls.sgml.in lxc-1.0.0~alpha1/doc/lxc-ls.sgml.in --- lxc-0.8.0~rc1/doc/lxc-ls.sgml.in 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/lxc-ls.sgml.in 2013-09-10 22:22:00.000000000 +0000 @@ -1,12 +1,12 @@ - - ]> @@ -48,8 +48,16 @@ - lxc-ls ls option - + lxc-ls + -1 + --active + --frozen + --running + --stopped + --fancy + --fancy-format + --nesting + filter @@ -64,66 +72,149 @@ Options + + + + + + + Show one entry per line. (default when /dev/stdout isn't a tty) + + + - - - - - - The option passed to lxc-ls are the - same as the ls command. - - + + + + + + List only active containers (same as --frozen --running). + + - + + + + + + + List only frozen containers. + + + - + + + + + + + List only running containers. + + + + + + + + + + + List only stopped containers. + + + - - Examples - - lxc-ls -l - - - list all the container and their permissions. - - + + + + + + Use a fancy, column-based output. + + - lxc-ls -1 - - - list all the containers and display the list in one column. - - + + + + + + Comma separate list of column to show in the fancy output. + Valid values are: name, state, ipv4, ipv6 and pid + Default is: name,state,ipv4,ipv6 + + + + + + + + + Show nested containers. + + + + + + + + + + + The filter passed to lxc-ls will be + applied to the container name. The format is a regular expression. + + + See Also - + - ls - 1 + ls + 1 , + Examples + + + lxc-ls --fancy + + + list all the containers, listing one per line along with its + name, state, ipv4 and ipv6 addresses. + + + + + + lxc-ls --active -1 + + + list active containers and display the list in one column. + + + + &seealso; Author - Daniel Lezcano daniel.lezcano@free.fr + Stéphane Graber stgraber@ubuntu.com - - @@ -48,8 +48,8 @@ - lxc-monitor -n name - + lxc-monitor + -n name @@ -63,22 +63,17 @@ to monitor all the containers, several of them or just one. - - - &commonoptions; - - - Bugs - - Only one lxc-monitor can run at a time. Other - invocations will fail with the following error: - - - lxc-monitor: bind : Address already in use + The =PATH option may be specified multiple + times to monitor more than one container path. Note however that + containers with the same name in multiple paths will be + indistinguishable in the output. + + &commonoptions; + Examples @@ -135,7 +130,7 @@ the lxc-create command. - + @@ -145,7 +140,7 @@ See Also - + regex 7 diff -Nru lxc-0.8.0~rc1/doc/lxc-netstat.sgml.in lxc-1.0.0~alpha1/doc/lxc-netstat.sgml.in --- lxc-0.8.0~rc1/doc/lxc-netstat.sgml.in 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/lxc-netstat.sgml.in 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,143 @@ + + + +]> + + + + @LXC_GENERATE_DATE@ + + + lxc-netstat + 1 + + + + lxc-netstat + + + run netstat for the specified container + + + + + + lxc-netstat + --name name + -- netstat option + + + + + Description + + lxc-netstat is a wrapper to the netstat command. + + + + + Options + + + + + + + + + The container name. + + + + + + + + + + + The netstat options must be separated + from lxc-netstat options by + the parameter. + + + + + + + + + + Example + + + lxc-netstat --name foo -- -lnp + + + Call netstat -lnp for container foo. + + + + + + + + See Also + + + + netstat + 1 + , + + + + + &seealso; + + + Author + Stéphane Graber stgraber@ubuntu.com + + + + + diff -Nru lxc-0.8.0~rc1/doc/lxc-ps.1 lxc-1.0.0~alpha1/doc/lxc-ps.1 --- lxc-0.8.0~rc1/doc/lxc-ps.1 2012-03-01 23:04:54.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/lxc-ps.1 1970-01-01 00:00:00.000000000 +0000 @@ -1,76 +0,0 @@ -.\" This manpage has been automatically generated by docbook2man -.\" from a DocBook document. This tool can be found at: -.\" -.\" Please send any bug reports, improvements, comments, patches, -.\" etc. to Steve Cheng . -.TH "LXC-PS" "1" "02 March 2012" "" "" - -.SH NAME -lxc-ps \- list the processes belonging to a specific container. -.SH SYNOPSIS - -\fBlxc-ps [--name name] -[--lxc] -[ps option] -\fR - -.SH "DESCRIPTION" -.PP -\fBlxc-ps\fR is a wrapper tp ps command -to report the name of lxc container associated -to reported processes. -.PP -The cgroup fs must be mounted before container creation, -to be able to have \fBlxc-ps\fR to find -the container associated to processes. -.PP -The additionnal specified ps options must not -remove the default ps header and the pid information, -to be able to have the \fBlxc-ps\fR to find -the container associated to processes. -.SH "OPTIONS" -.TP -\fB \fI--name NAME\fB \fR -specify the container \fINAME\fR -to limit the output to the processes belonging -to this container name. -.TP -\fB \fI--lxc\fB \fR -limit the output to the processes belonging -to all lxc containers. -.TP -\fB [ps options] \fR -The \fBps\fR options must be separated -from \fBlxc-ps\fR options by -the \fB--\fR parameter. -.SH "EXAMPLE" -.TP -\fBlxc-ps --name foo -- --forest\fR -list all the processes belonging to container 'foo' and show -dependencies. -.SH "SEE ALSO" -.PP -\fBps\fR(1), -.SH "SEE ALSO" -.PP -\fBlxc\fR(1), -\fBlxc-create\fR(1), -\fBlxc-destroy\fR(1), -\fBlxc-start\fR(1), -\fBlxc-stop\fR(1), -\fBlxc-execute\fR(1), -\fBlxc-kill\fR(1), -\fBlxc-console\fR(1), -\fBlxc-monitor\fR(1), -\fBlxc-wait\fR(1), -\fBlxc-cgroup\fR(1), -\fBlxc-ls\fR(1), -\fBlxc-ps\fR(1), -\fBlxc-info\fR(1), -\fBlxc-freeze\fR(1), -\fBlxc-unfreeze\fR(1), -\fBlxc-attach\fR(1), -\fBlxc.conf\fR(5) -.SH "AUTHOR" -.PP -Daniel Lezcano diff -Nru lxc-0.8.0~rc1/doc/lxc-ps.sgml.in lxc-1.0.0~alpha1/doc/lxc-ps.sgml.in --- lxc-0.8.0~rc1/doc/lxc-ps.sgml.in 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/lxc-ps.sgml.in 2013-09-10 22:22:00.000000000 +0000 @@ -1,12 +1,12 @@ - - ]> @@ -48,17 +48,18 @@ - lxc-ps --name name - --lxc - ps option - + lxc-ps + --name name + --lxc + --host + -- ps options Description - lxc-ps is a wrapper tp ps command + lxc-ps is a wrapper to the ps command to report the name of lxc container associated to reported processes. @@ -68,7 +69,7 @@ the container associated to processes. - The additionnal specified ps options must not + The additional specified ps options must not remove the default ps header and the pid information, to be able to have the lxc-ps to find the container associated to processes. @@ -81,24 +82,24 @@ - + - specify the container NAME - to limit the output to the processes belonging - to this container name. + specify the container name + to limit the output to the processes belonging + to this container name. - + - limit the output to the processes belonging + limit the output to the processes belonging to all lxc containers. @@ -106,7 +107,19 @@ - + + + + + limit the output to the processes belonging + to the host. + + + + + + + @@ -139,7 +152,7 @@ See Also - + ps 1 diff -Nru lxc-0.8.0~rc1/doc/lxc-restart.1 lxc-1.0.0~alpha1/doc/lxc-restart.1 --- lxc-0.8.0~rc1/doc/lxc-restart.1 2012-03-01 23:04:53.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/lxc-restart.1 1970-01-01 00:00:00.000000000 +0000 @@ -1,147 +0,0 @@ -.\" This manpage has been automatically generated by docbook2man -.\" from a DocBook document. This tool can be found at: -.\" -.\" Please send any bug reports, improvements, comments, patches, -.\" etc. to Steve Cheng . -.TH "LXC-RESTART" "1" "02 March 2012" "IBM" "" - -.SH NAME -lxc-restart \- restart a container from a file (not implemented yet) -.SH SYNOPSIS - -\fBlxc-restart [-f -config_file][-s KEY=VAL] ---statefile=\fIFILE\fB ---statefd=\fIFD\fB\fR \fB--name=\fINAME\fB\fR - -.SH "DESCRIPTION" -.PP -\fBlxc-restart\fR is a command -to restart an application from the state read in the specified -\fIFILE\fR, in a container with the -identifier \fINAME\fR\&. -If the option \fB--pause\fR -is specified, the application will be stopped after the -restart just before resuming execution. The command -\fBlxc-unfreeze\fR will be needed to resume its -execution. -.SH "RESTART OPTIONS" -.TP -\fB-S, --statefile=\fIFILE\fB\fR -read the state of the container in this -\fIFILE\fR\&. -This option is exclusive with \fB--statefd\fR below. -.TP -\fB-d, --statefd=\fIFD\fB\fR -read the state of the container in this -\fIFD\fR file descriptor. -This option is exclusive with above \fB--statefile\fR\&. -.TP -\fB-p\fR -Pause container processes after restart. The container will be -stopped until you resume it with the lxc-unfreeze command. -.TP -\fB-f, --rcfile=\fIconfig_file\fB\fR -Specify the configuration file to configure the -virtualization and isolation functionalities for the -container. This parameter should be specified if it was -specified for the \fBlxc-execute\fR -or \fBlxc-start\fR commands or if the -container configuration has to be changed at restart. The -latter may fail if the needed resources are not available -for the restart. If the container was created and -configured with \fBlxc-create\fR, this option -is not needed, the configuration will be automatically -found. -.TP -\fB -s \fIKEY=VAL\fB \fR -Assign value \fIVAL\fR to configuration -variable \fIKEY\fR\&. This overrides any -assignment done in \fIconfig_file\fR\&. -.SH "COMMON OPTIONS" -.PP -These options are common to most of lxc commands. -.TP -\fB-?, -h, --help\fR -Print a longer usage message than normal. -.TP -\fB--usage\fR -Give the usage message -.TP -\fB-q, --quiet\fR -mute on -.TP -\fB-o, --logfile=\fIFILE\fB\fR -Output to an alternate log -\fIFILE\fR\&. The default is no log. -.TP -\fB-l, --logpriority=\fILEVEL\fB\fR -Set log priority to -\fILEVEL\fR\&. The default log -priority is ERROR\&. Possible values are : -FATAL, CRIT, -WARN, ERROR, -NOTICE, INFO, -DEBUG\&. - -Note that this option is setting the priority of the events -log in the alternate log file. It do not have effect on the -ERROR events log on stderr. -.TP -\fB-n, --name=\fINAME\fB\fR -Use container identifier \fINAME\fR\&. -The container identifier format is an alphanumeric string. -.SH "EXAMPLES" -.PP -To start a new container 123 computing decimals of pi - -.nf - lxc-execute -n 123 -- pi1 -d 500000 - lxc-execute --name=123 -- pi1 -d 500000 - -.fi -.PP -to checkpoint the same container in \fBdump-death\fR -mode - -.nf - lxc-checkpoint -n 123 -S /share/123/chkpt1 -k - lxc-checkpoint --name=123 --statefile=/share/123/chkpt1 -k - -.fi -.PP -and to restart the same container with a different id - -.nf - lxc-restart -n 200 -S /share/123/chkpt1 - lxc-restart --name=200 --statefile=/share/123/chkpt1 - -.fi -.SH "NOTES" -.PP -Actually, this command does not operate. Its description -helps to define a CLI api for future Checkpoint / Restart -solution -.SH "SEE ALSO" -.PP -\fBlxc\fR(1), -\fBlxc-create\fR(1), -\fBlxc-destroy\fR(1), -\fBlxc-start\fR(1), -\fBlxc-stop\fR(1), -\fBlxc-execute\fR(1), -\fBlxc-kill\fR(1), -\fBlxc-console\fR(1), -\fBlxc-monitor\fR(1), -\fBlxc-wait\fR(1), -\fBlxc-cgroup\fR(1), -\fBlxc-ls\fR(1), -\fBlxc-ps\fR(1), -\fBlxc-info\fR(1), -\fBlxc-freeze\fR(1), -\fBlxc-unfreeze\fR(1), -\fBlxc-attach\fR(1), -\fBlxc.conf\fR(5) -.SH "AUTHOR" -.PP -Daniel Lezcano diff -Nru lxc-0.8.0~rc1/doc/lxc-restart.sgml.in lxc-1.0.0~alpha1/doc/lxc-restart.sgml.in --- lxc-0.8.0~rc1/doc/lxc-restart.sgml.in 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/lxc-restart.sgml.in 2013-09-10 22:22:00.000000000 +0000 @@ -5,7 +5,7 @@ (C) Copyright IBM Corp. 2007, 2008 Authors: -Daniel Lezcano +Daniel Lezcano This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -19,11 +19,11 @@ 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 +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA --> - @@ -49,11 +49,12 @@ - lxc-restart -f - config_file-s KEY=VAL - --statefile=FILE - --statefd=FD - + lxc-restart + -f config_file + -s KEY=VAL + --statefile=FILE + --statefd=FD + --name=NAME diff -Nru lxc-0.8.0~rc1/doc/lxc-start-ephemeral.sgml.in lxc-1.0.0~alpha1/doc/lxc-start-ephemeral.sgml.in --- lxc-0.8.0~rc1/doc/lxc-start-ephemeral.sgml.in 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/lxc-start-ephemeral.sgml.in 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,239 @@ + + + + +]> + + + + @LXC_GENERATE_DATE@ + + + lxc-start-ephemeral + 1 + + + + lxc-start-ephemeral + + + start an ephemeral copy of an existing container + + + + + + lxc-start-ephemeral + -o + -n + -d + --bdir + --user + --key + --union-type + --keep-data + COMMAND + + + + + Description + + lxc-start-ephemeral start an ephemeral copy of an + existing container. + + + + + Options + + + + + + + + Original container name + + + + + + + + + + + Name of the ephemeral container (defaults to a random suffix). + + + + + + + + + + + Start the container in background and print the name and IP. + This option can't be used if a command is passed. + + + + + + + + + + + Directory to bind mount into container. + Can be passed multiple times. + + + + + + + + + + + The user to connect to the container as. + Used when passing a command to lxc-start-ephemeral. + + + + + + + + + + + Copy the provided SSH public key into the container. + + + + + + + + + + + Force a specific union file system. + Can be one of: overlayfs aufs + + + + + + + + + + + Use a persistent backend instead of tmpfs. + With this option, you can lxc-stop and lxc-start the no longer so + ephemeral container (it's still an overlay, but a persistent one). + + + + + + + + + + + Immediately run the provided command in the container. + This currently uses ssh (not attach) and is incompatible + with daemon mode. + + + + + + + + See Also + + + + lxc-start + 1 + , + + + Examples + + + lxc-start-ephemeral -o p1 + + + Simply start an ephemeral container and attach to the console. + This container will be based on existing container "p1". + + + + + + lxc-start-ephemeral -o p1 -n p1-ephemeral -d + + + Start an ephemeral container based on p1 called p1-ephemeral and + print its IP and name to the console instead of attaching. + + + + + + + &seealso; + + + Author + Stéphane Graber stgraber@ubuntu.com + + + + diff -Nru lxc-0.8.0~rc1/doc/lxc-start.1 lxc-1.0.0~alpha1/doc/lxc-start.1 --- lxc-0.8.0~rc1/doc/lxc-start.1 2012-03-01 23:04:52.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/lxc-start.1 1970-01-01 00:00:00.000000000 +0000 @@ -1,124 +0,0 @@ -.\" This manpage has been automatically generated by docbook2man -.\" from a DocBook document. This tool can be found at: -.\" -.\" Please send any bug reports, improvements, comments, patches, -.\" etc. to Steve Cheng . -.TH "LXC-START" "1" "02 March 2012" "" "" - -.SH NAME -lxc-start \- run an application inside a container. -.SH SYNOPSIS - -\fBlxc-start \fI-n -name\fB [-f -config_file] [-c -console_file] [-d] [-s -KEY=VAL] -[command]\fR - -.SH "DESCRIPTION" -.PP -\fBlxc-start\fR runs the specified -\fIcommand\fR inside the container -specified by \fIname\fR\&. -.PP -It will setup the container -according to the configuration previously defined with the -lxc-create command or with the configuration file parameter. -If no configuration is -defined, the default isolation is used. -.PP -The orphan process group -and daemon are not supported by this command, use -the \fBlxc-execute\fR command instead. -.PP -If no command is specified, \fBlxc-start\fR will -use the default -\fB"/sbin/init"\fR command to run a system -container. -.SH "OPTIONS" -.TP -\fB -d, --daemon \fR -Run the container as a daemon. As the container has no -more tty, if an error occurs nothing will be displayed, -the log file can be used to check the error. -.TP -\fB -f, --rcfile \fIconfig_file\fB \fR -Specify the configuration file to configure the virtualization -and isolation functionalities for the container. - -This configuration file if present will be used even if there is -already a configuration file present in the previously created -container (via lxc-create). -.TP -\fB -c, --console \fIconsole_file\fB \fR -Specify a file to output the container console. If the -option is not specified the output will go the terminal -except if the \fB-d\fR is specified. -.TP -\fB -s, --define \fIKEY=VAL\fB \fR -Assign value \fIVAL\fR to configuration -variable \fIKEY\fR\&. This overrides any -assignment done in \fIconfig_file\fR\&. -.SH "COMMON OPTIONS" -.PP -These options are common to most of lxc commands. -.TP -\fB-?, -h, --help\fR -Print a longer usage message than normal. -.TP -\fB--usage\fR -Give the usage message -.TP -\fB-q, --quiet\fR -mute on -.TP -\fB-o, --logfile=\fIFILE\fB\fR -Output to an alternate log -\fIFILE\fR\&. The default is no log. -.TP -\fB-l, --logpriority=\fILEVEL\fB\fR -Set log priority to -\fILEVEL\fR\&. The default log -priority is ERROR\&. Possible values are : -FATAL, CRIT, -WARN, ERROR, -NOTICE, INFO, -DEBUG\&. - -Note that this option is setting the priority of the events -log in the alternate log file. It do not have effect on the -ERROR events log on stderr. -.TP -\fB-n, --name=\fINAME\fB\fR -Use container identifier \fINAME\fR\&. -The container identifier format is an alphanumeric string. -.SH "DIAGNOSTIC" -.TP -\fBThe container is busy\fR -The specified container is already running an -application. You should stop it before reuse this -container or create a new one. -.SH "SEE ALSO" -.PP -\fBlxc\fR(1), -\fBlxc-create\fR(1), -\fBlxc-destroy\fR(1), -\fBlxc-start\fR(1), -\fBlxc-stop\fR(1), -\fBlxc-execute\fR(1), -\fBlxc-kill\fR(1), -\fBlxc-console\fR(1), -\fBlxc-monitor\fR(1), -\fBlxc-wait\fR(1), -\fBlxc-cgroup\fR(1), -\fBlxc-ls\fR(1), -\fBlxc-ps\fR(1), -\fBlxc-info\fR(1), -\fBlxc-freeze\fR(1), -\fBlxc-unfreeze\fR(1), -\fBlxc-attach\fR(1), -\fBlxc.conf\fR(5) -.SH "AUTHOR" -.PP -Daniel Lezcano diff -Nru lxc-0.8.0~rc1/doc/lxc-start.sgml.in lxc-1.0.0~alpha1/doc/lxc-start.sgml.in --- lxc-0.8.0~rc1/doc/lxc-start.sgml.in 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/lxc-start.sgml.in 2013-09-10 22:22:00.000000000 +0000 @@ -1,11 +1,11 @@ - - @@ -47,12 +47,18 @@ - lxc-start -n - name -f - config_file -c - console_file -d -s - KEY=VAL - command + + lxc-start + -n name + -f config_file + -c console_device + -L console_logfile + -d + -p pid_file + -s KEY=VAL + -C + command + @@ -71,11 +77,6 @@ defined, the default isolation is used. - The orphan process group - and daemon are not supported by this command, use - the lxc-execute command instead. - - If no command is specified, lxc-start will use the default "/sbin/init" command to run a system @@ -105,6 +106,17 @@ + + + + + Create a file with the process id. + + + + + + @@ -123,13 +135,25 @@ + --console console_device + + + + Specify a device to use for the container's console, for example + /dev/tty8. If this option is not specified the current terminal + will be used unless is specified. + + + + + + + - Specify a file to output the container console. If the - option is not specified the output will go the terminal - except if the is specified. + Specify a file to log the container's console output to. @@ -147,6 +171,21 @@ + + + + + + + If any file descriptors are inherited, close them. If this option + is not specified, then lxc-start will exit with + failure instead. Note: --daemon implies + --close-all-fds. + + + + @@ -167,7 +206,7 @@ container or create a new one. - + diff -Nru lxc-0.8.0~rc1/doc/lxc-stop.1 lxc-1.0.0~alpha1/doc/lxc-stop.1 --- lxc-0.8.0~rc1/doc/lxc-stop.1 2012-03-01 23:04:52.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/lxc-stop.1 1970-01-01 00:00:00.000000000 +0000 @@ -1,85 +0,0 @@ -.\" This manpage has been automatically generated by docbook2man -.\" from a DocBook document. This tool can be found at: -.\" -.\" Please send any bug reports, improvements, comments, patches, -.\" etc. to Steve Cheng . -.TH "LXC-STOP" "1" "02 March 2012" "" "" - -.SH NAME -lxc-stop \- stop the application running inside a container -.SH SYNOPSIS - -\fBlxc-stop \fI-n name\fB -\fR - -.SH "DESCRIPTION" -.PP -\fBlxc-stop\fR kills all the processes inside the -container. This command should be used if the processes are no -longer accessible and can no be exited normally. -.SH "COMMON OPTIONS" -.PP -These options are common to most of lxc commands. -.TP -\fB-?, -h, --help\fR -Print a longer usage message than normal. -.TP -\fB--usage\fR -Give the usage message -.TP -\fB-q, --quiet\fR -mute on -.TP -\fB-o, --logfile=\fIFILE\fB\fR -Output to an alternate log -\fIFILE\fR\&. The default is no log. -.TP -\fB-l, --logpriority=\fILEVEL\fB\fR -Set log priority to -\fILEVEL\fR\&. The default log -priority is ERROR\&. Possible values are : -FATAL, CRIT, -WARN, ERROR, -NOTICE, INFO, -DEBUG\&. - -Note that this option is setting the priority of the events -log in the alternate log file. It do not have effect on the -ERROR events log on stderr. -.TP -\fB-n, --name=\fINAME\fB\fR -Use container identifier \fINAME\fR\&. -The container identifier format is an alphanumeric string. -.SH "DIAGNOSTIC" -.TP -\fBThe container is busy\fR -The specified container is already running an -application. You should stop it before reuse this -container or create a new one. -.TP -\fBThe container was not found\fR -The specified container was not created before with -the \fBlxc-create\fR command. -.SH "SEE ALSO" -.PP -\fBlxc\fR(1), -\fBlxc-create\fR(1), -\fBlxc-destroy\fR(1), -\fBlxc-start\fR(1), -\fBlxc-stop\fR(1), -\fBlxc-execute\fR(1), -\fBlxc-kill\fR(1), -\fBlxc-console\fR(1), -\fBlxc-monitor\fR(1), -\fBlxc-wait\fR(1), -\fBlxc-cgroup\fR(1), -\fBlxc-ls\fR(1), -\fBlxc-ps\fR(1), -\fBlxc-info\fR(1), -\fBlxc-freeze\fR(1), -\fBlxc-unfreeze\fR(1), -\fBlxc-attach\fR(1), -\fBlxc.conf\fR(5) -.SH "AUTHOR" -.PP -Daniel Lezcano diff -Nru lxc-0.8.0~rc1/doc/lxc-stop.sgml.in lxc-1.0.0~alpha1/doc/lxc-stop.sgml.in --- lxc-0.8.0~rc1/doc/lxc-stop.sgml.in 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/lxc-stop.sgml.in 2013-09-10 22:22:00.000000000 +0000 @@ -1,11 +1,11 @@ - - @@ -48,8 +48,13 @@ - lxc-stop -n name - + lxc-stop + -n name + -W + -r + -t timeout + -k + -s @@ -57,14 +62,90 @@ Description - lxc-stop kills all the processes inside the - container. This command should be used if the processes are no - longer accessible and can no be exited normally. + lxc-stop reboots, cleanly shuts down, or kills + all the processes inside the container. By default, it will + request a clean shutdown of the container (by sending SIGPWR to + the container), wait 60 seconds for the container to exit, and + returns. If the container fails to cleanly exit, then after 60 + seconds the container will be sent the + lxc.stopsignal to force it to shut down. - + + The -W, -r, -s + and -k options specify the action to perform. + -W indicates that after performing the specified + action, lxc-stop should immediately exit, while + -t TIMEOUT specifies the maximum amount of time + to wait for the container to complete the shutdown or reboot. + - &commonoptions; + + Options + + + + + + + + + Request a reboot of the container. + + + + + + + + + + + Only request a clean shutdown, do not kill the container tasks if the + clean shutdown fails. + + + + + + + + + + + Rather than requesting a clean shutdown of the container, explicitly + kill all tasks in the container. This is the legacy + lxc-stop behavior. + + + + + + + + + + + Simply perform the requestion action (reboot, shutdown, or hard + kill) and exit. + + + + + + + + + + + Wait TIMEOUT seconds before hard-stopping the container of (in + the reboot case) returning failure. + + + + + + Diagnostic @@ -80,7 +161,7 @@ container or create a new one. - + The container was not found @@ -90,8 +171,7 @@ the lxc-create command. - - + diff -Nru lxc-0.8.0~rc1/doc/lxc-top.sgml.in lxc-1.0.0~alpha1/doc/lxc-top.sgml.in --- lxc-0.8.0~rc1/doc/lxc-top.sgml.in 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/lxc-top.sgml.in 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,164 @@ + + + +]> + + + + @LXC_GENERATE_DATE@ + + + lxc-top + 1 + + + + lxc-top + + + monitor container statistics + + + + + + lxc-top + --help + --max count + --delay delay + --sort sortby + --reverse + + + + + Description + + lxc-top displays container statistics. The output + is updated every delay seconds, and is + ordered according to the sortby value + given. Specifying count will limit the + number of containers displayed, otherwise lxc-top + will display as many containers as can fit in your terminal. + + + + + Options + + + + + + + + + Limit the number of containers displayed to + count. + + + + + + + + + + + Amount of time in seconds to delay between screen updates. + This can be specified as less than a second by giving a + rational number, for example 0.5 for a half second delay. The + default is 3 seconds. + + + + + + + + + + Sort the containers by name, cpu use, or memory use. The + sortby argument should be one of + the letters n,c,d,m to sort by name, cpu use, disk I/O, or + memory use respectively. The default is 'n'. + + + + + + + + + + Reverse the default sort order. By default, names sort in + ascending alphabetical order and values sort in descending + amounts (ie. largest value first). + + + + + + + + Example + + + lxc-top --delay 1 --sort m + + + Display containers, updating every second, sorted by memory use. + + + + + + + &seealso; + + + Author + Dwight Engen dwight.engen@oracle.com + + + + + diff -Nru lxc-0.8.0~rc1/doc/lxc-unfreeze.1 lxc-1.0.0~alpha1/doc/lxc-unfreeze.1 --- lxc-0.8.0~rc1/doc/lxc-unfreeze.1 2012-03-01 23:04:53.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/lxc-unfreeze.1 1970-01-01 00:00:00.000000000 +0000 @@ -1,79 +0,0 @@ -.\" This manpage has been automatically generated by docbook2man -.\" from a DocBook document. This tool can be found at: -.\" -.\" Please send any bug reports, improvements, comments, patches, -.\" etc. to Steve Cheng . -.TH "LXC-UNFREEZE" "1" "02 March 2012" "" "" - -.SH NAME -lxc-unfreeze \- thaw all the container's processes -.SH SYNOPSIS - -\fBlxc-unfreeze \fI-n name\fB -\fR - -.SH "DESCRIPTION" -.PP -\fBlxc-unfreeze\fR will thaw all the processes -previously frozen by the \fBlxc-freeze\fR command. -.SH "COMMON OPTIONS" -.PP -These options are common to most of lxc commands. -.TP -\fB-?, -h, --help\fR -Print a longer usage message than normal. -.TP -\fB--usage\fR -Give the usage message -.TP -\fB-q, --quiet\fR -mute on -.TP -\fB-o, --logfile=\fIFILE\fB\fR -Output to an alternate log -\fIFILE\fR\&. The default is no log. -.TP -\fB-l, --logpriority=\fILEVEL\fB\fR -Set log priority to -\fILEVEL\fR\&. The default log -priority is ERROR\&. Possible values are : -FATAL, CRIT, -WARN, ERROR, -NOTICE, INFO, -DEBUG\&. - -Note that this option is setting the priority of the events -log in the alternate log file. It do not have effect on the -ERROR events log on stderr. -.TP -\fB-n, --name=\fINAME\fB\fR -Use container identifier \fINAME\fR\&. -The container identifier format is an alphanumeric string. -.SH "DIAGNOSTIC" -.TP -\fBThe container was not found\fR -The specified container was not created before with -the \fBlxc-create\fR command. -.SH "SEE ALSO" -.PP -\fBlxc\fR(1), -\fBlxc-create\fR(1), -\fBlxc-destroy\fR(1), -\fBlxc-start\fR(1), -\fBlxc-stop\fR(1), -\fBlxc-execute\fR(1), -\fBlxc-kill\fR(1), -\fBlxc-console\fR(1), -\fBlxc-monitor\fR(1), -\fBlxc-wait\fR(1), -\fBlxc-cgroup\fR(1), -\fBlxc-ls\fR(1), -\fBlxc-ps\fR(1), -\fBlxc-info\fR(1), -\fBlxc-freeze\fR(1), -\fBlxc-unfreeze\fR(1), -\fBlxc-attach\fR(1), -\fBlxc.conf\fR(5) -.SH "AUTHOR" -.PP -Daniel Lezcano diff -Nru lxc-0.8.0~rc1/doc/lxc-unfreeze.sgml.in lxc-1.0.0~alpha1/doc/lxc-unfreeze.sgml.in --- lxc-0.8.0~rc1/doc/lxc-unfreeze.sgml.in 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/lxc-unfreeze.sgml.in 2013-09-10 22:22:00.000000000 +0000 @@ -1,11 +1,11 @@ - - @@ -48,8 +48,8 @@ - lxc-unfreeze -n name - + lxc-unfreeze + -n name @@ -78,7 +78,7 @@ the lxc-create command. - + diff -Nru lxc-0.8.0~rc1/doc/lxc-unshare.sgml.in lxc-1.0.0~alpha1/doc/lxc-unshare.sgml.in --- lxc-0.8.0~rc1/doc/lxc-unshare.sgml.in 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/lxc-unshare.sgml.in 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,161 @@ + + + + +]> + + + + @LXC_GENERATE_DATE@ + + + lxc-unshare + 1 + + + + lxc-unshare + + + Run a task in a new set of namespaces. + + + + + + lxc-unshare + -s namespaces + -u user + command + + + + + Description + + + lxc-unshare can be used to run a task in a cloned set + of namespaces. This command is mainly provided for testing purposes. + Despite its name, it always uses clone rather than unshare to create + the new task with fresh namespaces. Apart from testing kernel + regressions this should make no difference. + + + + + + + Options + + + + + + + + + + Specify the namespaces to attach to, as a pipe-separated list, + e.g. NETWORK|IPC. Allowed values are + MOUNT, PID, + UTSNAME, IPC, + USER and + NETWORK. This allows one to change + the context of the process to e.g. the network namespace of the + container while retaining the other namespaces as those of the + host. + + + + + + + + + + + Specify a user which the new task should become. This option is + only valid if a user namespace is unshared. + + + + + + + + + + Examples + + To spawn a new shell with its own UTS (hostname) namespace, + + lxc-unshare -s UTSNAME /bin/bash + + If the hostname is changed in that shell, the change will not be + reflected on the host. + + + To spawn a shell in a new network, pid, and mount namespace, + + lxc-unshare -s "NETWORK|PID|MOUNT" /bin/bash + + The resulting shell will have pid 1 and will see no network interfaces. + After re-mounting /proc in that shell, + + mount -t proc proc /proc + + ps output will show there are no other processes in the namespace. + + + + &seealso; + + + Author + Daniel Lezcano daniel.lezcano@free.fr + + + + + diff -Nru lxc-0.8.0~rc1/doc/lxc-version.sgml.in lxc-1.0.0~alpha1/doc/lxc-version.sgml.in --- lxc-0.8.0~rc1/doc/lxc-version.sgml.in 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/lxc-version.sgml.in 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,96 @@ + + + +]> + + + + @LXC_GENERATE_DATE@ + + + lxc-version + 1 + + + + lxc-version + + + print the currently installed lxc version + + + + + + lxc-version + + + + + Description + + lxc-version print the currently installed lxc version + + + + + Examples + + + lxc-version + + + print the currently installed lxc version. + + + + + + + &seealso; + + + Author + Stéphane Graber stgraber@ubuntu.com + + + + diff -Nru lxc-0.8.0~rc1/doc/lxc-wait.1 lxc-1.0.0~alpha1/doc/lxc-wait.1 --- lxc-0.8.0~rc1/doc/lxc-wait.1 2012-03-01 23:04:53.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/lxc-wait.1 1970-01-01 00:00:00.000000000 +0000 @@ -1,92 +0,0 @@ -.\" This manpage has been automatically generated by docbook2man -.\" from a DocBook document. This tool can be found at: -.\" -.\" Please send any bug reports, improvements, comments, patches, -.\" etc. to Steve Cheng . -.TH "LXC-WAIT" "1" "02 March 2012" "" "" - -.SH NAME -lxc-wait \- wait for a specific container state -.SH SYNOPSIS - -\fBlxc-wait \fI-n name\fB -\fI-s states\fB -\fR - -.SH "DESCRIPTION" -.PP -\fBlxc-wait\fR waits for a specific container state -before exiting, this is useful for scripting. -.SH "OPTIONS" -.TP -\fB -s \fIstates\fB \fR -Specify the container state(s) to wait for. The container -states can be ORed to specify several states. -.SH "COMMON OPTIONS" -.PP -These options are common to most of lxc commands. -.TP -\fB-?, -h, --help\fR -Print a longer usage message than normal. -.TP -\fB--usage\fR -Give the usage message -.TP -\fB-q, --quiet\fR -mute on -.TP -\fB-o, --logfile=\fIFILE\fB\fR -Output to an alternate log -\fIFILE\fR\&. The default is no log. -.TP -\fB-l, --logpriority=\fILEVEL\fB\fR -Set log priority to -\fILEVEL\fR\&. The default log -priority is ERROR\&. Possible values are : -FATAL, CRIT, -WARN, ERROR, -NOTICE, INFO, -DEBUG\&. - -Note that this option is setting the priority of the events -log in the alternate log file. It do not have effect on the -ERROR events log on stderr. -.TP -\fB-n, --name=\fINAME\fB\fR -Use container identifier \fINAME\fR\&. -The container identifier format is an alphanumeric string. -.SH "EXAMPLES" -.TP -\fBlxc-wait -n foo -s RUNNING\fR -exits when 'RUNNING' is reached. -.TP -\fBlxc-wait -n foo -s 'RUNNING|STOPPED'\fR -exits when 'RUNNING' or 'STOPPED' state is reached. -.SH "DIAGNOSTIC" -.TP -\fBThe container was not found\fR -The specified container was not created before with -the \fBlxc-create\fR command. -.SH "SEE ALSO" -.PP -\fBlxc\fR(1), -\fBlxc-create\fR(1), -\fBlxc-destroy\fR(1), -\fBlxc-start\fR(1), -\fBlxc-stop\fR(1), -\fBlxc-execute\fR(1), -\fBlxc-kill\fR(1), -\fBlxc-console\fR(1), -\fBlxc-monitor\fR(1), -\fBlxc-wait\fR(1), -\fBlxc-cgroup\fR(1), -\fBlxc-ls\fR(1), -\fBlxc-ps\fR(1), -\fBlxc-info\fR(1), -\fBlxc-freeze\fR(1), -\fBlxc-unfreeze\fR(1), -\fBlxc-attach\fR(1), -\fBlxc.conf\fR(5) -.SH "AUTHOR" -.PP -Daniel Lezcano diff -Nru lxc-0.8.0~rc1/doc/lxc-wait.sgml.in lxc-1.0.0~alpha1/doc/lxc-wait.sgml.in --- lxc-0.8.0~rc1/doc/lxc-wait.sgml.in 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/lxc-wait.sgml.in 2013-09-10 22:22:00.000000000 +0000 @@ -1,12 +1,12 @@ - - @@ -49,9 +49,9 @@ - lxc-wait -n name - -s states - + lxc-wait + -n name + -s states @@ -79,6 +79,17 @@ + + + + + + + Wait timeout seconds for desired state to be reached. + + + + @@ -122,7 +133,7 @@ the lxc-create command. - + diff -Nru lxc-0.8.0~rc1/doc/lxc.7 lxc-1.0.0~alpha1/doc/lxc.7 --- lxc-0.8.0~rc1/doc/lxc.7 2012-03-01 23:04:55.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/lxc.7 1970-01-01 00:00:00.000000000 +0000 @@ -1,536 +0,0 @@ -.\" This manpage has been automatically generated by docbook2man -.\" from a DocBook document. This tool can be found at: -.\" -.\" Please send any bug reports, improvements, comments, patches, -.\" etc. to Steve Cheng . -.TH "LXC" "7" "02 March 2012" "Version 0.8.0-rc1" "" - -.SH NAME -lxc \- linux containers -.SH "QUICK START" -.PP -You are in a hurry, and you don't want to read this man page. Ok, -without warranty, here are the commands to launch a shell inside -a container with a predefined configuration template, it may -work. -\fB/usr/bin/lxc-execute -n foo -f -/usr/share/doc/lxc/examples/lxc-macvlan.conf /bin/bash\fR -.SH "OVERVIEW" -.PP -The container technology is actively being pushed into the -mainstream linux kernel. It provides the resource management -through the control groups aka process containers and resource -isolation through the namespaces. -.PP -The linux containers, \fBlxc\fR, aims to use these -new functionalities to provide an userspace container object -which provides full resource isolation and resource control for -an applications or a system. -.PP -The first objective of this project is to make the life easier -for the kernel developers involved in the containers project and -especially to continue working on the Checkpoint/Restart new -features. The \fBlxc\fR is small enough to easily -manage a container with simple command lines and complete enough -to be used for other purposes. -.SH "REQUIREMENTS" -.PP -The \fBlxc\fR relies on a set of functionalities -provided by the kernel which needs to be active. Depending of -the missing functionalities the \fBlxc\fR will -work with a restricted number of functionalities or will simply -fails. -.PP -The following list gives the kernel features to be enabled in -the kernel to have the full features container: - -.nf - * General setup - * Control Group support - -> Namespace cgroup subsystem - -> Freezer cgroup subsystem - -> Cpuset support - -> Simple CPU accounting cgroup subsystem - -> Resource counters - -> Memory resource controllers for Control Groups - * Group CPU scheduler - -> Basis for grouping tasks (Control Groups) - * Namespaces support - -> UTS namespace - -> IPC namespace - -> User namespace - -> Pid namespace - -> Network namespace - * Device Drivers - * Character devices - -> Support multiple instances of devpts - * Network device support - -> MAC-VLAN support - -> Virtual ethernet pair device - * Networking - * Networking options - -> 802.1d Ethernet Bridging - * Security options - -> File POSIX Capabilities - -.fi -.PP -The kernel version >= 2.6.27 shipped with the distros, will -work with \fBlxc\fR, this one will have less -functionalities but enough to be interesting. -With the kernel 2.6.29, \fBlxc\fR is fully -functional. -The helper script \fBlxc-checkconfig\fR will give -you information about your kernel configuration. -.PP -Before using the \fBlxc\fR, your system should be -configured with the file capabilities, otherwise you will need -to run the \fBlxc\fR commands as root. -.PP -The control group can be mounted anywhere, eg: -\fBmount -t cgroup cgroup /cgroup\fR\&. -If you want to dedicate a specific cgroup mount point -for \fBlxc\fR, that is to have different cgroups -mounted at different places with different options but -let \fBlxc\fR to use one location, you can bind -the mount point with the \fBlxc\fR name, eg: -\fBmount -t cgroup lxc /cgroup4lxc\fR or -\fBmount -t cgroup -ons,cpuset,freezer,devices -lxc /cgroup4lxc\fR -.SH "FUNCTIONAL SPECIFICATION" -.PP -A container is an object isolating some resources of the host, -for the application or system running in it. -.PP -The application / system will be launched inside a -container specified by a configuration that is either -initially created or passed as parameter of the starting commands. -.PP -How to run an application in a container ? -.PP -Before running an application, you should know what are the -resources you want to isolate. The default configuration is to -isolate the pids, the sysv ipc and the mount points. If you want -to run a simple shell inside a container, a basic configuration -is needed, especially if you want to share the rootfs. If you -want to run an application like \fBsshd\fR, you -should provide a new network stack and a new hostname. If you -want to avoid conflicts with some files -eg. \fI/var/run/httpd.pid\fR, you should -remount \fI/var/run\fR with an empty -directory. If you want to avoid the conflicts in all the cases, -you can specify a rootfs for the container. The rootfs can be a -directory tree, previously bind mounted with the initial rootfs, -so you can still use your distro but with your -own \fI/etc\fR and \fI/home\fR -.PP -Here is an example of directory tree -for \fBsshd\fR: - -.nf - -[root@lxc sshd]$ tree -d rootfs - -rootfs -|-- bin -|-- dev -| |-- pts -| `-- shm -| `-- network -|-- etc -| `-- ssh -|-- lib -|-- proc -|-- root -|-- sbin -|-- sys -|-- usr -`-- var - |-- empty - | `-- sshd - |-- lib - | `-- empty - | `-- sshd - `-- run - `-- sshd - -.fi -and the mount points file associated with it: - -.nf - [root@lxc sshd]$ cat fstab - - /lib /home/root/sshd/rootfs/lib none ro,bind 0 0 - /bin /home/root/sshd/rootfs/bin none ro,bind 0 0 - /usr /home/root/sshd/rootfs/usr none ro,bind 0 0 - /sbin /home/root/sshd/rootfs/sbin none ro,bind 0 0 - -.fi -.PP -How to run a system in a container ? -.PP -Running a system inside a container is paradoxically easier -than running an application. Why ? Because you don't have to care -about the resources to be isolated, everything need to be -isolated, the other resources are specified as being isolated but -without configuration because the container will set them -up. eg. the ipv4 address will be setup by the system container -init scripts. Here is an example of the mount points file: - -.nf - [root@lxc debian]$ cat fstab - - /dev /home/root/debian/rootfs/dev none bind 0 0 - /dev/pts /home/root/debian/rootfs/dev/pts none bind 0 0 - -.fi -More information can be added to the container to facilitate the -configuration. For example, make accessible from the container -the resolv.conf file belonging to the host. - -.nf - /etc/resolv.conf /home/root/debian/rootfs/etc/resolv.conf none bind 0 0 - -.fi -.SS "CONTAINER LIFE CYCLE" -.PP -When the container is created, it contains the configuration -information. When a process is launched, the container will be -starting and running. When the last process running inside the -container exits, the container is stopped. -.PP -In case of failure when the container is initialized, it will -pass through the aborting state. - -.nf - - --------- - | STOPPED |<--------------- - --------- | - | | - start | - | | - V | - ---------- | - | STARTING |--error- | - ---------- | | - | | | - V V | - --------- ---------- | - | RUNNING | | ABORTING | | - --------- ---------- | - | | | - no process | | - | | | - V | | - ---------- | | - | STOPPING |<------- | - ---------- | - | | - --------------------- - - -.fi -.SS "CONFIGURATION" -.PP -The container is configured through a configuration -file, the format of the configuration file is described in -\fB\fIlxc.conf\fB\fR(5) -.SS "CREATING / DESTROYING CONTAINER (PERSISTENT CONTAINER)" -.PP -A persistent container object can be -created via the \fBlxc-create\fR -command. It takes a container name as parameter and -optional configuration file and template. -The name is used by the different -commands to refer to this -container. The \fBlxc-destroy\fR command will -destroy the container object. - -.nf - lxc-create -n foo - lxc-destroy -n foo - -.fi -.SS "VOLATILE CONTAINER" -.PP -It is not mandatory to create a container object -before to start it. -The container can be directly started with a -configuration file as parameter. -.SS "STARTING / STOPPING CONTAINER" -.PP -When the container has been created, it is ready to run an -application / system. -This is the purpose of the \fBlxc-execute\fR and -\fBlxc-start\fR commands. -If the container was not created before -starting the application, the container will use the -configuration file passed as parameter to the command, -and if there is no such parameter either, then -it will use a default isolation. -If the application is ended, the container will be stopped also, -but if needed the \fBlxc-stop\fR command can -be used to kill the still running application. -.PP -Running an application inside a container is not exactly the -same thing as running a system. For this reason, there are two -different commands to run an application into a container: - -.nf - lxc-execute -n foo [-f config] /bin/bash - lxc-start -n foo [-f config] [/bin/bash] - -.fi -.PP -\fBlxc-execute\fR command will run the -specified command into the container via an intermediate -process, \fBlxc-init\fR\&. -This lxc-init after launching the specified command, -will wait for its end and all other reparented processes. -(that allows to support daemons in the container). -In other words, in the -container, \fBlxc-init\fR has the pid 1 and the -first process of the application has the pid 2. -.PP -\fBlxc-start\fR command will run directly the specified -command into the container. -The pid of the first process is 1. If no command is -specified \fBlxc-start\fR will -run \fI/sbin/init\fR\&. -.PP -To summarize, \fBlxc-execute\fR is for running -an application and \fBlxc-start\fR is better suited for -running a system. -.PP -If the application is no longer responding, is inaccessible or is -not able to finish by itself, a -wild \fBlxc-stop\fR command will kill all the -processes in the container without pity. - -.nf - lxc-stop -n foo - -.fi -.SS "CONNECT TO AN AVAILABLE TTY" -.PP -If the container is configured with the ttys, it is possible -to access it through them. It is up to the container to -provide a set of available tty to be used by the following -command. When the tty is lost, it is possible to reconnect it -without login again. - -.nf - lxc-console -n foo -t 3 - -.fi -.SS "FREEZE / UNFREEZE CONTAINER" -.PP -Sometime, it is useful to stop all the processes belonging to -a container, eg. for job scheduling. The commands: - -.nf - lxc-freeze -n foo - -.fi -will put all the processes in an uninteruptible state and - -.nf - lxc-unfreeze -n foo - -.fi -will resume them. -.PP -This feature is enabled if the cgroup freezer is enabled in the -kernel. -.SS "GETTING INFORMATION ABOUT CONTAINER" -.PP -When there are a lot of containers, it is hard to follow -what has been created or destroyed, what is running or what are -the pids running into a specific container. For this reason, the -following commands may be usefull: - -.nf - lxc-ls - lxc-ps --name foo - lxc-info -n foo - -.fi -.PP -\fBlxc-ls\fR lists the containers of the -system. The command is a script built on top -of \fBls\fR, so it accepts the options of the ls -commands, eg: - -.nf - lxc-ls -C1 - -.fi -will display the containers list in one column or: - -.nf - lxc-ls -l - -.fi -will display the containers list and their permissions. -.PP -\fBlxc-ps\fR will display the pids for a specific -container. Like \fBlxc-ls\fR, \fBlxc-ps\fR -is built on top of \fBps\fR and accepts the same -options, eg: - -.nf -lxc-ps --name foo --forest -.fi -will display the processes hierarchy for the processes -belonging the 'foo' container. - -.nf -lxc-ps --lxc -.fi -will display all the containers and their processes. -.PP -\fBlxc-info\fR gives informations for a specific -container, at present time, only the state of the container is -displayed. -.PP -Here is an example on how the combination of these commands -allow to list all the containers and retrieve their state. - -.nf - for i in $(lxc-ls -1); do - lxc-info -n $i - done - -.fi -And displaying all the pids of all the containers: - -.nf - for i in $(lxc-ls -1); do - lxc-ps --name $i --forest - done - -.fi -.PP -\fBlxc-netstat\fR display network information for -a specific container. This command is built on top of -the \fBnetstat\fR command and will accept its -options -.PP -The following command will display the socket informations for -the container 'foo'. - -.nf - lxc-netstat -n foo -tano - -.fi -.SS "MONITORING CONTAINER" -.PP -It is sometime useful to track the states of a container, -for example to monitor it or just to wait for a specific -state in a script. -.PP -\fBlxc-monitor\fR command will monitor one or -several containers. The parameter of this command accept a -regular expression for example: - -.nf - lxc-monitor -n "foo|bar" - -.fi -will monitor the states of containers named 'foo' and 'bar', and: - -.nf - lxc-monitor -n ".*" - -.fi -will monitor all the containers. -.PP -For a container 'foo' starting, doing some work and exiting, -the output will be in the form: - -.nf -\&'foo' changed state to [STARTING] -\&'foo' changed state to [RUNNING] -\&'foo' changed state to [STOPPING] -\&'foo' changed state to [STOPPED] - -.fi -.PP -\fBlxc-wait\fR command will wait for a specific -state change and exit. This is useful for scripting to -synchronize the launch of a container or the end. The -parameter is an ORed combination of different states. The -following example shows how to wait for a container if he went -to the background. - -.nf - - # launch lxc-wait in background - lxc-wait -n foo -s STOPPED & - LXC_WAIT_PID=$! - - # this command goes in background - lxc-execute -n foo mydaemon & - - # block until the lxc-wait exits - # and lxc-wait exits when the container - # is STOPPED - wait $LXC_WAIT_PID - echo "'foo' is finished" - - -.fi -.SS "SETTING THE CONTROL GROUP FOR CONTAINER" -.PP -The container is tied with the control groups, when a -container is started a control group is created and associated -with it. The control group properties can be read and modified -when the container is running by using the lxc-cgroup command. -.PP -\fBlxc-cgroup\fR command is used to set or get a -control group subsystem which is associated with a -container. The subsystem name is handled by the user, the -command won't do any syntax checking on the subsystem name, if -the subsystem name does not exists, the command will fail. -.PP - -.nf - lxc-cgroup -n foo cpuset.cpus - -.fi -will display the content of this subsystem. - -.nf - lxc-cgroup -n foo cpu.shares 512 - -.fi -will set the subsystem to the specified value. -.SH "BUGS" -.PP -The \fBlxc\fR is still in development, so the -command syntax and the API can change. The version 1.0.0 will be -the frozen version. -.SH "SEE ALSO" -.PP -\fBlxc\fR(1), -\fBlxc-create\fR(1), -\fBlxc-destroy\fR(1), -\fBlxc-start\fR(1), -\fBlxc-stop\fR(1), -\fBlxc-execute\fR(1), -\fBlxc-kill\fR(1), -\fBlxc-console\fR(1), -\fBlxc-monitor\fR(1), -\fBlxc-wait\fR(1), -\fBlxc-cgroup\fR(1), -\fBlxc-ls\fR(1), -\fBlxc-ps\fR(1), -\fBlxc-info\fR(1), -\fBlxc-freeze\fR(1), -\fBlxc-unfreeze\fR(1), -\fBlxc-attach\fR(1), -\fBlxc.conf\fR(5) -.SH "AUTHOR" -.PP -Daniel Lezcano diff -Nru lxc-0.8.0~rc1/doc/lxc.conf.5 lxc-1.0.0~alpha1/doc/lxc.conf.5 --- lxc-0.8.0~rc1/doc/lxc.conf.5 2012-03-01 23:04:55.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/lxc.conf.5 1970-01-01 00:00:00.000000000 +0000 @@ -1,423 +0,0 @@ -.\" This manpage has been automatically generated by docbook2man -.\" from a DocBook document. This tool can be found at: -.\" -.\" Please send any bug reports, improvements, comments, patches, -.\" etc. to Steve Cheng . -.TH "LXC.CONF" "5" "02 March 2012" "" "" - -.SH NAME -lxc.conf \- linux container configuration file -.SH "DESCRIPTION" -.PP -The linux containers (\fBlxc\fR) are always created -before being used. This creation defines a set of system -resources to be virtualized / isolated when a process is using -the container. By default, the pids, sysv ipc and mount points -are virtualized and isolated. The other system resources are -shared across containers, until they are explicitly defined in -the configuration file. For example, if there is no network -configuration, the network will be shared between the creator of -the container and the container itself, but if the network is -specified, a new network stack is created for the container and -the container can no longer use the network of its ancestor. -.PP -The configuration file defines the different system resources to -be assigned for the container. At present, the utsname, the -network, the mount points, the root file system and the control -groups are supported. -.PP -Each option in the configuration file has the form \fBkey -= value\fR fitting in one line. The '#' character means -the line is a comment. -.SS "ARCHITECTURE" -.PP -Allows to set the architecture for the container. For example, -set a 32bits architecture for a container running 32bits -binaries on a 64bits host. That fix the container scripts -which rely on the architecture to do some work like -downloading the packages. -.TP -\fB lxc.arch \fR -Specify the architecture for the container. - -Valid options are -\fBx86\fR, -\fBi686\fR, -\fBx86_64\fR, -\fBamd64\fR -.SS "HOSTNAME" -.PP -The utsname section defines the hostname to be set for the -container. That means the container can set its own hostname -without changing the one from the system. That makes the -hostname private for the container. -.TP -\fB lxc.utsname \fR -specify the hostname for the container -.SS "NETWORK" -.PP -The network section defines how the network is virtualized in -the container. The network virtualization acts at layer -two. In order to use the network virtualization, parameters -must be specified to define the network interfaces of the -container. Several virtual interfaces can be assigned and used -in a container even if the system has only one physical -network interface. -.TP -\fB lxc.network.type \fR -specify what kind of network virtualization to be used -for the container. Each time -a \fBlxc.network.type\fR field is found a new -round of network configuration begins. In this way, -several network virtualization types can be specified -for the same container, as well as assigning several -network interfaces for one container. The different -virtualization types can be: - -\fBempty:\fR will create only the loopback -interface. - -\fBveth:\fR a peer network device is created -with one side assigned to the container and the other -side is attached to a bridge specified by -the \fBlxc.network.link\fR\&. If the bridge is -not specified, then the veth pair device will be created -but not attached to any bridge. Otherwise, the bridge -has to be setup before on the -system, \fBlxc\fR won't handle any -configuration outside of the container. By -default \fBlxc\fR choose a name for the -network device belonging to the outside of the -container, this name is handled -by \fBlxc\fR, but if you wish to handle -this name yourself, you can tell \fBlxc\fR -to set a specific name with -the \fBlxc.network.veth.pair\fR option. - -\fBvlan:\fR a vlan interface is linked with -the interface specified by -the \fBlxc.network.link\fR and assigned to -the container. The vlan identifier is specified with the -option \fBlxc.network.vlan.id\fR\&. - -\fBmacvlan:\fR a macvlan interface is linked -with the interface specified by -the \fBlxc.network.link\fR and assigned to -the container. -\fBlxc.network.macvlan.mode\fR specifies the -mode the macvlan will use to communicate between -different macvlan on the same upper device. The accepted -modes are \fBprivate\fR, the device never -communicates with any other device on the same upper_dev (default), -\fBvepa\fR, the new Virtual Ethernet Port -Aggregator (VEPA) mode, it assumes that the adjacent -bridge returns all frames where both source and -destination are local to the macvlan port, i.e. the -bridge is set up as a reflective relay. Broadcast -frames coming in from the upper_dev get flooded to all -macvlan interfaces in VEPA mode, local frames are not -delivered locallay, or \fBbridge\fR, it -provides the behavior of a simple bridge between -different macvlan interfaces on the same port. Frames -from one interface to another one get delivered directly -and are not sent out externally. Broadcast frames get -flooded to all other bridge ports and to the external -interface, but when they come back from a reflective -relay, we don't deliver them again. Since we know all -the MAC addresses, the macvlan bridge mode does not -require learning or STP like the bridge module does. - -\fBphys:\fR an already existing interface -specified by the \fBlxc.network.link\fR is -assigned to the container. -.TP -\fB lxc.network.flags \fR -specify an action to do for the -network. - -\fBup:\fR activates the interface. -.TP -\fB lxc.network.link \fR -specify the interface to be used for real network -traffic. -.TP -\fB lxc.network.name \fR -the interface name is dynamically allocated, but if -another name is needed because the configuration files -being used by the container use a generic name, -eg. eth0, this option will rename the interface in the -container. -.TP -\fB lxc.network.hwaddr \fR -the interface mac address is dynamically allocated by -default to the virtual interface, but in some cases, -this is needed to resolve a mac address conflict or to -always have the same link-local ipv6 address -.TP -\fB lxc.network.ipv4 \fR -specify the ipv4 address to assign to the virtualized -interface. Several lines specify several ipv4 addresses. -The address is in format x.y.z.t/m, -eg. 192.168.1.123/24. The broadcast address should be -specified on the same line, right after the ipv4 -address. -.TP -\fB lxc.network.ipv4.gateway \fR -specify the ipv4 address to use as the gateway inside the -container. The address is in format x.y.z.t, eg. -192.168.1.123. -Can also have the special value \fBauto\fR, -which means to take the primary address from the bridge -interface (as specified by the -\fBlxc.network.link\fR option) and use that as -the gateway. \fBauto\fR is only available when -using the \fBveth\fR and -\fBmacvlan\fR network types. -.TP -\fB lxc.network.ipv6 \fR -specify the ipv6 address to assign to the virtualized -interface. Several lines specify several ipv6 addresses. -The address is in format x::y/m, -eg. 2003:db8:1:0:214:1234:fe0b:3596/64 -.TP -\fB lxc.network.ipv6.gateway \fR -specify the ipv6 address to use as the gateway inside the -container. The address is in format x::y, -eg. 2003:db8:1:0::1 -Can also have the special value \fBauto\fR, -which means to take the primary address from the bridge -interface (as specified by the -\fBlxc.network.link\fR option) and use that as -the gateway. \fBauto\fR is only available when -using the \fBveth\fR and -\fBmacvlan\fR network types. -.TP -\fB lxc.network.script.up \fR -add a configuration option to specify a script to be -executed after creating and configuring the network used -from the host side. The following arguments are passed -to the script: container name and config section name -(net) Additional arguments depend on the config section -employing a script hook; the following are used by the -network system: execution context (up), network type -(empty/veth/macvlan/phys), Depending on the network -type, other arguments may be passed: -veth/macvlan/phys. And finally (host-sided) device name. -.SS "NEW PSEUDO TTY INSTANCE (DEVPTS)" -.PP -For stricter isolation the container can have its own private -instance of the pseudo tty. -.TP -\fB lxc.pts \fR -If set, the container will have a new pseudo tty -instance, making this private to it. The value specifies -the maximum number of pseudo ttys allowed for a pts -instance (this limitation is not implemented yet). -.SS "CONTAINER SYSTEM CONSOLE" -.PP -If the container is configured with a root filesystem and the -inittab file is setup to use the console, you may want to specify -where goes the output of this console. -.TP -\fB lxc.console \fR -Specify a path to a file where the console output will -be written. The keyword 'none' will simply disable the -console. This is dangerous once if have a rootfs with a -console device file where the application can write, the -messages will fall in the host. -.SS "CONSOLE THROUGH THE TTYS" -.PP -If the container is configured with a root filesystem and the -inittab file is setup to launch a getty on the ttys. This -option will specify the number of ttys to be available for the -container. The number of getty in the inittab file of the -container should not be greater than the number of ttys -specified in this configuration file, otherwise the excess -getty sessions will die and respawn indefinitly giving -annoying messages on the console. -.TP -\fB lxc.tty \fR -Specify the number of tty to make available to the -container. -.SS "MOUNT POINTS" -.PP -The mount points section specifies the different places to be -mounted. These mount points will be private to the container -and won't be visible by the processes running outside of the -container. This is useful to mount /etc, /var or /home for -examples. -.TP -\fB lxc.mount \fR -specify a file location in -the \fIfstab\fR format, containing the -mount informations. If the rootfs is an image file or a -device block and the fstab is used to mount a point -somewhere in this rootfs, the path of the rootfs mount -point should be prefixed with the -\fI${libdir}/lxc/rootfs\fR default path or -the value of \fBlxc.rootfs.mount\fR if -specified. -.TP -\fB lxc.mount.entry \fR -specify a mount point corresponding to a line in the -fstab format. -.SS "ROOT FILE SYSTEM" -.PP -The root file system of the container can be different than that -of the host system. -.TP -\fB lxc.rootfs \fR -specify the root file system for the container. It can -be an image file, a directory or a block device. If not -specified, the container shares its root file system -with the host. -.TP -\fB lxc.rootfs.mount \fR -where to recursively bind \fBlxc.rootfs\fR -before pivoting. This is to ensure success of the -\fBpivot_root\fR(8) -syscall. Any directory suffices, the default should -generally work. -.TP -\fB lxc.pivotdir \fR -where to pivot the original root file system under -\fBlxc.rootfs\fR, specified relatively to -that. The default is \fImnt\fR\&. -It is created if necessary, and also removed after -unmounting everything from it during container setup. -.SS "CONTROL GROUP" -.PP -The control group section contains the configuration for the -different subsystem. \fBlxc\fR does not check the -correctness of the subsystem name. This has the disadvantage -of not detecting configuration errors until the container is -started, but has the advantage of permitting any future -subsystem. -.TP -\fB lxc.cgroup.[subsystem name] \fR -specify the control group value to be set. The -subsystem name is the literal name of the control group -subsystem. The permitted names and the syntax of their -values is not dictated by LXC, instead it depends on the -features of the Linux kernel running at the time the -container is started, -eg. \fBlxc.cgroup.cpuset.cpus\fR -.SS "CAPABILITIES" -.PP -The capabilities can be dropped in the container if this one -is run as root. -.TP -\fB lxc.cap.drop \fR -Specify the capability to be dropped in the container. A -single line defining several capabilities with a space -separation is allowed. The format is the lower case of -the capability definition without the "CAP_" prefix, -eg. CAP_SYS_MODULE should be specified as -sys_module. See -\fBcapabilities\fR(7), -.SH "EXAMPLES" -.PP -In addition to the few examples given below, you will find -some other examples of configuration file in /usr/share/doc/lxc/examples -.SS "NETWORK" -.PP -This configuration sets up a container to use a veth pair -device with one side plugged to a bridge br0 (which has been -configured before on the system by the administrator). The -virtual network device visible in the container is renamed to -eth0. - -.nf - lxc.utsname = myhostname - lxc.network.type = veth - lxc.network.flags = up - lxc.network.link = br0 - lxc.network.name = eth0 - lxc.network.hwaddr = 4a:49:43:49:79:bf - lxc.network.ipv4 = 1.2.3.5/24 1.2.3.255 - lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3597 - -.fi -.SS "CONTROL GROUP" -.PP -This configuration will setup several control groups for -the application, cpuset.cpus restricts usage of the defined cpu, -cpus.share prioritize the control group, devices.allow makes -usable the specified devices. - -.nf - lxc.cgroup.cpuset.cpus = 0,1 - lxc.cgroup.cpu.shares = 1234 - lxc.cgroup.devices.deny = a - lxc.cgroup.devices.allow = c 1:3 rw - lxc.cgroup.devices.allow = b 8:0 rw - -.fi -.SS "COMPLEX CONFIGURATION" -.PP -This example show a complex configuration making a complex -network stack, using the control groups, setting a new hostname, -mounting some locations and a changing root file system. - -.nf - lxc.utsname = complex - lxc.network.type = veth - lxc.network.flags = up - lxc.network.link = br0 - lxc.network.hwaddr = 4a:49:43:49:79:bf - lxc.network.ipv4 = 1.2.3.5/24 1.2.3.255 - lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3597 - lxc.network.ipv6 = 2003:db8:1:0:214:5432:feab:3588 - lxc.network.type = macvlan - lxc.network.flags = up - lxc.network.link = eth0 - lxc.network.hwaddr = 4a:49:43:49:79:bd - lxc.network.ipv4 = 1.2.3.4/24 - lxc.network.ipv4 = 192.168.10.125/24 - lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3596 - lxc.network.type = phys - lxc.network.flags = up - lxc.network.link = dummy0 - lxc.network.hwaddr = 4a:49:43:49:79:ff - lxc.network.ipv4 = 1.2.3.6/24 - lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3297 - lxc.cgroup.cpuset.cpus = 0,1 - lxc.cgroup.cpu.shares = 1234 - lxc.cgroup.devices.deny = a - lxc.cgroup.devices.allow = c 1:3 rw - lxc.cgroup.devices.allow = b 8:0 rw - lxc.mount = /etc/fstab.complex - lxc.mount.entry = /lib /root/myrootfs/lib none ro,bind 0 0 - lxc.rootfs = /mnt/rootfs.complex - lxc.cap.drop = sys_module mknod setuid net_raw - lxc.cap.drop = mac_override - -.fi -.SH "SEE ALSO" -.PP -\fBchroot\fR(1), -\fBpivot_root\fR(8), -\fB\fIfstab\fB\fR(5) -.SH "SEE ALSO" -.PP -\fBlxc\fR(1), -\fBlxc-create\fR(1), -\fBlxc-destroy\fR(1), -\fBlxc-start\fR(1), -\fBlxc-stop\fR(1), -\fBlxc-execute\fR(1), -\fBlxc-kill\fR(1), -\fBlxc-console\fR(1), -\fBlxc-monitor\fR(1), -\fBlxc-wait\fR(1), -\fBlxc-cgroup\fR(1), -\fBlxc-ls\fR(1), -\fBlxc-ps\fR(1), -\fBlxc-info\fR(1), -\fBlxc-freeze\fR(1), -\fBlxc-unfreeze\fR(1), -\fBlxc-attach\fR(1), -\fBlxc.conf\fR(5) -.SH "AUTHOR" -.PP -Daniel Lezcano diff -Nru lxc-0.8.0~rc1/doc/lxc.conf.sgml.in lxc-1.0.0~alpha1/doc/lxc.conf.sgml.in --- lxc-0.8.0~rc1/doc/lxc.conf.sgml.in 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/lxc.conf.sgml.in 2013-09-10 22:22:00.000000000 +0000 @@ -1,11 +1,11 @@ - - ]> @@ -65,8 +65,8 @@ The configuration file defines the different system resources to be assigned for the container. At present, the utsname, the - network, the mount points, the root file system and the control - groups are supported. + network, the mount points, the root file system, the user namespace, + and the control groups are supported. @@ -76,11 +76,37 @@ + Configuration + + In order to ease administration of multiple related containers, it + is possible to have a container configuration file cause another + file to be loaded. For instance, network configuration + can be defined in one common file which is included by multiple + containers. Then, if the containers are moved to another host, + only one file may need to be updated. + + + + + + + + + + Specify the file to be included. The included file must be + in the same valid lxc configuration file format. + + + + + + + Architecture Allows to set the architecture for the container. For example, set a 32bits architecture for a container running 32bits - binaries on a 64bits host. That fix the container scripts + binaries on a 64bits host. This fixes the container scripts which rely on the architecture to do some work like downloading the packages. @@ -130,6 +156,29 @@ + Stop signal + + Allows to specify signal name or number, sent by lxc-stop to + shutdown the container. Different init systems could use + different signals to perform clean shutdown sequence. Option + allows signal to be specified in kill(1) fashion, e.g. + SIGKILL, SIGRTMIN+14, SIGRTMAX-10 or plain number. + + + + + + + + + specify the signal used to stop the container + + + + + + + Network The network section defines how the network is virtualized in @@ -206,7 +255,7 @@ bridge is set up as a reflective relay. Broadcast frames coming in from the upper_dev get flooded to all macvlan interfaces in VEPA mode, local frames are not - delivered locallay, or , it + delivered locally, or , it provides the behavior of a simple bridge between different macvlan interfaces on the same port. Frames from one interface to another one get delivered directly @@ -235,7 +284,7 @@ specify an action to do for the network. - + activates the interface. @@ -372,6 +421,36 @@ type, other arguments may be passed: veth/macvlan/phys. And finally (host-sided) device name. + + Standard output from the script is logged at debug level. + Standard error is not logged, but can be captured by the + hook redirecting its standard error to standard output. + + + + + + + + + + + add a configuration option to specify a script to be + executed before destroying the network used from the + host side. The following arguments are passed to the + script: container name and config section name (net) + Additional arguments depend on the config section + employing a script hook; the following are used by the + network system: execution context (down), network type + (empty/veth/macvlan/phys), Depending on the network + type, other arguments may be passed: + veth/macvlan/phys. And finally (host-sided) device name. + + + Standard output from the script is logged at debug level. + Standard error is not logged, but can be captured by the + hook redirecting its standard error to standard output. + @@ -405,7 +484,7 @@ If the container is configured with a root filesystem and the inittab file is setup to use the console, you may want to specify - where goes the output of this console. + where the output of this console goes. @@ -428,14 +507,14 @@ Console through the ttys - If the container is configured with a root filesystem and the - inittab file is setup to launch a getty on the ttys. This - option will specify the number of ttys to be available for the - container. The number of getty in the inittab file of the - container should not be greater than the number of ttys - specified in this configuration file, otherwise the excess - getty sessions will die and respawn indefinitly giving - annoying messages on the console. + This option is useful if the container is configured with a root + filesystem and the inittab file is setup to launch a getty on the + ttys. The option specifies the number of ttys to be available for + the container. The number of gettys in the inittab file of the + container should not be greater than the number of ttys specified + in this option, otherwise the excess getty sessions will die and + respawn indefinitely giving annoying messages on the console or in + /var/log/messages. @@ -453,6 +532,83 @@ + Console devices location + + LXC consoles are provided through Unix98 PTYs created on the + host and bind-mounted over the expected devices in the container. + By default, they are bind-mounted over /dev/console + and /dev/ttyN. This can prevent package upgrades + in the guest. Therefore you can specify a directory location (under + /dev under which LXC will create the files and + bind-mount over them. These will then be symbolically linked to + /dev/console and /dev/ttyN. + A package upgrade can then succeed as it is able to remove and replace + the symbolic links. + + + + + + + + + Specify a directory under /dev + under which to create the container console devices. + + + + + + + + /dev directory + + By default, lxc does nothing with the container's + /dev. This allows the container's + /dev to be set up as needed in the container + rootfs. If lxc.autodev is set to 1, then after mounting the container's + rootfs LXC will mount a fresh tmpfs under /dev + (limited to 100k) and fill in a minimal set of initial devices. + This is generally required when starting a container containing + a "systemd" based "init" but may be optional at other times. Additional + devices in the containers /dev directory may be created through the + use of the hook. + + + + + + + + + Set this to 1 to have LXC mount and populate a minimal + /dev when starting the container. + + + + + + + + Enable kmsg symlink + + Enable creating /dev/kmsg as symlink to /dev/console. This defaults to 1. + + + + + + + + + Set this to 0 to disable /dev/kmsg symlinking. + + + + + + + Mount points The mount points section specifies the different places to be @@ -470,13 +626,20 @@ specify a file location in the fstab format, containing the - mount informations. If the rootfs is an image file or a - device block and the fstab is used to mount a point + mount information. If the rootfs is an image file or a + block device and the fstab is used to mount a point somewhere in this rootfs, the path of the rootfs mount point should be prefixed with the @LXCROOTFSMOUNT@ default path or the value of if - specified. + specified. Note that when mounting a filesystem from an + image file or block device the third field (fs_vfstype) + cannot be auto as with + + mount + 8 + + but must be explicitly specified. @@ -608,6 +771,382 @@ + + + + + + + Specify the capability to be kept in the container. All other + capabilities will be dropped. + + + + + + + + Apparmor profile + + If lxc was compiled and installed with apparmor support, and the host + system has apparmor enabled, then the apparmor profile under which the + container should be run can be specified in the container + configuration. The default is lxc-container-default. + + + + + + + + + Specify the apparmor profile under which the container should + be run. To specify that the container should be unconfined, + use + + lxc.aa_profile = unconfined + + + + + + + Seccomp configuration + + A container can be started with a reduced set of available + system calls by loading a seccomp profile at startup. The + seccomp configuration file should begin with a version number + (which currently must be 1) on the first line, a policy type + (which must be 'whitelist') on the second line, followed by a + list of allowed system call numbers, one per line. + + + + + + + + + Specify a file containing the seccomp configuration to + load before the container starts. + + + + + + + + UID mappings + + A container can be started in a private user namespace with + user and group id mappings. For instance, you can map userid + 0 in the container to userid 200000 on the host. The root + user in the container will be privileged in the container, + but unprivileged on the host. Normally a system container + will want a range of ids, so you would map, for instance, + user and group ids 0 through 20,000 in the container to the + ids 200,000 through 220,000. + + + + + + + + + Four values must be provided. First a character, either + 'u', or 'g', to specify whether user or group ids are + being mapped. Next is the first userid as seen in the + user namespace of the container. Next is the userid as + seen on the host. Finally, a range indicating the number + of consecutive ids to map. + + + + + + + + Container hooks + + Container hooks are programs or scripts which can be executed + at various times in a container's lifetime. + + + When a container hook is executed, information is passed both + as command line arguments and through environment variables. + The arguments are: + + Container name. + Section (always 'lxc'). + The hook type (i.e. 'clone' or 'pre-mount'). + Additional arguments In the + case of the clone hook, any extra arguments passed to + lxc-clone will appear as further arguments to the hook. + + The following environment variables are set: + + LXC_NAME: is the container's name. + LXC_ROOTFS_MOUNT: the path to the mounted root filesystem. + LXC_CONFIG_FILE: the path to the container configuration file. + LXC_SRC_NAME: in the case of the clone hook, this is the original container's name. + LXC_ROOTFS_PATH: this is the lxc.rootfs enty for the container. Note this is likely not where the mounted rootfs is to be found, use LXC_ROOTFS_MOUNT for that. + + + + Standard output from the hooks is logged at debug level. + Standard error is not logged, but can be captured by the + hook redirecting its standard error to standard output. + + + + + + + + + A hook to be run in the host's namespace before the + container ttys, consoles, or mounts are up. + + + + + + + + + + + + A hook to be run in the container's fs namespace but before + the rootfs has been set up. This allows for manipulation + of the rootfs, i.e. to mount an encrypted filesystem. Mounts + done in this hook will not be reflected on the host (apart from + mounts propagation), so they will be automatically cleaned up + when the container shuts down. + + + + + + + + + + + + A hook to be run in the container's namespace after + mounting has been done, but before the pivot_root. + + + + + + + + + + + + A hook to be run in the container's namespace after + mounting has been done and after any mount hooks have + run, but before the pivot_root, if + == 1. + The purpose of this hook is to assist in populating the + /dev directory of the container when using the autodev + option for systemd based containers. The container's /dev + directory is relative to the + ${} environment + variable available when the hook is run. + + + + + + + + + + + + A hook to be run in the container's namespace immediately + before executing the container's init. This requires the + program to be available in the container. + + + + + + + + + + + + A hook to be run in the host's namespace after the + container has been shut down. + + + + + + + + + + + + A hook to be run when the container is cloned to a new one. + See lxc-clone + 1 for more information. + + + + + + + + Container hooks Environment Variables + + A number of environment variables are made available to the startup + hooks to provide configuration information and assist in the + functioning of the hooks. Not all variables are valid in all + contexts. In particular, all paths are relative to the host system + and, as such, not valid during the hook. + + + + + + + + + The LXC name of the container. Useful for logging messages + in commmon log environments. [] + + + + + + + + + + + + Host relative path to the container configuration file. This + gives the container to reference the original, top level, + configuration file for the container in order to locate any + additional configuration information not otherwise made + available. [] + + + + + + + + + + + + The path to the console output of the container if not NULL. + [] [] + + + + + + + + + + + + The path to the console log output of the container if not NULL. + [] + + + + + + + + + + + + The mount location to which the container is initially bound. + This will be the host relative path to the container rootfs + for the container instance being started and is where changes + should be made for that instance. + [] + + + + + + + + + + + + The host relative path to the container root which has been + mounted to the rootfs.mount location. + [] + + + + + + + + Logging + + Logging can be configured on a per-container basis. By default, + depending upon how the lxc package was compiled, container startup + is logged only at the ERROR level, and logged to a file named after + the container (with '.log' appended) either under the container path, + or under @LOGPATH@. + + + Both the default log level and the log file can be specified in the + container configuration file, overriding the default behavior. Note + that the configuration file entries can in turn be overridden by the + command line options to lxc-start. + + + + + + + + + The level at which to log. The log level is an integer in + the range of 0..8 inclusive, where a lower number means more + verbose debugging. In particular 0 = trace, 1 = debug, 2 = + info, 3 = notice, 4 = warn, 5 = error, 6 = critical, 7 = + alert, and 8 = fatal. If unspecified, the level defaults + to 5 (error), so that only errors and above are logged. + + + Note that when a script (such as either a hook script or a + network interface up or down script) is called, the script's + standard output is logged at level 1, debug. + + + + + + + + + + The file to which logging info should be written. + + + @@ -633,12 +1172,23 @@ lxc.network.link = br0 lxc.network.name = eth0 lxc.network.hwaddr = 4a:49:43:49:79:bf - lxc.network.ipv4 = 1.2.3.5/24 1.2.3.255 + lxc.network.ipv4 = 10.2.3.5/24 10.2.3.255 lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3597 + UID/GID mapping + This configuration will map both user and group ids in the + range 0-9999 in the container to the ids 100000-109999 on the host. + + + lxc.id_map = u 0 100000 10000 + lxc.id_map = g 0 100000 10000 + + + + Control group This configuration will setup several control groups for the application, cpuset.cpus restricts usage of the defined cpu, @@ -664,21 +1214,21 @@ lxc.network.flags = up lxc.network.link = br0 lxc.network.hwaddr = 4a:49:43:49:79:bf - lxc.network.ipv4 = 1.2.3.5/24 1.2.3.255 + lxc.network.ipv4 = 10.2.3.5/24 10.2.3.255 lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3597 lxc.network.ipv6 = 2003:db8:1:0:214:5432:feab:3588 lxc.network.type = macvlan lxc.network.flags = up lxc.network.link = eth0 lxc.network.hwaddr = 4a:49:43:49:79:bd - lxc.network.ipv4 = 1.2.3.4/24 + lxc.network.ipv4 = 10.2.3.4/24 lxc.network.ipv4 = 192.168.10.125/24 lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3596 lxc.network.type = phys lxc.network.flags = up lxc.network.link = dummy0 lxc.network.hwaddr = 4a:49:43:49:79:ff - lxc.network.ipv4 = 1.2.3.6/24 + lxc.network.ipv4 = 10.2.3.6/24 lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3297 lxc.cgroup.cpuset.cpus = 0,1 lxc.cgroup.cpu.shares = 1234 @@ -697,7 +1247,7 @@ See Also - + chroot 1 @@ -711,18 +1261,22 @@ fstab 5 - + , + + capabilities + 7 + - + &seealso; Author Daniel Lezcano daniel.lezcano@free.fr - + - ]> @@ -96,7 +96,7 @@ provided by the kernel which needs to be active. Depending of the missing functionalities the lxc will work with a restricted number of functionalities or will simply - fails. + fail. @@ -239,7 +239,7 @@ /sbin /home/root/sshd/rootfs/sbin none ro,bind 0 0 - + How to run a system in a container ? Running a system inside a container is paradoxically easier @@ -249,7 +249,7 @@ without configuration because the container will set them up. eg. the ipv4 address will be setup by the system container init scripts. Here is an example of the mount points file: - + [root@lxc debian]$ cat fstab @@ -280,7 +280,7 @@ - + Configuration The container is configured through a configuration - file, the format of the configuration file is described in + file, the format of the configuration file is described in lxc.conf 5 @@ -363,7 +363,7 @@ but if needed the lxc-stop command can be used to kill the still running application. - + Running an application inside a container is not exactly the same thing as running a system. For this reason, there are two @@ -434,7 +434,7 @@ lxc-freeze -n foo - will put all the processes in an uninteruptible state and + will put all the processes in an uninteruptible state and lxc-unfreeze -n foo @@ -570,7 +570,7 @@ to the background. - + diff -Nru lxc-0.8.0~rc1/doc/rootfs/Makefile.am lxc-1.0.0~alpha1/doc/rootfs/Makefile.am --- lxc-0.8.0~rc1/doc/rootfs/Makefile.am 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/rootfs/Makefile.am 2013-07-08 15:50:40.000000000 +0000 @@ -1,3 +1,3 @@ READMEdir=@LXCROOTFSMOUNT@ -README_DATA=README \ No newline at end of file +README_DATA=README diff -Nru lxc-0.8.0~rc1/doc/rootfs/Makefile.in lxc-1.0.0~alpha1/doc/rootfs/Makefile.in --- lxc-0.8.0~rc1/doc/rootfs/Makefile.in 2012-03-01 23:04:43.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/rootfs/Makefile.in 2013-09-10 22:30:09.000000000 +0000 @@ -1,9 +1,8 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. +# Makefile.in generated by automake 1.13.3 from Makefile.am. # @configure_input@ -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -16,6 +15,51 @@ @SET_MAKE@ VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -35,18 +79,35 @@ build_triplet = @build@ host_triplet = @host@ subdir = doc/rootfs -DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am README ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/config/acinclude.m4 \ - $(top_srcdir)/config/linux.m4 $(top_srcdir)/configure.ac + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/src/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = SOURCES = DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ @@ -68,11 +129,20 @@ am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } am__installdirs = "$(DESTDIR)$(READMEdir)" DATA = $(README_DATA) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +APPARMOR_LIBS = @APPARMOR_LIBS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ @@ -103,19 +173,31 @@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBDIR = @LIBDIR@ +LIBEXECDIR = @LIBEXECDIR@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ -LINUX_DIR = @LINUX_DIR@ -LINUX_SRCARCH = @LINUX_SRCARCH@ LOCALSTATEDIR = @LOCALSTATEDIR@ +LOGPATH = @LOGPATH@ LTLIBOBJS = @LTLIBOBJS@ +LUA_CFLAGS = @LUA_CFLAGS@ +LUA_INSTALL_CMOD = @LUA_INSTALL_CMOD@ +LUA_INSTALL_LMOD = @LUA_INSTALL_LMOD@ +LUA_LIBS = @LUA_LIBS@ +LUA_VERSION = @LUA_VERSION@ +LXCHOOKDIR = @LXCHOOKDIR@ LXCINITDIR = @LXCINITDIR@ LXCPATH = @LXCPATH@ LXCROOTFSMOUNT = @LXCROOTFSMOUNT@ LXCTEMPLATEDIR = @LXCTEMPLATEDIR@ +LXC_DEFAULT_CONFIG = @LXC_DEFAULT_CONFIG@ +LXC_DISTRO_CONF = @LXC_DISTRO_CONF@ LXC_GENERATE_DATE = @LXC_GENERATE_DATE@ +LXC_GLOBAL_CONF = @LXC_GLOBAL_CONF@ +LXC_USERNIC_CONF = @LXC_USERNIC_CONF@ +LXC_USERNIC_DB = @LXC_USERNIC_DB@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +NEWUIDMAP = @NEWUIDMAP@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ @@ -125,8 +207,19 @@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PREFIX = @PREFIX@ -SETCAP = @SETCAP@ +PYTHON = @PYTHON@ +PYTHONDEV_CFLAGS = @PYTHONDEV_CFLAGS@ +PYTHONDEV_LIBS = @PYTHONDEV_LIBS@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +SECCOMP_LIBS = @SECCOMP_LIBS@ +SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ @@ -151,10 +244,11 @@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ +db2xman = @db2xman@ docdir = @docdir@ +docdtd = @docdtd@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ -have_docbook = @have_docbook@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ @@ -172,9 +266,13 @@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ @@ -220,8 +318,11 @@ $(am__aclocal_m4_deps): install-READMEDATA: $(README_DATA) @$(NORMAL_INSTALL) - test -z "$(READMEdir)" || $(MKDIR_P) "$(DESTDIR)$(READMEdir)" @list='$(README_DATA)'; test -n "$(READMEdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(READMEdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(READMEdir)" || exit 1; \ + fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ @@ -235,14 +336,12 @@ @$(NORMAL_UNINSTALL) @list='$(README_DATA)'; test -n "$(READMEdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - test -n "$$files" || exit 0; \ - echo " ( cd '$(DESTDIR)$(READMEdir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(READMEdir)" && rm -f $$files -tags: TAGS -TAGS: + dir='$(DESTDIR)$(READMEdir)'; $(am__uninstall_files_from_dir) +tags TAGS: + +ctags CTAGS: -ctags: CTAGS -CTAGS: +cscope cscopelist: distdir: $(DISTFILES) @@ -292,10 +391,15 @@ installcheck: installcheck-am install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi mostlyclean-generic: clean-generic: @@ -375,16 +479,17 @@ .MAKE: install-am install-strip -.PHONY: all all-am check check-am clean clean-generic distclean \ - distclean-generic distdir dvi dvi-am html html-am info info-am \ - install install-READMEDATA install-am install-data \ - install-data-am install-dvi install-dvi-am install-exec \ - install-exec-am install-html install-html-am install-info \ - install-info-am install-man install-pdf install-pdf-am \ - install-ps install-ps-am install-strip installcheck \ - installcheck-am installdirs maintainer-clean \ +.PHONY: all all-am check check-am clean clean-generic cscopelist-am \ + ctags-am distclean distclean-generic distdir dvi dvi-am html \ + html-am info info-am install install-READMEDATA install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ - pdf-am ps ps-am uninstall uninstall-READMEDATA uninstall-am + pdf-am ps ps-am tags-am uninstall uninstall-READMEDATA \ + uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. diff -Nru lxc-0.8.0~rc1/doc/see_also.sgml.in lxc-1.0.0~alpha1/doc/see_also.sgml.in --- lxc-0.8.0~rc1/doc/see_also.sgml.in 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/doc/see_also.sgml.in 2013-09-10 22:22:00.000000000 +0000 @@ -5,7 +5,7 @@ (C) Copyright IBM Corp. 2007, 2008 Authors: -Daniel Lezcano +Daniel Lezcano This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -19,7 +19,7 @@ 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 +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA --> diff -Nru lxc-0.8.0~rc1/hooks/Makefile.am lxc-1.0.0~alpha1/hooks/Makefile.am --- lxc-0.8.0~rc1/hooks/Makefile.am 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/hooks/Makefile.am 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,9 @@ +hooksdir=@LXCHOOKDIR@ + +hooks_SCRIPTS = \ + clonehostname \ + mountcgroups \ + mountecryptfsroot \ + ubuntu-cloud-prep + +EXTRA_DIST=$(hooks_SCRIPTS) diff -Nru lxc-0.8.0~rc1/hooks/Makefile.in lxc-1.0.0~alpha1/hooks/Makefile.in --- lxc-0.8.0~rc1/hooks/Makefile.in 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/hooks/Makefile.in 2013-09-10 22:30:09.000000000 +0000 @@ -0,0 +1,517 @@ +# Makefile.in generated by automake 1.13.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = hooks +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/src/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(hooksdir)" +SCRIPTS = $(hooks_SCRIPTS) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +APPARMOR_LIBS = @APPARMOR_LIBS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BINDIR = @BINDIR@ +CAP_LIBS = @CAP_LIBS@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIR = @DATADIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DOCDIR = @DOCDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GREP = @GREP@ +INCLUDEDIR = @INCLUDEDIR@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBDIR = @LIBDIR@ +LIBEXECDIR = @LIBEXECDIR@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LOCALSTATEDIR = @LOCALSTATEDIR@ +LOGPATH = @LOGPATH@ +LTLIBOBJS = @LTLIBOBJS@ +LUA_CFLAGS = @LUA_CFLAGS@ +LUA_INSTALL_CMOD = @LUA_INSTALL_CMOD@ +LUA_INSTALL_LMOD = @LUA_INSTALL_LMOD@ +LUA_LIBS = @LUA_LIBS@ +LUA_VERSION = @LUA_VERSION@ +LXCHOOKDIR = @LXCHOOKDIR@ +LXCINITDIR = @LXCINITDIR@ +LXCPATH = @LXCPATH@ +LXCROOTFSMOUNT = @LXCROOTFSMOUNT@ +LXCTEMPLATEDIR = @LXCTEMPLATEDIR@ +LXC_DEFAULT_CONFIG = @LXC_DEFAULT_CONFIG@ +LXC_DISTRO_CONF = @LXC_DISTRO_CONF@ +LXC_GENERATE_DATE = @LXC_GENERATE_DATE@ +LXC_GLOBAL_CONF = @LXC_GLOBAL_CONF@ +LXC_USERNIC_CONF = @LXC_USERNIC_CONF@ +LXC_USERNIC_DB = @LXC_USERNIC_DB@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +NEWUIDMAP = @NEWUIDMAP@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PREFIX = @PREFIX@ +PYTHON = @PYTHON@ +PYTHONDEV_CFLAGS = @PYTHONDEV_CFLAGS@ +PYTHONDEV_LIBS = @PYTHONDEV_LIBS@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +SECCOMP_LIBS = @SECCOMP_LIBS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SYSCONFDIR = @SYSCONFDIR@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +db2xman = @db2xman@ +docdir = @docdir@ +docdtd = @docdtd@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +hooksdir = @LXCHOOKDIR@ +hooks_SCRIPTS = \ + clonehostname \ + mountcgroups \ + mountecryptfsroot \ + ubuntu-cloud-prep + +EXTRA_DIST = $(hooks_SCRIPTS) +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu hooks/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu hooks/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-hooksSCRIPTS: $(hooks_SCRIPTS) + @$(NORMAL_INSTALL) + @list='$(hooks_SCRIPTS)'; test -n "$(hooksdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(hooksdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(hooksdir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n' \ + -e 'h;s|.*|.|' \ + -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) { files[d] = files[d] " " $$1; \ + if (++n[d] == $(am__install_max)) { \ + print "f", d, files[d]; n[d] = 0; files[d] = "" } } \ + else { print "f", d "/" $$4, $$1 } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(hooksdir)$$dir'"; \ + $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(hooksdir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-hooksSCRIPTS: + @$(NORMAL_UNINSTALL) + @list='$(hooks_SCRIPTS)'; test -n "$(hooksdir)" || exit 0; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 's,.*/,,;$(transform)'`; \ + dir='$(DESTDIR)$(hooksdir)'; $(am__uninstall_files_from_dir) +tags TAGS: + +ctags CTAGS: + +cscope cscopelist: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(SCRIPTS) +installdirs: + for dir in "$(DESTDIR)$(hooksdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-hooksSCRIPTS + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-hooksSCRIPTS + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic cscopelist-am \ + ctags-am distclean distclean-generic distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-hooksSCRIPTS install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-generic pdf pdf-am ps ps-am tags-am uninstall \ + uninstall-am uninstall-hooksSCRIPTS + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff -Nru lxc-0.8.0~rc1/hooks/clonehostname lxc-1.0.0~alpha1/hooks/clonehostname --- lxc-0.8.0~rc1/hooks/clonehostname 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/hooks/clonehostname 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,29 @@ +#!/bin/sh +# +# Update the hostname in the cloned container's scripts +# +# Copyright © 2013 Oracle. +# +# This library is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2, as +# published by the Free Software Foundation. +# +# 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., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +# Note that /etc/hostname is updated by lxc itself +for file in \ + $LXC_ROOTFS_PATH/etc/sysconfig/network \ + $LXC_ROOTFS_PATH/etc/sysconfig/network-scripts/ifcfg-* ; +do + if [ -f $file ]; then + sed -i "s|$LXC_SRC_NAME|$LXC_NAME|" $file + fi +done +exit 0 diff -Nru lxc-0.8.0~rc1/hooks/mountcgroups lxc-1.0.0~alpha1/hooks/mountcgroups --- lxc-0.8.0~rc1/hooks/mountcgroups 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/hooks/mountcgroups 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,67 @@ +#!/bin/bash + +# (C) Copyright Canonical 2011,2012 + +# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +# +# This is an example hook to mount all mounted cgroups in the +# container. Only the container's own cgroup (not parents) will be +# accessible to the container. You can enable this by adding +# lxc.hook.mount = /usr/share/lxc/hooks/mountcgroups +# to your container's configuration file. + +set -e + +c=$1 +configfile=$LXC_CONFIG_FILE +d=/sys/fs/cgroup +d2=$LXC_ROOTFS_MOUNT/${d} +# name lxc hook lxcpath +lxcpath=$4 +if [ ! -d "$d" ]; then + exit 0 +fi + +mount -n -t tmpfs tmpfs ${d2} + +do_devices_setup() { + local devdir="$1" + local c="$2" + local line + local w # which (allow or deny) + local v # value + egrep "^lxc.cgroup.devices.(allow|deny)[ \t]*=" ${configfile} | while read line; do + w=`echo $line | awk -F. '{ print $4 }' | awk '{ print $1 }'` + v=`echo $line | awk -F= '{ print $2 }'` + echo "$v" >> "$devdir"/devices.$w + done +} + +# XXX TODO - we'll need to account for other cgroup groups beside 'lxc', +# i.e. 'build' or 'users/joe'. +for dir in `/bin/ls $d`; do + if [ "$dir" = "devices" ]; then + devicesdir="${d}/${dir}/lxc/${c}" + mkdir -p "$devicesdir" + # set the devices cgroup perms now - we can't change from blacklist to + # whitelist, or add perms, once we have children. + do_devices_setup "$devicesdir" "${c}" + fi + mkdir -p "${d}/${dir}/lxc/${c}/${c}.real" + echo 1 > "${d}/${dir}/lxc/${c}/${c}.real/tasks" + mkdir -p ${d2}/${dir} + mount -n --bind "${d}/${dir}/lxc/${c}/${c}.real" "${d2}/${dir}" +done diff -Nru lxc-0.8.0~rc1/hooks/mountecryptfsroot lxc-1.0.0~alpha1/hooks/mountecryptfsroot --- lxc-0.8.0~rc1/hooks/mountecryptfsroot 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/hooks/mountecryptfsroot 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,50 @@ +#!/bin/sh + +# (C) Copyright Canonical 2011-2013 + +# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +# This hook can be used to mount an ecryptfs filesystem as a container's +# rootfs. +# To use this hook, assuming your container is called q1, +# 1. add 'lxc.hook.pre-mount = /usr/share/lxc/hooks/mountecryptfsroot' to +# the container's configuration file +# 2. Create /var/lib/lxc/q1/ecryptfs-root +# a. mkdir /var/lib/lxc/q1/ecryptfs-root +# 3. convert your container's root filesystem to be ecryptfs-backed. Assuming +# your container is called 'q1', do +# a. c=q1 +# b. mv /var/lib/lxc/$c/rootfs /var/lib/lxc/$c/rootfs.plain +# c. mkdir /var/lib/lxc/$c/rootfs{,.crypt} +# d. sig=`echo none | ecryptfs-add-passphrase | grep -v Passphrase | cut -d[ -f 2 | cut -d] -f 1` +# e. echo $sig > /var/lib/lxc/$c/sig +# f. mount -t ecryptfs -o ecryptfs_cipher=aes,ecryptfs_key_bytes=16,ecryptfs_passthrough=n,ecryptfs_enable_filename_crypto=n,ecryptfs_sig=${sig},sig=${sig},verbosity=0 /var/lib/lxc/$c/rootfs.crypt /var/lib/lxc/$c/rootfs +# g. rsync -va /var/lib/lxc/$c/rootfs.plain/ /var/lib/lxc/$c/rootfs/ +# h. umount /var/lib/lxc/$c/rootfs +# i. rm -rf /var/lib/lxc/$c/rootfs.plain +# 4. Now you can start your container by adding the passphrase to your +# in-kernel keyring using 'ecryptfs-add-passphrase', then starting your +# container as normal. +# a. echo none | ecryptfs-add-passphrase +# b. lxc-start -n q1 +# Note that you may well want to use a wrapped passhrase (see the ecryptfs-wrap-passphrase(1) manual page). + +set -e +ecryptfs_crypt=$(echo $LXC_ROOTFS_PATH | sed 's/rootfs$/rootfs.crypt/') +sigfile=$(echo $LXC_CONFIG_FILE | sed 's/config$/sig/') + +sig=`cat $sigfile` +mount -n -t ecryptfs -o ecryptfs_cipher=aes,ecryptfs_key_bytes=16,ecryptfs_passthrough=n,ecryptfs_enable_filename_crypto=n,ecryptfs_sig=${sig},sig=${sig},verbosity=0 $ecryptfs_crypt $LXC_ROOTFS_PATH +exit 0 diff -Nru lxc-0.8.0~rc1/hooks/ubuntu-cloud-prep lxc-1.0.0~alpha1/hooks/ubuntu-cloud-prep --- lxc-0.8.0~rc1/hooks/ubuntu-cloud-prep 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/hooks/ubuntu-cloud-prep 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,184 @@ +#!/bin/bash +## If the container being cloned has one or more lxc.hook.clone +## specified, then the specified hooks will be called for the new +## container. The arguments passed to the clone hook are: +## 1. the container name +## 2. a section ('lxc') +## 3. hook type ('clone') +## 4. .. additional arguments to lxc-clone +## Environment variables: +## LXC_ROOTFS_MOUNT: path to the root filesystem +## LXC_CONFIG_FILE: path to config file +## LXC_SRC_NAME: old container name +## LXC_ROOTFS_PATH: path or device on which the root fs is located + +set -f +VERBOSITY="0" + +error() { echo "$@" 1>&2; } +debug() { [ "$VERBOSITY" -ge "$1" ] || return; shift; error "$@"; } +fail() { [ $# -eq 0 ] || error "$@"; exit 1; } + +prep_usage() { +cat </dev/null) || + : + getopt_ret=$? + if [ $getopt_ret -eq 0 ]; then + eval set -- "${getopt_out}" || + { error "Unexpected error reading usage"; return 1; } + fi + + local cur="" next="" + local userdata="" hostid="" authkey="" locales=1 cloud=0 + local create_etc_init=0 name="ubuntucloud-lxc" + + while [ $# -ne 0 ]; do + cur="$1"; next="$2"; + case "$cur" in + -C|--cloud) cloud=1;; + -h|--help) prep_usage; return 0;; + --name) name="$next";; + -i|--hostid) hostid="$next";; + -L|--nolocales) locales=0;; + --create-etc-init) create_etc_init=1;; + -S|--auth-key) + [ -f "$next" ] || + { error "--auth-key: '$next' not a file"; return 1; } + authkey="$next";; + -u|--userdata) + [ -f "$next" ] || + { error "--userdata: '$next' not a file"; return 1; } + userdata="$next";; + -v|--verbose) VERBOSITY=$((${VERBOSITY}+1));; + --) shift; break;; + esac + shift; + done + + [ $# -eq 1 ] || { + prep_usage 1>&2; + error "expected 1 arguments, got ($_LXC_HOOK) $#: $*"; + return 1; + } + + local root_d="$1"; + + if [ $getopt_ret -ne 0 -a "$_LXC_HOOK" = "clone" ]; then + # getopt above failed, but we were called from lxc clone. there might + # be multiple clone hooks and the args provided here not for us. This + # seems like not the greatest interface, so all we'll do is mention it. + error "${0##*}: usage failed, continuing with defaults" + fi + + [ "$create_etc_init" -eq 0 ] || + echo "#upstart needs help for overlayfs (LP: #1213925)." > \ + "$root_d/etc/init/.overlayfs-upstart-helper" || + { error "failed to create /etc/init in overlay"; return 1; } + + local seed_d="" + seed_d="$root_d/var/lib/cloud/seed/nocloud-net" + + echo "$name" > "$root_d/etc/hostname" || + { error "failed to write /etc/hostname"; return 1; } + + if [ $cloud -eq 1 ]; then + debug 1 "--cloud provided, not modifying seed in '$seed_d'" + else + if [ -z "$hostid" ]; then + hostid=$(uuidgen | cut -c -8) && [ -n "$hostid" ] || + { error "failed to get hostid"; return 1; } + fi + mkdir -p "$seed_d" || + { error "failed to create '$seed_d'"; return 1; } + + echo "instance-id: lxc-$hostid" > "$seed_d/meta-data" || + { error "failed to write to $seed_d/meta-data"; return 1; } + + echo "local-hostname: $name" >> "$seed_d/meta-data" || + { error "failed to write to $seed_d/meta-data"; return 1; } + + if [ -n "$authkey" ]; then + { + echo "public-keys:" && + sed -e '/^$/d' -e 's,^,- ,' "$authkey" + } >> "$seed_d/meta-data" + [ $? -eq 0 ] || + { error "failed to write public keys to metadata"; return 1; } + fi + + local larch="usr/lib/locale/locale-archive" + if [ $locales -eq 1 ]; then + cp "/$larch" "$root_d/$larch" || { + error "failed to cp '/$larch' '$root_d/$larch'"; + return 1; + } + fi + + if [ -z "$MIRROR" ]; then + MIRROR="http://archive.ubuntu.com/ubuntu" + fi + + if [ -n "$userdata" ]; then + cp "$userdata" "$seed_d/user-data" + else + { + local lc=$(locale | awk -F= '/LANG=/ {print $NF; }') + echo "#cloud-config" + echo "output: {all: '| tee -a /var/log/cloud-init-output.log'}" + echo "apt_mirror: $MIRROR" + echo "manage_etc_hosts: localhost" + [ -z "$LANG" ] || echo "locale: $LANG"; + echo "password: ubuntu" + echo "chpasswd: { expire: false; }" + } > "$seed_d/user-data" + fi + [ $? -eq 0 ] || { + error "failed to write user-data write to '$seed_d/user-data'"; + return 1; + } + fi + +} + +main() { + # main just joins 2 modes of being called. from user one from lxc clone + local _LXC_HOOK + if [ -n "$LXC_ROOTFS_MOUNT" -a "$3" = "clone" ]; then + _LXC_HOOK="clone" + local name="$1" create_etc_init="" + shift 3 + # if mountpoint is overlayfs then add '--create-etc-init' + [ "${LXC_ROOTFS_PATH#overlayfs}" != "${LXC_ROOTFS_PATH}" ] && + create_etc_init="--create-etc-init" + debug 1 prep "--name=$name" $create_etc_init "$LXC_ROOTFS_MOUNT" "$@" + prep "--name=$name" $create_etc_init "$LXC_ROOTFS_MOUNT" "$@" + else + _LXC_HOOK="" + prep "$@" + fi + return $? +} + +main "$@" + +# vi: ts=4 expandtab diff -Nru lxc-0.8.0~rc1/lxc.spec lxc-1.0.0~alpha1/lxc.spec --- lxc-0.8.0~rc1/lxc.spec 2012-03-01 23:04:47.000000000 +0000 +++ lxc-1.0.0~alpha1/lxc.spec 2013-09-10 22:30:30.000000000 +0000 @@ -4,7 +4,7 @@ # (C) Copyright IBM Corp. 2007, 2008 # # Authors: -# Daniel Lezcano +# Daniel Lezcano # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -18,19 +18,31 @@ # # 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 +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Name: lxc -Version: 0.8.0-rc1 -Release: 1 +Version: 1.0.0.alpha1 +Release: 1%{?dist} URL: http://lxc.sourceforge.net Source: http://dl.sourceforge.net/sourceforge/%{name}/%{name}-%{version}.tar.gz Summary: %{name} : Linux Container Group: Applications/System License: LGPL BuildRoot: %{_tmppath}/%{name}-%{version}-build -Requires: libcap -BuildRequires: libcap libcap-devel docbook-utils +Requires: libcap openssl rsync +BuildRequires: libcap libcap-devel docbook2X + +%define with_python %{?_with_python: 1} %{?!_with_python: 0} +%if %{with_python} +Requires: python3 +BuildRequires: python3-devel +%endif + +%define with_lua %{?_with_lua: 1} %{?!_with_lua: 0} +%if %{with_lua} +Requires: lua-filesystem +BuildRequires: lua-devel +%endif %description @@ -52,7 +64,6 @@ The %{name}-libs package contains libraries for running %{name} applications. %package devel -Release: 1 Summary: development library for %{name} Group: Development/Libraries @@ -63,14 +74,20 @@ %prep %setup %build -test "%{ksrc}" != "none" && args="--with-linuxdir=%{ksrc}" -PATH=$PATH:/usr/sbin:/sbin %configure $args --disable-rpath +PATH=$PATH:/usr/sbin:/sbin %configure $args \ +%if %{with_lua} + --enable-lua \ +%endif +%if %{with_python} + --enable-python \ +%endif + --disable-rpath make %{?_smp_mflags} %install -%makeinstall - -find $RPM_BUILD_ROOT -type f -name '*.la' -exec rm -f {} ';' +rm -rf %{buildroot} +make install DESTDIR=%{buildroot} +find %{buildroot} -type f -name '*.la' -exec rm -f {} ';' %clean rm -rf %{buildroot} @@ -91,20 +108,35 @@ %attr(4111,root,root) %{_bindir}/lxc-restart %{_mandir}/* %{_datadir}/doc/* +%{_datadir}/lxc/* +%{_sysconfdir}/lxc/* %files libs %defattr(-,root,root) %{_libdir}/*.so.* %{_libdir}/%{name} -%attr(4555,root,root) %{_libdir}/%{name}/lxc-init +%if %{with_lua} +%{_datadir}/lua +%{_libdir}/lua +%endif +%if %{with_python} +%{_libdir}/python* +%endif +%{_localstatedir}/* +%attr(4555,root,root) %{_libexecdir}/%{name}/lxc-init %files devel %defattr(-,root,root) %{_includedir}/%{name}/* %{_libdir}/*.so -%{_datadir}/pkgconfig/* +%{_libdir}/pkgconfig/* %changelog +* Mon Sep 10 2012 Dwight Engen - Version 0.8.0 +- fix lxc-init moved to libexec +- .pc moved to _libdir +- package template files /usr/share/lxc/templates + * Thu Sep 8 2011 Greg Kurz - Version 0.7.5.1 - fix installed files for rpmbuild - introduce lxc-libs package diff -Nru lxc-0.8.0~rc1/lxc.spec.in lxc-1.0.0~alpha1/lxc.spec.in --- lxc-0.8.0~rc1/lxc.spec.in 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/lxc.spec.in 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ # (C) Copyright IBM Corp. 2007, 2008 # # Authors: -# Daniel Lezcano +# Daniel Lezcano # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -18,19 +18,31 @@ # # 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 +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Name: @PACKAGE@ Version: @VERSION@ -Release: 1 +Release: 1%{?dist} URL: http://lxc.sourceforge.net Source: http://dl.sourceforge.net/sourceforge/%{name}/%{name}-%{version}.tar.gz Summary: %{name} : Linux Container Group: Applications/System License: LGPL BuildRoot: %{_tmppath}/%{name}-%{version}-build -Requires: libcap -BuildRequires: libcap libcap-devel docbook-utils +Requires: libcap openssl rsync +BuildRequires: libcap libcap-devel docbook2X + +%define with_python %{?_with_python: 1} %{?!_with_python: 0} +%if %{with_python} +Requires: python3 +BuildRequires: python3-devel +%endif + +%define with_lua %{?_with_lua: 1} %{?!_with_lua: 0} +%if %{with_lua} +Requires: lua-filesystem +BuildRequires: lua-devel +%endif %description @@ -52,7 +64,6 @@ The %{name}-libs package contains libraries for running %{name} applications. %package devel -Release: 1 Summary: development library for %{name} Group: Development/Libraries @@ -63,14 +74,20 @@ %prep %setup %build -test "%{ksrc}" != "none" && args="--with-linuxdir=%{ksrc}" -PATH=$PATH:/usr/sbin:/sbin %configure $args --disable-rpath +PATH=$PATH:/usr/sbin:/sbin %configure $args \ +%if %{with_lua} + --enable-lua \ +%endif +%if %{with_python} + --enable-python \ +%endif + --disable-rpath make %{?_smp_mflags} %install -%makeinstall - -find $RPM_BUILD_ROOT -type f -name '*.la' -exec rm -f {} ';' +rm -rf %{buildroot} +make install DESTDIR=%{buildroot} +find %{buildroot} -type f -name '*.la' -exec rm -f {} ';' %clean rm -rf %{buildroot} @@ -91,20 +108,35 @@ %attr(4111,root,root) %{_bindir}/lxc-restart %{_mandir}/* %{_datadir}/doc/* +%{_datadir}/lxc/* +%{_sysconfdir}/lxc/* %files libs %defattr(-,root,root) %{_libdir}/*.so.* %{_libdir}/%{name} -%attr(4555,root,root) %{_libdir}/%{name}/lxc-init +%if %{with_lua} +%{_datadir}/lua +%{_libdir}/lua +%endif +%if %{with_python} +%{_libdir}/python* +%endif +%{_localstatedir}/* +%attr(4555,root,root) %{_libexecdir}/%{name}/lxc-init %files devel %defattr(-,root,root) %{_includedir}/%{name}/* %{_libdir}/*.so -%{_datadir}/pkgconfig/* +%{_libdir}/pkgconfig/* %changelog +* Mon Sep 10 2012 Dwight Engen - Version 0.8.0 +- fix lxc-init moved to libexec +- .pc moved to _libdir +- package template files /usr/share/lxc/templates + * Thu Sep 8 2011 Greg Kurz - Version 0.7.5.1 - fix installed files for rpmbuild - introduce lxc-libs package diff -Nru lxc-0.8.0~rc1/runapitests.sh lxc-1.0.0~alpha1/runapitests.sh --- lxc-0.8.0~rc1/runapitests.sh 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/runapitests.sh 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,50 @@ +#!/bin/sh +# liblxcapi +# +# Copyright © 2012 Serge Hallyn . +# Copyright © 2012 Canonical Ltd. +# +# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +cleanup() { + rm -f /etc/lxc/test-busybox.conf + rm -f liblxc.so.0 +} + +if [ `id -u` -ne 0 ]; then + echo "Run as root" + exit 1 +fi + +cat > /etc/lxc/test-busybox.conf << EOF +lxc.network.type=veth +lxc.network.link=lxcbr0 +lxc.network.flags=up +EOF + +[ -f liblxc.so.0 ] || ln -s src/lxc/liblxc.so ./liblxc.so.0 +export LD_LIBRARY_PATH=. +TESTS="lxc-test-containertests lxc-test-locktests lxc-test-startone" +for curtest in $TESTS; do + echo "running $curtest" + ./src/tests/$curtest + if [ $? -ne 0 ]; then + echo "Test $curtest failed. Stopping" + cleanup + exit 1 + fi +done +echo "All tests passed" +cleanup diff -Nru lxc-0.8.0~rc1/src/Makefile.am lxc-1.0.0~alpha1/src/Makefile.am --- lxc-0.8.0~rc1/src/Makefile.am 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/src/Makefile.am 2013-07-08 15:50:40.000000000 +0000 @@ -1 +1 @@ -SUBDIRS = lxc +SUBDIRS = lxc tests python-lxc lua-lxc diff -Nru lxc-0.8.0~rc1/src/Makefile.in lxc-1.0.0~alpha1/src/Makefile.in --- lxc-0.8.0~rc1/src/Makefile.in 2012-03-01 23:04:43.000000000 +0000 +++ lxc-1.0.0~alpha1/src/Makefile.in 2013-09-10 22:30:09.000000000 +0000 @@ -1,9 +1,8 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. +# Makefile.in generated by automake 1.13.3 from Makefile.am. # @configure_input@ -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -15,6 +14,51 @@ @SET_MAKE@ VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -34,31 +78,70 @@ build_triplet = @build@ host_triplet = @host@ subdir = src -DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(srcdir)/config.h.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/config/acinclude.m4 \ - $(top_srcdir)/config/linux.m4 $(top_srcdir)/configure.ac + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = SOURCES = DIST_SOURCES = -RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ - html-recursive info-recursive install-data-recursive \ - install-dvi-recursive install-exec-recursive \ - install-html-recursive install-info-recursive \ - install-pdf-recursive install-ps-recursive install-recursive \ - installcheck-recursive installdirs-recursive pdf-recursive \ - ps-recursive uninstall-recursive +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive -AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ - $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ + $(LISP)config.h.in +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) @@ -90,6 +173,8 @@ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +APPARMOR_LIBS = @APPARMOR_LIBS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ @@ -120,19 +205,31 @@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBDIR = @LIBDIR@ +LIBEXECDIR = @LIBEXECDIR@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ -LINUX_DIR = @LINUX_DIR@ -LINUX_SRCARCH = @LINUX_SRCARCH@ LOCALSTATEDIR = @LOCALSTATEDIR@ +LOGPATH = @LOGPATH@ LTLIBOBJS = @LTLIBOBJS@ +LUA_CFLAGS = @LUA_CFLAGS@ +LUA_INSTALL_CMOD = @LUA_INSTALL_CMOD@ +LUA_INSTALL_LMOD = @LUA_INSTALL_LMOD@ +LUA_LIBS = @LUA_LIBS@ +LUA_VERSION = @LUA_VERSION@ +LXCHOOKDIR = @LXCHOOKDIR@ LXCINITDIR = @LXCINITDIR@ LXCPATH = @LXCPATH@ LXCROOTFSMOUNT = @LXCROOTFSMOUNT@ LXCTEMPLATEDIR = @LXCTEMPLATEDIR@ +LXC_DEFAULT_CONFIG = @LXC_DEFAULT_CONFIG@ +LXC_DISTRO_CONF = @LXC_DISTRO_CONF@ LXC_GENERATE_DATE = @LXC_GENERATE_DATE@ +LXC_GLOBAL_CONF = @LXC_GLOBAL_CONF@ +LXC_USERNIC_CONF = @LXC_USERNIC_CONF@ +LXC_USERNIC_DB = @LXC_USERNIC_DB@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +NEWUIDMAP = @NEWUIDMAP@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ @@ -142,8 +239,19 @@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PREFIX = @PREFIX@ -SETCAP = @SETCAP@ +PYTHON = @PYTHON@ +PYTHONDEV_CFLAGS = @PYTHONDEV_CFLAGS@ +PYTHONDEV_LIBS = @PYTHONDEV_LIBS@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +SECCOMP_LIBS = @SECCOMP_LIBS@ +SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ @@ -168,10 +276,11 @@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ +db2xman = @db2xman@ docdir = @docdir@ +docdtd = @docdtd@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ -have_docbook = @have_docbook@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ @@ -189,9 +298,13 @@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ @@ -200,7 +313,7 @@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -SUBDIRS = lxc +SUBDIRS = lxc tests python-lxc lua-lxc all: config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive @@ -237,10 +350,8 @@ $(am__aclocal_m4_deps): config.h: stamp-h1 - @if test ! -f $@; then \ - rm -f stamp-h1; \ - $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \ - else :; fi + @if test ! -f $@; then rm -f stamp-h1; else :; fi + @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) stamp-h1; else :; fi stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status @rm -f stamp-h1 @@ -254,22 +365,25 @@ -rm -f config.h stamp-h1 # This directory's subdirectories are mostly independent; you can cd -# into them and run `make' without going through this Makefile. -# To change the values of `make' variables: instead of editing Makefiles, -# (1) if the variable is set in `config.status', edit `config.status' -# (which will cause the Makefiles to be regenerated when you run `make'); -# (2) otherwise, pass the desired values on the `make' command line. -$(RECURSIVE_TARGETS): - @fail= failcom='exit 1'; \ - for f in x $$MAKEFLAGS; do \ - case $$f in \ - *=* | --[!k]*);; \ - *k*) failcom='fail=yes';; \ - esac; \ - done; \ +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ @@ -284,57 +398,12 @@ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" -$(RECURSIVE_CLEAN_TARGETS): - @fail= failcom='exit 1'; \ - for f in x $$MAKEFLAGS; do \ - case $$f in \ - *=* | --[!k]*);; \ - *k*) failcom='fail=yes';; \ - esac; \ - done; \ - dot_seen=no; \ - case "$@" in \ - distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ - *) list='$(SUBDIRS)' ;; \ - esac; \ - rev=''; for subdir in $$list; do \ - if test "$$subdir" = "."; then :; else \ - rev="$$subdir $$rev"; \ - fi; \ - done; \ - rev="$$rev ."; \ - target=`echo $@ | sed s/-recursive//`; \ - for subdir in $$rev; do \ - echo "Making $$target in $$subdir"; \ - if test "$$subdir" = "."; then \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || eval $$failcom; \ - done && test -z "$$fail" -tags-recursive: - list='$(SUBDIRS)'; for subdir in $$list; do \ - test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ - done -ctags-recursive: - list='$(SUBDIRS)'; for subdir in $$list; do \ - test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ - done +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ @@ -350,12 +419,7 @@ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ - list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ + $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ @@ -367,15 +431,11 @@ $$unique; \ fi; \ fi -ctags: CTAGS -CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique @@ -384,6 +444,21 @@ here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags @@ -420,13 +495,10 @@ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ - test -d "$(distdir)/$$subdir" \ - || $(MKDIR_P) "$(distdir)/$$subdir" \ - || exit 1; \ - fi; \ - done - @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ @@ -461,10 +533,15 @@ installcheck: installcheck-recursive install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi mostlyclean-generic: clean-generic: @@ -542,21 +619,20 @@ uninstall-am: -.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all \ - ctags-recursive install-am install-strip tags-recursive +.MAKE: $(am__recursive_targets) all install-am install-strip -.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ - all all-am check check-am clean clean-generic ctags \ - ctags-recursive distclean distclean-generic distclean-hdr \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ + check-am clean clean-generic cscopelist-am ctags ctags-am \ + distclean distclean-generic distclean-hdr distclean-tags \ + distdir dvi dvi-am html html-am info info-am install \ + install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic pdf pdf-am ps ps-am tags \ - tags-recursive uninstall uninstall-am + tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. diff -Nru lxc-0.8.0~rc1/src/config.h.in lxc-1.0.0~alpha1/src/config.h.in --- lxc-0.8.0~rc1/src/config.h.in 2012-03-01 23:04:51.000000000 +0000 +++ lxc-1.0.0~alpha1/src/config.h.in 2013-09-10 22:30:07.000000000 +0000 @@ -1,21 +1,81 @@ /* src/config.h.in. Generated from configure.ac by autoheader. */ +/* Python3 is available */ +#undef ENABLE_PYTHON + +/* Define to 1 if you have the `confstr' function. */ +#undef HAVE_CONFSTR + /* Define to 1 if you have the declaration of `PR_CAPBSET_DROP', and to 0 if you don't. */ #undef HAVE_DECL_PR_CAPBSET_DROP +/* Define to 1 if you have the `endmntent' function. */ +#undef HAVE_ENDMNTENT + +/* Define to 1 if you have the `fgetln' function. */ +#undef HAVE_FGETLN + +/* Define to 1 if you have the `getline' function. */ +#undef HAVE_GETLINE + +/* Define to 1 if you have the `hasmntopt' function. */ +#undef HAVE_HASMNTOPT + +/* Define to 1 if you have the header file. */ +#undef HAVE_IFADDRS_H + /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H +/* Define to 1 if you have the `apparmor' library (-lapparmor). */ +#undef HAVE_LIBAPPARMOR + +/* Define to 1 if you have the `gnutls' library (-lgnutls). */ +#undef HAVE_LIBGNUTLS + +/* Define to 1 if you have the `seccomp' library (-lseccomp). */ +#undef HAVE_LIBSECCOMP + +/* Define to 1 if you have the `util' library (-lutil). */ +#undef HAVE_LIBUTIL + /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_GENETLINK_H /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_NETLINK_H +/* Define to 1 if you have the header file. */ +#undef HAVE_LINUX_UNISTD_H + /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H +/* Define to 1 if you have the `openpty' function. */ +#undef HAVE_OPENPTY + +/* Define to 1 if you have the `pivot_root' function. */ +#undef HAVE_PIVOT_ROOT + +/* Define to 1 if you have the header file. */ +#undef HAVE_PTY_H + +/* Define to 1 if you have the `rand_r' function. */ +#undef HAVE_RAND_R + +/* Define to 1 if the system has the type `scmp_filter_ctx'. */ +#undef HAVE_SCMP_FILTER_CTX + +/* Define to 1 if you have the `sethostname' function. */ +#undef HAVE_SETHOSTNAME + +/* Define to 1 if you have the `setmntent' function. */ +#undef HAVE_SETMNTENT + +/* Define to 1 if you have the `setns' function. */ +#undef HAVE_SETNS + /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H @@ -31,18 +91,33 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYS_CAPABILITY_H +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_PERSONALITY_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SIGNALFD_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TIMERFD_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H +/* Define to 1 if you have the `unshare' function. */ +#undef HAVE_UNSHARE + +/* Define to 1 if you have the header file. */ +#undef HAVE_UTMPX_H + +/* bionic libc */ +#undef IS_BIONIC + /* Define to 1 if your C compiler doesn't accept -c and -o together. */ #undef NO_MINUS_C_MINUS_O diff -Nru lxc-0.8.0~rc1/src/include/getline.c lxc-1.0.0~alpha1/src/include/getline.c --- lxc-0.8.0~rc1/src/include/getline.c 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/include/getline.c 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2006 SPARTA, Inc. + * All rights reserved. + * + * This software was developed by SPARTA ISSO under SPAWAR contract + * N66001-04-C-6019 ("SEFOS"). + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include + +/* + * Emulate glibc getline() via BSD fgetln(). + * Note that outsize is not changed unless memory is allocated. + */ +ssize_t +getline(char **outbuf, size_t *outsize, FILE *fp) +{ + size_t len; + char *buf; + buf = fgetln(fp, &len); + + if (buf == NULL) + return (-1); + + /* Assumes realloc() accepts NULL for ptr (C99) */ + if (*outbuf == NULL || *outsize < len + 1) { + void *tmp = realloc(*outbuf, len + 1); + if (tmp == NULL) + return (-1); + *outbuf = tmp; + *outsize = len + 1; + } + memcpy(*outbuf, buf, len); + (*outbuf)[len] = '\0'; + return (len); +} diff -Nru lxc-0.8.0~rc1/src/include/getline.h lxc-1.0.0~alpha1/src/include/getline.h --- lxc-0.8.0~rc1/src/include/getline.h 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/include/getline.h 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2006 SPARTA, Inc. + * All rights reserved. + * + * This software was developed by SPARTA ISSO under SPAWAR contract + * N66001-04-C-6019 ("SEFOS"). + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _getline_h +#define _getline_h + +#include + +extern ssize_t getline(char **outbuf, size_t *outsize, FILE *fp); + +#endif diff -Nru lxc-0.8.0~rc1/src/include/ifaddrs.c lxc-1.0.0~alpha1/src/include/ifaddrs.c --- lxc-0.8.0~rc1/src/include/ifaddrs.c 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/include/ifaddrs.c 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,597 @@ +/* +Copyright (c) 2013, Kenneth MacKay +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "ifaddrs.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef struct NetlinkList +{ + struct NetlinkList *m_next; + struct nlmsghdr *m_data; + unsigned int m_size; +} NetlinkList; + +static int netlink_socket(void) +{ + int l_socket = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); + if(l_socket < 0) + { + return -1; + } + + struct sockaddr_nl l_addr; + memset(&l_addr, 0, sizeof(l_addr)); + l_addr.nl_family = AF_NETLINK; + if(bind(l_socket, (struct sockaddr *)&l_addr, sizeof(l_addr)) < 0) + { + close(l_socket); + return -1; + } + + return l_socket; +} + +static int netlink_send(int p_socket, int p_request) +{ + char l_buffer[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + NLMSG_ALIGN(sizeof(struct rtgenmsg))]; + memset(l_buffer, 0, sizeof(l_buffer)); + struct nlmsghdr *l_hdr = (struct nlmsghdr *)l_buffer; + struct rtgenmsg *l_msg = (struct rtgenmsg *)NLMSG_DATA(l_hdr); + + l_hdr->nlmsg_len = NLMSG_LENGTH(sizeof(*l_msg)); + l_hdr->nlmsg_type = p_request; + l_hdr->nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST; + l_hdr->nlmsg_pid = 0; + l_hdr->nlmsg_seq = p_socket; + l_msg->rtgen_family = AF_UNSPEC; + + struct sockaddr_nl l_addr; + memset(&l_addr, 0, sizeof(l_addr)); + l_addr.nl_family = AF_NETLINK; + return (sendto(p_socket, l_hdr, l_hdr->nlmsg_len, 0, (struct sockaddr *)&l_addr, sizeof(l_addr))); +} + +static int netlink_recv(int p_socket, void *p_buffer, size_t p_len) +{ + struct msghdr l_msg; + struct iovec l_iov = { p_buffer, p_len }; + struct sockaddr_nl l_addr; + + for(;;) + { + l_msg.msg_name = (void *)&l_addr; + l_msg.msg_namelen = sizeof(l_addr); + l_msg.msg_iov = &l_iov; + l_msg.msg_iovlen = 1; + l_msg.msg_control = NULL; + l_msg.msg_controllen = 0; + l_msg.msg_flags = 0; + int l_result = recvmsg(p_socket, &l_msg, 0); + + if(l_result < 0) + { + if(errno == EINTR) + { + continue; + } + return -2; + } + + if(l_msg.msg_flags & MSG_TRUNC) + { // buffer was too small + return -1; + } + return l_result; + } +} + +static struct nlmsghdr *getNetlinkResponse(int p_socket, int *p_size, int *p_done) +{ + size_t l_size = 4096; + void *l_buffer = NULL; + + for(;;) + { + free(l_buffer); + l_buffer = malloc(l_size); + + int l_read = netlink_recv(p_socket, l_buffer, l_size); + *p_size = l_read; + if(l_read == -2) + { + free(l_buffer); + return NULL; + } + if(l_read >= 0) + { + pid_t l_pid = getpid(); + struct nlmsghdr *l_hdr; + for(l_hdr = (struct nlmsghdr *)l_buffer; NLMSG_OK(l_hdr, (unsigned int)l_read); l_hdr = (struct nlmsghdr *)NLMSG_NEXT(l_hdr, l_read)) + { + if((pid_t)l_hdr->nlmsg_pid != l_pid || (int)l_hdr->nlmsg_seq != p_socket) + { + continue; + } + + if(l_hdr->nlmsg_type == NLMSG_DONE) + { + *p_done = 1; + break; + } + + if(l_hdr->nlmsg_type == NLMSG_ERROR) + { + free(l_buffer); + return NULL; + } + } + return l_buffer; + } + + l_size *= 2; + } +} + +static NetlinkList *newListItem(struct nlmsghdr *p_data, unsigned int p_size) +{ + NetlinkList *l_item = malloc(sizeof(NetlinkList)); + l_item->m_next = NULL; + l_item->m_data = p_data; + l_item->m_size = p_size; + return l_item; +} + +static void freeResultList(NetlinkList *p_list) +{ + NetlinkList *l_cur; + while(p_list) + { + l_cur = p_list; + p_list = p_list->m_next; + free(l_cur->m_data); + free(l_cur); + } +} + +static NetlinkList *getResultList(int p_socket, int p_request) +{ + if(netlink_send(p_socket, p_request) < 0) + { + return NULL; + } + + NetlinkList *l_list = NULL; + NetlinkList *l_end = NULL; + int l_size; + int l_done = 0; + while(!l_done) + { + struct nlmsghdr *l_hdr = getNetlinkResponse(p_socket, &l_size, &l_done); + if(!l_hdr) + { // error + freeResultList(l_list); + return NULL; + } + + NetlinkList *l_item = newListItem(l_hdr, l_size); + if(!l_list) + { + l_list = l_item; + } + else + { + l_end->m_next = l_item; + } + l_end = l_item; + } + return l_list; +} + +static size_t maxSize(size_t a, size_t b) +{ + return (a > b ? a : b); +} + +static size_t calcAddrLen(sa_family_t p_family, int p_dataSize) +{ + switch(p_family) + { + case AF_INET: + return sizeof(struct sockaddr_in); + case AF_INET6: + return sizeof(struct sockaddr_in6); + case AF_PACKET: + return maxSize(sizeof(struct sockaddr_ll), offsetof(struct sockaddr_ll, sll_addr) + p_dataSize); + default: + return maxSize(sizeof(struct sockaddr), offsetof(struct sockaddr, sa_data) + p_dataSize); + } +} + +static void makeSockaddr(sa_family_t p_family, struct sockaddr *p_dest, void *p_data, size_t p_size) +{ + switch(p_family) + { + case AF_INET: + memcpy(&((struct sockaddr_in*)p_dest)->sin_addr, p_data, p_size); + break; + case AF_INET6: + memcpy(&((struct sockaddr_in6*)p_dest)->sin6_addr, p_data, p_size); + break; + case AF_PACKET: + memcpy(((struct sockaddr_ll*)p_dest)->sll_addr, p_data, p_size); + ((struct sockaddr_ll*)p_dest)->sll_halen = p_size; + break; + default: + memcpy(p_dest->sa_data, p_data, p_size); + break; + } + p_dest->sa_family = p_family; +} + +static void addToEnd(struct ifaddrs **p_resultList, struct ifaddrs *p_entry) +{ + if(!*p_resultList) + { + *p_resultList = p_entry; + } + else + { + struct ifaddrs *l_cur = *p_resultList; + while(l_cur->ifa_next) + { + l_cur = l_cur->ifa_next; + } + l_cur->ifa_next = p_entry; + } +} + +static void interpretLink(struct nlmsghdr *p_hdr, struct ifaddrs **p_links, struct ifaddrs **p_resultList) +{ + struct ifinfomsg *l_info = (struct ifinfomsg *)NLMSG_DATA(p_hdr); + + size_t l_nameSize = 0; + size_t l_addrSize = 0; + size_t l_dataSize = 0; + + size_t l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifinfomsg)); + struct rtattr *l_rta; + for(l_rta = (struct rtattr *)(((char *)l_info) + NLMSG_ALIGN(sizeof(struct ifinfomsg))); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize)) + { + size_t l_rtaDataSize = RTA_PAYLOAD(l_rta); + switch(l_rta->rta_type) + { + case IFLA_ADDRESS: + case IFLA_BROADCAST: + l_addrSize += NLMSG_ALIGN(calcAddrLen(AF_PACKET, l_rtaDataSize)); + break; + case IFLA_IFNAME: + l_nameSize += NLMSG_ALIGN(l_rtaSize + 1); + break; + case IFLA_STATS: + l_dataSize += NLMSG_ALIGN(l_rtaSize); + break; + default: + break; + } + } + + struct ifaddrs *l_entry = malloc(sizeof(struct ifaddrs) + l_nameSize + l_addrSize + l_dataSize); + memset(l_entry, 0, sizeof(struct ifaddrs)); + l_entry->ifa_name = ""; + + char *l_name = ((char *)l_entry) + sizeof(struct ifaddrs); + char *l_addr = l_name + l_nameSize; + char *l_data = l_addr + l_addrSize; + + l_entry->ifa_flags = l_info->ifi_flags; + + l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifinfomsg)); + for(l_rta = (struct rtattr *)(((char *)l_info) + NLMSG_ALIGN(sizeof(struct ifinfomsg))); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize)) + { + void *l_rtaData = RTA_DATA(l_rta); + size_t l_rtaDataSize = RTA_PAYLOAD(l_rta); + switch(l_rta->rta_type) + { + case IFLA_ADDRESS: + case IFLA_BROADCAST: + { + size_t l_addrLen = calcAddrLen(AF_PACKET, l_rtaDataSize); + makeSockaddr(AF_PACKET, (struct sockaddr *)l_addr, l_rtaData, l_rtaDataSize); + ((struct sockaddr_ll *)l_addr)->sll_ifindex = l_info->ifi_index; + ((struct sockaddr_ll *)l_addr)->sll_hatype = l_info->ifi_type; + if(l_rta->rta_type == IFLA_ADDRESS) + { + l_entry->ifa_addr = (struct sockaddr *)l_addr; + } + else + { + l_entry->ifa_broadaddr = (struct sockaddr *)l_addr; + } + l_addr += NLMSG_ALIGN(l_addrLen); + break; + } + case IFLA_IFNAME: + strncpy(l_name, l_rtaData, l_rtaDataSize); + l_name[l_rtaDataSize] = '\0'; + l_entry->ifa_name = l_name; + break; + case IFLA_STATS: + memcpy(l_data, l_rtaData, l_rtaDataSize); + l_entry->ifa_data = l_data; + break; + default: + break; + } + } + + addToEnd(p_resultList, l_entry); + p_links[l_info->ifi_index - 1] = l_entry; +} + +static void interpretAddr(struct nlmsghdr *p_hdr, struct ifaddrs **p_links, struct ifaddrs **p_resultList) +{ + struct ifaddrmsg *l_info = (struct ifaddrmsg *)NLMSG_DATA(p_hdr); + + size_t l_nameSize = 0; + size_t l_addrSize = 0; + + int l_addedNetmask = 0; + + size_t l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifaddrmsg)); + struct rtattr *l_rta; + for(l_rta = (struct rtattr *)(((char *)l_info) + NLMSG_ALIGN(sizeof(struct ifaddrmsg))); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize)) + { + size_t l_rtaDataSize = RTA_PAYLOAD(l_rta); + if(l_info->ifa_family == AF_PACKET) + { + continue; + } + + switch(l_rta->rta_type) + { + case IFA_ADDRESS: + case IFA_LOCAL: + if((l_info->ifa_family == AF_INET || l_info->ifa_family == AF_INET6) && !l_addedNetmask) + { // make room for netmask + l_addrSize += NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, l_rtaDataSize)); + l_addedNetmask = 1; + } + case IFA_BROADCAST: + l_addrSize += NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, l_rtaDataSize)); + break; + case IFA_LABEL: + l_nameSize += NLMSG_ALIGN(l_rtaSize + 1); + break; + default: + break; + } + } + + struct ifaddrs *l_entry = malloc(sizeof(struct ifaddrs) + l_nameSize + l_addrSize); + memset(l_entry, 0, sizeof(struct ifaddrs)); + l_entry->ifa_name = p_links[l_info->ifa_index - 1]->ifa_name; + + char *l_name = ((char *)l_entry) + sizeof(struct ifaddrs); + char *l_addr = l_name + l_nameSize; + + l_entry->ifa_flags = l_info->ifa_flags | p_links[l_info->ifa_index - 1]->ifa_flags; + + l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifaddrmsg)); + for(l_rta = (struct rtattr *)(((char *)l_info) + NLMSG_ALIGN(sizeof(struct ifaddrmsg))); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize)) + { + void *l_rtaData = RTA_DATA(l_rta); + size_t l_rtaDataSize = RTA_PAYLOAD(l_rta); + switch(l_rta->rta_type) + { + case IFA_ADDRESS: + case IFA_BROADCAST: + case IFA_LOCAL: + { + size_t l_addrLen = calcAddrLen(l_info->ifa_family, l_rtaDataSize); + makeSockaddr(l_info->ifa_family, (struct sockaddr *)l_addr, l_rtaData, l_rtaDataSize); + if(l_info->ifa_family == AF_INET6) + { + if(IN6_IS_ADDR_LINKLOCAL((struct in6_addr *)l_rtaData) || IN6_IS_ADDR_MC_LINKLOCAL((struct in6_addr *)l_rtaData)) + { + ((struct sockaddr_in6 *)l_addr)->sin6_scope_id = l_info->ifa_index; + } + } + + if(l_rta->rta_type == IFA_ADDRESS) + { // apparently in a point-to-point network IFA_ADDRESS contains the dest address and IFA_LOCAL contains the local address + if(l_entry->ifa_addr) + { + l_entry->ifa_dstaddr = (struct sockaddr *)l_addr; + } + else + { + l_entry->ifa_addr = (struct sockaddr *)l_addr; + } + } + else if(l_rta->rta_type == IFA_LOCAL) + { + if(l_entry->ifa_addr) + { + l_entry->ifa_dstaddr = l_entry->ifa_addr; + } + l_entry->ifa_addr = (struct sockaddr *)l_addr; + } + else + { + l_entry->ifa_broadaddr = (struct sockaddr *)l_addr; + } + l_addr += NLMSG_ALIGN(l_addrLen); + break; + } + case IFA_LABEL: + strncpy(l_name, l_rtaData, l_rtaDataSize); + l_name[l_rtaDataSize] = '\0'; + l_entry->ifa_name = l_name; + break; + default: + break; + } + } + + if(l_entry->ifa_addr && (l_entry->ifa_addr->sa_family == AF_INET || l_entry->ifa_addr->sa_family == AF_INET6)) + { + unsigned l_maxPrefix = (l_entry->ifa_addr->sa_family == AF_INET ? 32 : 128); + unsigned l_prefix = (l_info->ifa_prefixlen > l_maxPrefix ? l_maxPrefix : l_info->ifa_prefixlen); + char l_mask[16] = {0}; + unsigned i; + for(i=0; i<(l_prefix/8); ++i) + { + l_mask[i] = 0xff; + } + l_mask[i] = 0xff << (8 - (l_prefix % 8)); + + makeSockaddr(l_entry->ifa_addr->sa_family, (struct sockaddr *)l_addr, l_mask, l_maxPrefix / 8); + l_entry->ifa_netmask = (struct sockaddr *)l_addr; + } + + addToEnd(p_resultList, l_entry); +} + +static void interpret(int p_socket, NetlinkList *p_netlinkList, struct ifaddrs **p_links, struct ifaddrs **p_resultList) +{ + pid_t l_pid = getpid(); + for(; p_netlinkList; p_netlinkList = p_netlinkList->m_next) + { + unsigned int l_nlsize = p_netlinkList->m_size; + struct nlmsghdr *l_hdr; + for(l_hdr = p_netlinkList->m_data; NLMSG_OK(l_hdr, l_nlsize); l_hdr = NLMSG_NEXT(l_hdr, l_nlsize)) + { + if((pid_t)l_hdr->nlmsg_pid != l_pid || (int)l_hdr->nlmsg_seq != p_socket) + { + continue; + } + + if(l_hdr->nlmsg_type == NLMSG_DONE) + { + break; + } + + if(l_hdr->nlmsg_type == RTM_NEWLINK) + { + interpretLink(l_hdr, p_links, p_resultList); + } + else if(l_hdr->nlmsg_type == RTM_NEWADDR) + { + interpretAddr(l_hdr, p_links, p_resultList); + } + } + } +} + +static unsigned countLinks(int p_socket, NetlinkList *p_netlinkList) +{ + unsigned l_links = 0; + pid_t l_pid = getpid(); + for(; p_netlinkList; p_netlinkList = p_netlinkList->m_next) + { + unsigned int l_nlsize = p_netlinkList->m_size; + struct nlmsghdr *l_hdr; + for(l_hdr = p_netlinkList->m_data; NLMSG_OK(l_hdr, l_nlsize); l_hdr = NLMSG_NEXT(l_hdr, l_nlsize)) + { + if((pid_t)l_hdr->nlmsg_pid != l_pid || (int)l_hdr->nlmsg_seq != p_socket) + { + continue; + } + + if(l_hdr->nlmsg_type == NLMSG_DONE) + { + break; + } + + if(l_hdr->nlmsg_type == RTM_NEWLINK) + { + ++l_links; + } + } + } + + return l_links; +} + +int getifaddrs(struct ifaddrs **ifap) +{ + if(!ifap) + { + return -1; + } + *ifap = NULL; + + int l_socket = netlink_socket(); + if(l_socket < 0) + { + return -1; + } + + NetlinkList *l_linkResults = getResultList(l_socket, RTM_GETLINK); + if(!l_linkResults) + { + close(l_socket); + return -1; + } + + NetlinkList *l_addrResults = getResultList(l_socket, RTM_GETADDR); + if(!l_addrResults) + { + close(l_socket); + freeResultList(l_linkResults); + return -1; + } + + unsigned l_numLinks = countLinks(l_socket, l_linkResults) + countLinks(l_socket, l_addrResults); + struct ifaddrs *l_links[l_numLinks]; + memset(l_links, 0, l_numLinks * sizeof(struct ifaddrs *)); + + interpret(l_socket, l_linkResults, l_links, ifap); + interpret(l_socket, l_addrResults, l_links, ifap); + + freeResultList(l_linkResults); + freeResultList(l_addrResults); + close(l_socket); + return 0; +} + +void freeifaddrs(struct ifaddrs *ifa) +{ + struct ifaddrs *l_cur; + while(ifa) + { + l_cur = ifa; + ifa = ifa->ifa_next; + free(l_cur); + } +} diff -Nru lxc-0.8.0~rc1/src/include/ifaddrs.h lxc-1.0.0~alpha1/src/include/ifaddrs.h --- lxc-0.8.0~rc1/src/include/ifaddrs.h 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/include/ifaddrs.h 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,54 @@ +/* + * Copyright (c) 1995, 1999 + * Berkeley Software Design, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * BSDI ifaddrs.h,v 2.5 2000/02/23 14:51:59 dab Exp + */ + +#ifndef _IFADDRS_H_ +#define _IFADDRS_H_ + +struct ifaddrs { + struct ifaddrs *ifa_next; + char *ifa_name; + unsigned int ifa_flags; + struct sockaddr *ifa_addr; + struct sockaddr *ifa_netmask; + struct sockaddr *ifa_dstaddr; + void *ifa_data; +}; + +/* + * This may have been defined in . Note that if is + * to be included it must be included before this header file. + */ +#ifndef ifa_broadaddr +#define ifa_broadaddr ifa_dstaddr /* broadcast address interface */ +#endif + +#include + +__BEGIN_DECLS +extern int getifaddrs(struct ifaddrs **ifap); +extern void freeifaddrs(struct ifaddrs *ifa); +__END_DECLS + +#endif diff -Nru lxc-0.8.0~rc1/src/include/lxcmntent.c lxc-1.0.0~alpha1/src/include/lxcmntent.c --- lxc-0.8.0~rc1/src/include/lxcmntent.c 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/include/lxcmntent.c 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,193 @@ +/* Utilities for reading/writing fstab, mtab, etc. + Copyright (C) 1995-2000, 2001, 2002, 2003, 2006 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C 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. + + The GNU C 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +/* Since the values in a line are separated by spaces, a name cannot + contain a space. Therefore some programs encode spaces in names + by the strings "\040". We undo the encoding when reading an entry. + The decoding happens in place. */ +static char * +decode_name (char *buf) +{ + char *rp = buf; + char *wp = buf; + + do + if (rp[0] == '\\' && rp[1] == '0' && rp[2] == '4' && rp[3] == '0') + { + /* \040 is a SPACE. */ + *wp++ = ' '; + rp += 3; + } + else if (rp[0] == '\\' && rp[1] == '0' && rp[2] == '1' && rp[3] == '1') + { + /* \011 is a TAB. */ + *wp++ = '\t'; + rp += 3; + } + else if (rp[0] == '\\' && rp[1] == '0' && rp[2] == '1' && rp[3] == '2') + { + /* \012 is a NEWLINE. */ + *wp++ = '\n'; + rp += 3; + } + else if (rp[0] == '\\' && rp[1] == '\\') + { + /* We have to escape \\ to be able to represent all characters. */ + *wp++ = '\\'; + rp += 1; + } + else if (rp[0] == '\\' && rp[1] == '1' && rp[2] == '3' && rp[3] == '4') + { + /* \134 is also \\. */ + *wp++ = '\\'; + rp += 3; + } + else + *wp++ = *rp; + while (*rp++ != '\0'); + + return buf; +} + +/* Read one mount table entry from STREAM. Returns a pointer to storage + reused on the next call, or null for EOF or error (use feof/ferror to + check). */ +struct mntent *getmntent_r (FILE *stream, struct mntent *mp, char *buffer, int bufsiz) +{ + char *cp; + char *head; + + do + { + char *end_ptr; + + if (fgets (buffer, bufsiz, stream) == NULL) + { + return NULL; + } + + end_ptr = strchr (buffer, '\n'); + if (end_ptr != NULL) /* chop newline */ + *end_ptr = '\0'; + else + { + /* Not the whole line was read. Do it now but forget it. */ + char tmp[1024]; + while (fgets (tmp, sizeof tmp, stream) != NULL) + if (strchr (tmp, '\n') != NULL) + break; + } + + head = buffer + strspn (buffer, " \t"); + /* skip empty lines and comment lines: */ + } + while (head[0] == '\0' || head[0] == '#'); + + cp = strsep (&head, " \t"); + mp->mnt_fsname = cp != NULL ? decode_name (cp) : (char *) ""; + if (head) + head += strspn (head, " \t"); + cp = strsep (&head, " \t"); + mp->mnt_dir = cp != NULL ? decode_name (cp) : (char *) ""; + if (head) + head += strspn (head, " \t"); + cp = strsep (&head, " \t"); + mp->mnt_type = cp != NULL ? decode_name (cp) : (char *) ""; + if (head) + head += strspn (head, " \t"); + cp = strsep (&head, " \t"); + mp->mnt_opts = cp != NULL ? decode_name (cp) : (char *) ""; + switch (head ? sscanf (head, " %d %d ", &mp->mnt_freq, &mp->mnt_passno) : 0) + { + case 0: + mp->mnt_freq = 0; + case 1: + mp->mnt_passno = 0; + case 2: + break; + } + + return mp; +} + +struct mntent *getmntent (FILE *stream) +{ + static struct mntent m; + static char *getmntent_buffer; + + #define BUFFER_SIZE 4096 + if (getmntent_buffer == NULL) { + getmntent_buffer = (char *) malloc (BUFFER_SIZE); + } + + return getmntent_r (stream, &m, getmntent_buffer, BUFFER_SIZE); + #undef BUFFER_SIZE +} + + +/* Prepare to begin reading and/or writing mount table entries from the + beginning of FILE. MODE is as for `fopen'. */ +FILE *setmntent (const char *file, const char *mode) +{ + /* Extend the mode parameter with "c" to disable cancellation in the + I/O functions and "e" to set FD_CLOEXEC. */ + size_t modelen = strlen (mode); + char newmode[modelen + 3]; + memcpy (newmode, mode, modelen); + memcpy (newmode + modelen, "ce", 3); + FILE *result = fopen (file, newmode); + + return result; +} + + +/* Close a stream opened with `setmntent'. */ +int endmntent (FILE *stream) +{ + if (stream) /* SunOS 4.x allows for NULL stream */ + fclose (stream); + return 1; /* SunOS 4.x says to always return 1 */ +} + +/* Search MNT->mnt_opts for an option matching OPT. + Returns the address of the substring, or null if none found. */ +char *hasmntopt (const struct mntent *mnt, const char *opt) +{ + const size_t optlen = strlen (opt); + char *rest = mnt->mnt_opts, *p; + + while ((p = strstr (rest, opt)) != NULL) + { + if ((p == rest || p[-1] == ',') + && (p[optlen] == '\0' || p[optlen] == '=' || p[optlen] == ',')) + return p; + + rest = strchr (p, ','); + if (rest == NULL) + break; + ++rest; + } + + return NULL; +} diff -Nru lxc-0.8.0~rc1/src/include/lxcmntent.h lxc-1.0.0~alpha1/src/include/lxcmntent.h --- lxc-0.8.0~rc1/src/include/lxcmntent.h 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/include/lxcmntent.h 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,53 @@ +/* Utilities for reading/writing fstab, mtab, etc. + Copyright (C) 1995-2000, 2001, 2002, 2003, 2006 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C 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. + + The GNU C 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _lxcmntent_h +#define _lxcmntent_h + +#include <../config.h> + +#if IS_BIONIC +struct mntent +{ + char* mnt_fsname; + char* mnt_dir; + char* mnt_type; + char* mnt_opts; + int mnt_freq; + int mnt_passno; +}; + +extern struct mntent *getmntent (FILE *stream); +extern struct mntent *getmntent_r (FILE *stream, struct mntent *mp, char *buffer, int bufsiz); +#endif + +#ifndef HAVE_SETMNTENT +FILE *setmntent (const char *file, const char *mode); +#endif + +#ifndef HAVE_ENDMNTENT +int endmntent (FILE *stream); +#endif + +#ifndef HAVE_HASMNTOPT +extern char *hasmntopt (const struct mntent *mnt, const char *opt); +#endif + +#endif diff -Nru lxc-0.8.0~rc1/src/include/openpty.c lxc-1.0.0~alpha1/src/include/openpty.c --- lxc-0.8.0~rc1/src/include/openpty.c 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/include/openpty.c 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,76 @@ + /* + * openpty: glibc implementation + * + * Copyright (C) 1998, 1999, 2004 Free Software Foundation, Inc. + * + * Authors: + * Zack Weinberg , 1998. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define _XOPEN_SOURCE /* See feature_test_macros(7) */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define _PATH_DEVPTMX "/dev/ptmx" + +int openpty (int *amaster, int *aslave, char *name, struct termios *termp, + struct winsize *winp) +{ + char buf[PATH_MAX]; + int master, slave; + + master = open(_PATH_DEVPTMX, O_RDWR); + if (master == -1) + return -1; + + if (grantpt(master)) + goto fail; + + if (unlockpt(master)) + goto fail; + + if (ptsname_r(master, buf, sizeof buf)) + goto fail; + + slave = open(buf, O_RDWR | O_NOCTTY); + if (slave == -1) + goto fail; + + /* XXX Should we ignore errors here? */ + if (termp) + tcsetattr(slave, TCSAFLUSH, termp); + if (winp) + ioctl(slave, TIOCSWINSZ, winp); + + *amaster = master; + *aslave = slave; + if (name != NULL) + strcpy(name, buf); + + return 0; + +fail: + close(master); + return -1; +} diff -Nru lxc-0.8.0~rc1/src/include/openpty.h lxc-1.0.0~alpha1/src/include/openpty.h --- lxc-0.8.0~rc1/src/include/openpty.h 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/include/openpty.h 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,37 @@ +/* + * openpty: glibc implementation + * + * Copyright (C) 1998, 1999, 2004 Free Software Foundation, Inc. + * + * Authors: + * Zack Weinberg , 1998. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _openpty_h +#define _openpty_h + +#include +#include + +/* Create pseudo tty master slave pair with NAME and set terminal + attributes according to TERMP and WINP and return handles for both + ends in AMASTER and ASLAVE. */ +extern int openpty (int *__amaster, int *__aslave, char *__name, + const struct termios *__termp, + const struct winsize *__winp); + +#endif diff -Nru lxc-0.8.0~rc1/src/lua-lxc/Makefile.am lxc-1.0.0~alpha1/src/lua-lxc/Makefile.am --- lxc-0.8.0~rc1/src/lua-lxc/Makefile.am 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lua-lxc/Makefile.am 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,29 @@ +if ENABLE_LUA + +luadir=$(LUA_INSTALL_LMOD) +sodir=$(LUA_INSTALL_CMOD)/lxc + +lua_SCRIPTS=lxc.lua + +so_PROGRAMS = core.so + +core_so_SOURCES = core.c + +AM_CFLAGS=-I$(top_srcdir)/src $(LUA_CFLAGS) -DVERSION=\"$(VERSION)\" -DLXCPATH=\"$(LXCPATH)\" + +core_so_CFLAGS = -fPIC -DPIC $(AM_CFLAGS) + +core_so_LDFLAGS = \ + -shared \ + -L$(top_srcdir)/src/lxc \ + -Wl,-soname,core.so.$(firstword $(subst ., ,$(VERSION))) + +core_so_LDADD = -llxc $(LUA_LIBS) + +lxc.lua: + +endif + +EXTRA_DIST= \ + lxc.lua \ + test/apitest.lua diff -Nru lxc-0.8.0~rc1/src/lua-lxc/Makefile.in lxc-1.0.0~alpha1/src/lua-lxc/Makefile.in --- lxc-0.8.0~rc1/src/lua-lxc/Makefile.in 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lua-lxc/Makefile.in 2013-09-10 22:30:09.000000000 +0000 @@ -0,0 +1,712 @@ +# Makefile.in generated by automake 1.13.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + +VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@ENABLE_LUA_TRUE@so_PROGRAMS = core.so$(EXEEXT) +subdir = src/lua-lxc +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(top_srcdir)/config/depcomp +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/src/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__installdirs = "$(DESTDIR)$(sodir)" "$(DESTDIR)$(luadir)" +PROGRAMS = $(so_PROGRAMS) +am__core_so_SOURCES_DIST = core.c +@ENABLE_LUA_TRUE@am_core_so_OBJECTS = core_so-core.$(OBJEXT) +core_so_OBJECTS = $(am_core_so_OBJECTS) +am__DEPENDENCIES_1 = +@ENABLE_LUA_TRUE@core_so_DEPENDENCIES = $(am__DEPENDENCIES_1) +core_so_LINK = $(CCLD) $(core_so_CFLAGS) $(CFLAGS) $(core_so_LDFLAGS) \ + $(LDFLAGS) -o $@ +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +SCRIPTS = $(lua_SCRIPTS) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src +depcomp = $(SHELL) $(top_srcdir)/config/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(core_so_SOURCES) +DIST_SOURCES = $(am__core_so_SOURCES_DIST) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +APPARMOR_LIBS = @APPARMOR_LIBS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BINDIR = @BINDIR@ +CAP_LIBS = @CAP_LIBS@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIR = @DATADIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DOCDIR = @DOCDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GREP = @GREP@ +INCLUDEDIR = @INCLUDEDIR@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBDIR = @LIBDIR@ +LIBEXECDIR = @LIBEXECDIR@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LOCALSTATEDIR = @LOCALSTATEDIR@ +LOGPATH = @LOGPATH@ +LTLIBOBJS = @LTLIBOBJS@ +LUA_CFLAGS = @LUA_CFLAGS@ +LUA_INSTALL_CMOD = @LUA_INSTALL_CMOD@ +LUA_INSTALL_LMOD = @LUA_INSTALL_LMOD@ +LUA_LIBS = @LUA_LIBS@ +LUA_VERSION = @LUA_VERSION@ +LXCHOOKDIR = @LXCHOOKDIR@ +LXCINITDIR = @LXCINITDIR@ +LXCPATH = @LXCPATH@ +LXCROOTFSMOUNT = @LXCROOTFSMOUNT@ +LXCTEMPLATEDIR = @LXCTEMPLATEDIR@ +LXC_DEFAULT_CONFIG = @LXC_DEFAULT_CONFIG@ +LXC_DISTRO_CONF = @LXC_DISTRO_CONF@ +LXC_GENERATE_DATE = @LXC_GENERATE_DATE@ +LXC_GLOBAL_CONF = @LXC_GLOBAL_CONF@ +LXC_USERNIC_CONF = @LXC_USERNIC_CONF@ +LXC_USERNIC_DB = @LXC_USERNIC_DB@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +NEWUIDMAP = @NEWUIDMAP@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PREFIX = @PREFIX@ +PYTHON = @PYTHON@ +PYTHONDEV_CFLAGS = @PYTHONDEV_CFLAGS@ +PYTHONDEV_LIBS = @PYTHONDEV_LIBS@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +SECCOMP_LIBS = @SECCOMP_LIBS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SYSCONFDIR = @SYSCONFDIR@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +db2xman = @db2xman@ +docdir = @docdir@ +docdtd = @docdtd@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +@ENABLE_LUA_TRUE@luadir = $(LUA_INSTALL_LMOD) +@ENABLE_LUA_TRUE@sodir = $(LUA_INSTALL_CMOD)/lxc +@ENABLE_LUA_TRUE@lua_SCRIPTS = lxc.lua +@ENABLE_LUA_TRUE@core_so_SOURCES = core.c +@ENABLE_LUA_TRUE@AM_CFLAGS = -I$(top_srcdir)/src $(LUA_CFLAGS) -DVERSION=\"$(VERSION)\" -DLXCPATH=\"$(LXCPATH)\" +@ENABLE_LUA_TRUE@core_so_CFLAGS = -fPIC -DPIC $(AM_CFLAGS) +@ENABLE_LUA_TRUE@core_so_LDFLAGS = \ +@ENABLE_LUA_TRUE@ -shared \ +@ENABLE_LUA_TRUE@ -L$(top_srcdir)/src/lxc \ +@ENABLE_LUA_TRUE@ -Wl,-soname,core.so.$(firstword $(subst ., ,$(VERSION))) + +@ENABLE_LUA_TRUE@core_so_LDADD = -llxc $(LUA_LIBS) +EXTRA_DIST = \ + lxc.lua \ + test/apitest.lua + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/lua-lxc/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/lua-lxc/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-soPROGRAMS: $(so_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(so_PROGRAMS)'; test -n "$(sodir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(sodir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(sodir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sodir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sodir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-soPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(so_PROGRAMS)'; test -n "$(sodir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' \ + `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(sodir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(sodir)" && rm -f $$files + +clean-soPROGRAMS: + -test -z "$(so_PROGRAMS)" || rm -f $(so_PROGRAMS) + +core.so$(EXEEXT): $(core_so_OBJECTS) $(core_so_DEPENDENCIES) $(EXTRA_core_so_DEPENDENCIES) + @rm -f core.so$(EXEEXT) + $(AM_V_CCLD)$(core_so_LINK) $(core_so_OBJECTS) $(core_so_LDADD) $(LIBS) +install-luaSCRIPTS: $(lua_SCRIPTS) + @$(NORMAL_INSTALL) + @list='$(lua_SCRIPTS)'; test -n "$(luadir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(luadir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(luadir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n' \ + -e 'h;s|.*|.|' \ + -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) { files[d] = files[d] " " $$1; \ + if (++n[d] == $(am__install_max)) { \ + print "f", d, files[d]; n[d] = 0; files[d] = "" } } \ + else { print "f", d "/" $$4, $$1 } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(luadir)$$dir'"; \ + $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(luadir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-luaSCRIPTS: + @$(NORMAL_UNINSTALL) + @list='$(lua_SCRIPTS)'; test -n "$(luadir)" || exit 0; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 's,.*/,,;$(transform)'`; \ + dir='$(DESTDIR)$(luadir)'; $(am__uninstall_files_from_dir) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/core_so-core.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +core_so-core.o: core.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(core_so_CFLAGS) $(CFLAGS) -MT core_so-core.o -MD -MP -MF $(DEPDIR)/core_so-core.Tpo -c -o core_so-core.o `test -f 'core.c' || echo '$(srcdir)/'`core.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/core_so-core.Tpo $(DEPDIR)/core_so-core.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='core.c' object='core_so-core.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(core_so_CFLAGS) $(CFLAGS) -c -o core_so-core.o `test -f 'core.c' || echo '$(srcdir)/'`core.c + +core_so-core.obj: core.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(core_so_CFLAGS) $(CFLAGS) -MT core_so-core.obj -MD -MP -MF $(DEPDIR)/core_so-core.Tpo -c -o core_so-core.obj `if test -f 'core.c'; then $(CYGPATH_W) 'core.c'; else $(CYGPATH_W) '$(srcdir)/core.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/core_so-core.Tpo $(DEPDIR)/core_so-core.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='core.c' object='core_so-core.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(core_so_CFLAGS) $(CFLAGS) -c -o core_so-core.obj `if test -f 'core.c'; then $(CYGPATH_W) 'core.c'; else $(CYGPATH_W) '$(srcdir)/core.c'; fi` + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) $(SCRIPTS) +installdirs: + for dir in "$(DESTDIR)$(sodir)" "$(DESTDIR)$(luadir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-soPROGRAMS mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-luaSCRIPTS install-soPROGRAMS + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-luaSCRIPTS uninstall-soPROGRAMS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-soPROGRAMS cscopelist-am ctags ctags-am distclean \ + distclean-compile distclean-generic distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-luaSCRIPTS install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-soPROGRAMS install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \ + ps ps-am tags tags-am uninstall uninstall-am \ + uninstall-luaSCRIPTS uninstall-soPROGRAMS + + +@ENABLE_LUA_TRUE@lxc.lua: + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff -Nru lxc-0.8.0~rc1/src/lua-lxc/core.c lxc-1.0.0~alpha1/src/lua-lxc/core.c --- lxc-0.8.0~rc1/src/lua-lxc/core.c 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lua-lxc/core.c 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,435 @@ +/* + * lua-lxc: lua bindings for lxc + * + * Copyright © 2012 Oracle. + * + * Authors: + * Dwight Engen + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define LUA_LIB +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include + +#if LUA_VERSION_NUM < 502 +#define luaL_newlib(L,l) (lua_newtable(L), luaL_register(L,NULL,l)) +#define luaL_setfuncs(L,l,n) (assert(n==0), luaL_register(L,NULL,l)) +#define luaL_checkunsigned(L,n) luaL_checknumber(L,n) +#endif + +#ifdef NO_CHECK_UDATA +#define checkudata(L,i,tname) lua_touserdata(L, i) +#else +#define checkudata(L,i,tname) luaL_checkudata(L, i, tname) +#endif + +#define lua_boxpointer(L,u) \ + (*(void **) (lua_newuserdata(L, sizeof(void *))) = (u)) + +#define lua_unboxpointer(L,i,tname) \ + (*(void **) (checkudata(L, i, tname))) + +#define CONTAINER_TYPENAME "lxc.container" + +static int container_new(lua_State *L) +{ + struct lxc_container *c; + const char *name = luaL_checkstring(L, 1); + const char *configpath = NULL; + int argc = lua_gettop(L); + + if (argc > 1) + configpath = luaL_checkstring(L, 2); + + c = lxc_container_new(name, configpath); + if (c) { + lua_boxpointer(L, c); + luaL_getmetatable(L, CONTAINER_TYPENAME); + lua_setmetatable(L, -2); + } else { + lua_pushnil(L); + } + return 1; +} + +static int container_gc(lua_State *L) +{ + struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME); + + /* XXX what to do if this fails? */ + lxc_container_put(c); + return 0; +} + +static int container_config_file_name(lua_State *L) +{ + struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME); + char *config_file_name; + + config_file_name = c->config_file_name(c); + lua_pushstring(L, config_file_name); + free(config_file_name); + return 1; +} + +static int container_defined(lua_State *L) +{ + struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME); + + lua_pushboolean(L, !!c->is_defined(c)); + return 1; +} + +static int container_name(lua_State *L) +{ + struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME); + + lua_pushstring(L, c->name); + return 1; +} + +static int container_create(lua_State *L) +{ + struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME); + char *template_name = strdupa(luaL_checkstring(L, 2)); + int argc = lua_gettop(L); + char **argv; + int i; + + argv = alloca((argc+1) * sizeof(char *)); + for (i = 0; i < argc-2; i++) + argv[i] = strdupa(luaL_checkstring(L, i+3)); + argv[i] = NULL; + + lua_pushboolean(L, !!c->create(c, template_name, NULL, NULL, 0, argv)); + return 1; +} + +static int container_destroy(lua_State *L) +{ + struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME); + + lua_pushboolean(L, !!c->destroy(c)); + return 1; +} + +/* container state */ +static int container_start(lua_State *L) +{ + struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME); + int argc = lua_gettop(L); + char **argv = NULL; + int i,j; + int useinit = 0; + + if (argc > 1) { + argv = alloca((argc+1) * sizeof(char *)); + for (i = 0, j = 0; i < argc-1; i++) { + const char *arg = luaL_checkstring(L, i+2); + + if (!strcmp(arg, "useinit")) + useinit = 1; + else + argv[j++] = strdupa(arg); + } + argv[j] = NULL; + } + + c->want_daemonize(c); + lua_pushboolean(L, !!c->start(c, useinit, argv)); + return 1; +} + +static int container_stop(lua_State *L) +{ + struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME); + + lua_pushboolean(L, !!c->stop(c)); + return 1; +} + +static int container_shutdown(lua_State *L) +{ + struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME); + int timeout = luaL_checkinteger(L, 2); + + lua_pushboolean(L, !!c->shutdown(c, timeout)); + return 1; +} + +static int container_wait(lua_State *L) +{ + struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME); + const char *state = luaL_checkstring(L, 2); + int timeout = luaL_checkinteger(L, 3); + + lua_pushboolean(L, !!c->wait(c, state, timeout)); + return 1; +} + +static int container_freeze(lua_State *L) +{ + struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME); + + lua_pushboolean(L, !!c->freeze(c)); + return 1; +} + +static int container_unfreeze(lua_State *L) +{ + struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME); + + lua_pushboolean(L, !!c->unfreeze(c)); + return 1; +} + +static int container_running(lua_State *L) +{ + struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME); + + lua_pushboolean(L, !!c->is_running(c)); + return 1; +} + +static int container_state(lua_State *L) +{ + struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME); + + lua_pushstring(L, c->state(c)); + return 1; +} + +static int container_init_pid(lua_State *L) +{ + struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME); + + lua_pushinteger(L, c->init_pid(c)); + return 1; +} + +/* configuration file methods */ +static int container_load_config(lua_State *L) +{ + struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME); + int arg_cnt = lua_gettop(L); + const char *alt_path = NULL; + + if (arg_cnt > 1) + alt_path = luaL_checkstring(L, 2); + + lua_pushboolean(L, !!c->load_config(c, alt_path)); + return 1; +} + +static int container_save_config(lua_State *L) +{ + struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME); + int arg_cnt = lua_gettop(L); + const char *alt_path = NULL; + + if (arg_cnt > 1) + alt_path = luaL_checkstring(L, 2); + + lua_pushboolean(L, !!c->save_config(c, alt_path)); + return 1; +} + +static int container_get_config_path(lua_State *L) +{ + struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME); + const char *config_path; + + config_path = c->get_config_path(c); + lua_pushstring(L, config_path); + return 1; +} + +static int container_set_config_path(lua_State *L) +{ + struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME); + const char *config_path = luaL_checkstring(L, 2); + + lua_pushboolean(L, !!c->set_config_path(c, config_path)); + return 1; +} + +static int container_clear_config_item(lua_State *L) +{ + struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME); + const char *key = luaL_checkstring(L, 2); + + lua_pushboolean(L, !!c->clear_config_item(c, key)); + return 1; +} + +static int container_get_config_item(lua_State *L) +{ + struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME); + const char *key = luaL_checkstring(L, 2); + int len; + char *value; + + len = c->get_config_item(c, key, NULL, 0); + if (len <= 0) + goto not_found; + + value = alloca(sizeof(char)*len + 1); + if (c->get_config_item(c, key, value, len + 1) != len) + goto not_found; + + lua_pushstring(L, value); + return 1; + +not_found: + lua_pushnil(L); + return 1; +} + +static int container_set_config_item(lua_State *L) +{ + struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME); + const char *key = luaL_checkstring(L, 2); + const char *value = luaL_checkstring(L, 3); + + lua_pushboolean(L, !!c->set_config_item(c, key, value)); + return 1; +} + +static int container_get_keys(lua_State *L) +{ + struct lxc_container *c = lua_unboxpointer(L, 1, CONTAINER_TYPENAME); + const char *key = NULL; + int len; + char *value; + int arg_cnt = lua_gettop(L); + + if (arg_cnt > 1) + key = luaL_checkstring(L, 2); + + len = c->get_keys(c, key, NULL, 0); + if (len <= 0) + goto not_found; + + value = alloca(sizeof(char)*len + 1); + if (c->get_keys(c, key, value, len + 1) != len) + goto not_found; + + lua_pushstring(L, value); + return 1; + +not_found: + lua_pushnil(L); + return 1; +} + +static luaL_Reg lxc_container_methods[] = +{ + {"create", container_create}, + {"defined", container_defined}, + {"destroy", container_destroy}, + {"init_pid", container_init_pid}, + {"name", container_name}, + {"running", container_running}, + {"state", container_state}, + {"freeze", container_freeze}, + {"unfreeze", container_unfreeze}, + {"start", container_start}, + {"stop", container_stop}, + {"shutdown", container_shutdown}, + {"wait", container_wait}, + + {"config_file_name", container_config_file_name}, + {"load_config", container_load_config}, + {"save_config", container_save_config}, + {"get_config_path", container_get_config_path}, + {"set_config_path", container_set_config_path}, + {"get_config_item", container_get_config_item}, + {"set_config_item", container_set_config_item}, + {"clear_config_item", container_clear_config_item}, + {"get_keys", container_get_keys}, + {NULL, NULL} +}; + +static int lxc_version_get(lua_State *L) { + lua_pushstring(L, VERSION); + return 1; +} + +static int lxc_default_config_path_get(lua_State *L) { + const char *lxcpath = lxc_get_default_config_path(); + + lua_pushstring(L, lxcpath); + return 1; +} + +/* utility functions */ +static int lxc_util_usleep(lua_State *L) { + usleep((useconds_t)luaL_checkunsigned(L, 1)); + return 0; +} + +static int lxc_util_dirname(lua_State *L) { + char *path = strdupa(luaL_checkstring(L, 1)); + lua_pushstring(L, dirname(path)); + return 1; +} + +static luaL_Reg lxc_lib_methods[] = { + {"version_get", lxc_version_get}, + {"default_config_path_get", lxc_default_config_path_get}, + {"container_new", container_new}, + {"usleep", lxc_util_usleep}, + {"dirname", lxc_util_dirname}, + {NULL, NULL} +}; + +static int lxc_lib_uninit(lua_State *L) { + (void) L; + /* this is where we would fini liblxc.so if we needed to */ + return 0; +} + +LUALIB_API int luaopen_lxc_core(lua_State *L) { + /* this is where we would initialize liblxc.so if we needed to */ + + luaL_newlib(L, lxc_lib_methods); + + lua_newuserdata(L, 0); + lua_newtable(L); /* metatable */ + lua_pushvalue(L, -1); + lua_pushliteral(L, "__gc"); + lua_pushcfunction(L, lxc_lib_uninit); + lua_rawset(L, -3); + lua_setmetatable(L, -3); + lua_rawset(L, -3); + + luaL_newmetatable(L, CONTAINER_TYPENAME); + luaL_setfuncs(L, lxc_container_methods, 0); + lua_pushvalue(L, -1); /* push metatable */ + lua_pushstring(L, "__gc"); + lua_pushcfunction(L, container_gc); + lua_settable(L, -3); + lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */ + lua_pop(L, 1); + return 1; +} diff -Nru lxc-0.8.0~rc1/src/lua-lxc/lxc.lua lxc-1.0.0~alpha1/src/lua-lxc/lxc.lua --- lxc-0.8.0~rc1/src/lua-lxc/lxc.lua 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lua-lxc/lxc.lua 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,416 @@ +-- +-- lua lxc module +-- +-- Copyright © 2012 Oracle. +-- +-- Authors: +-- Dwight Engen +-- +-- 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +-- + +local core = require("lxc.core") +local lfs = require("lfs") +local table = require("table") +local string = require("string") +local io = require("io") +module("lxc", package.seeall) + +local lxc_path +local cgroup_path +local log_level = 3 + +-- lua 5.1 compat +if table.unpack == nil then + table.unpack = unpack +end + +-- the following two functions can be useful for debugging +function printf(...) + local function wrapper(...) io.write(string.format(...)) end + local status, result = pcall(wrapper, ...) + if not status then + error(result, 2) + end +end + +function log(level, ...) + if (log_level >= level) then + printf(os.date("%Y-%m-%d %T ")) + printf(...) + end +end + +function string:split(delim, max_cols) + local cols = {} + local start = 1 + local nextc + repeat + nextc = string.find(self, delim, start) + if (nextc and #cols ~= max_cols - 1) then + table.insert(cols, string.sub(self, start, nextc-1)) + start = nextc + #delim + else + table.insert(cols, string.sub(self, start, string.len(self))) + nextc = nil + end + until nextc == nil or start > #self + return cols +end + +function cgroup_path_get() + local f,line,cgroup_path + + f = io.open("/proc/mounts", "r") + if (f) then + while true do + local c + line = f:read() + if line == nil then + break + end + c = line:split(" ", 6) + if (c[1] == "cgroup") then + cgroup_path = core.dirname(c[2]) + break + end + end + f:close() + end + if (not cgroup_path) then + cgroup_path = "/sys/fs/cgroup" + end + return cgroup_path +end + +-- container class +container = {} +container_mt = {} +container_mt.__index = container + +function container:new(lname, config) + local lcore + local lnetcfg = {} + local lstats = {} + + if lname then + if config then + lcore = core.container_new(lname, config) + else + lcore = core.container_new(lname) + end + end + + return setmetatable({ctname = lname, core = lcore, netcfg = lnetcfg, stats = lstats}, container_mt) +end + +-- methods interfacing to core functionality +function container:config_file_name() + return self.core:config_file_name() +end + +function container:defined() + return self.core:defined() +end + +function container:init_pid() + return self.core:init_pid() +end + +function container:name() + return self.core:name() +end + +function container:start() + return self.core:start() +end + +function container:stop() + return self.core:stop() +end + +function container:shutdown(timeout) + return self.core:shutdown(timeout) +end + +function container:wait(state, timeout) + return self.core:wait(state, timeout) +end + +function container:freeze() + return self.core:freeze() +end + +function container:unfreeze() + return self.core:unfreeze() +end + +function container:running() + return self.core:running() +end + +function container:state() + return self.core:state() +end + +function container:create(template, ...) + return self.core:create(template, ...) +end + +function container:destroy() + return self.core:destroy() +end + +function container:get_config_path() + return self.core:get_config_path() +end + +function container:set_config_path(path) + return self.core:set_config_path(path) +end + +function container:append_config_item(key, value) + return self.core:set_config_item(key, value) +end + +function container:clear_config_item(key) + return self.core:clear_config_item(key) +end + +function container:get_config_item(key) + local value + local vals = {} + + value = self.core:get_config_item(key) + + -- check if it is a single item + if (not value or not string.find(value, "\n")) then + return value + end + + -- it must be a list type item, make a table of it + vals = value:split("\n", 1000) + -- make it a "mixed" table, ie both dictionary and list for ease of use + for _,v in ipairs(vals) do + vals[v] = true + end + return vals +end + +function container:set_config_item(key, value) + return self.core:set_config_item(key, value) +end + +function container:get_keys(base) + local ktab = {} + local keys + + if (base) then + keys = self.core:get_keys(base) + base = base .. "." + else + keys = self.core:get_keys() + base = "" + end + if (keys == nil) then + return nil + end + keys = keys:split("\n", 1000) + for _,v in ipairs(keys) do + local config_item = base .. v + ktab[v] = self.core:get_config_item(config_item) + end + return ktab +end + +function container:load_config(alt_path) + if (alt_path) then + return self.core:load_config(alt_path) + else + return self.core:load_config() + end +end + +function container:save_config(alt_path) + if (alt_path) then + return self.core:save_config(alt_path) + else + return self.core:save_config() + end +end + +-- methods for stats collection from various cgroup files +-- read integers at given coordinates from a cgroup file +function container:stat_get_ints(controller, item, coords) + local f = io.open(cgroup_path.."/"..controller.."/"..self.ctname.."/"..item, "r") + local lines = {} + local result = {} + + if (not f) then + for k,c in ipairs(coords) do + table.insert(result, 0) + end + else + for line in f:lines() do + table.insert(lines, line) + end + f:close() + for k,c in ipairs(coords) do + local col + + col = lines[c[1]]:split(" ", 80) + local val = tonumber(col[c[2]]) + table.insert(result, val) + end + end + return table.unpack(result) +end + +-- read an integer from a cgroup file +function container:stat_get_int(controller, item) + local f = io.open(cgroup_path.."/"..controller.."/"..self.ctname.."/"..item, "r") + if (not f) then + return 0 + end + + local line = f:read() + f:close() + -- if line is nil (on an error like Operation not supported because + -- CONFIG_MEMCG_SWAP_ENABLED isn't enabled) return 0 + return tonumber(line) or 0 +end + +function container:stat_match_get_int(controller, item, match, column) + local val + local f = io.open(cgroup_path.."/"..controller.."/"..self.ctname.."/"..item, "r") + if (not f) then + return 0 + end + + for line in f:lines() do + if (string.find(line, match)) then + local col + + col = line:split(" ", 80) + val = tonumber(col[column]) or 0 + end + end + f:close() + return val +end + +function container:stats_get(total) + local stat = {} + stat.mem_used = self:stat_get_int("memory", "memory.usage_in_bytes") + stat.mem_limit = self:stat_get_int("memory", "memory.limit_in_bytes") + stat.memsw_used = self:stat_get_int("memory", "memory.memsw.usage_in_bytes") + stat.memsw_limit = self:stat_get_int("memory", "memory.memsw.limit_in_bytes") + stat.cpu_use_nanos = self:stat_get_int("cpuacct", "cpuacct.usage") + stat.cpu_use_user, + stat.cpu_use_sys = self:stat_get_ints("cpuacct", "cpuacct.stat", {{1, 2}, {2, 2}}) + stat.blkio = self:stat_match_get_int("blkio", "blkio.throttle.io_service_bytes", "Total", 2) + + if (total) then + total.mem_used = total.mem_used + stat.mem_used + total.mem_limit = total.mem_limit + stat.mem_limit + total.memsw_used = total.memsw_used + stat.memsw_used + total.memsw_limit = total.memsw_limit + stat.memsw_limit + total.cpu_use_nanos = total.cpu_use_nanos + stat.cpu_use_nanos + total.cpu_use_user = total.cpu_use_user + stat.cpu_use_user + total.cpu_use_sys = total.cpu_use_sys + stat.cpu_use_sys + total.blkio = total.blkio + stat.blkio + end + return stat +end + +local M = { container = container } + +function M.stats_clear(stat) + stat.mem_used = 0 + stat.mem_limit = 0 + stat.memsw_used = 0 + stat.memsw_limit = 0 + stat.cpu_use_nanos = 0 + stat.cpu_use_user = 0 + stat.cpu_use_sys = 0 + stat.blkio = 0 +end + +function M.stats_clear(stat) + stat.mem_used = 0 + stat.mem_limit = 0 + stat.memsw_used = 0 + stat.memsw_limit = 0 + stat.cpu_use_nanos = 0 + stat.cpu_use_user = 0 + stat.cpu_use_sys = 0 + stat.blkio = 0 +end + +-- return configured containers found in LXC_PATH directory +function M.containers_configured(names_only) + local containers = {} + + for dir in lfs.dir(lxc_path) do + if (dir ~= "." and dir ~= "..") + then + local cfgfile = lxc_path .. "/" .. dir .. "/config" + local cfgattr = lfs.attributes(cfgfile) + + if (cfgattr and cfgattr.mode == "file") then + if (names_only) then + -- note, this is a "mixed" table, ie both dictionary and list + containers[dir] = true + table.insert(containers, dir) + else + local ct = container:new(dir) + -- note, this is a "mixed" table, ie both dictionary and list + containers[dir] = ct + table.insert(containers, dir) + end + end + end + end + table.sort(containers, function (a,b) return (a < b) end) + return containers +end + +-- return running containers found in cgroup fs +function M.containers_running(names_only) + local containers = {} + local names = M.containers_configured(true) + + for _,name in ipairs(names) do + local ct = container:new(name) + if ct:running() then + -- note, this is a "mixed" table, ie both dictionary and list + table.insert(containers, name) + if (names_only) then + containers[name] = true + ct = nil + else + containers[name] = ct + end + end + end + + table.sort(containers, function (a,b) return (a < b) end) + return containers +end + +lxc_path = core.default_config_path_get() +cgroup_path = cgroup_path_get() + +return M diff -Nru lxc-0.8.0~rc1/src/lua-lxc/test/apitest.lua lxc-1.0.0~alpha1/src/lua-lxc/test/apitest.lua --- lxc-0.8.0~rc1/src/lua-lxc/test/apitest.lua 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lua-lxc/test/apitest.lua 2013-09-03 18:26:12.000000000 +0000 @@ -0,0 +1,326 @@ +#!/usr/bin/env lua +-- +-- test the lxc lua api +-- +-- Copyright © 2012 Oracle. +-- +-- Authors: +-- Dwight Engen +-- +-- This library is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License version 2, as +-- published by the Free Software Foundation. +-- +-- 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., +-- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +-- + +local lxc = require("lxc") +local lfs = require("lfs") +local getopt = require("alt_getopt") + +local LXC_PATH = lxc.default_config_path_get() + +local container +local cfg_containers = {} +local optarg = {} +local optind = {} + +function printf(...) + local function wrapper(...) io.write(string.format(...)) end + local status, result = pcall(wrapper, ...) + if not status then + error(result, 2) + end +end + +function log(level, ...) + if (optarg["v"] >= level) then + printf(os.date("%Y-%m-%d %T ")) + printf(...) + printf("\n") + end +end + +function die(...) + printf(...) + os.exit(1) +end + +function test_global_info() + local cfg_containers + local run_containers + + log(0, "%-20s %s", "LXC version:", lxc.version_get()) + log(0, "%-20s %s", "Container name:", optarg["n"]) + if (optarg["c"]) then + log(0, "%-20s %s", "Creating container:", "yes") + log(0, "%-20s %s", "With template:", optarg["t"]) + end + log(0, "%-20s %s", "Containers path:", LXC_PATH) + + cfg_containers = lxc.containers_configured() + log(0, "%-20s", "Containers configured:") + for _,v in ipairs(cfg_containers) do + log(0, " %s", v) + end + + run_containers = lxc.containers_running(true) + log(0, "%-20s", "Containers running:") + for _,v in ipairs(run_containers) do + log(0, " %s", v) + end +end + +function test_container_new() + container = lxc.container:new(optarg["n"]) + assert(container ~= nil) + assert(container:config_file_name() == string.format("%s/%s/config", LXC_PATH, optarg["n"])) +end + +function test_container_config_path() + local cfgcontainer + local cfgpath = "/tmp/" .. optarg["n"] + local cfgname = cfgpath .. "/config" + + log(0, "Test container config path...") + + -- create a config file in the new location from container's config + assert(lfs.mkdir(cfgpath)) + assert(container:save_config(cfgname)) + cfgcontainer = lxc.container:new(optarg["n"], "/tmp") + assert(cfgcontainer ~= nil) + log(0, "cfgname:%s cfgpath:%s", cfgcontainer:config_file_name(), cfgcontainer:get_config_path()) + assert(cfgcontainer:config_file_name() == cfgname) + assert(cfgcontainer:get_config_path() == "/tmp") + assert(cfgcontainer:set_config_path(LXC_PATH)) + assert(cfgcontainer:get_config_path() == LXC_PATH) + + assert(os.remove(cfgname)) + assert(lfs.rmdir(cfgpath)) +end + +function test_container_create() + if (optarg["c"]) then + log(0, "%-20s %s", "Destroy existing container:", optarg["n"]) + container:destroy() + assert(container:defined() == false) + else + local cfg_containers = lxc.containers_configured() + if (cfg_containers[optarg["n"]]) then + log(0, "%-20s %s", "Use existing container:", optarg["n"]) + return + end + end + log(0, "%-20s %s", "Creating rootfs using:", optarg["t"]) + container:create(optarg["t"]) + assert(container:defined() == true) + assert(container:name() == optarg["n"]) +end + +function test_container_started() + local now_running + log(2, "state:%s pid:%d\n", container:state(), container:init_pid()) + assert(container:init_pid() > 1) + assert(container:running() == true) + assert(container:state() == "RUNNING") + now_running = lxc.containers_running(true) + assert(now_running[optarg["n"]] ~= nil) + log(1, "%-20s %s", "Running, init pid:", container:init_pid()) +end + +function test_container_stopped() + local now_running + assert(container:init_pid() == -1) + assert(container:running() == false) + assert(container:state() == "STOPPED") + now_running = lxc.containers_running(true) + assert(now_running[optarg["n"]] == nil) +end + +function test_container_frozen() + local now_running + assert(container:init_pid() > 1) + assert(container:running() == true) + assert(container:state() == "FROZEN") + now_running = lxc.containers_running(true) + assert(now_running[optarg["n"]] ~= nil) +end + +function test_container_start() + log(0, "Starting...") + if (not container:start()) then + log(1, "Start returned failure, waiting another 10 seconds...") + container:wait("RUNNING", 10) + end + container:wait("RUNNING", 1) +end + +function test_container_stop() + log(0, "Stopping...") + if (not container:stop()) then + log(1, "Stop returned failure, waiting another 10 seconds...") + container:wait("STOPPED", 10) + end + container:wait("STOPPED", 1) +end + +function test_container_freeze() + log(0, "Freezing...") + if (not container:freeze()) then + log(1, "Freeze returned failure, waiting another 10 seconds...") + container:wait("FROZEN", 10) + end +end + +function test_container_unfreeze() + log(0, "Unfreezing...") + if (not container:unfreeze()) then + log(1, "Unfreeze returned failure, waiting another 10 seconds...") + container:wait("RUNNING", 10) + end +end + +function test_container_shutdown() + log(0, "Shutting down...") + container:shutdown(5) + + if (container:running()) then + test_container_stop() + end +end + +function test_container_in_cfglist(should_find) + local cfg_containers = lxc.containers_configured() + + if (should_find) then + assert(cfg_containers[container:name()] ~= nil) + else + assert(cfg_containers[container:name()] == nil) + end +end + +function test_config_items() + log(0, "Test set/clear configuration items...") + + -- test setting a 'single type' item + assert(container:get_config_item("lxc.utsname") == optarg["n"]) + container:set_config_item("lxc.utsname", "foobar") + assert(container:get_config_item("lxc.utsname") == "foobar") + container:set_config_item("lxc.utsname", optarg["n"]) + assert(container:get_config_item("lxc.utsname") == optarg["n"]) + + -- test clearing/setting a 'list type' item + container:clear_config_item("lxc.cap.drop") + container:set_config_item("lxc.cap.drop", "new_cap1") + container:set_config_item("lxc.cap.drop", "new_cap2") + local cap_drop = container:get_config_item("lxc.cap.drop") + assert(cap_drop["new_cap1"] ~= nil) + assert(cap_drop["new_cap2"] ~= nil) + -- note: clear_config_item only works on list type items + container:clear_config_item("lxc.cap.drop") + assert(container:get_config_item("lxc.cap.drop") == nil) + + local altname = "/tmp/" .. optarg["n"] .. ".altconfig" + log(0, "Test saving to an alternate (%s) config file...", altname) + assert(container:save_config(altname)) + assert(os.remove(altname)) +end + +function test_config_mount_entries() + local mntents + + -- mount entries are a list type item + mntents = container:get_config_item("lxc.mount.entry") + log(0, "Mount entries:") + for _,v in ipairs(mntents) do + log(0, " %s", v) + end +end + +function test_config_keys() + local keys + + keys = container:get_keys() + log(0, "Top level keys:") + for k,v in pairs(keys) do + log(0, " %s = %s", k, v or "") + end +end + +function test_config_network(net_nr) + log(0, "Test network %d config...", net_nr) + local netcfg + + netcfg = container:get_keys("lxc.network." .. net_nr) + if (netcfg == nil) then + return + end + for k,v in pairs(netcfg) do + log(0, " %s = %s", k, v or "") + end + assert(netcfg["flags"] == "up") + assert(container:get_config_item("lxc.network."..net_nr..".type") == "veth") +end + + +function usage() + die("Usage: apitest \n" .. + " -v|--verbose increase verbosity with each -v\n" .. + " -h|--help print help message\n" .. + " -n|--name name of container to use for testing\n" .. + " -c|--create create the test container anew\n" .. + " -l|--login do interactive login test\n" .. + " -t|--template template to use when creating test container\n" + ) +end + +local long_opts = { + verbose = "v", + help = "h", + name = "n", + create = "c", + template = "t", +} + +optarg,optind = alt_getopt.get_opts (arg, "hvn:ct:", long_opts) +optarg["v"] = tonumber(optarg["v"]) or 0 +optarg["n"] = optarg["n"] or "lua-apitest" +optarg["c"] = optarg["c"] or nil +optarg["t"] = optarg["t"] or "busybox" +if (optarg["h"] ~= nil) then + usage() +end + +test_global_info() +test_container_new() +test_container_create() +test_container_stopped() +test_container_in_cfglist(true) +test_container_config_path() + +test_config_items() +test_config_keys() +test_config_mount_entries() +test_config_network(0) + +test_container_start() +test_container_started() + +test_container_freeze() +test_container_frozen() +test_container_unfreeze() +test_container_started() + +test_container_shutdown() +test_container_stopped() +container:destroy() +test_container_in_cfglist(false) + +log(0, "All tests passed") diff -Nru lxc-0.8.0~rc1/src/lxc/Makefile.am lxc-1.0.0~alpha1/src/lxc/Makefile.am --- lxc-0.8.0~rc1/src/lxc/Makefile.am 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/Makefile.am 2013-09-10 22:22:00.000000000 +0000 @@ -1,19 +1,37 @@ pkginclude_HEADERS = \ arguments.h \ - start.h \ - console.h \ - error.h \ - monitor.h \ - utils.h \ - namespace.h \ + attach.h \ + attach_options.h \ + bdev.h \ caps.h \ - lxc.h \ cgroup.h \ conf.h \ + console.h \ + error.h \ list.h \ log.h \ + lxccontainer.h \ + lxc.h \ + lxclock.h \ + monitor.h \ + namespace.h \ + start.h \ state.h \ - attach.h + utils.h \ + version.h + +if IS_BIONIC +pkginclude_HEADERS += \ + ../include/ifaddrs.h \ + ../include/openpty.h \ + ../include/lxcmntent.h +endif + +if !HAVE_GETLINE +if HAVE_FGETLN +pkginclude_HEADERS += ../include/getline.h +endif +endif sodir=$(libdir) # use PROGRAMS to avoid complains from automake @@ -21,9 +39,9 @@ liblxc_so_SOURCES = \ arguments.c arguments.h \ + bdev.c bdev.h \ commands.c commands.h \ start.c start.h \ - stop.c \ execute.c \ monitor.c monitor.h \ console.c \ @@ -45,20 +63,61 @@ attach.c attach.h \ \ network.c network.h \ - nl.c nl.h \ - rtnl.c rtnl.h \ - genl.c genl.h \ + nl.c nl.h \ + rtnl.c rtnl.h \ + genl.c genl.h \ \ caps.c caps.h \ + lxcseccomp.h \ mainloop.c mainloop.h \ af_unix.c af_unix.h \ \ - utmp.c utmp.h + lxcutmp.c lxcutmp.h \ + apparmor.c apparmor.h \ + lxclock.h lxclock.c \ + lxccontainer.c lxccontainer.h \ + version.c version.h + +if IS_BIONIC +liblxc_so_SOURCES += \ + ../include/ifaddrs.c ../include/ifaddrs.h \ + ../include/openpty.c ../include/openpty.h \ + ../include/lxcmntent.c ../include/lxcmntent.h +endif + +if !HAVE_GETLINE +if HAVE_FGETLN +liblxc_so_SOURCES += ../include/getline.c ../include/getline.h +endif +endif AM_CFLAGS=-I$(top_srcdir)/src \ -DLXCROOTFSMOUNT=\"$(LXCROOTFSMOUNT)\" \ -DLXCPATH=\"$(LXCPATH)\" \ - -DLXCINITDIR=\"$(LXCINITDIR)\" + -DLXC_GLOBAL_CONF=\"$(LXC_GLOBAL_CONF)\" \ + -DLXCINITDIR=\"$(LXCINITDIR)\" \ + -DLXCTEMPLATEDIR=\"$(LXCTEMPLATEDIR)\" \ + -DLOGPATH=\"$(LOGPATH)\" \ + -DLXC_DEFAULT_CONFIG=\"$(LXC_DEFAULT_CONFIG)\" \ + -DLXC_USERNIC_DB=\"$(LXC_USERNIC_DB)\" \ + -DLXC_USERNIC_CONF=\"$(LXC_USERNIC_CONF)\" + +if ENABLE_APPARMOR +AM_CFLAGS += -DHAVE_APPARMOR +endif + +if HAVE_NEWUIDMAP +AM_CFLAGS += -DHAVE_NEWUIDMAP +endif + +if USE_CONFIGPATH_LOGS +AM_CFLAGS += -DUSE_CONFIGPATH_LOGS +endif + +if ENABLE_SECCOMP +AM_CFLAGS += -DHAVE_SECCOMP +liblxc_so_SOURCES += seccomp.c +endif liblxc_so_CFLAGS = -fPIC -DPIC $(AM_CFLAGS) @@ -66,27 +125,40 @@ -shared \ -Wl,-soname,liblxc.so.$(firstword $(subst ., ,$(VERSION))) -liblxc_so_LDADD = -lutil $(CAP_LIBS) +liblxc_so_LDADD = $(CAP_LIBS) $(APPARMOR_LIBS) $(SECCOMP_LIBS) bin_SCRIPTS = \ lxc-ps \ lxc-netstat \ - lxc-ls \ lxc-checkconfig \ - lxc-setcap \ - lxc-setuid \ - lxc-version \ - lxc-create \ - lxc-clone \ - lxc-destroy + lxc-version + +EXTRA_DIST = \ + lxc-device \ + lxc-ls \ + lxc-top + +if ENABLE_PYTHON +bin_SCRIPTS += lxc-device +bin_SCRIPTS += lxc-ls +bin_SCRIPTS += lxc-start-ephemeral +else +bin_SCRIPTS += legacy/lxc-ls +endif + +if ENABLE_LUA +bin_SCRIPTS += lxc-top +endif bin_PROGRAMS = \ lxc-attach \ lxc-unshare \ lxc-stop \ lxc-start \ + lxc-clone \ lxc-execute \ lxc-monitor \ + lxc-monitord \ lxc-wait \ lxc-console \ lxc-freeze \ @@ -95,7 +167,15 @@ lxc-unfreeze \ lxc-checkpoint \ lxc-restart \ - lxc-kill + lxc-kill \ + lxc-config \ + lxc-destroy \ + lxc-create \ + lxc-user-nic + +if HAVE_NEWUIDMAP +bin_PROGRAMS += lxc-usernsexec +endif pkglibexec_PROGRAMS = \ lxc-init @@ -104,41 +184,40 @@ if ENABLE_RPATH AM_LDFLAGS += -Wl,-rpath -Wl,$(libdir) endif -LDADD=liblxc.so @CAP_LIBS@ +LDADD=liblxc.so @CAP_LIBS@ @APPARMOR_LIBS@ @SECCOMP_LIBS@ lxc_attach_SOURCES = lxc_attach.c lxc_cgroup_SOURCES = lxc_cgroup.c lxc_checkpoint_SOURCES = lxc_checkpoint.c +lxc_config_SOURCES = lxc_config.c lxc_console_SOURCES = lxc_console.c +lxc_destroy_SOURCES = lxc_destroy.c lxc_execute_SOURCES = lxc_execute.c lxc_freeze_SOURCES = lxc_freeze.c lxc_info_SOURCES = lxc_info.c lxc_init_SOURCES = lxc_init.c lxc_monitor_SOURCES = lxc_monitor.c +lxc_monitord_SOURCES = lxc_monitord.c lxc_restart_SOURCES = lxc_restart.c +lxc_clone_SOURCES = lxc_clone.c lxc_start_SOURCES = lxc_start.c lxc_stop_SOURCES = lxc_stop.c lxc_unfreeze_SOURCES = lxc_unfreeze.c lxc_unshare_SOURCES = lxc_unshare.c lxc_wait_SOURCES = lxc_wait.c lxc_kill_SOURCES = lxc_kill.c +lxc_create_SOURCES = lxc_create.c +lxc_usernsexec_SOURCES = lxc_usernsexec.c +lxc_user_nic_SOURCES = lxc_user_nic.c install-exec-local: install-soPROGRAMS + mkdir -p $(DESTDIR)$(datadir)/lxc + install -c -m 644 lxc.functions $(DESTDIR)$(datadir)/lxc mv $(DESTDIR)$(libdir)/liblxc.so $(DESTDIR)$(libdir)/liblxc.so.$(VERSION) /sbin/ldconfig -l $(DESTDIR)$(libdir)/liblxc.so.$(VERSION) cd $(DESTDIR)$(libdir); \ + ln -sf liblxc.so.$(VERSION) liblxc.so.$(firstword $(subst ., ,$(VERSION))); \ ln -sf liblxc.so.$(firstword $(subst ., ,$(VERSION))) liblxc.so uninstall-local: $(RM) $(DESTDIR)$(libdir)/liblxc.so* - -namespace.c: setns.h - -setns.h: - -$(CC) $(CPPFLAGS) -M -MT$@ $(LINUX_DIR)/arch/$(LINUX_SRCARCH)/include/asm/unistd.h >setns.P - -$(CPP) $(CPPFLAGS) -dM $(LINUX_DIR)/arch/$(LINUX_SRCARCH)/include/asm/unistd.h |grep setns > $@ - -clean-local: - $(RM) setns.h setns.P - --include setns.P diff -Nru lxc-0.8.0~rc1/src/lxc/Makefile.in lxc-1.0.0~alpha1/src/lxc/Makefile.in --- lxc-0.8.0~rc1/src/lxc/Makefile.in 2012-03-01 23:04:43.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/Makefile.in 2013-09-10 22:30:09.000000000 +0000 @@ -1,9 +1,8 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. +# Makefile.in generated by automake 1.13.3 from Makefile.am. # @configure_input@ -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -18,6 +17,51 @@ VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -36,41 +80,85 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ +@IS_BIONIC_TRUE@am__append_1 = \ +@IS_BIONIC_TRUE@ ../include/ifaddrs.h \ +@IS_BIONIC_TRUE@ ../include/openpty.h \ +@IS_BIONIC_TRUE@ ../include/lxcmntent.h + +@HAVE_FGETLN_TRUE@@HAVE_GETLINE_FALSE@am__append_2 = ../include/getline.h so_PROGRAMS = liblxc.so$(EXEEXT) +@IS_BIONIC_TRUE@am__append_3 = \ +@IS_BIONIC_TRUE@ ../include/ifaddrs.c ../include/ifaddrs.h \ +@IS_BIONIC_TRUE@ ../include/openpty.c ../include/openpty.h \ +@IS_BIONIC_TRUE@ ../include/lxcmntent.c ../include/lxcmntent.h + +@HAVE_FGETLN_TRUE@@HAVE_GETLINE_FALSE@am__append_4 = ../include/getline.c ../include/getline.h +@ENABLE_APPARMOR_TRUE@am__append_5 = -DHAVE_APPARMOR +@HAVE_NEWUIDMAP_TRUE@am__append_6 = -DHAVE_NEWUIDMAP +@USE_CONFIGPATH_LOGS_TRUE@am__append_7 = -DUSE_CONFIGPATH_LOGS +@ENABLE_SECCOMP_TRUE@am__append_8 = -DHAVE_SECCOMP +@ENABLE_SECCOMP_TRUE@am__append_9 = seccomp.c +@ENABLE_PYTHON_TRUE@am__append_10 = lxc-device lxc-ls \ +@ENABLE_PYTHON_TRUE@ lxc-start-ephemeral +@ENABLE_PYTHON_FALSE@am__append_11 = legacy/lxc-ls +@ENABLE_LUA_TRUE@am__append_12 = lxc-top bin_PROGRAMS = lxc-attach$(EXEEXT) lxc-unshare$(EXEEXT) \ - lxc-stop$(EXEEXT) lxc-start$(EXEEXT) lxc-execute$(EXEEXT) \ - lxc-monitor$(EXEEXT) lxc-wait$(EXEEXT) lxc-console$(EXEEXT) \ + lxc-stop$(EXEEXT) lxc-start$(EXEEXT) lxc-clone$(EXEEXT) \ + lxc-execute$(EXEEXT) lxc-monitor$(EXEEXT) \ + lxc-monitord$(EXEEXT) lxc-wait$(EXEEXT) lxc-console$(EXEEXT) \ lxc-freeze$(EXEEXT) lxc-info$(EXEEXT) lxc-cgroup$(EXEEXT) \ lxc-unfreeze$(EXEEXT) lxc-checkpoint$(EXEEXT) \ - lxc-restart$(EXEEXT) lxc-kill$(EXEEXT) + lxc-restart$(EXEEXT) lxc-kill$(EXEEXT) lxc-config$(EXEEXT) \ + lxc-destroy$(EXEEXT) lxc-create$(EXEEXT) lxc-user-nic$(EXEEXT) \ + $(am__EXEEXT_1) +@HAVE_NEWUIDMAP_TRUE@am__append_13 = lxc-usernsexec pkglibexec_PROGRAMS = lxc-init$(EXEEXT) -@ENABLE_RPATH_TRUE@am__append_1 = -Wl,-rpath -Wl,$(libdir) +@ENABLE_RPATH_TRUE@am__append_14 = -Wl,-rpath -Wl,$(libdir) subdir = src/lxc -DIST_COMMON = $(pkginclude_HEADERS) $(srcdir)/Makefile.am \ - $(srcdir)/Makefile.in $(srcdir)/lxc-checkconfig.in \ - $(srcdir)/lxc-clone.in $(srcdir)/lxc-create.in \ - $(srcdir)/lxc-destroy.in $(srcdir)/lxc-ls.in \ - $(srcdir)/lxc-netstat.in $(srcdir)/lxc-ps.in \ - $(srcdir)/lxc-setcap.in $(srcdir)/lxc-setuid.in \ - $(srcdir)/lxc-version.in +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(srcdir)/lxc-ps.in $(srcdir)/lxc-netstat.in \ + $(srcdir)/lxc-checkconfig.in $(srcdir)/lxc-version.in \ + $(srcdir)/lxc-start-ephemeral.in $(srcdir)/lxc.functions.in \ + $(top_srcdir)/config/depcomp $(am__pkginclude_HEADERS_DIST) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/config/acinclude.m4 \ - $(top_srcdir)/config/linux.m4 $(top_srcdir)/configure.ac + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/src/config.h -CONFIG_CLEAN_FILES = lxc-ps lxc-ls lxc-netstat lxc-checkconfig \ - lxc-setcap lxc-setuid lxc-version lxc-create lxc-clone \ - lxc-destroy +CONFIG_CLEAN_FILES = lxc-ps lxc-netstat lxc-checkconfig lxc-version \ + lxc-start-ephemeral lxc.functions CONFIG_CLEAN_VPATH_FILES = +@HAVE_NEWUIDMAP_TRUE@am__EXEEXT_1 = lxc-usernsexec$(EXEEXT) am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkglibexecdir)" \ "$(DESTDIR)$(sodir)" "$(DESTDIR)$(bindir)" \ "$(DESTDIR)$(pkgincludedir)" PROGRAMS = $(bin_PROGRAMS) $(pkglibexec_PROGRAMS) $(so_PROGRAMS) +am__liblxc_so_SOURCES_DIST = arguments.c arguments.h bdev.c bdev.h \ + commands.c commands.h start.c start.h execute.c monitor.c \ + monitor.h console.c freezer.c checkpoint.c restart.c error.h \ + error.c parse.c parse.h cgroup.c cgroup.h lxc.h utils.c \ + utils.h sync.c sync.h namespace.h namespace.c conf.c conf.h \ + confile.c confile.h list.h state.c state.h log.c log.h \ + attach.c attach.h network.c network.h nl.c nl.h rtnl.c rtnl.h \ + genl.c genl.h caps.c caps.h lxcseccomp.h mainloop.c mainloop.h \ + af_unix.c af_unix.h lxcutmp.c lxcutmp.h apparmor.c apparmor.h \ + lxclock.h lxclock.c lxccontainer.c lxccontainer.h version.c \ + version.h ../include/ifaddrs.c ../include/ifaddrs.h \ + ../include/openpty.c ../include/openpty.h \ + ../include/lxcmntent.c ../include/lxcmntent.h \ + ../include/getline.c ../include/getline.h seccomp.c +am__dirstamp = $(am__leading_dot)dirstamp +@IS_BIONIC_TRUE@am__objects_1 = \ +@IS_BIONIC_TRUE@ ../include/liblxc_so-ifaddrs.$(OBJEXT) \ +@IS_BIONIC_TRUE@ ../include/liblxc_so-openpty.$(OBJEXT) \ +@IS_BIONIC_TRUE@ ../include/liblxc_so-lxcmntent.$(OBJEXT) +@HAVE_FGETLN_TRUE@@HAVE_GETLINE_FALSE@am__objects_2 = ../include/liblxc_so-getline.$(OBJEXT) +@ENABLE_SECCOMP_TRUE@am__objects_3 = liblxc_so-seccomp.$(OBJEXT) am_liblxc_so_OBJECTS = liblxc_so-arguments.$(OBJEXT) \ - liblxc_so-commands.$(OBJEXT) liblxc_so-start.$(OBJEXT) \ - liblxc_so-stop.$(OBJEXT) liblxc_so-execute.$(OBJEXT) \ + liblxc_so-bdev.$(OBJEXT) liblxc_so-commands.$(OBJEXT) \ + liblxc_so-start.$(OBJEXT) liblxc_so-execute.$(OBJEXT) \ liblxc_so-monitor.$(OBJEXT) liblxc_so-console.$(OBJEXT) \ liblxc_so-freezer.$(OBJEXT) liblxc_so-checkpoint.$(OBJEXT) \ liblxc_so-restart.$(OBJEXT) liblxc_so-error.$(OBJEXT) \ @@ -82,10 +170,14 @@ liblxc_so-network.$(OBJEXT) liblxc_so-nl.$(OBJEXT) \ liblxc_so-rtnl.$(OBJEXT) liblxc_so-genl.$(OBJEXT) \ liblxc_so-caps.$(OBJEXT) liblxc_so-mainloop.$(OBJEXT) \ - liblxc_so-af_unix.$(OBJEXT) liblxc_so-utmp.$(OBJEXT) + liblxc_so-af_unix.$(OBJEXT) liblxc_so-lxcutmp.$(OBJEXT) \ + liblxc_so-apparmor.$(OBJEXT) liblxc_so-lxclock.$(OBJEXT) \ + liblxc_so-lxccontainer.$(OBJEXT) liblxc_so-version.$(OBJEXT) \ + $(am__objects_1) $(am__objects_2) $(am__objects_3) liblxc_so_OBJECTS = $(am_liblxc_so_OBJECTS) am__DEPENDENCIES_1 = -liblxc_so_DEPENDENCIES = $(am__DEPENDENCIES_1) +liblxc_so_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) liblxc_so_LINK = $(CCLD) $(liblxc_so_CFLAGS) $(CFLAGS) \ $(liblxc_so_LDFLAGS) $(LDFLAGS) -o $@ am_lxc_attach_OBJECTS = lxc_attach.$(OBJEXT) @@ -100,10 +192,26 @@ lxc_checkpoint_OBJECTS = $(am_lxc_checkpoint_OBJECTS) lxc_checkpoint_LDADD = $(LDADD) lxc_checkpoint_DEPENDENCIES = liblxc.so +am_lxc_clone_OBJECTS = lxc_clone.$(OBJEXT) +lxc_clone_OBJECTS = $(am_lxc_clone_OBJECTS) +lxc_clone_LDADD = $(LDADD) +lxc_clone_DEPENDENCIES = liblxc.so +am_lxc_config_OBJECTS = lxc_config.$(OBJEXT) +lxc_config_OBJECTS = $(am_lxc_config_OBJECTS) +lxc_config_LDADD = $(LDADD) +lxc_config_DEPENDENCIES = liblxc.so am_lxc_console_OBJECTS = lxc_console.$(OBJEXT) lxc_console_OBJECTS = $(am_lxc_console_OBJECTS) lxc_console_LDADD = $(LDADD) lxc_console_DEPENDENCIES = liblxc.so +am_lxc_create_OBJECTS = lxc_create.$(OBJEXT) +lxc_create_OBJECTS = $(am_lxc_create_OBJECTS) +lxc_create_LDADD = $(LDADD) +lxc_create_DEPENDENCIES = liblxc.so +am_lxc_destroy_OBJECTS = lxc_destroy.$(OBJEXT) +lxc_destroy_OBJECTS = $(am_lxc_destroy_OBJECTS) +lxc_destroy_LDADD = $(LDADD) +lxc_destroy_DEPENDENCIES = liblxc.so am_lxc_execute_OBJECTS = lxc_execute.$(OBJEXT) lxc_execute_OBJECTS = $(am_lxc_execute_OBJECTS) lxc_execute_LDADD = $(LDADD) @@ -128,6 +236,10 @@ lxc_monitor_OBJECTS = $(am_lxc_monitor_OBJECTS) lxc_monitor_LDADD = $(LDADD) lxc_monitor_DEPENDENCIES = liblxc.so +am_lxc_monitord_OBJECTS = lxc_monitord.$(OBJEXT) +lxc_monitord_OBJECTS = $(am_lxc_monitord_OBJECTS) +lxc_monitord_LDADD = $(LDADD) +lxc_monitord_DEPENDENCIES = liblxc.so am_lxc_restart_OBJECTS = lxc_restart.$(OBJEXT) lxc_restart_OBJECTS = $(am_lxc_restart_OBJECTS) lxc_restart_LDADD = $(LDADD) @@ -148,6 +260,14 @@ lxc_unshare_OBJECTS = $(am_lxc_unshare_OBJECTS) lxc_unshare_LDADD = $(LDADD) lxc_unshare_DEPENDENCIES = liblxc.so +am_lxc_user_nic_OBJECTS = lxc_user_nic.$(OBJEXT) +lxc_user_nic_OBJECTS = $(am_lxc_user_nic_OBJECTS) +lxc_user_nic_LDADD = $(LDADD) +lxc_user_nic_DEPENDENCIES = liblxc.so +am_lxc_usernsexec_OBJECTS = lxc_usernsexec.$(OBJEXT) +lxc_usernsexec_OBJECTS = $(am_lxc_usernsexec_OBJECTS) +lxc_usernsexec_LDADD = $(LDADD) +lxc_usernsexec_DEPENDENCIES = liblxc.so am_lxc_wait_OBJECTS = lxc_wait.$(OBJEXT) lxc_wait_OBJECTS = $(am_lxc_wait_OBJECTS) lxc_wait_LDADD = $(LDADD) @@ -173,37 +293,105 @@ am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } SCRIPTS = $(bin_SCRIPTS) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles am__mv = mv -f +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = SOURCES = $(liblxc_so_SOURCES) $(lxc_attach_SOURCES) \ $(lxc_cgroup_SOURCES) $(lxc_checkpoint_SOURCES) \ - $(lxc_console_SOURCES) $(lxc_execute_SOURCES) \ + $(lxc_clone_SOURCES) $(lxc_config_SOURCES) \ + $(lxc_console_SOURCES) $(lxc_create_SOURCES) \ + $(lxc_destroy_SOURCES) $(lxc_execute_SOURCES) \ $(lxc_freeze_SOURCES) $(lxc_info_SOURCES) $(lxc_init_SOURCES) \ $(lxc_kill_SOURCES) $(lxc_monitor_SOURCES) \ - $(lxc_restart_SOURCES) $(lxc_start_SOURCES) \ - $(lxc_stop_SOURCES) $(lxc_unfreeze_SOURCES) \ - $(lxc_unshare_SOURCES) $(lxc_wait_SOURCES) -DIST_SOURCES = $(liblxc_so_SOURCES) $(lxc_attach_SOURCES) \ + $(lxc_monitord_SOURCES) $(lxc_restart_SOURCES) \ + $(lxc_start_SOURCES) $(lxc_stop_SOURCES) \ + $(lxc_unfreeze_SOURCES) $(lxc_unshare_SOURCES) \ + $(lxc_user_nic_SOURCES) $(lxc_usernsexec_SOURCES) \ + $(lxc_wait_SOURCES) +DIST_SOURCES = $(am__liblxc_so_SOURCES_DIST) $(lxc_attach_SOURCES) \ $(lxc_cgroup_SOURCES) $(lxc_checkpoint_SOURCES) \ - $(lxc_console_SOURCES) $(lxc_execute_SOURCES) \ + $(lxc_clone_SOURCES) $(lxc_config_SOURCES) \ + $(lxc_console_SOURCES) $(lxc_create_SOURCES) \ + $(lxc_destroy_SOURCES) $(lxc_execute_SOURCES) \ $(lxc_freeze_SOURCES) $(lxc_info_SOURCES) $(lxc_init_SOURCES) \ $(lxc_kill_SOURCES) $(lxc_monitor_SOURCES) \ - $(lxc_restart_SOURCES) $(lxc_start_SOURCES) \ - $(lxc_stop_SOURCES) $(lxc_unfreeze_SOURCES) \ - $(lxc_unshare_SOURCES) $(lxc_wait_SOURCES) + $(lxc_monitord_SOURCES) $(lxc_restart_SOURCES) \ + $(lxc_start_SOURCES) $(lxc_stop_SOURCES) \ + $(lxc_unfreeze_SOURCES) $(lxc_unshare_SOURCES) \ + $(lxc_user_nic_SOURCES) $(lxc_usernsexec_SOURCES) \ + $(lxc_wait_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__pkginclude_HEADERS_DIST = arguments.h attach.h attach_options.h \ + bdev.h caps.h cgroup.h conf.h console.h error.h list.h log.h \ + lxccontainer.h lxc.h lxclock.h monitor.h namespace.h start.h \ + state.h utils.h version.h ../include/ifaddrs.h \ + ../include/openpty.h ../include/lxcmntent.h \ + ../include/getline.h HEADERS = $(pkginclude_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +APPARMOR_LIBS = @APPARMOR_LIBS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ @@ -234,19 +422,31 @@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBDIR = @LIBDIR@ +LIBEXECDIR = @LIBEXECDIR@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ -LINUX_DIR = @LINUX_DIR@ -LINUX_SRCARCH = @LINUX_SRCARCH@ LOCALSTATEDIR = @LOCALSTATEDIR@ +LOGPATH = @LOGPATH@ LTLIBOBJS = @LTLIBOBJS@ +LUA_CFLAGS = @LUA_CFLAGS@ +LUA_INSTALL_CMOD = @LUA_INSTALL_CMOD@ +LUA_INSTALL_LMOD = @LUA_INSTALL_LMOD@ +LUA_LIBS = @LUA_LIBS@ +LUA_VERSION = @LUA_VERSION@ +LXCHOOKDIR = @LXCHOOKDIR@ LXCINITDIR = @LXCINITDIR@ LXCPATH = @LXCPATH@ LXCROOTFSMOUNT = @LXCROOTFSMOUNT@ LXCTEMPLATEDIR = @LXCTEMPLATEDIR@ +LXC_DEFAULT_CONFIG = @LXC_DEFAULT_CONFIG@ +LXC_DISTRO_CONF = @LXC_DISTRO_CONF@ LXC_GENERATE_DATE = @LXC_GENERATE_DATE@ +LXC_GLOBAL_CONF = @LXC_GLOBAL_CONF@ +LXC_USERNIC_CONF = @LXC_USERNIC_CONF@ +LXC_USERNIC_DB = @LXC_USERNIC_DB@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +NEWUIDMAP = @NEWUIDMAP@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ @@ -256,8 +456,19 @@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PREFIX = @PREFIX@ -SETCAP = @SETCAP@ +PYTHON = @PYTHON@ +PYTHONDEV_CFLAGS = @PYTHONDEV_CFLAGS@ +PYTHONDEV_LIBS = @PYTHONDEV_LIBS@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +SECCOMP_LIBS = @SECCOMP_LIBS@ +SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ @@ -282,10 +493,11 @@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ +db2xman = @db2xman@ docdir = @docdir@ +docdtd = @docdtd@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ -have_docbook = @have_docbook@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ @@ -303,9 +515,13 @@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ @@ -314,101 +530,70 @@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -pkginclude_HEADERS = \ - arguments.h \ - start.h \ - console.h \ - error.h \ - monitor.h \ - utils.h \ - namespace.h \ - caps.h \ - lxc.h \ - cgroup.h \ - conf.h \ - list.h \ - log.h \ - state.h \ - attach.h - +pkginclude_HEADERS = arguments.h attach.h attach_options.h bdev.h \ + caps.h cgroup.h conf.h console.h error.h list.h log.h \ + lxccontainer.h lxc.h lxclock.h monitor.h namespace.h start.h \ + state.h utils.h version.h $(am__append_1) $(am__append_2) sodir = $(libdir) -liblxc_so_SOURCES = \ - arguments.c arguments.h \ - commands.c commands.h \ - start.c start.h \ - stop.c \ - execute.c \ - monitor.c monitor.h \ - console.c \ - freezer.c \ - checkpoint.c \ - restart.c \ - error.h error.c \ - parse.c parse.h \ - cgroup.c cgroup.h \ - lxc.h \ - utils.c utils.h \ - sync.c sync.h \ - namespace.h namespace.c \ - conf.c conf.h \ - confile.c confile.h \ - list.h \ - state.c state.h \ - log.c log.h \ - attach.c attach.h \ - \ - network.c network.h \ - nl.c nl.h \ - rtnl.c rtnl.h \ - genl.c genl.h \ - \ - caps.c caps.h \ - mainloop.c mainloop.h \ - af_unix.c af_unix.h \ - \ - utmp.c utmp.h - -AM_CFLAGS = -I$(top_srcdir)/src \ - -DLXCROOTFSMOUNT=\"$(LXCROOTFSMOUNT)\" \ +liblxc_so_SOURCES = arguments.c arguments.h bdev.c bdev.h commands.c \ + commands.h start.c start.h execute.c monitor.c monitor.h \ + console.c freezer.c checkpoint.c restart.c error.h error.c \ + parse.c parse.h cgroup.c cgroup.h lxc.h utils.c utils.h sync.c \ + sync.h namespace.h namespace.c conf.c conf.h confile.c \ + confile.h list.h state.c state.h log.c log.h attach.c attach.h \ + network.c network.h nl.c nl.h rtnl.c rtnl.h genl.c genl.h \ + caps.c caps.h lxcseccomp.h mainloop.c mainloop.h af_unix.c \ + af_unix.h lxcutmp.c lxcutmp.h apparmor.c apparmor.h lxclock.h \ + lxclock.c lxccontainer.c lxccontainer.h version.c version.h \ + $(am__append_3) $(am__append_4) $(am__append_9) +AM_CFLAGS = -I$(top_srcdir)/src -DLXCROOTFSMOUNT=\"$(LXCROOTFSMOUNT)\" \ -DLXCPATH=\"$(LXCPATH)\" \ - -DLXCINITDIR=\"$(LXCINITDIR)\" - + -DLXC_GLOBAL_CONF=\"$(LXC_GLOBAL_CONF)\" \ + -DLXCINITDIR=\"$(LXCINITDIR)\" \ + -DLXCTEMPLATEDIR=\"$(LXCTEMPLATEDIR)\" \ + -DLOGPATH=\"$(LOGPATH)\" \ + -DLXC_DEFAULT_CONFIG=\"$(LXC_DEFAULT_CONFIG)\" \ + -DLXC_USERNIC_DB=\"$(LXC_USERNIC_DB)\" \ + -DLXC_USERNIC_CONF=\"$(LXC_USERNIC_CONF)\" $(am__append_5) \ + $(am__append_6) $(am__append_7) $(am__append_8) liblxc_so_CFLAGS = -fPIC -DPIC $(AM_CFLAGS) liblxc_so_LDFLAGS = \ -shared \ -Wl,-soname,liblxc.so.$(firstword $(subst ., ,$(VERSION))) -liblxc_so_LDADD = -lutil $(CAP_LIBS) -bin_SCRIPTS = \ - lxc-ps \ - lxc-netstat \ +liblxc_so_LDADD = $(CAP_LIBS) $(APPARMOR_LIBS) $(SECCOMP_LIBS) +bin_SCRIPTS = lxc-ps lxc-netstat lxc-checkconfig lxc-version \ + $(am__append_10) $(am__append_11) $(am__append_12) +EXTRA_DIST = \ + lxc-device \ lxc-ls \ - lxc-checkconfig \ - lxc-setcap \ - lxc-setuid \ - lxc-version \ - lxc-create \ - lxc-clone \ - lxc-destroy + lxc-top -AM_LDFLAGS = -Wl,-E $(am__append_1) -LDADD = liblxc.so @CAP_LIBS@ +AM_LDFLAGS = -Wl,-E $(am__append_14) +LDADD = liblxc.so @CAP_LIBS@ @APPARMOR_LIBS@ @SECCOMP_LIBS@ lxc_attach_SOURCES = lxc_attach.c lxc_cgroup_SOURCES = lxc_cgroup.c lxc_checkpoint_SOURCES = lxc_checkpoint.c +lxc_config_SOURCES = lxc_config.c lxc_console_SOURCES = lxc_console.c +lxc_destroy_SOURCES = lxc_destroy.c lxc_execute_SOURCES = lxc_execute.c lxc_freeze_SOURCES = lxc_freeze.c lxc_info_SOURCES = lxc_info.c lxc_init_SOURCES = lxc_init.c lxc_monitor_SOURCES = lxc_monitor.c +lxc_monitord_SOURCES = lxc_monitord.c lxc_restart_SOURCES = lxc_restart.c +lxc_clone_SOURCES = lxc_clone.c lxc_start_SOURCES = lxc_start.c lxc_stop_SOURCES = lxc_stop.c lxc_unfreeze_SOURCES = lxc_unfreeze.c lxc_unshare_SOURCES = lxc_unshare.c lxc_wait_SOURCES = lxc_wait.c lxc_kill_SOURCES = lxc_kill.c +lxc_create_SOURCES = lxc_create.c +lxc_usernsexec_SOURCES = lxc_usernsexec.c +lxc_user_nic_SOURCES = lxc_user_nic.c all: all-am .SUFFIXES: @@ -445,34 +630,30 @@ $(am__aclocal_m4_deps): lxc-ps: $(top_builddir)/config.status $(srcdir)/lxc-ps.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ -lxc-ls: $(top_builddir)/config.status $(srcdir)/lxc-ls.in - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ lxc-netstat: $(top_builddir)/config.status $(srcdir)/lxc-netstat.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ lxc-checkconfig: $(top_builddir)/config.status $(srcdir)/lxc-checkconfig.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ -lxc-setcap: $(top_builddir)/config.status $(srcdir)/lxc-setcap.in - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ -lxc-setuid: $(top_builddir)/config.status $(srcdir)/lxc-setuid.in - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ lxc-version: $(top_builddir)/config.status $(srcdir)/lxc-version.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ -lxc-create: $(top_builddir)/config.status $(srcdir)/lxc-create.in - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ -lxc-clone: $(top_builddir)/config.status $(srcdir)/lxc-clone.in +lxc-start-ephemeral: $(top_builddir)/config.status $(srcdir)/lxc-start-ephemeral.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ -lxc-destroy: $(top_builddir)/config.status $(srcdir)/lxc-destroy.in +lxc.functions: $(top_builddir)/config.status $(srcdir)/lxc.functions.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) - test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ - while read p p1; do if test -f $$p; \ - then echo "$$p"; echo "$$p"; else :; fi; \ + while read p p1; do if test -f $$p \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ - sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ @@ -493,7 +674,8 @@ @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ - -e 's/$$/$(EXEEXT)/' `; \ + -e 's/$$/$(EXEEXT)/' \ + `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files @@ -502,14 +684,18 @@ -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) install-pkglibexecPROGRAMS: $(pkglibexec_PROGRAMS) @$(NORMAL_INSTALL) - test -z "$(pkglibexecdir)" || $(MKDIR_P) "$(DESTDIR)$(pkglibexecdir)" @list='$(pkglibexec_PROGRAMS)'; test -n "$(pkglibexecdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkglibexecdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkglibexecdir)" || exit 1; \ + fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ - while read p p1; do if test -f $$p; \ - then echo "$$p"; echo "$$p"; else :; fi; \ + while read p p1; do if test -f $$p \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ - sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ @@ -530,7 +716,8 @@ @list='$(pkglibexec_PROGRAMS)'; test -n "$(pkglibexecdir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ - -e 's/$$/$(EXEEXT)/' `; \ + -e 's/$$/$(EXEEXT)/' \ + `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(pkglibexecdir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(pkglibexecdir)" && rm -f $$files @@ -539,14 +726,18 @@ -test -z "$(pkglibexec_PROGRAMS)" || rm -f $(pkglibexec_PROGRAMS) install-soPROGRAMS: $(so_PROGRAMS) @$(NORMAL_INSTALL) - test -z "$(sodir)" || $(MKDIR_P) "$(DESTDIR)$(sodir)" @list='$(so_PROGRAMS)'; test -n "$(sodir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(sodir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(sodir)" || exit 1; \ + fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ - while read p p1; do if test -f $$p; \ - then echo "$$p"; echo "$$p"; else :; fi; \ + while read p p1; do if test -f $$p \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ - sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ @@ -567,68 +758,131 @@ @list='$(so_PROGRAMS)'; test -n "$(sodir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ - -e 's/$$/$(EXEEXT)/' `; \ + -e 's/$$/$(EXEEXT)/' \ + `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(sodir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(sodir)" && rm -f $$files clean-soPROGRAMS: -test -z "$(so_PROGRAMS)" || rm -f $(so_PROGRAMS) -liblxc.so$(EXEEXT): $(liblxc_so_OBJECTS) $(liblxc_so_DEPENDENCIES) +../include/$(am__dirstamp): + @$(MKDIR_P) ../include + @: > ../include/$(am__dirstamp) +../include/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) ../include/$(DEPDIR) + @: > ../include/$(DEPDIR)/$(am__dirstamp) +../include/liblxc_so-ifaddrs.$(OBJEXT): ../include/$(am__dirstamp) \ + ../include/$(DEPDIR)/$(am__dirstamp) +../include/liblxc_so-openpty.$(OBJEXT): ../include/$(am__dirstamp) \ + ../include/$(DEPDIR)/$(am__dirstamp) +../include/liblxc_so-lxcmntent.$(OBJEXT): ../include/$(am__dirstamp) \ + ../include/$(DEPDIR)/$(am__dirstamp) +../include/liblxc_so-getline.$(OBJEXT): ../include/$(am__dirstamp) \ + ../include/$(DEPDIR)/$(am__dirstamp) + +liblxc.so$(EXEEXT): $(liblxc_so_OBJECTS) $(liblxc_so_DEPENDENCIES) $(EXTRA_liblxc_so_DEPENDENCIES) @rm -f liblxc.so$(EXEEXT) - $(liblxc_so_LINK) $(liblxc_so_OBJECTS) $(liblxc_so_LDADD) $(LIBS) -lxc-attach$(EXEEXT): $(lxc_attach_OBJECTS) $(lxc_attach_DEPENDENCIES) + $(AM_V_CCLD)$(liblxc_so_LINK) $(liblxc_so_OBJECTS) $(liblxc_so_LDADD) $(LIBS) + +lxc-attach$(EXEEXT): $(lxc_attach_OBJECTS) $(lxc_attach_DEPENDENCIES) $(EXTRA_lxc_attach_DEPENDENCIES) @rm -f lxc-attach$(EXEEXT) - $(LINK) $(lxc_attach_OBJECTS) $(lxc_attach_LDADD) $(LIBS) -lxc-cgroup$(EXEEXT): $(lxc_cgroup_OBJECTS) $(lxc_cgroup_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) $(lxc_attach_OBJECTS) $(lxc_attach_LDADD) $(LIBS) + +lxc-cgroup$(EXEEXT): $(lxc_cgroup_OBJECTS) $(lxc_cgroup_DEPENDENCIES) $(EXTRA_lxc_cgroup_DEPENDENCIES) @rm -f lxc-cgroup$(EXEEXT) - $(LINK) $(lxc_cgroup_OBJECTS) $(lxc_cgroup_LDADD) $(LIBS) -lxc-checkpoint$(EXEEXT): $(lxc_checkpoint_OBJECTS) $(lxc_checkpoint_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) $(lxc_cgroup_OBJECTS) $(lxc_cgroup_LDADD) $(LIBS) + +lxc-checkpoint$(EXEEXT): $(lxc_checkpoint_OBJECTS) $(lxc_checkpoint_DEPENDENCIES) $(EXTRA_lxc_checkpoint_DEPENDENCIES) @rm -f lxc-checkpoint$(EXEEXT) - $(LINK) $(lxc_checkpoint_OBJECTS) $(lxc_checkpoint_LDADD) $(LIBS) -lxc-console$(EXEEXT): $(lxc_console_OBJECTS) $(lxc_console_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) $(lxc_checkpoint_OBJECTS) $(lxc_checkpoint_LDADD) $(LIBS) + +lxc-clone$(EXEEXT): $(lxc_clone_OBJECTS) $(lxc_clone_DEPENDENCIES) $(EXTRA_lxc_clone_DEPENDENCIES) + @rm -f lxc-clone$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(lxc_clone_OBJECTS) $(lxc_clone_LDADD) $(LIBS) + +lxc-config$(EXEEXT): $(lxc_config_OBJECTS) $(lxc_config_DEPENDENCIES) $(EXTRA_lxc_config_DEPENDENCIES) + @rm -f lxc-config$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(lxc_config_OBJECTS) $(lxc_config_LDADD) $(LIBS) + +lxc-console$(EXEEXT): $(lxc_console_OBJECTS) $(lxc_console_DEPENDENCIES) $(EXTRA_lxc_console_DEPENDENCIES) @rm -f lxc-console$(EXEEXT) - $(LINK) $(lxc_console_OBJECTS) $(lxc_console_LDADD) $(LIBS) -lxc-execute$(EXEEXT): $(lxc_execute_OBJECTS) $(lxc_execute_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) $(lxc_console_OBJECTS) $(lxc_console_LDADD) $(LIBS) + +lxc-create$(EXEEXT): $(lxc_create_OBJECTS) $(lxc_create_DEPENDENCIES) $(EXTRA_lxc_create_DEPENDENCIES) + @rm -f lxc-create$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(lxc_create_OBJECTS) $(lxc_create_LDADD) $(LIBS) + +lxc-destroy$(EXEEXT): $(lxc_destroy_OBJECTS) $(lxc_destroy_DEPENDENCIES) $(EXTRA_lxc_destroy_DEPENDENCIES) + @rm -f lxc-destroy$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(lxc_destroy_OBJECTS) $(lxc_destroy_LDADD) $(LIBS) + +lxc-execute$(EXEEXT): $(lxc_execute_OBJECTS) $(lxc_execute_DEPENDENCIES) $(EXTRA_lxc_execute_DEPENDENCIES) @rm -f lxc-execute$(EXEEXT) - $(LINK) $(lxc_execute_OBJECTS) $(lxc_execute_LDADD) $(LIBS) -lxc-freeze$(EXEEXT): $(lxc_freeze_OBJECTS) $(lxc_freeze_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) $(lxc_execute_OBJECTS) $(lxc_execute_LDADD) $(LIBS) + +lxc-freeze$(EXEEXT): $(lxc_freeze_OBJECTS) $(lxc_freeze_DEPENDENCIES) $(EXTRA_lxc_freeze_DEPENDENCIES) @rm -f lxc-freeze$(EXEEXT) - $(LINK) $(lxc_freeze_OBJECTS) $(lxc_freeze_LDADD) $(LIBS) -lxc-info$(EXEEXT): $(lxc_info_OBJECTS) $(lxc_info_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) $(lxc_freeze_OBJECTS) $(lxc_freeze_LDADD) $(LIBS) + +lxc-info$(EXEEXT): $(lxc_info_OBJECTS) $(lxc_info_DEPENDENCIES) $(EXTRA_lxc_info_DEPENDENCIES) @rm -f lxc-info$(EXEEXT) - $(LINK) $(lxc_info_OBJECTS) $(lxc_info_LDADD) $(LIBS) -lxc-init$(EXEEXT): $(lxc_init_OBJECTS) $(lxc_init_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) $(lxc_info_OBJECTS) $(lxc_info_LDADD) $(LIBS) + +lxc-init$(EXEEXT): $(lxc_init_OBJECTS) $(lxc_init_DEPENDENCIES) $(EXTRA_lxc_init_DEPENDENCIES) @rm -f lxc-init$(EXEEXT) - $(LINK) $(lxc_init_OBJECTS) $(lxc_init_LDADD) $(LIBS) -lxc-kill$(EXEEXT): $(lxc_kill_OBJECTS) $(lxc_kill_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) $(lxc_init_OBJECTS) $(lxc_init_LDADD) $(LIBS) + +lxc-kill$(EXEEXT): $(lxc_kill_OBJECTS) $(lxc_kill_DEPENDENCIES) $(EXTRA_lxc_kill_DEPENDENCIES) @rm -f lxc-kill$(EXEEXT) - $(LINK) $(lxc_kill_OBJECTS) $(lxc_kill_LDADD) $(LIBS) -lxc-monitor$(EXEEXT): $(lxc_monitor_OBJECTS) $(lxc_monitor_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) $(lxc_kill_OBJECTS) $(lxc_kill_LDADD) $(LIBS) + +lxc-monitor$(EXEEXT): $(lxc_monitor_OBJECTS) $(lxc_monitor_DEPENDENCIES) $(EXTRA_lxc_monitor_DEPENDENCIES) @rm -f lxc-monitor$(EXEEXT) - $(LINK) $(lxc_monitor_OBJECTS) $(lxc_monitor_LDADD) $(LIBS) -lxc-restart$(EXEEXT): $(lxc_restart_OBJECTS) $(lxc_restart_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) $(lxc_monitor_OBJECTS) $(lxc_monitor_LDADD) $(LIBS) + +lxc-monitord$(EXEEXT): $(lxc_monitord_OBJECTS) $(lxc_monitord_DEPENDENCIES) $(EXTRA_lxc_monitord_DEPENDENCIES) + @rm -f lxc-monitord$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(lxc_monitord_OBJECTS) $(lxc_monitord_LDADD) $(LIBS) + +lxc-restart$(EXEEXT): $(lxc_restart_OBJECTS) $(lxc_restart_DEPENDENCIES) $(EXTRA_lxc_restart_DEPENDENCIES) @rm -f lxc-restart$(EXEEXT) - $(LINK) $(lxc_restart_OBJECTS) $(lxc_restart_LDADD) $(LIBS) -lxc-start$(EXEEXT): $(lxc_start_OBJECTS) $(lxc_start_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) $(lxc_restart_OBJECTS) $(lxc_restart_LDADD) $(LIBS) + +lxc-start$(EXEEXT): $(lxc_start_OBJECTS) $(lxc_start_DEPENDENCIES) $(EXTRA_lxc_start_DEPENDENCIES) @rm -f lxc-start$(EXEEXT) - $(LINK) $(lxc_start_OBJECTS) $(lxc_start_LDADD) $(LIBS) -lxc-stop$(EXEEXT): $(lxc_stop_OBJECTS) $(lxc_stop_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) $(lxc_start_OBJECTS) $(lxc_start_LDADD) $(LIBS) + +lxc-stop$(EXEEXT): $(lxc_stop_OBJECTS) $(lxc_stop_DEPENDENCIES) $(EXTRA_lxc_stop_DEPENDENCIES) @rm -f lxc-stop$(EXEEXT) - $(LINK) $(lxc_stop_OBJECTS) $(lxc_stop_LDADD) $(LIBS) -lxc-unfreeze$(EXEEXT): $(lxc_unfreeze_OBJECTS) $(lxc_unfreeze_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) $(lxc_stop_OBJECTS) $(lxc_stop_LDADD) $(LIBS) + +lxc-unfreeze$(EXEEXT): $(lxc_unfreeze_OBJECTS) $(lxc_unfreeze_DEPENDENCIES) $(EXTRA_lxc_unfreeze_DEPENDENCIES) @rm -f lxc-unfreeze$(EXEEXT) - $(LINK) $(lxc_unfreeze_OBJECTS) $(lxc_unfreeze_LDADD) $(LIBS) -lxc-unshare$(EXEEXT): $(lxc_unshare_OBJECTS) $(lxc_unshare_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) $(lxc_unfreeze_OBJECTS) $(lxc_unfreeze_LDADD) $(LIBS) + +lxc-unshare$(EXEEXT): $(lxc_unshare_OBJECTS) $(lxc_unshare_DEPENDENCIES) $(EXTRA_lxc_unshare_DEPENDENCIES) @rm -f lxc-unshare$(EXEEXT) - $(LINK) $(lxc_unshare_OBJECTS) $(lxc_unshare_LDADD) $(LIBS) -lxc-wait$(EXEEXT): $(lxc_wait_OBJECTS) $(lxc_wait_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) $(lxc_unshare_OBJECTS) $(lxc_unshare_LDADD) $(LIBS) + +lxc-user-nic$(EXEEXT): $(lxc_user_nic_OBJECTS) $(lxc_user_nic_DEPENDENCIES) $(EXTRA_lxc_user_nic_DEPENDENCIES) + @rm -f lxc-user-nic$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(lxc_user_nic_OBJECTS) $(lxc_user_nic_LDADD) $(LIBS) + +lxc-usernsexec$(EXEEXT): $(lxc_usernsexec_OBJECTS) $(lxc_usernsexec_DEPENDENCIES) $(EXTRA_lxc_usernsexec_DEPENDENCIES) + @rm -f lxc-usernsexec$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(lxc_usernsexec_OBJECTS) $(lxc_usernsexec_LDADD) $(LIBS) + +lxc-wait$(EXEEXT): $(lxc_wait_OBJECTS) $(lxc_wait_DEPENDENCIES) $(EXTRA_lxc_wait_DEPENDENCIES) @rm -f lxc-wait$(EXEEXT) - $(LINK) $(lxc_wait_OBJECTS) $(lxc_wait_LDADD) $(LIBS) + $(AM_V_CCLD)$(LINK) $(lxc_wait_OBJECTS) $(lxc_wait_LDADD) $(LIBS) install-binSCRIPTS: $(bin_SCRIPTS) @$(NORMAL_INSTALL) - test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ @@ -656,19 +910,24 @@ @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 's,.*/,,;$(transform)'`; \ - test -n "$$list" || exit 0; \ - echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(bindir)" && rm -f $$files + dir='$(DESTDIR)$(bindir)'; $(am__uninstall_files_from_dir) mostlyclean-compile: -rm -f *.$(OBJEXT) + -rm -f ../include/*.$(OBJEXT) distclean-compile: -rm -f *.tab.c +@AMDEP_TRUE@@am__include@ @am__quote@../include/$(DEPDIR)/liblxc_so-getline.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@../include/$(DEPDIR)/liblxc_so-ifaddrs.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@../include/$(DEPDIR)/liblxc_so-lxcmntent.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@../include/$(DEPDIR)/liblxc_so-openpty.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblxc_so-af_unix.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblxc_so-apparmor.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblxc_so-arguments.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblxc_so-attach.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblxc_so-bdev.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblxc_so-caps.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblxc_so-cgroup.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblxc_so-checkpoint.Po@am__quote@ @@ -681,6 +940,9 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblxc_so-freezer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblxc_so-genl.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblxc_so-log.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblxc_so-lxccontainer.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblxc_so-lxclock.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblxc_so-lxcutmp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblxc_so-mainloop.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblxc_so-monitor.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblxc_so-namespace.Po@am__quote@ @@ -689,452 +951,590 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblxc_so-parse.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblxc_so-restart.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblxc_so-rtnl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblxc_so-seccomp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblxc_so-start.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblxc_so-state.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblxc_so-stop.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblxc_so-sync.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblxc_so-utils.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblxc_so-utmp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblxc_so-version.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxc_attach.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxc_cgroup.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxc_checkpoint.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxc_clone.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxc_config.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxc_console.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxc_create.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxc_destroy.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxc_execute.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxc_freeze.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxc_info.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxc_init.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxc_kill.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxc_monitor.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxc_monitord.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxc_restart.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxc_start.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxc_stop.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxc_unfreeze.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxc_unshare.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxc_user_nic.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxc_usernsexec.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxc_wait.Po@am__quote@ .c.o: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` liblxc_so-arguments.o: arguments.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-arguments.o -MD -MP -MF $(DEPDIR)/liblxc_so-arguments.Tpo -c -o liblxc_so-arguments.o `test -f 'arguments.c' || echo '$(srcdir)/'`arguments.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-arguments.Tpo $(DEPDIR)/liblxc_so-arguments.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='arguments.c' object='liblxc_so-arguments.o' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-arguments.o -MD -MP -MF $(DEPDIR)/liblxc_so-arguments.Tpo -c -o liblxc_so-arguments.o `test -f 'arguments.c' || echo '$(srcdir)/'`arguments.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-arguments.Tpo $(DEPDIR)/liblxc_so-arguments.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='arguments.c' object='liblxc_so-arguments.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-arguments.o `test -f 'arguments.c' || echo '$(srcdir)/'`arguments.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-arguments.o `test -f 'arguments.c' || echo '$(srcdir)/'`arguments.c liblxc_so-arguments.obj: arguments.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-arguments.obj -MD -MP -MF $(DEPDIR)/liblxc_so-arguments.Tpo -c -o liblxc_so-arguments.obj `if test -f 'arguments.c'; then $(CYGPATH_W) 'arguments.c'; else $(CYGPATH_W) '$(srcdir)/arguments.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-arguments.Tpo $(DEPDIR)/liblxc_so-arguments.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='arguments.c' object='liblxc_so-arguments.obj' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-arguments.obj -MD -MP -MF $(DEPDIR)/liblxc_so-arguments.Tpo -c -o liblxc_so-arguments.obj `if test -f 'arguments.c'; then $(CYGPATH_W) 'arguments.c'; else $(CYGPATH_W) '$(srcdir)/arguments.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-arguments.Tpo $(DEPDIR)/liblxc_so-arguments.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='arguments.c' object='liblxc_so-arguments.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-arguments.obj `if test -f 'arguments.c'; then $(CYGPATH_W) 'arguments.c'; else $(CYGPATH_W) '$(srcdir)/arguments.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-arguments.obj `if test -f 'arguments.c'; then $(CYGPATH_W) 'arguments.c'; else $(CYGPATH_W) '$(srcdir)/arguments.c'; fi` -liblxc_so-commands.o: commands.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-commands.o -MD -MP -MF $(DEPDIR)/liblxc_so-commands.Tpo -c -o liblxc_so-commands.o `test -f 'commands.c' || echo '$(srcdir)/'`commands.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-commands.Tpo $(DEPDIR)/liblxc_so-commands.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='commands.c' object='liblxc_so-commands.o' libtool=no @AMDEPBACKSLASH@ +liblxc_so-bdev.o: bdev.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-bdev.o -MD -MP -MF $(DEPDIR)/liblxc_so-bdev.Tpo -c -o liblxc_so-bdev.o `test -f 'bdev.c' || echo '$(srcdir)/'`bdev.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-bdev.Tpo $(DEPDIR)/liblxc_so-bdev.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='bdev.c' object='liblxc_so-bdev.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-commands.o `test -f 'commands.c' || echo '$(srcdir)/'`commands.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-bdev.o `test -f 'bdev.c' || echo '$(srcdir)/'`bdev.c -liblxc_so-commands.obj: commands.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-commands.obj -MD -MP -MF $(DEPDIR)/liblxc_so-commands.Tpo -c -o liblxc_so-commands.obj `if test -f 'commands.c'; then $(CYGPATH_W) 'commands.c'; else $(CYGPATH_W) '$(srcdir)/commands.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-commands.Tpo $(DEPDIR)/liblxc_so-commands.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='commands.c' object='liblxc_so-commands.obj' libtool=no @AMDEPBACKSLASH@ +liblxc_so-bdev.obj: bdev.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-bdev.obj -MD -MP -MF $(DEPDIR)/liblxc_so-bdev.Tpo -c -o liblxc_so-bdev.obj `if test -f 'bdev.c'; then $(CYGPATH_W) 'bdev.c'; else $(CYGPATH_W) '$(srcdir)/bdev.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-bdev.Tpo $(DEPDIR)/liblxc_so-bdev.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='bdev.c' object='liblxc_so-bdev.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-commands.obj `if test -f 'commands.c'; then $(CYGPATH_W) 'commands.c'; else $(CYGPATH_W) '$(srcdir)/commands.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-bdev.obj `if test -f 'bdev.c'; then $(CYGPATH_W) 'bdev.c'; else $(CYGPATH_W) '$(srcdir)/bdev.c'; fi` -liblxc_so-start.o: start.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-start.o -MD -MP -MF $(DEPDIR)/liblxc_so-start.Tpo -c -o liblxc_so-start.o `test -f 'start.c' || echo '$(srcdir)/'`start.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-start.Tpo $(DEPDIR)/liblxc_so-start.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='start.c' object='liblxc_so-start.o' libtool=no @AMDEPBACKSLASH@ +liblxc_so-commands.o: commands.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-commands.o -MD -MP -MF $(DEPDIR)/liblxc_so-commands.Tpo -c -o liblxc_so-commands.o `test -f 'commands.c' || echo '$(srcdir)/'`commands.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-commands.Tpo $(DEPDIR)/liblxc_so-commands.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='commands.c' object='liblxc_so-commands.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-start.o `test -f 'start.c' || echo '$(srcdir)/'`start.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-commands.o `test -f 'commands.c' || echo '$(srcdir)/'`commands.c -liblxc_so-start.obj: start.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-start.obj -MD -MP -MF $(DEPDIR)/liblxc_so-start.Tpo -c -o liblxc_so-start.obj `if test -f 'start.c'; then $(CYGPATH_W) 'start.c'; else $(CYGPATH_W) '$(srcdir)/start.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-start.Tpo $(DEPDIR)/liblxc_so-start.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='start.c' object='liblxc_so-start.obj' libtool=no @AMDEPBACKSLASH@ +liblxc_so-commands.obj: commands.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-commands.obj -MD -MP -MF $(DEPDIR)/liblxc_so-commands.Tpo -c -o liblxc_so-commands.obj `if test -f 'commands.c'; then $(CYGPATH_W) 'commands.c'; else $(CYGPATH_W) '$(srcdir)/commands.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-commands.Tpo $(DEPDIR)/liblxc_so-commands.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='commands.c' object='liblxc_so-commands.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-start.obj `if test -f 'start.c'; then $(CYGPATH_W) 'start.c'; else $(CYGPATH_W) '$(srcdir)/start.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-commands.obj `if test -f 'commands.c'; then $(CYGPATH_W) 'commands.c'; else $(CYGPATH_W) '$(srcdir)/commands.c'; fi` -liblxc_so-stop.o: stop.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-stop.o -MD -MP -MF $(DEPDIR)/liblxc_so-stop.Tpo -c -o liblxc_so-stop.o `test -f 'stop.c' || echo '$(srcdir)/'`stop.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-stop.Tpo $(DEPDIR)/liblxc_so-stop.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='stop.c' object='liblxc_so-stop.o' libtool=no @AMDEPBACKSLASH@ +liblxc_so-start.o: start.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-start.o -MD -MP -MF $(DEPDIR)/liblxc_so-start.Tpo -c -o liblxc_so-start.o `test -f 'start.c' || echo '$(srcdir)/'`start.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-start.Tpo $(DEPDIR)/liblxc_so-start.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='start.c' object='liblxc_so-start.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-stop.o `test -f 'stop.c' || echo '$(srcdir)/'`stop.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-start.o `test -f 'start.c' || echo '$(srcdir)/'`start.c -liblxc_so-stop.obj: stop.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-stop.obj -MD -MP -MF $(DEPDIR)/liblxc_so-stop.Tpo -c -o liblxc_so-stop.obj `if test -f 'stop.c'; then $(CYGPATH_W) 'stop.c'; else $(CYGPATH_W) '$(srcdir)/stop.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-stop.Tpo $(DEPDIR)/liblxc_so-stop.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='stop.c' object='liblxc_so-stop.obj' libtool=no @AMDEPBACKSLASH@ +liblxc_so-start.obj: start.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-start.obj -MD -MP -MF $(DEPDIR)/liblxc_so-start.Tpo -c -o liblxc_so-start.obj `if test -f 'start.c'; then $(CYGPATH_W) 'start.c'; else $(CYGPATH_W) '$(srcdir)/start.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-start.Tpo $(DEPDIR)/liblxc_so-start.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='start.c' object='liblxc_so-start.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-stop.obj `if test -f 'stop.c'; then $(CYGPATH_W) 'stop.c'; else $(CYGPATH_W) '$(srcdir)/stop.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-start.obj `if test -f 'start.c'; then $(CYGPATH_W) 'start.c'; else $(CYGPATH_W) '$(srcdir)/start.c'; fi` liblxc_so-execute.o: execute.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-execute.o -MD -MP -MF $(DEPDIR)/liblxc_so-execute.Tpo -c -o liblxc_so-execute.o `test -f 'execute.c' || echo '$(srcdir)/'`execute.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-execute.Tpo $(DEPDIR)/liblxc_so-execute.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='execute.c' object='liblxc_so-execute.o' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-execute.o -MD -MP -MF $(DEPDIR)/liblxc_so-execute.Tpo -c -o liblxc_so-execute.o `test -f 'execute.c' || echo '$(srcdir)/'`execute.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-execute.Tpo $(DEPDIR)/liblxc_so-execute.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='execute.c' object='liblxc_so-execute.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-execute.o `test -f 'execute.c' || echo '$(srcdir)/'`execute.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-execute.o `test -f 'execute.c' || echo '$(srcdir)/'`execute.c liblxc_so-execute.obj: execute.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-execute.obj -MD -MP -MF $(DEPDIR)/liblxc_so-execute.Tpo -c -o liblxc_so-execute.obj `if test -f 'execute.c'; then $(CYGPATH_W) 'execute.c'; else $(CYGPATH_W) '$(srcdir)/execute.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-execute.Tpo $(DEPDIR)/liblxc_so-execute.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='execute.c' object='liblxc_so-execute.obj' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-execute.obj -MD -MP -MF $(DEPDIR)/liblxc_so-execute.Tpo -c -o liblxc_so-execute.obj `if test -f 'execute.c'; then $(CYGPATH_W) 'execute.c'; else $(CYGPATH_W) '$(srcdir)/execute.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-execute.Tpo $(DEPDIR)/liblxc_so-execute.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='execute.c' object='liblxc_so-execute.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-execute.obj `if test -f 'execute.c'; then $(CYGPATH_W) 'execute.c'; else $(CYGPATH_W) '$(srcdir)/execute.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-execute.obj `if test -f 'execute.c'; then $(CYGPATH_W) 'execute.c'; else $(CYGPATH_W) '$(srcdir)/execute.c'; fi` liblxc_so-monitor.o: monitor.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-monitor.o -MD -MP -MF $(DEPDIR)/liblxc_so-monitor.Tpo -c -o liblxc_so-monitor.o `test -f 'monitor.c' || echo '$(srcdir)/'`monitor.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-monitor.Tpo $(DEPDIR)/liblxc_so-monitor.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='monitor.c' object='liblxc_so-monitor.o' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-monitor.o -MD -MP -MF $(DEPDIR)/liblxc_so-monitor.Tpo -c -o liblxc_so-monitor.o `test -f 'monitor.c' || echo '$(srcdir)/'`monitor.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-monitor.Tpo $(DEPDIR)/liblxc_so-monitor.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='monitor.c' object='liblxc_so-monitor.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-monitor.o `test -f 'monitor.c' || echo '$(srcdir)/'`monitor.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-monitor.o `test -f 'monitor.c' || echo '$(srcdir)/'`monitor.c liblxc_so-monitor.obj: monitor.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-monitor.obj -MD -MP -MF $(DEPDIR)/liblxc_so-monitor.Tpo -c -o liblxc_so-monitor.obj `if test -f 'monitor.c'; then $(CYGPATH_W) 'monitor.c'; else $(CYGPATH_W) '$(srcdir)/monitor.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-monitor.Tpo $(DEPDIR)/liblxc_so-monitor.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='monitor.c' object='liblxc_so-monitor.obj' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-monitor.obj -MD -MP -MF $(DEPDIR)/liblxc_so-monitor.Tpo -c -o liblxc_so-monitor.obj `if test -f 'monitor.c'; then $(CYGPATH_W) 'monitor.c'; else $(CYGPATH_W) '$(srcdir)/monitor.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-monitor.Tpo $(DEPDIR)/liblxc_so-monitor.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='monitor.c' object='liblxc_so-monitor.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-monitor.obj `if test -f 'monitor.c'; then $(CYGPATH_W) 'monitor.c'; else $(CYGPATH_W) '$(srcdir)/monitor.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-monitor.obj `if test -f 'monitor.c'; then $(CYGPATH_W) 'monitor.c'; else $(CYGPATH_W) '$(srcdir)/monitor.c'; fi` liblxc_so-console.o: console.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-console.o -MD -MP -MF $(DEPDIR)/liblxc_so-console.Tpo -c -o liblxc_so-console.o `test -f 'console.c' || echo '$(srcdir)/'`console.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-console.Tpo $(DEPDIR)/liblxc_so-console.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='console.c' object='liblxc_so-console.o' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-console.o -MD -MP -MF $(DEPDIR)/liblxc_so-console.Tpo -c -o liblxc_so-console.o `test -f 'console.c' || echo '$(srcdir)/'`console.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-console.Tpo $(DEPDIR)/liblxc_so-console.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='console.c' object='liblxc_so-console.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-console.o `test -f 'console.c' || echo '$(srcdir)/'`console.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-console.o `test -f 'console.c' || echo '$(srcdir)/'`console.c liblxc_so-console.obj: console.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-console.obj -MD -MP -MF $(DEPDIR)/liblxc_so-console.Tpo -c -o liblxc_so-console.obj `if test -f 'console.c'; then $(CYGPATH_W) 'console.c'; else $(CYGPATH_W) '$(srcdir)/console.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-console.Tpo $(DEPDIR)/liblxc_so-console.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='console.c' object='liblxc_so-console.obj' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-console.obj -MD -MP -MF $(DEPDIR)/liblxc_so-console.Tpo -c -o liblxc_so-console.obj `if test -f 'console.c'; then $(CYGPATH_W) 'console.c'; else $(CYGPATH_W) '$(srcdir)/console.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-console.Tpo $(DEPDIR)/liblxc_so-console.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='console.c' object='liblxc_so-console.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-console.obj `if test -f 'console.c'; then $(CYGPATH_W) 'console.c'; else $(CYGPATH_W) '$(srcdir)/console.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-console.obj `if test -f 'console.c'; then $(CYGPATH_W) 'console.c'; else $(CYGPATH_W) '$(srcdir)/console.c'; fi` liblxc_so-freezer.o: freezer.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-freezer.o -MD -MP -MF $(DEPDIR)/liblxc_so-freezer.Tpo -c -o liblxc_so-freezer.o `test -f 'freezer.c' || echo '$(srcdir)/'`freezer.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-freezer.Tpo $(DEPDIR)/liblxc_so-freezer.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='freezer.c' object='liblxc_so-freezer.o' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-freezer.o -MD -MP -MF $(DEPDIR)/liblxc_so-freezer.Tpo -c -o liblxc_so-freezer.o `test -f 'freezer.c' || echo '$(srcdir)/'`freezer.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-freezer.Tpo $(DEPDIR)/liblxc_so-freezer.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='freezer.c' object='liblxc_so-freezer.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-freezer.o `test -f 'freezer.c' || echo '$(srcdir)/'`freezer.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-freezer.o `test -f 'freezer.c' || echo '$(srcdir)/'`freezer.c liblxc_so-freezer.obj: freezer.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-freezer.obj -MD -MP -MF $(DEPDIR)/liblxc_so-freezer.Tpo -c -o liblxc_so-freezer.obj `if test -f 'freezer.c'; then $(CYGPATH_W) 'freezer.c'; else $(CYGPATH_W) '$(srcdir)/freezer.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-freezer.Tpo $(DEPDIR)/liblxc_so-freezer.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='freezer.c' object='liblxc_so-freezer.obj' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-freezer.obj -MD -MP -MF $(DEPDIR)/liblxc_so-freezer.Tpo -c -o liblxc_so-freezer.obj `if test -f 'freezer.c'; then $(CYGPATH_W) 'freezer.c'; else $(CYGPATH_W) '$(srcdir)/freezer.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-freezer.Tpo $(DEPDIR)/liblxc_so-freezer.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='freezer.c' object='liblxc_so-freezer.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-freezer.obj `if test -f 'freezer.c'; then $(CYGPATH_W) 'freezer.c'; else $(CYGPATH_W) '$(srcdir)/freezer.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-freezer.obj `if test -f 'freezer.c'; then $(CYGPATH_W) 'freezer.c'; else $(CYGPATH_W) '$(srcdir)/freezer.c'; fi` liblxc_so-checkpoint.o: checkpoint.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-checkpoint.o -MD -MP -MF $(DEPDIR)/liblxc_so-checkpoint.Tpo -c -o liblxc_so-checkpoint.o `test -f 'checkpoint.c' || echo '$(srcdir)/'`checkpoint.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-checkpoint.Tpo $(DEPDIR)/liblxc_so-checkpoint.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='checkpoint.c' object='liblxc_so-checkpoint.o' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-checkpoint.o -MD -MP -MF $(DEPDIR)/liblxc_so-checkpoint.Tpo -c -o liblxc_so-checkpoint.o `test -f 'checkpoint.c' || echo '$(srcdir)/'`checkpoint.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-checkpoint.Tpo $(DEPDIR)/liblxc_so-checkpoint.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='checkpoint.c' object='liblxc_so-checkpoint.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-checkpoint.o `test -f 'checkpoint.c' || echo '$(srcdir)/'`checkpoint.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-checkpoint.o `test -f 'checkpoint.c' || echo '$(srcdir)/'`checkpoint.c liblxc_so-checkpoint.obj: checkpoint.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-checkpoint.obj -MD -MP -MF $(DEPDIR)/liblxc_so-checkpoint.Tpo -c -o liblxc_so-checkpoint.obj `if test -f 'checkpoint.c'; then $(CYGPATH_W) 'checkpoint.c'; else $(CYGPATH_W) '$(srcdir)/checkpoint.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-checkpoint.Tpo $(DEPDIR)/liblxc_so-checkpoint.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='checkpoint.c' object='liblxc_so-checkpoint.obj' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-checkpoint.obj -MD -MP -MF $(DEPDIR)/liblxc_so-checkpoint.Tpo -c -o liblxc_so-checkpoint.obj `if test -f 'checkpoint.c'; then $(CYGPATH_W) 'checkpoint.c'; else $(CYGPATH_W) '$(srcdir)/checkpoint.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-checkpoint.Tpo $(DEPDIR)/liblxc_so-checkpoint.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='checkpoint.c' object='liblxc_so-checkpoint.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-checkpoint.obj `if test -f 'checkpoint.c'; then $(CYGPATH_W) 'checkpoint.c'; else $(CYGPATH_W) '$(srcdir)/checkpoint.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-checkpoint.obj `if test -f 'checkpoint.c'; then $(CYGPATH_W) 'checkpoint.c'; else $(CYGPATH_W) '$(srcdir)/checkpoint.c'; fi` liblxc_so-restart.o: restart.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-restart.o -MD -MP -MF $(DEPDIR)/liblxc_so-restart.Tpo -c -o liblxc_so-restart.o `test -f 'restart.c' || echo '$(srcdir)/'`restart.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-restart.Tpo $(DEPDIR)/liblxc_so-restart.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='restart.c' object='liblxc_so-restart.o' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-restart.o -MD -MP -MF $(DEPDIR)/liblxc_so-restart.Tpo -c -o liblxc_so-restart.o `test -f 'restart.c' || echo '$(srcdir)/'`restart.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-restart.Tpo $(DEPDIR)/liblxc_so-restart.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='restart.c' object='liblxc_so-restart.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-restart.o `test -f 'restart.c' || echo '$(srcdir)/'`restart.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-restart.o `test -f 'restart.c' || echo '$(srcdir)/'`restart.c liblxc_so-restart.obj: restart.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-restart.obj -MD -MP -MF $(DEPDIR)/liblxc_so-restart.Tpo -c -o liblxc_so-restart.obj `if test -f 'restart.c'; then $(CYGPATH_W) 'restart.c'; else $(CYGPATH_W) '$(srcdir)/restart.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-restart.Tpo $(DEPDIR)/liblxc_so-restart.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='restart.c' object='liblxc_so-restart.obj' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-restart.obj -MD -MP -MF $(DEPDIR)/liblxc_so-restart.Tpo -c -o liblxc_so-restart.obj `if test -f 'restart.c'; then $(CYGPATH_W) 'restart.c'; else $(CYGPATH_W) '$(srcdir)/restart.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-restart.Tpo $(DEPDIR)/liblxc_so-restart.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='restart.c' object='liblxc_so-restart.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-restart.obj `if test -f 'restart.c'; then $(CYGPATH_W) 'restart.c'; else $(CYGPATH_W) '$(srcdir)/restart.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-restart.obj `if test -f 'restart.c'; then $(CYGPATH_W) 'restart.c'; else $(CYGPATH_W) '$(srcdir)/restart.c'; fi` liblxc_so-error.o: error.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-error.o -MD -MP -MF $(DEPDIR)/liblxc_so-error.Tpo -c -o liblxc_so-error.o `test -f 'error.c' || echo '$(srcdir)/'`error.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-error.Tpo $(DEPDIR)/liblxc_so-error.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='error.c' object='liblxc_so-error.o' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-error.o -MD -MP -MF $(DEPDIR)/liblxc_so-error.Tpo -c -o liblxc_so-error.o `test -f 'error.c' || echo '$(srcdir)/'`error.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-error.Tpo $(DEPDIR)/liblxc_so-error.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='error.c' object='liblxc_so-error.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-error.o `test -f 'error.c' || echo '$(srcdir)/'`error.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-error.o `test -f 'error.c' || echo '$(srcdir)/'`error.c liblxc_so-error.obj: error.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-error.obj -MD -MP -MF $(DEPDIR)/liblxc_so-error.Tpo -c -o liblxc_so-error.obj `if test -f 'error.c'; then $(CYGPATH_W) 'error.c'; else $(CYGPATH_W) '$(srcdir)/error.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-error.Tpo $(DEPDIR)/liblxc_so-error.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='error.c' object='liblxc_so-error.obj' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-error.obj -MD -MP -MF $(DEPDIR)/liblxc_so-error.Tpo -c -o liblxc_so-error.obj `if test -f 'error.c'; then $(CYGPATH_W) 'error.c'; else $(CYGPATH_W) '$(srcdir)/error.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-error.Tpo $(DEPDIR)/liblxc_so-error.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='error.c' object='liblxc_so-error.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-error.obj `if test -f 'error.c'; then $(CYGPATH_W) 'error.c'; else $(CYGPATH_W) '$(srcdir)/error.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-error.obj `if test -f 'error.c'; then $(CYGPATH_W) 'error.c'; else $(CYGPATH_W) '$(srcdir)/error.c'; fi` liblxc_so-parse.o: parse.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-parse.o -MD -MP -MF $(DEPDIR)/liblxc_so-parse.Tpo -c -o liblxc_so-parse.o `test -f 'parse.c' || echo '$(srcdir)/'`parse.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-parse.Tpo $(DEPDIR)/liblxc_so-parse.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='parse.c' object='liblxc_so-parse.o' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-parse.o -MD -MP -MF $(DEPDIR)/liblxc_so-parse.Tpo -c -o liblxc_so-parse.o `test -f 'parse.c' || echo '$(srcdir)/'`parse.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-parse.Tpo $(DEPDIR)/liblxc_so-parse.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='parse.c' object='liblxc_so-parse.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-parse.o `test -f 'parse.c' || echo '$(srcdir)/'`parse.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-parse.o `test -f 'parse.c' || echo '$(srcdir)/'`parse.c liblxc_so-parse.obj: parse.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-parse.obj -MD -MP -MF $(DEPDIR)/liblxc_so-parse.Tpo -c -o liblxc_so-parse.obj `if test -f 'parse.c'; then $(CYGPATH_W) 'parse.c'; else $(CYGPATH_W) '$(srcdir)/parse.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-parse.Tpo $(DEPDIR)/liblxc_so-parse.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='parse.c' object='liblxc_so-parse.obj' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-parse.obj -MD -MP -MF $(DEPDIR)/liblxc_so-parse.Tpo -c -o liblxc_so-parse.obj `if test -f 'parse.c'; then $(CYGPATH_W) 'parse.c'; else $(CYGPATH_W) '$(srcdir)/parse.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-parse.Tpo $(DEPDIR)/liblxc_so-parse.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='parse.c' object='liblxc_so-parse.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-parse.obj `if test -f 'parse.c'; then $(CYGPATH_W) 'parse.c'; else $(CYGPATH_W) '$(srcdir)/parse.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-parse.obj `if test -f 'parse.c'; then $(CYGPATH_W) 'parse.c'; else $(CYGPATH_W) '$(srcdir)/parse.c'; fi` liblxc_so-cgroup.o: cgroup.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-cgroup.o -MD -MP -MF $(DEPDIR)/liblxc_so-cgroup.Tpo -c -o liblxc_so-cgroup.o `test -f 'cgroup.c' || echo '$(srcdir)/'`cgroup.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-cgroup.Tpo $(DEPDIR)/liblxc_so-cgroup.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='cgroup.c' object='liblxc_so-cgroup.o' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-cgroup.o -MD -MP -MF $(DEPDIR)/liblxc_so-cgroup.Tpo -c -o liblxc_so-cgroup.o `test -f 'cgroup.c' || echo '$(srcdir)/'`cgroup.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-cgroup.Tpo $(DEPDIR)/liblxc_so-cgroup.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cgroup.c' object='liblxc_so-cgroup.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-cgroup.o `test -f 'cgroup.c' || echo '$(srcdir)/'`cgroup.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-cgroup.o `test -f 'cgroup.c' || echo '$(srcdir)/'`cgroup.c liblxc_so-cgroup.obj: cgroup.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-cgroup.obj -MD -MP -MF $(DEPDIR)/liblxc_so-cgroup.Tpo -c -o liblxc_so-cgroup.obj `if test -f 'cgroup.c'; then $(CYGPATH_W) 'cgroup.c'; else $(CYGPATH_W) '$(srcdir)/cgroup.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-cgroup.Tpo $(DEPDIR)/liblxc_so-cgroup.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='cgroup.c' object='liblxc_so-cgroup.obj' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-cgroup.obj -MD -MP -MF $(DEPDIR)/liblxc_so-cgroup.Tpo -c -o liblxc_so-cgroup.obj `if test -f 'cgroup.c'; then $(CYGPATH_W) 'cgroup.c'; else $(CYGPATH_W) '$(srcdir)/cgroup.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-cgroup.Tpo $(DEPDIR)/liblxc_so-cgroup.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cgroup.c' object='liblxc_so-cgroup.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-cgroup.obj `if test -f 'cgroup.c'; then $(CYGPATH_W) 'cgroup.c'; else $(CYGPATH_W) '$(srcdir)/cgroup.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-cgroup.obj `if test -f 'cgroup.c'; then $(CYGPATH_W) 'cgroup.c'; else $(CYGPATH_W) '$(srcdir)/cgroup.c'; fi` liblxc_so-utils.o: utils.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-utils.o -MD -MP -MF $(DEPDIR)/liblxc_so-utils.Tpo -c -o liblxc_so-utils.o `test -f 'utils.c' || echo '$(srcdir)/'`utils.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-utils.Tpo $(DEPDIR)/liblxc_so-utils.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='utils.c' object='liblxc_so-utils.o' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-utils.o -MD -MP -MF $(DEPDIR)/liblxc_so-utils.Tpo -c -o liblxc_so-utils.o `test -f 'utils.c' || echo '$(srcdir)/'`utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-utils.Tpo $(DEPDIR)/liblxc_so-utils.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='utils.c' object='liblxc_so-utils.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-utils.o `test -f 'utils.c' || echo '$(srcdir)/'`utils.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-utils.o `test -f 'utils.c' || echo '$(srcdir)/'`utils.c liblxc_so-utils.obj: utils.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-utils.obj -MD -MP -MF $(DEPDIR)/liblxc_so-utils.Tpo -c -o liblxc_so-utils.obj `if test -f 'utils.c'; then $(CYGPATH_W) 'utils.c'; else $(CYGPATH_W) '$(srcdir)/utils.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-utils.Tpo $(DEPDIR)/liblxc_so-utils.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='utils.c' object='liblxc_so-utils.obj' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-utils.obj -MD -MP -MF $(DEPDIR)/liblxc_so-utils.Tpo -c -o liblxc_so-utils.obj `if test -f 'utils.c'; then $(CYGPATH_W) 'utils.c'; else $(CYGPATH_W) '$(srcdir)/utils.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-utils.Tpo $(DEPDIR)/liblxc_so-utils.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='utils.c' object='liblxc_so-utils.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-utils.obj `if test -f 'utils.c'; then $(CYGPATH_W) 'utils.c'; else $(CYGPATH_W) '$(srcdir)/utils.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-utils.obj `if test -f 'utils.c'; then $(CYGPATH_W) 'utils.c'; else $(CYGPATH_W) '$(srcdir)/utils.c'; fi` liblxc_so-sync.o: sync.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-sync.o -MD -MP -MF $(DEPDIR)/liblxc_so-sync.Tpo -c -o liblxc_so-sync.o `test -f 'sync.c' || echo '$(srcdir)/'`sync.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-sync.Tpo $(DEPDIR)/liblxc_so-sync.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sync.c' object='liblxc_so-sync.o' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-sync.o -MD -MP -MF $(DEPDIR)/liblxc_so-sync.Tpo -c -o liblxc_so-sync.o `test -f 'sync.c' || echo '$(srcdir)/'`sync.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-sync.Tpo $(DEPDIR)/liblxc_so-sync.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sync.c' object='liblxc_so-sync.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-sync.o `test -f 'sync.c' || echo '$(srcdir)/'`sync.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-sync.o `test -f 'sync.c' || echo '$(srcdir)/'`sync.c liblxc_so-sync.obj: sync.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-sync.obj -MD -MP -MF $(DEPDIR)/liblxc_so-sync.Tpo -c -o liblxc_so-sync.obj `if test -f 'sync.c'; then $(CYGPATH_W) 'sync.c'; else $(CYGPATH_W) '$(srcdir)/sync.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-sync.Tpo $(DEPDIR)/liblxc_so-sync.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sync.c' object='liblxc_so-sync.obj' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-sync.obj -MD -MP -MF $(DEPDIR)/liblxc_so-sync.Tpo -c -o liblxc_so-sync.obj `if test -f 'sync.c'; then $(CYGPATH_W) 'sync.c'; else $(CYGPATH_W) '$(srcdir)/sync.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-sync.Tpo $(DEPDIR)/liblxc_so-sync.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sync.c' object='liblxc_so-sync.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-sync.obj `if test -f 'sync.c'; then $(CYGPATH_W) 'sync.c'; else $(CYGPATH_W) '$(srcdir)/sync.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-sync.obj `if test -f 'sync.c'; then $(CYGPATH_W) 'sync.c'; else $(CYGPATH_W) '$(srcdir)/sync.c'; fi` liblxc_so-namespace.o: namespace.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-namespace.o -MD -MP -MF $(DEPDIR)/liblxc_so-namespace.Tpo -c -o liblxc_so-namespace.o `test -f 'namespace.c' || echo '$(srcdir)/'`namespace.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-namespace.Tpo $(DEPDIR)/liblxc_so-namespace.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='namespace.c' object='liblxc_so-namespace.o' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-namespace.o -MD -MP -MF $(DEPDIR)/liblxc_so-namespace.Tpo -c -o liblxc_so-namespace.o `test -f 'namespace.c' || echo '$(srcdir)/'`namespace.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-namespace.Tpo $(DEPDIR)/liblxc_so-namespace.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='namespace.c' object='liblxc_so-namespace.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-namespace.o `test -f 'namespace.c' || echo '$(srcdir)/'`namespace.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-namespace.o `test -f 'namespace.c' || echo '$(srcdir)/'`namespace.c liblxc_so-namespace.obj: namespace.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-namespace.obj -MD -MP -MF $(DEPDIR)/liblxc_so-namespace.Tpo -c -o liblxc_so-namespace.obj `if test -f 'namespace.c'; then $(CYGPATH_W) 'namespace.c'; else $(CYGPATH_W) '$(srcdir)/namespace.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-namespace.Tpo $(DEPDIR)/liblxc_so-namespace.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='namespace.c' object='liblxc_so-namespace.obj' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-namespace.obj -MD -MP -MF $(DEPDIR)/liblxc_so-namespace.Tpo -c -o liblxc_so-namespace.obj `if test -f 'namespace.c'; then $(CYGPATH_W) 'namespace.c'; else $(CYGPATH_W) '$(srcdir)/namespace.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-namespace.Tpo $(DEPDIR)/liblxc_so-namespace.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='namespace.c' object='liblxc_so-namespace.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-namespace.obj `if test -f 'namespace.c'; then $(CYGPATH_W) 'namespace.c'; else $(CYGPATH_W) '$(srcdir)/namespace.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-namespace.obj `if test -f 'namespace.c'; then $(CYGPATH_W) 'namespace.c'; else $(CYGPATH_W) '$(srcdir)/namespace.c'; fi` liblxc_so-conf.o: conf.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-conf.o -MD -MP -MF $(DEPDIR)/liblxc_so-conf.Tpo -c -o liblxc_so-conf.o `test -f 'conf.c' || echo '$(srcdir)/'`conf.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-conf.Tpo $(DEPDIR)/liblxc_so-conf.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='conf.c' object='liblxc_so-conf.o' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-conf.o -MD -MP -MF $(DEPDIR)/liblxc_so-conf.Tpo -c -o liblxc_so-conf.o `test -f 'conf.c' || echo '$(srcdir)/'`conf.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-conf.Tpo $(DEPDIR)/liblxc_so-conf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='conf.c' object='liblxc_so-conf.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-conf.o `test -f 'conf.c' || echo '$(srcdir)/'`conf.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-conf.o `test -f 'conf.c' || echo '$(srcdir)/'`conf.c liblxc_so-conf.obj: conf.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-conf.obj -MD -MP -MF $(DEPDIR)/liblxc_so-conf.Tpo -c -o liblxc_so-conf.obj `if test -f 'conf.c'; then $(CYGPATH_W) 'conf.c'; else $(CYGPATH_W) '$(srcdir)/conf.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-conf.Tpo $(DEPDIR)/liblxc_so-conf.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='conf.c' object='liblxc_so-conf.obj' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-conf.obj -MD -MP -MF $(DEPDIR)/liblxc_so-conf.Tpo -c -o liblxc_so-conf.obj `if test -f 'conf.c'; then $(CYGPATH_W) 'conf.c'; else $(CYGPATH_W) '$(srcdir)/conf.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-conf.Tpo $(DEPDIR)/liblxc_so-conf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='conf.c' object='liblxc_so-conf.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-conf.obj `if test -f 'conf.c'; then $(CYGPATH_W) 'conf.c'; else $(CYGPATH_W) '$(srcdir)/conf.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-conf.obj `if test -f 'conf.c'; then $(CYGPATH_W) 'conf.c'; else $(CYGPATH_W) '$(srcdir)/conf.c'; fi` liblxc_so-confile.o: confile.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-confile.o -MD -MP -MF $(DEPDIR)/liblxc_so-confile.Tpo -c -o liblxc_so-confile.o `test -f 'confile.c' || echo '$(srcdir)/'`confile.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-confile.Tpo $(DEPDIR)/liblxc_so-confile.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='confile.c' object='liblxc_so-confile.o' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-confile.o -MD -MP -MF $(DEPDIR)/liblxc_so-confile.Tpo -c -o liblxc_so-confile.o `test -f 'confile.c' || echo '$(srcdir)/'`confile.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-confile.Tpo $(DEPDIR)/liblxc_so-confile.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='confile.c' object='liblxc_so-confile.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-confile.o `test -f 'confile.c' || echo '$(srcdir)/'`confile.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-confile.o `test -f 'confile.c' || echo '$(srcdir)/'`confile.c liblxc_so-confile.obj: confile.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-confile.obj -MD -MP -MF $(DEPDIR)/liblxc_so-confile.Tpo -c -o liblxc_so-confile.obj `if test -f 'confile.c'; then $(CYGPATH_W) 'confile.c'; else $(CYGPATH_W) '$(srcdir)/confile.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-confile.Tpo $(DEPDIR)/liblxc_so-confile.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='confile.c' object='liblxc_so-confile.obj' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-confile.obj -MD -MP -MF $(DEPDIR)/liblxc_so-confile.Tpo -c -o liblxc_so-confile.obj `if test -f 'confile.c'; then $(CYGPATH_W) 'confile.c'; else $(CYGPATH_W) '$(srcdir)/confile.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-confile.Tpo $(DEPDIR)/liblxc_so-confile.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='confile.c' object='liblxc_so-confile.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-confile.obj `if test -f 'confile.c'; then $(CYGPATH_W) 'confile.c'; else $(CYGPATH_W) '$(srcdir)/confile.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-confile.obj `if test -f 'confile.c'; then $(CYGPATH_W) 'confile.c'; else $(CYGPATH_W) '$(srcdir)/confile.c'; fi` liblxc_so-state.o: state.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-state.o -MD -MP -MF $(DEPDIR)/liblxc_so-state.Tpo -c -o liblxc_so-state.o `test -f 'state.c' || echo '$(srcdir)/'`state.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-state.Tpo $(DEPDIR)/liblxc_so-state.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='state.c' object='liblxc_so-state.o' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-state.o -MD -MP -MF $(DEPDIR)/liblxc_so-state.Tpo -c -o liblxc_so-state.o `test -f 'state.c' || echo '$(srcdir)/'`state.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-state.Tpo $(DEPDIR)/liblxc_so-state.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='state.c' object='liblxc_so-state.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-state.o `test -f 'state.c' || echo '$(srcdir)/'`state.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-state.o `test -f 'state.c' || echo '$(srcdir)/'`state.c liblxc_so-state.obj: state.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-state.obj -MD -MP -MF $(DEPDIR)/liblxc_so-state.Tpo -c -o liblxc_so-state.obj `if test -f 'state.c'; then $(CYGPATH_W) 'state.c'; else $(CYGPATH_W) '$(srcdir)/state.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-state.Tpo $(DEPDIR)/liblxc_so-state.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='state.c' object='liblxc_so-state.obj' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-state.obj -MD -MP -MF $(DEPDIR)/liblxc_so-state.Tpo -c -o liblxc_so-state.obj `if test -f 'state.c'; then $(CYGPATH_W) 'state.c'; else $(CYGPATH_W) '$(srcdir)/state.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-state.Tpo $(DEPDIR)/liblxc_so-state.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='state.c' object='liblxc_so-state.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-state.obj `if test -f 'state.c'; then $(CYGPATH_W) 'state.c'; else $(CYGPATH_W) '$(srcdir)/state.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-state.obj `if test -f 'state.c'; then $(CYGPATH_W) 'state.c'; else $(CYGPATH_W) '$(srcdir)/state.c'; fi` liblxc_so-log.o: log.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-log.o -MD -MP -MF $(DEPDIR)/liblxc_so-log.Tpo -c -o liblxc_so-log.o `test -f 'log.c' || echo '$(srcdir)/'`log.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-log.Tpo $(DEPDIR)/liblxc_so-log.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='log.c' object='liblxc_so-log.o' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-log.o -MD -MP -MF $(DEPDIR)/liblxc_so-log.Tpo -c -o liblxc_so-log.o `test -f 'log.c' || echo '$(srcdir)/'`log.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-log.Tpo $(DEPDIR)/liblxc_so-log.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='log.c' object='liblxc_so-log.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-log.o `test -f 'log.c' || echo '$(srcdir)/'`log.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-log.o `test -f 'log.c' || echo '$(srcdir)/'`log.c liblxc_so-log.obj: log.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-log.obj -MD -MP -MF $(DEPDIR)/liblxc_so-log.Tpo -c -o liblxc_so-log.obj `if test -f 'log.c'; then $(CYGPATH_W) 'log.c'; else $(CYGPATH_W) '$(srcdir)/log.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-log.Tpo $(DEPDIR)/liblxc_so-log.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='log.c' object='liblxc_so-log.obj' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-log.obj -MD -MP -MF $(DEPDIR)/liblxc_so-log.Tpo -c -o liblxc_so-log.obj `if test -f 'log.c'; then $(CYGPATH_W) 'log.c'; else $(CYGPATH_W) '$(srcdir)/log.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-log.Tpo $(DEPDIR)/liblxc_so-log.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='log.c' object='liblxc_so-log.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-log.obj `if test -f 'log.c'; then $(CYGPATH_W) 'log.c'; else $(CYGPATH_W) '$(srcdir)/log.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-log.obj `if test -f 'log.c'; then $(CYGPATH_W) 'log.c'; else $(CYGPATH_W) '$(srcdir)/log.c'; fi` liblxc_so-attach.o: attach.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-attach.o -MD -MP -MF $(DEPDIR)/liblxc_so-attach.Tpo -c -o liblxc_so-attach.o `test -f 'attach.c' || echo '$(srcdir)/'`attach.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-attach.Tpo $(DEPDIR)/liblxc_so-attach.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='attach.c' object='liblxc_so-attach.o' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-attach.o -MD -MP -MF $(DEPDIR)/liblxc_so-attach.Tpo -c -o liblxc_so-attach.o `test -f 'attach.c' || echo '$(srcdir)/'`attach.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-attach.Tpo $(DEPDIR)/liblxc_so-attach.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='attach.c' object='liblxc_so-attach.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-attach.o `test -f 'attach.c' || echo '$(srcdir)/'`attach.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-attach.o `test -f 'attach.c' || echo '$(srcdir)/'`attach.c liblxc_so-attach.obj: attach.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-attach.obj -MD -MP -MF $(DEPDIR)/liblxc_so-attach.Tpo -c -o liblxc_so-attach.obj `if test -f 'attach.c'; then $(CYGPATH_W) 'attach.c'; else $(CYGPATH_W) '$(srcdir)/attach.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-attach.Tpo $(DEPDIR)/liblxc_so-attach.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='attach.c' object='liblxc_so-attach.obj' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-attach.obj -MD -MP -MF $(DEPDIR)/liblxc_so-attach.Tpo -c -o liblxc_so-attach.obj `if test -f 'attach.c'; then $(CYGPATH_W) 'attach.c'; else $(CYGPATH_W) '$(srcdir)/attach.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-attach.Tpo $(DEPDIR)/liblxc_so-attach.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='attach.c' object='liblxc_so-attach.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-attach.obj `if test -f 'attach.c'; then $(CYGPATH_W) 'attach.c'; else $(CYGPATH_W) '$(srcdir)/attach.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-attach.obj `if test -f 'attach.c'; then $(CYGPATH_W) 'attach.c'; else $(CYGPATH_W) '$(srcdir)/attach.c'; fi` liblxc_so-network.o: network.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-network.o -MD -MP -MF $(DEPDIR)/liblxc_so-network.Tpo -c -o liblxc_so-network.o `test -f 'network.c' || echo '$(srcdir)/'`network.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-network.Tpo $(DEPDIR)/liblxc_so-network.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='network.c' object='liblxc_so-network.o' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-network.o -MD -MP -MF $(DEPDIR)/liblxc_so-network.Tpo -c -o liblxc_so-network.o `test -f 'network.c' || echo '$(srcdir)/'`network.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-network.Tpo $(DEPDIR)/liblxc_so-network.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='network.c' object='liblxc_so-network.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-network.o `test -f 'network.c' || echo '$(srcdir)/'`network.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-network.o `test -f 'network.c' || echo '$(srcdir)/'`network.c liblxc_so-network.obj: network.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-network.obj -MD -MP -MF $(DEPDIR)/liblxc_so-network.Tpo -c -o liblxc_so-network.obj `if test -f 'network.c'; then $(CYGPATH_W) 'network.c'; else $(CYGPATH_W) '$(srcdir)/network.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-network.Tpo $(DEPDIR)/liblxc_so-network.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='network.c' object='liblxc_so-network.obj' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-network.obj -MD -MP -MF $(DEPDIR)/liblxc_so-network.Tpo -c -o liblxc_so-network.obj `if test -f 'network.c'; then $(CYGPATH_W) 'network.c'; else $(CYGPATH_W) '$(srcdir)/network.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-network.Tpo $(DEPDIR)/liblxc_so-network.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='network.c' object='liblxc_so-network.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-network.obj `if test -f 'network.c'; then $(CYGPATH_W) 'network.c'; else $(CYGPATH_W) '$(srcdir)/network.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-network.obj `if test -f 'network.c'; then $(CYGPATH_W) 'network.c'; else $(CYGPATH_W) '$(srcdir)/network.c'; fi` liblxc_so-nl.o: nl.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-nl.o -MD -MP -MF $(DEPDIR)/liblxc_so-nl.Tpo -c -o liblxc_so-nl.o `test -f 'nl.c' || echo '$(srcdir)/'`nl.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-nl.Tpo $(DEPDIR)/liblxc_so-nl.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nl.c' object='liblxc_so-nl.o' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-nl.o -MD -MP -MF $(DEPDIR)/liblxc_so-nl.Tpo -c -o liblxc_so-nl.o `test -f 'nl.c' || echo '$(srcdir)/'`nl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-nl.Tpo $(DEPDIR)/liblxc_so-nl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nl.c' object='liblxc_so-nl.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-nl.o `test -f 'nl.c' || echo '$(srcdir)/'`nl.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-nl.o `test -f 'nl.c' || echo '$(srcdir)/'`nl.c liblxc_so-nl.obj: nl.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-nl.obj -MD -MP -MF $(DEPDIR)/liblxc_so-nl.Tpo -c -o liblxc_so-nl.obj `if test -f 'nl.c'; then $(CYGPATH_W) 'nl.c'; else $(CYGPATH_W) '$(srcdir)/nl.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-nl.Tpo $(DEPDIR)/liblxc_so-nl.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nl.c' object='liblxc_so-nl.obj' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-nl.obj -MD -MP -MF $(DEPDIR)/liblxc_so-nl.Tpo -c -o liblxc_so-nl.obj `if test -f 'nl.c'; then $(CYGPATH_W) 'nl.c'; else $(CYGPATH_W) '$(srcdir)/nl.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-nl.Tpo $(DEPDIR)/liblxc_so-nl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nl.c' object='liblxc_so-nl.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-nl.obj `if test -f 'nl.c'; then $(CYGPATH_W) 'nl.c'; else $(CYGPATH_W) '$(srcdir)/nl.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-nl.obj `if test -f 'nl.c'; then $(CYGPATH_W) 'nl.c'; else $(CYGPATH_W) '$(srcdir)/nl.c'; fi` liblxc_so-rtnl.o: rtnl.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-rtnl.o -MD -MP -MF $(DEPDIR)/liblxc_so-rtnl.Tpo -c -o liblxc_so-rtnl.o `test -f 'rtnl.c' || echo '$(srcdir)/'`rtnl.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-rtnl.Tpo $(DEPDIR)/liblxc_so-rtnl.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='rtnl.c' object='liblxc_so-rtnl.o' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-rtnl.o -MD -MP -MF $(DEPDIR)/liblxc_so-rtnl.Tpo -c -o liblxc_so-rtnl.o `test -f 'rtnl.c' || echo '$(srcdir)/'`rtnl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-rtnl.Tpo $(DEPDIR)/liblxc_so-rtnl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rtnl.c' object='liblxc_so-rtnl.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-rtnl.o `test -f 'rtnl.c' || echo '$(srcdir)/'`rtnl.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-rtnl.o `test -f 'rtnl.c' || echo '$(srcdir)/'`rtnl.c liblxc_so-rtnl.obj: rtnl.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-rtnl.obj -MD -MP -MF $(DEPDIR)/liblxc_so-rtnl.Tpo -c -o liblxc_so-rtnl.obj `if test -f 'rtnl.c'; then $(CYGPATH_W) 'rtnl.c'; else $(CYGPATH_W) '$(srcdir)/rtnl.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-rtnl.Tpo $(DEPDIR)/liblxc_so-rtnl.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='rtnl.c' object='liblxc_so-rtnl.obj' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-rtnl.obj -MD -MP -MF $(DEPDIR)/liblxc_so-rtnl.Tpo -c -o liblxc_so-rtnl.obj `if test -f 'rtnl.c'; then $(CYGPATH_W) 'rtnl.c'; else $(CYGPATH_W) '$(srcdir)/rtnl.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-rtnl.Tpo $(DEPDIR)/liblxc_so-rtnl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rtnl.c' object='liblxc_so-rtnl.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-rtnl.obj `if test -f 'rtnl.c'; then $(CYGPATH_W) 'rtnl.c'; else $(CYGPATH_W) '$(srcdir)/rtnl.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-rtnl.obj `if test -f 'rtnl.c'; then $(CYGPATH_W) 'rtnl.c'; else $(CYGPATH_W) '$(srcdir)/rtnl.c'; fi` liblxc_so-genl.o: genl.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-genl.o -MD -MP -MF $(DEPDIR)/liblxc_so-genl.Tpo -c -o liblxc_so-genl.o `test -f 'genl.c' || echo '$(srcdir)/'`genl.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-genl.Tpo $(DEPDIR)/liblxc_so-genl.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='genl.c' object='liblxc_so-genl.o' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-genl.o -MD -MP -MF $(DEPDIR)/liblxc_so-genl.Tpo -c -o liblxc_so-genl.o `test -f 'genl.c' || echo '$(srcdir)/'`genl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-genl.Tpo $(DEPDIR)/liblxc_so-genl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='genl.c' object='liblxc_so-genl.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-genl.o `test -f 'genl.c' || echo '$(srcdir)/'`genl.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-genl.o `test -f 'genl.c' || echo '$(srcdir)/'`genl.c liblxc_so-genl.obj: genl.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-genl.obj -MD -MP -MF $(DEPDIR)/liblxc_so-genl.Tpo -c -o liblxc_so-genl.obj `if test -f 'genl.c'; then $(CYGPATH_W) 'genl.c'; else $(CYGPATH_W) '$(srcdir)/genl.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-genl.Tpo $(DEPDIR)/liblxc_so-genl.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='genl.c' object='liblxc_so-genl.obj' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-genl.obj -MD -MP -MF $(DEPDIR)/liblxc_so-genl.Tpo -c -o liblxc_so-genl.obj `if test -f 'genl.c'; then $(CYGPATH_W) 'genl.c'; else $(CYGPATH_W) '$(srcdir)/genl.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-genl.Tpo $(DEPDIR)/liblxc_so-genl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='genl.c' object='liblxc_so-genl.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-genl.obj `if test -f 'genl.c'; then $(CYGPATH_W) 'genl.c'; else $(CYGPATH_W) '$(srcdir)/genl.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-genl.obj `if test -f 'genl.c'; then $(CYGPATH_W) 'genl.c'; else $(CYGPATH_W) '$(srcdir)/genl.c'; fi` liblxc_so-caps.o: caps.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-caps.o -MD -MP -MF $(DEPDIR)/liblxc_so-caps.Tpo -c -o liblxc_so-caps.o `test -f 'caps.c' || echo '$(srcdir)/'`caps.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-caps.Tpo $(DEPDIR)/liblxc_so-caps.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='caps.c' object='liblxc_so-caps.o' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-caps.o -MD -MP -MF $(DEPDIR)/liblxc_so-caps.Tpo -c -o liblxc_so-caps.o `test -f 'caps.c' || echo '$(srcdir)/'`caps.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-caps.Tpo $(DEPDIR)/liblxc_so-caps.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='caps.c' object='liblxc_so-caps.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-caps.o `test -f 'caps.c' || echo '$(srcdir)/'`caps.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-caps.o `test -f 'caps.c' || echo '$(srcdir)/'`caps.c liblxc_so-caps.obj: caps.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-caps.obj -MD -MP -MF $(DEPDIR)/liblxc_so-caps.Tpo -c -o liblxc_so-caps.obj `if test -f 'caps.c'; then $(CYGPATH_W) 'caps.c'; else $(CYGPATH_W) '$(srcdir)/caps.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-caps.Tpo $(DEPDIR)/liblxc_so-caps.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='caps.c' object='liblxc_so-caps.obj' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-caps.obj -MD -MP -MF $(DEPDIR)/liblxc_so-caps.Tpo -c -o liblxc_so-caps.obj `if test -f 'caps.c'; then $(CYGPATH_W) 'caps.c'; else $(CYGPATH_W) '$(srcdir)/caps.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-caps.Tpo $(DEPDIR)/liblxc_so-caps.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='caps.c' object='liblxc_so-caps.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-caps.obj `if test -f 'caps.c'; then $(CYGPATH_W) 'caps.c'; else $(CYGPATH_W) '$(srcdir)/caps.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-caps.obj `if test -f 'caps.c'; then $(CYGPATH_W) 'caps.c'; else $(CYGPATH_W) '$(srcdir)/caps.c'; fi` liblxc_so-mainloop.o: mainloop.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-mainloop.o -MD -MP -MF $(DEPDIR)/liblxc_so-mainloop.Tpo -c -o liblxc_so-mainloop.o `test -f 'mainloop.c' || echo '$(srcdir)/'`mainloop.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-mainloop.Tpo $(DEPDIR)/liblxc_so-mainloop.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mainloop.c' object='liblxc_so-mainloop.o' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-mainloop.o -MD -MP -MF $(DEPDIR)/liblxc_so-mainloop.Tpo -c -o liblxc_so-mainloop.o `test -f 'mainloop.c' || echo '$(srcdir)/'`mainloop.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-mainloop.Tpo $(DEPDIR)/liblxc_so-mainloop.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mainloop.c' object='liblxc_so-mainloop.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-mainloop.o `test -f 'mainloop.c' || echo '$(srcdir)/'`mainloop.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-mainloop.o `test -f 'mainloop.c' || echo '$(srcdir)/'`mainloop.c liblxc_so-mainloop.obj: mainloop.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-mainloop.obj -MD -MP -MF $(DEPDIR)/liblxc_so-mainloop.Tpo -c -o liblxc_so-mainloop.obj `if test -f 'mainloop.c'; then $(CYGPATH_W) 'mainloop.c'; else $(CYGPATH_W) '$(srcdir)/mainloop.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-mainloop.Tpo $(DEPDIR)/liblxc_so-mainloop.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mainloop.c' object='liblxc_so-mainloop.obj' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-mainloop.obj -MD -MP -MF $(DEPDIR)/liblxc_so-mainloop.Tpo -c -o liblxc_so-mainloop.obj `if test -f 'mainloop.c'; then $(CYGPATH_W) 'mainloop.c'; else $(CYGPATH_W) '$(srcdir)/mainloop.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-mainloop.Tpo $(DEPDIR)/liblxc_so-mainloop.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mainloop.c' object='liblxc_so-mainloop.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-mainloop.obj `if test -f 'mainloop.c'; then $(CYGPATH_W) 'mainloop.c'; else $(CYGPATH_W) '$(srcdir)/mainloop.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-mainloop.obj `if test -f 'mainloop.c'; then $(CYGPATH_W) 'mainloop.c'; else $(CYGPATH_W) '$(srcdir)/mainloop.c'; fi` liblxc_so-af_unix.o: af_unix.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-af_unix.o -MD -MP -MF $(DEPDIR)/liblxc_so-af_unix.Tpo -c -o liblxc_so-af_unix.o `test -f 'af_unix.c' || echo '$(srcdir)/'`af_unix.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-af_unix.Tpo $(DEPDIR)/liblxc_so-af_unix.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='af_unix.c' object='liblxc_so-af_unix.o' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-af_unix.o -MD -MP -MF $(DEPDIR)/liblxc_so-af_unix.Tpo -c -o liblxc_so-af_unix.o `test -f 'af_unix.c' || echo '$(srcdir)/'`af_unix.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-af_unix.Tpo $(DEPDIR)/liblxc_so-af_unix.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='af_unix.c' object='liblxc_so-af_unix.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-af_unix.o `test -f 'af_unix.c' || echo '$(srcdir)/'`af_unix.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-af_unix.o `test -f 'af_unix.c' || echo '$(srcdir)/'`af_unix.c liblxc_so-af_unix.obj: af_unix.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-af_unix.obj -MD -MP -MF $(DEPDIR)/liblxc_so-af_unix.Tpo -c -o liblxc_so-af_unix.obj `if test -f 'af_unix.c'; then $(CYGPATH_W) 'af_unix.c'; else $(CYGPATH_W) '$(srcdir)/af_unix.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-af_unix.Tpo $(DEPDIR)/liblxc_so-af_unix.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='af_unix.c' object='liblxc_so-af_unix.obj' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-af_unix.obj -MD -MP -MF $(DEPDIR)/liblxc_so-af_unix.Tpo -c -o liblxc_so-af_unix.obj `if test -f 'af_unix.c'; then $(CYGPATH_W) 'af_unix.c'; else $(CYGPATH_W) '$(srcdir)/af_unix.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-af_unix.Tpo $(DEPDIR)/liblxc_so-af_unix.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='af_unix.c' object='liblxc_so-af_unix.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-af_unix.obj `if test -f 'af_unix.c'; then $(CYGPATH_W) 'af_unix.c'; else $(CYGPATH_W) '$(srcdir)/af_unix.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-af_unix.obj `if test -f 'af_unix.c'; then $(CYGPATH_W) 'af_unix.c'; else $(CYGPATH_W) '$(srcdir)/af_unix.c'; fi` -liblxc_so-utmp.o: utmp.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-utmp.o -MD -MP -MF $(DEPDIR)/liblxc_so-utmp.Tpo -c -o liblxc_so-utmp.o `test -f 'utmp.c' || echo '$(srcdir)/'`utmp.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-utmp.Tpo $(DEPDIR)/liblxc_so-utmp.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='utmp.c' object='liblxc_so-utmp.o' libtool=no @AMDEPBACKSLASH@ +liblxc_so-lxcutmp.o: lxcutmp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-lxcutmp.o -MD -MP -MF $(DEPDIR)/liblxc_so-lxcutmp.Tpo -c -o liblxc_so-lxcutmp.o `test -f 'lxcutmp.c' || echo '$(srcdir)/'`lxcutmp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-lxcutmp.Tpo $(DEPDIR)/liblxc_so-lxcutmp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lxcutmp.c' object='liblxc_so-lxcutmp.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-utmp.o `test -f 'utmp.c' || echo '$(srcdir)/'`utmp.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-lxcutmp.o `test -f 'lxcutmp.c' || echo '$(srcdir)/'`lxcutmp.c -liblxc_so-utmp.obj: utmp.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-utmp.obj -MD -MP -MF $(DEPDIR)/liblxc_so-utmp.Tpo -c -o liblxc_so-utmp.obj `if test -f 'utmp.c'; then $(CYGPATH_W) 'utmp.c'; else $(CYGPATH_W) '$(srcdir)/utmp.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liblxc_so-utmp.Tpo $(DEPDIR)/liblxc_so-utmp.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='utmp.c' object='liblxc_so-utmp.obj' libtool=no @AMDEPBACKSLASH@ +liblxc_so-lxcutmp.obj: lxcutmp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-lxcutmp.obj -MD -MP -MF $(DEPDIR)/liblxc_so-lxcutmp.Tpo -c -o liblxc_so-lxcutmp.obj `if test -f 'lxcutmp.c'; then $(CYGPATH_W) 'lxcutmp.c'; else $(CYGPATH_W) '$(srcdir)/lxcutmp.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-lxcutmp.Tpo $(DEPDIR)/liblxc_so-lxcutmp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lxcutmp.c' object='liblxc_so-lxcutmp.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-utmp.obj `if test -f 'utmp.c'; then $(CYGPATH_W) 'utmp.c'; else $(CYGPATH_W) '$(srcdir)/utmp.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-lxcutmp.obj `if test -f 'lxcutmp.c'; then $(CYGPATH_W) 'lxcutmp.c'; else $(CYGPATH_W) '$(srcdir)/lxcutmp.c'; fi` + +liblxc_so-apparmor.o: apparmor.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-apparmor.o -MD -MP -MF $(DEPDIR)/liblxc_so-apparmor.Tpo -c -o liblxc_so-apparmor.o `test -f 'apparmor.c' || echo '$(srcdir)/'`apparmor.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-apparmor.Tpo $(DEPDIR)/liblxc_so-apparmor.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='apparmor.c' object='liblxc_so-apparmor.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-apparmor.o `test -f 'apparmor.c' || echo '$(srcdir)/'`apparmor.c + +liblxc_so-apparmor.obj: apparmor.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-apparmor.obj -MD -MP -MF $(DEPDIR)/liblxc_so-apparmor.Tpo -c -o liblxc_so-apparmor.obj `if test -f 'apparmor.c'; then $(CYGPATH_W) 'apparmor.c'; else $(CYGPATH_W) '$(srcdir)/apparmor.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-apparmor.Tpo $(DEPDIR)/liblxc_so-apparmor.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='apparmor.c' object='liblxc_so-apparmor.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-apparmor.obj `if test -f 'apparmor.c'; then $(CYGPATH_W) 'apparmor.c'; else $(CYGPATH_W) '$(srcdir)/apparmor.c'; fi` + +liblxc_so-lxclock.o: lxclock.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-lxclock.o -MD -MP -MF $(DEPDIR)/liblxc_so-lxclock.Tpo -c -o liblxc_so-lxclock.o `test -f 'lxclock.c' || echo '$(srcdir)/'`lxclock.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-lxclock.Tpo $(DEPDIR)/liblxc_so-lxclock.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lxclock.c' object='liblxc_so-lxclock.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-lxclock.o `test -f 'lxclock.c' || echo '$(srcdir)/'`lxclock.c + +liblxc_so-lxclock.obj: lxclock.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-lxclock.obj -MD -MP -MF $(DEPDIR)/liblxc_so-lxclock.Tpo -c -o liblxc_so-lxclock.obj `if test -f 'lxclock.c'; then $(CYGPATH_W) 'lxclock.c'; else $(CYGPATH_W) '$(srcdir)/lxclock.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-lxclock.Tpo $(DEPDIR)/liblxc_so-lxclock.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lxclock.c' object='liblxc_so-lxclock.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-lxclock.obj `if test -f 'lxclock.c'; then $(CYGPATH_W) 'lxclock.c'; else $(CYGPATH_W) '$(srcdir)/lxclock.c'; fi` + +liblxc_so-lxccontainer.o: lxccontainer.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-lxccontainer.o -MD -MP -MF $(DEPDIR)/liblxc_so-lxccontainer.Tpo -c -o liblxc_so-lxccontainer.o `test -f 'lxccontainer.c' || echo '$(srcdir)/'`lxccontainer.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-lxccontainer.Tpo $(DEPDIR)/liblxc_so-lxccontainer.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lxccontainer.c' object='liblxc_so-lxccontainer.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-lxccontainer.o `test -f 'lxccontainer.c' || echo '$(srcdir)/'`lxccontainer.c + +liblxc_so-lxccontainer.obj: lxccontainer.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-lxccontainer.obj -MD -MP -MF $(DEPDIR)/liblxc_so-lxccontainer.Tpo -c -o liblxc_so-lxccontainer.obj `if test -f 'lxccontainer.c'; then $(CYGPATH_W) 'lxccontainer.c'; else $(CYGPATH_W) '$(srcdir)/lxccontainer.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-lxccontainer.Tpo $(DEPDIR)/liblxc_so-lxccontainer.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lxccontainer.c' object='liblxc_so-lxccontainer.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-lxccontainer.obj `if test -f 'lxccontainer.c'; then $(CYGPATH_W) 'lxccontainer.c'; else $(CYGPATH_W) '$(srcdir)/lxccontainer.c'; fi` + +liblxc_so-version.o: version.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-version.o -MD -MP -MF $(DEPDIR)/liblxc_so-version.Tpo -c -o liblxc_so-version.o `test -f 'version.c' || echo '$(srcdir)/'`version.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-version.Tpo $(DEPDIR)/liblxc_so-version.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='version.c' object='liblxc_so-version.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-version.o `test -f 'version.c' || echo '$(srcdir)/'`version.c + +liblxc_so-version.obj: version.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-version.obj -MD -MP -MF $(DEPDIR)/liblxc_so-version.Tpo -c -o liblxc_so-version.obj `if test -f 'version.c'; then $(CYGPATH_W) 'version.c'; else $(CYGPATH_W) '$(srcdir)/version.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-version.Tpo $(DEPDIR)/liblxc_so-version.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='version.c' object='liblxc_so-version.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-version.obj `if test -f 'version.c'; then $(CYGPATH_W) 'version.c'; else $(CYGPATH_W) '$(srcdir)/version.c'; fi` + +../include/liblxc_so-ifaddrs.o: ../include/ifaddrs.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT ../include/liblxc_so-ifaddrs.o -MD -MP -MF ../include/$(DEPDIR)/liblxc_so-ifaddrs.Tpo -c -o ../include/liblxc_so-ifaddrs.o `test -f '../include/ifaddrs.c' || echo '$(srcdir)/'`../include/ifaddrs.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../include/$(DEPDIR)/liblxc_so-ifaddrs.Tpo ../include/$(DEPDIR)/liblxc_so-ifaddrs.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../include/ifaddrs.c' object='../include/liblxc_so-ifaddrs.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o ../include/liblxc_so-ifaddrs.o `test -f '../include/ifaddrs.c' || echo '$(srcdir)/'`../include/ifaddrs.c + +../include/liblxc_so-ifaddrs.obj: ../include/ifaddrs.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT ../include/liblxc_so-ifaddrs.obj -MD -MP -MF ../include/$(DEPDIR)/liblxc_so-ifaddrs.Tpo -c -o ../include/liblxc_so-ifaddrs.obj `if test -f '../include/ifaddrs.c'; then $(CYGPATH_W) '../include/ifaddrs.c'; else $(CYGPATH_W) '$(srcdir)/../include/ifaddrs.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../include/$(DEPDIR)/liblxc_so-ifaddrs.Tpo ../include/$(DEPDIR)/liblxc_so-ifaddrs.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../include/ifaddrs.c' object='../include/liblxc_so-ifaddrs.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o ../include/liblxc_so-ifaddrs.obj `if test -f '../include/ifaddrs.c'; then $(CYGPATH_W) '../include/ifaddrs.c'; else $(CYGPATH_W) '$(srcdir)/../include/ifaddrs.c'; fi` + +../include/liblxc_so-openpty.o: ../include/openpty.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT ../include/liblxc_so-openpty.o -MD -MP -MF ../include/$(DEPDIR)/liblxc_so-openpty.Tpo -c -o ../include/liblxc_so-openpty.o `test -f '../include/openpty.c' || echo '$(srcdir)/'`../include/openpty.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../include/$(DEPDIR)/liblxc_so-openpty.Tpo ../include/$(DEPDIR)/liblxc_so-openpty.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../include/openpty.c' object='../include/liblxc_so-openpty.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o ../include/liblxc_so-openpty.o `test -f '../include/openpty.c' || echo '$(srcdir)/'`../include/openpty.c + +../include/liblxc_so-openpty.obj: ../include/openpty.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT ../include/liblxc_so-openpty.obj -MD -MP -MF ../include/$(DEPDIR)/liblxc_so-openpty.Tpo -c -o ../include/liblxc_so-openpty.obj `if test -f '../include/openpty.c'; then $(CYGPATH_W) '../include/openpty.c'; else $(CYGPATH_W) '$(srcdir)/../include/openpty.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../include/$(DEPDIR)/liblxc_so-openpty.Tpo ../include/$(DEPDIR)/liblxc_so-openpty.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../include/openpty.c' object='../include/liblxc_so-openpty.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o ../include/liblxc_so-openpty.obj `if test -f '../include/openpty.c'; then $(CYGPATH_W) '../include/openpty.c'; else $(CYGPATH_W) '$(srcdir)/../include/openpty.c'; fi` + +../include/liblxc_so-lxcmntent.o: ../include/lxcmntent.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT ../include/liblxc_so-lxcmntent.o -MD -MP -MF ../include/$(DEPDIR)/liblxc_so-lxcmntent.Tpo -c -o ../include/liblxc_so-lxcmntent.o `test -f '../include/lxcmntent.c' || echo '$(srcdir)/'`../include/lxcmntent.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../include/$(DEPDIR)/liblxc_so-lxcmntent.Tpo ../include/$(DEPDIR)/liblxc_so-lxcmntent.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../include/lxcmntent.c' object='../include/liblxc_so-lxcmntent.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o ../include/liblxc_so-lxcmntent.o `test -f '../include/lxcmntent.c' || echo '$(srcdir)/'`../include/lxcmntent.c + +../include/liblxc_so-lxcmntent.obj: ../include/lxcmntent.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT ../include/liblxc_so-lxcmntent.obj -MD -MP -MF ../include/$(DEPDIR)/liblxc_so-lxcmntent.Tpo -c -o ../include/liblxc_so-lxcmntent.obj `if test -f '../include/lxcmntent.c'; then $(CYGPATH_W) '../include/lxcmntent.c'; else $(CYGPATH_W) '$(srcdir)/../include/lxcmntent.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../include/$(DEPDIR)/liblxc_so-lxcmntent.Tpo ../include/$(DEPDIR)/liblxc_so-lxcmntent.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../include/lxcmntent.c' object='../include/liblxc_so-lxcmntent.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o ../include/liblxc_so-lxcmntent.obj `if test -f '../include/lxcmntent.c'; then $(CYGPATH_W) '../include/lxcmntent.c'; else $(CYGPATH_W) '$(srcdir)/../include/lxcmntent.c'; fi` + +../include/liblxc_so-getline.o: ../include/getline.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT ../include/liblxc_so-getline.o -MD -MP -MF ../include/$(DEPDIR)/liblxc_so-getline.Tpo -c -o ../include/liblxc_so-getline.o `test -f '../include/getline.c' || echo '$(srcdir)/'`../include/getline.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../include/$(DEPDIR)/liblxc_so-getline.Tpo ../include/$(DEPDIR)/liblxc_so-getline.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../include/getline.c' object='../include/liblxc_so-getline.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o ../include/liblxc_so-getline.o `test -f '../include/getline.c' || echo '$(srcdir)/'`../include/getline.c + +../include/liblxc_so-getline.obj: ../include/getline.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT ../include/liblxc_so-getline.obj -MD -MP -MF ../include/$(DEPDIR)/liblxc_so-getline.Tpo -c -o ../include/liblxc_so-getline.obj `if test -f '../include/getline.c'; then $(CYGPATH_W) '../include/getline.c'; else $(CYGPATH_W) '$(srcdir)/../include/getline.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../include/$(DEPDIR)/liblxc_so-getline.Tpo ../include/$(DEPDIR)/liblxc_so-getline.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../include/getline.c' object='../include/liblxc_so-getline.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o ../include/liblxc_so-getline.obj `if test -f '../include/getline.c'; then $(CYGPATH_W) '../include/getline.c'; else $(CYGPATH_W) '$(srcdir)/../include/getline.c'; fi` + +liblxc_so-seccomp.o: seccomp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-seccomp.o -MD -MP -MF $(DEPDIR)/liblxc_so-seccomp.Tpo -c -o liblxc_so-seccomp.o `test -f 'seccomp.c' || echo '$(srcdir)/'`seccomp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-seccomp.Tpo $(DEPDIR)/liblxc_so-seccomp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='seccomp.c' object='liblxc_so-seccomp.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-seccomp.o `test -f 'seccomp.c' || echo '$(srcdir)/'`seccomp.c + +liblxc_so-seccomp.obj: seccomp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -MT liblxc_so-seccomp.obj -MD -MP -MF $(DEPDIR)/liblxc_so-seccomp.Tpo -c -o liblxc_so-seccomp.obj `if test -f 'seccomp.c'; then $(CYGPATH_W) 'seccomp.c'; else $(CYGPATH_W) '$(srcdir)/seccomp.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblxc_so-seccomp.Tpo $(DEPDIR)/liblxc_so-seccomp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='seccomp.c' object='liblxc_so-seccomp.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblxc_so_CFLAGS) $(CFLAGS) -c -o liblxc_so-seccomp.obj `if test -f 'seccomp.c'; then $(CYGPATH_W) 'seccomp.c'; else $(CYGPATH_W) '$(srcdir)/seccomp.c'; fi` install-pkgincludeHEADERS: $(pkginclude_HEADERS) @$(NORMAL_INSTALL) - test -z "$(pkgincludedir)" || $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkgincludedir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" || exit 1; \ + fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ @@ -1148,30 +1548,17 @@ @$(NORMAL_UNINSTALL) @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - test -n "$$files" || exit 0; \ - echo " ( cd '$(DESTDIR)$(pkgincludedir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(pkgincludedir)" && rm -f $$files - -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS + dir='$(DESTDIR)$(pkgincludedir)'; $(am__uninstall_files_from_dir) + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ + $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ @@ -1183,15 +1570,11 @@ $$unique; \ fi; \ fi -ctags: CTAGS -CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique @@ -1200,6 +1583,21 @@ here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags @@ -1251,10 +1649,15 @@ installcheck: installcheck-am install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi mostlyclean-generic: clean-generic: @@ -1262,17 +1665,19 @@ distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -rm -f ../include/$(DEPDIR)/$(am__dirstamp) + -rm -f ../include/$(am__dirstamp) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am -clean-am: clean-binPROGRAMS clean-generic clean-local \ - clean-pkglibexecPROGRAMS clean-soPROGRAMS mostlyclean-am +clean-am: clean-binPROGRAMS clean-generic clean-pkglibexecPROGRAMS \ + clean-soPROGRAMS mostlyclean-am distclean: distclean-am - -rm -rf ./$(DEPDIR) + -rm -rf ../include/$(DEPDIR) ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -1319,7 +1724,7 @@ installcheck-am: maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) + -rm -rf ../include/$(DEPDIR) ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -1341,45 +1746,38 @@ .MAKE: install-am install-strip -.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ - clean-generic clean-local clean-pkglibexecPROGRAMS \ - clean-soPROGRAMS ctags distclean distclean-compile \ - distclean-generic distclean-tags distdir dvi dvi-am html \ - html-am info info-am install install-am install-binPROGRAMS \ - install-binSCRIPTS install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-exec-local \ - install-html install-html-am install-info install-info-am \ - install-man install-pdf install-pdf-am \ - install-pkgincludeHEADERS install-pkglibexecPROGRAMS \ - install-ps install-ps-am install-soPROGRAMS install-strip \ - installcheck installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ - uninstall-am uninstall-binPROGRAMS uninstall-binSCRIPTS \ - uninstall-local uninstall-pkgincludeHEADERS \ - uninstall-pkglibexecPROGRAMS uninstall-soPROGRAMS +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ + clean-binPROGRAMS clean-generic clean-pkglibexecPROGRAMS \ + clean-soPROGRAMS cscopelist-am ctags ctags-am distclean \ + distclean-compile distclean-generic distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-binPROGRAMS install-binSCRIPTS install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-exec-local install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-pkgincludeHEADERS \ + install-pkglibexecPROGRAMS install-ps install-ps-am \ + install-soPROGRAMS install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \ + ps ps-am tags tags-am uninstall uninstall-am \ + uninstall-binPROGRAMS uninstall-binSCRIPTS uninstall-local \ + uninstall-pkgincludeHEADERS uninstall-pkglibexecPROGRAMS \ + uninstall-soPROGRAMS install-exec-local: install-soPROGRAMS + mkdir -p $(DESTDIR)$(datadir)/lxc + install -c -m 644 lxc.functions $(DESTDIR)$(datadir)/lxc mv $(DESTDIR)$(libdir)/liblxc.so $(DESTDIR)$(libdir)/liblxc.so.$(VERSION) /sbin/ldconfig -l $(DESTDIR)$(libdir)/liblxc.so.$(VERSION) cd $(DESTDIR)$(libdir); \ + ln -sf liblxc.so.$(VERSION) liblxc.so.$(firstword $(subst ., ,$(VERSION))); \ ln -sf liblxc.so.$(firstword $(subst ., ,$(VERSION))) liblxc.so uninstall-local: $(RM) $(DESTDIR)$(libdir)/liblxc.so* -namespace.c: setns.h - -setns.h: - -$(CC) $(CPPFLAGS) -M -MT$@ $(LINUX_DIR)/arch/$(LINUX_SRCARCH)/include/asm/unistd.h >setns.P - -$(CPP) $(CPPFLAGS) -dM $(LINUX_DIR)/arch/$(LINUX_SRCARCH)/include/asm/unistd.h |grep setns > $@ - -clean-local: - $(RM) setns.h setns.P - --include setns.P - # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff -Nru lxc-0.8.0~rc1/src/lxc/af_unix.c lxc-1.0.0~alpha1/src/lxc/af_unix.c --- lxc-0.8.0~rc1/src/lxc/af_unix.c 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/af_unix.c 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,7 +18,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include @@ -36,6 +36,7 @@ int lxc_af_unix_open(const char *path, int type, int flags) { int fd; + size_t len; struct sockaddr_un addr; if (flags & O_TRUNC) @@ -52,16 +53,28 @@ addr.sun_family = AF_UNIX; /* copy entire buffer in case of abstract socket */ - memcpy(addr.sun_path, path, - path[0]?strlen(path):sizeof(addr.sun_path)); + len = sizeof(addr.sun_path); + if (path[0]) { + len = strlen(path); + if (len >= sizeof(addr.sun_path)) { + close(fd); + errno = ENAMETOOLONG; + return -1; + } + } + memcpy(addr.sun_path, path, len); if (bind(fd, (struct sockaddr *)&addr, sizeof(addr))) { + int tmp = errno; close(fd); + errno = tmp; return -1; } - + if (type == SOCK_STREAM && listen(fd, 100)) { + int tmp = errno; close(fd); + errno = tmp; return -1; } @@ -71,9 +84,9 @@ int lxc_af_unix_close(int fd) { struct sockaddr_un addr; - socklen_t addrlen; - - if (!getsockname(fd, (struct sockaddr *)&addr, &addrlen) && + socklen_t addrlen = sizeof(addr); + + if (!getsockname(fd, (struct sockaddr *)&addr, &addrlen) && addr.sun_path[0]) unlink(addr.sun_path); @@ -95,11 +108,13 @@ addr.sun_family = AF_UNIX; /* copy entire buffer in case of abstract socket */ - memcpy(addr.sun_path, path, + memcpy(addr.sun_path, path, path[0]?strlen(path):sizeof(addr.sun_path)); if (connect(fd, (struct sockaddr *)&addr, sizeof(addr))) { + int tmp = errno; close(fd); + errno = tmp; return -1; } @@ -161,7 +176,7 @@ cmsg = CMSG_FIRSTHDR(&msg); - /* if the message is wrong the variable will not be + /* if the message is wrong the variable will not be * filled and the peer will notified about a problem */ *recvfd = -1; diff -Nru lxc-0.8.0~rc1/src/lxc/af_unix.h lxc-1.0.0~alpha1/src/lxc/af_unix.h --- lxc-0.8.0~rc1/src/lxc/af_unix.h 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/af_unix.h 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,7 +18,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ extern int lxc_af_unix_open(const char *path, int type, int flags); diff -Nru lxc-0.8.0~rc1/src/lxc/apparmor.c lxc-1.0.0~alpha1/src/lxc/apparmor.c --- lxc-0.8.0~rc1/src/lxc/apparmor.c 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/apparmor.c 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,216 @@ +/* apparmor + * + * Copyright © 2012 Serge Hallyn . + * Copyright © 2012 Canonical Ltd. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "apparmor.h" + +lxc_log_define(lxc_apparmor, lxc); + +#if HAVE_APPARMOR +#include + +#define AA_MOUNT_RESTR "/sys/kernel/security/apparmor/features/mount/mask" +#define AA_ENABLED_FILE "/sys/module/apparmor/parameters/enabled" + + +/* caller must free the returned profile */ +extern char *aa_get_profile(pid_t pid) +{ + char path[100], *space; + int ret; + char *buf = NULL; + int sz = 0; + FILE *f; + + ret = snprintf(path, 100, "/proc/%d/attr/current", pid); + if (ret < 0 || ret >= 100) { + ERROR("path name too long"); + return NULL; + } +again: + f = fopen(path, "r"); + if (!f) { + SYSERROR("opening %s\n", path); + if (buf) + free(buf); + return NULL; + } + sz += 1024; + buf = realloc(buf, sz); + memset(buf, 0, sz); + if (!buf) { + ERROR("out of memory"); + fclose(f); + return NULL; + } + ret = fread(buf, 1, sz - 1, f); + fclose(f); + if (ret >= sz) + goto again; + if (ret < 0) { + ERROR("reading %s\n", path); + free(buf); + return NULL; + } + space = index(buf, ' '); + if (space) + *space = '\0'; + return buf; +} + +static int aa_am_unconfined(void) +{ + char *p = aa_get_profile(getpid()); + int ret = 0; + if (!p || strcmp(p, "unconfined") == 0) + ret = 1; + if (p) + free(p); + return ret; +} + +/* aa_getcon is not working right now. Use our hand-rolled version below */ +static int check_apparmor_enabled(void) +{ + struct stat statbuf; + FILE *fin; + char e; + int ret; + + ret = stat(AA_MOUNT_RESTR, &statbuf); + if (ret != 0) + return 0; + fin = fopen(AA_ENABLED_FILE, "r"); + if (!fin) + return 0; + ret = fscanf(fin, "%c", &e); + fclose(fin); + if (ret == 1 && e == 'Y') + return 1; + return 0; +} + +extern void apparmor_handler_init(struct lxc_handler *handler) +{ + handler->aa_enabled = check_apparmor_enabled(); + INFO("aa_enabled set to %d\n", handler->aa_enabled); +} + +#define AA_DEF_PROFILE "lxc-container-default" + +extern int do_apparmor_load(int aa_enabled, char *aa_profile, + int umount_proc, int dropprivs) +{ + if (!aa_enabled) { + INFO("apparmor not enabled"); + return 0; + } + INFO("setting up apparmor"); + + if (!aa_profile) + aa_profile = AA_DEF_PROFILE; + + if (strcmp(aa_profile, "unconfined") == 0 && !dropprivs && aa_am_unconfined()) { + INFO("apparmor profile unchanged"); + return 0; + } + + //if (aa_change_onexec(aa_profile) < 0) { + if (aa_change_profile(aa_profile) < 0) { + SYSERROR("failed to change apparmor profile to %s", aa_profile); + return -1; + } + if (umount_proc == 1) + umount("/proc"); + + INFO("changed apparmor profile to %s", aa_profile); + + return 0; +} + +extern int apparmor_load(struct lxc_handler *handler) +{ + if (!handler->conf->aa_profile) + handler->conf->aa_profile = AA_DEF_PROFILE; + return do_apparmor_load(handler->aa_enabled, + handler->conf->aa_profile, + handler->conf->lsm_umount_proc, 0); +} + +extern int attach_apparmor(char *profile) +{ + if (!profile) + return 0; + if (!check_apparmor_enabled()) + return 0; + if (strcmp(profile, "unconfined") == 0) + return 0; + return do_apparmor_load(1, profile, 0, 1); +} + +/* + * this will likely move to a generic lsm.c, as selinux and smack will both + * also want proc mounted in the container so as to transition + */ +extern int lsm_mount_proc_if_needed(char *root_src, char *rootfs_tgt) +{ + char path[MAXPATHLEN]; + char link[20]; + int linklen, ret; + + ret = snprintf(path, MAXPATHLEN, "%s/proc/self", root_src ? rootfs_tgt : ""); + if (ret < 0 || ret >= MAXPATHLEN) { + SYSERROR("proc path name too long"); + return -1; + } + memset(link, 0, 20); + linklen = readlink(path, link, 20); + INFO("I am %d, /proc/self points to %s\n", getpid(), link); + ret = snprintf(path, MAXPATHLEN, "%s/proc", root_src ? rootfs_tgt : ""); + if (linklen < 0) /* /proc not mounted */ + goto domount; + /* can't be longer than rootfs/proc/1 */ + if (strncmp(link, "1", linklen) != 0) { + /* wrong /procs mounted */ + umount2(path, MNT_DETACH); /* ignore failure */ + goto domount; + } + /* the right proc is already mounted */ + return 0; + +domount: + if (mount("proc", path, "proc", 0, NULL)) + return -1; + INFO("Mounted /proc for the container\n"); + return 1; +} +#else +extern void apparmor_handler_init(struct lxc_handler *handler) { + INFO("apparmor_load - apparmor is disabled"); +} +#endif diff -Nru lxc-0.8.0~rc1/src/lxc/apparmor.h lxc-1.0.0~alpha1/src/lxc/apparmor.h --- lxc-0.8.0~rc1/src/lxc/apparmor.h 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/apparmor.h 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,56 @@ +/* apparmor + * + * Copyright © 2012 Serge Hallyn . + * Copyright © 2012 Canonical Ltd. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include /* for lxc_handler */ +#include + +struct lxc_handler; + +/* + * apparmor_handler_init is really just a wrapper around check_apparmor_enabled + * to allow us to keep from having #ifdef APPARMOR in start.c + */ +extern void apparmor_handler_init(struct lxc_handler *handler); + +#if HAVE_APPARMOR +extern char *aa_get_profile(pid_t pid); +extern int do_apparmor_load(int aa_enabled, char *aa_profile, + int umount_proc, int dropprivs); +extern int apparmor_load(struct lxc_handler *handler); +extern int attach_apparmor(char *profile); +extern int lsm_mount_proc_if_needed(char *root_src, char *rootfs_tgt); +#else +static inline char *aa_get_profile(pid_t pid) { + return NULL; +} +static inline int do_apparmor_load(int aa_enabled, char *aa_profile, + int umount_proc, int dropprivs) { + return 0; +} +static inline int attach_apparmor(char *profile) { + return 0; +} +static inline int apparmor_load(struct lxc_handler *handler) { + return 0; +} +static inline int lsm_mount_proc_if_needed(char *root_src, char *rootfs_tgt) { + return 0; +} +#endif diff -Nru lxc-0.8.0~rc1/src/lxc/arguments.c lxc-1.0.0~alpha1/src/lxc/arguments.c --- lxc-0.8.0~rc1/src/lxc/arguments.c 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/arguments.c 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * Michel Normand * * This library is free software; you can redistribute it and/or @@ -19,7 +19,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include @@ -32,6 +32,7 @@ #include #include "arguments.h" +#include "utils.h" /*---------------------------------------------------------------------------*/ static int build_shortopts(const struct option *a_options, @@ -136,6 +137,7 @@ -o, --logfile=FILE Output log to FILE instead of stderr\n\ -l, --logpriority=LEVEL Set log priority to LEVEL\n\ -q, --quiet Don't produce any output\n\ + -P, --lxcpath=PATH Use specified container path\n\ -?, --help Give this help list\n\ --usage Give a short usage message\n\ \n\ @@ -145,9 +147,31 @@ See the %s man page for further information.\n\n", args->progname, args->help, args->progname); + if (args->helpfn) + args->helpfn(args); exit(code); } +static int lxc_arguments_lxcpath_add(struct lxc_arguments *args, + const char *lxcpath) +{ + if (args->lxcpath_additional != -1 && + args->lxcpath_cnt > args->lxcpath_additional) { + fprintf(stderr, "This command only accepts %d -P,--lxcpath arguments\n", + args->lxcpath_additional + 1); + exit(EXIT_FAILURE); + } + + args->lxcpath = realloc(args->lxcpath, (args->lxcpath_cnt + 1) * + sizeof(args->lxcpath[0])); + if (args->lxcpath == NULL) { + lxc_error(args, "no memory"); + return -ENOMEM; + } + args->lxcpath[args->lxcpath_cnt++] = lxcpath; + return 0; +} + extern int lxc_arguments_parse(struct lxc_arguments *args, int argc, char * const argv[]) { @@ -171,8 +195,12 @@ case 'n': args->name = optarg; break; case 'o': args->log_file = optarg; break; case 'l': args->log_priority = optarg; break; - case 'c': args->console = optarg; break; case 'q': args->quiet = 1; break; + case 'P': + ret = lxc_arguments_lxcpath_add(args, optarg); + if (ret < 0) + return ret; + break; case OPT_USAGE: print_usage(args->options, args); case '?': print_help(args, 1); case 'h': print_help(args, 0); @@ -191,6 +219,13 @@ args->argv = &argv[optind]; args->argc = argc - optind; + /* If no lxcpaths were given, use default */ + if (!args->lxcpath_cnt) { + ret = lxc_arguments_lxcpath_add(args, default_lxc_path()); + if (ret < 0) + return ret; + } + /* Check the command options */ if (!args->name) { diff -Nru lxc-0.8.0~rc1/src/lxc/arguments.h lxc-1.0.0~alpha1/src/lxc/arguments.h --- lxc-0.8.0~rc1/src/lxc/arguments.h 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/arguments.h 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * Michel Normand * * This library is free software; you can redistribute it and/or @@ -19,7 +19,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __arguments_h #define __arguments_h @@ -33,6 +33,7 @@ struct lxc_arguments { const char *help; + void(*helpfn)(const struct lxc_arguments *); const char *progname; const struct option* options; lxc_arguments_parser_t parser; @@ -45,6 +46,12 @@ int daemonize; const char *rcfile; const char *console; + const char *console_log; + const char *pidfile; + const char **lxcpath; + int lxcpath_cnt; + /* set to 0 to accept only 1 lxcpath, -1 for unlimited */ + int lxcpath_additional; /* for lxc-checkpoint/restart */ const char *statefile; @@ -55,12 +62,27 @@ int ttynum; char escape; - /* for lxc-wait */ + /* for lxc-wait and lxc-shutdown */ char *states; + long timeout; + int nowait; + int reboot; + int hardstop; + int shutdown; + + /* for lxc-destroy */ + int force; /* close fds from parent? */ int close_all_fds; + /* lxc-create */ + char *bdevtype, *configfile, *template; + char *fstype; + unsigned long fssize; + char *lvname, *vgname; + char *zfsroot, *lowerdir, *dir; + /* remaining arguments */ char *const *argv; int argc; @@ -76,6 +98,7 @@ {"quiet", no_argument, 0, 'q'}, \ {"logfile", required_argument, 0, 'o'}, \ {"logpriority", required_argument, 0, 'l'}, \ + {"lxcpath", required_argument, 0, 'P'}, \ {0, 0, 0, 0} /* option keys for long only options */ diff -Nru lxc-0.8.0~rc1/src/lxc/attach.c lxc-1.0.0~alpha1/src/lxc/attach.c --- lxc-0.8.0~rc1/src/lxc/attach.c 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/attach.c 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,7 +18,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #define _GNU_SOURCE @@ -30,6 +30,12 @@ #include #include #include +#include +#include +#include +#include +#include +#include #if !HAVE_DECL_PR_CAPBSET_DROP #define PR_CAPBSET_DROP 24 @@ -39,32 +45,30 @@ #include "log.h" #include "attach.h" #include "caps.h" -#include "cgroup.h" #include "config.h" +#include "apparmor.h" +#include "utils.h" +#include "commands.h" +#include "cgroup.h" -#include "setns.h" - -lxc_log_define(lxc_attach, lxc); +#if HAVE_SYS_PERSONALITY_H +#include +#endif -int setns(int fd, int nstype) -{ -#ifndef __NR_setns - errno = ENOSYS; - return -1; -#else - return syscall(__NR_setns, fd, nstype); +#ifndef SOCK_CLOEXEC +# define SOCK_CLOEXEC 02000000 #endif -} + +lxc_log_define(lxc_attach, lxc); struct lxc_proc_context_info *lxc_proc_get_context_info(pid_t pid) { struct lxc_proc_context_info *info = calloc(1, sizeof(*info)); FILE *proc_file; char proc_fn[MAXPATHLEN]; - char *line = NULL, *ptr, *ptr2; + char *line = NULL; size_t line_bufsz = 0; - int ret, found, l; - int i; + int ret, found; if (!info) { SYSERROR("Could not allocate memory."); @@ -89,6 +93,8 @@ } } + if (line) + free(line); fclose(proc_file); if (!found) { @@ -114,148 +120,120 @@ errno = ENOENT; goto out_error; } - - /* read cgroups */ - snprintf(proc_fn, MAXPATHLEN, "/proc/%d/cgroup", pid); - - proc_file = fopen(proc_fn, "r"); - if (!proc_file) { - SYSERROR("Could not open %s", proc_fn); - goto out_error; - } - - /* we don't really know how many cgroup subsystems there are - * mounted, so we go through the whole file twice */ - i = 0; - while (getline(&line, &line_bufsz, proc_file) != -1) { - /* we assume that all lines containing at least two colons - * are valid */ - ptr = strchr(line, ':'); - if (ptr && strchr(ptr + 1, ':')) - i++; - } - - rewind(proc_file); - - info->cgroups = calloc(i, sizeof(*(info->cgroups))); - info->cgroups_count = i; - - i = 0; - while (getline(&line, &line_bufsz, proc_file) != -1 && i < info->cgroups_count) { - /* format of the lines is: - * id:subsystems:path, where subsystems are separated by - * commas and each subsystem may also be of the form - * name=xxx if it describes a private named hierarchy - * we will ignore the id in the following */ - ptr = strchr(line, ':'); - ptr2 = ptr ? strchr(ptr + 1, ':') : NULL; - - /* ignore invalid lines */ - if (!ptr || !ptr2) continue; - - l = strlen(ptr2) - 1; - if (ptr2[l] == '\n') - ptr2[l] = '\0'; - - info->cgroups[i].subsystems = strndup(ptr + 1, ptr2 - (ptr + 1)); - info->cgroups[i].cgroup = strdup(ptr2 + 1); - - i++; - } - - free(line); - fclose(proc_file); + info->aa_profile = aa_get_profile(pid); return info; out_error: - lxc_proc_free_context_info(info); - free(line); + free(info); return NULL; } -void lxc_proc_free_context_info(struct lxc_proc_context_info *info) +int lxc_attach_to_ns(pid_t pid, int which) { - if (!info) - return; - - if (info->cgroups) { - int i; - for (i = 0; i < info->cgroups_count; i++) { - free(info->cgroups[i].subsystems); - free(info->cgroups[i].cgroup); - } - } - free(info->cgroups); - free(info); -} + char path[MAXPATHLEN]; + /* according to , + * the file for user namepsaces in /proc/$pid/ns will be called + * 'user' once the kernel supports it + */ + static char *ns[] = { "mnt", "pid", "uts", "ipc", "user", "net" }; + static int flags[] = { + CLONE_NEWNS, CLONE_NEWPID, CLONE_NEWUTS, CLONE_NEWIPC, + CLONE_NEWUSER, CLONE_NEWNET + }; + static const int size = sizeof(ns) / sizeof(char *); + int fd[size]; + int i, j, saved_errno; -int lxc_attach_proc_to_cgroups(pid_t pid, struct lxc_proc_context_info *ctx) -{ - int i, ret; - if (!ctx) { - ERROR("No valid context supplied when asked to attach " - "process to cgroups."); + snprintf(path, MAXPATHLEN, "/proc/%d/ns", pid); + if (access(path, X_OK)) { + ERROR("Does this kernel version support 'attach' ?"); return -1; } - for (i = 0; i < ctx->cgroups_count; i++) { - char *path; + for (i = 0; i < size; i++) { + /* ignore if we are not supposed to attach to that + * namespace + */ + if (which != -1 && !(which & flags[i])) { + fd[i] = -1; + continue; + } + + snprintf(path, MAXPATHLEN, "/proc/%d/ns/%s", pid, ns[i]); + fd[i] = open(path, O_RDONLY | O_CLOEXEC); + if (fd[i] < 0) { + saved_errno = errno; - /* the kernel should return paths that start with '/' */ - if (ctx->cgroups[i].cgroup[0] != '/') { - ERROR("For cgroup subsystem(s) %s the path '%s' does " - "not start with a '/'", - ctx->cgroups[i].subsystems, - ctx->cgroups[i].cgroup); + /* close all already opened file descriptors before + * we return an error, so we don't leak them + */ + for (j = 0; j < i; j++) + close(fd[j]); + + errno = saved_errno; + SYSERROR("failed to open '%s'", path); return -1; } + } - /* lxc_cgroup_path_get can process multiple subsystems */ - ret = lxc_cgroup_path_get(&path, ctx->cgroups[i].subsystems, - &ctx->cgroups[i].cgroup[1]); - if (ret) - return -1; + for (i = 0; i < size; i++) { + if (fd[i] >= 0 && setns(fd[i], 0) != 0) { + saved_errno = errno; - ret = lxc_cgroup_attach(path, pid); - if (ret) + for (j = i; j < size; j++) + close(fd[j]); + + errno = saved_errno; + SYSERROR("failed to set namespace '%s'", ns[i]); return -1; + } + + close(fd[i]); } return 0; } -int lxc_attach_to_ns(pid_t pid) +int lxc_attach_remount_sys_proc() { - char path[MAXPATHLEN]; - char *ns[] = { "pid", "mnt", "net", "ipc", "uts" }; - const int size = sizeof(ns) / sizeof(char *); - int fd[size]; - int i; + int ret; - snprintf(path, MAXPATHLEN, "/proc/%d/ns", pid); - if (access(path, X_OK)) { - ERROR("Does this kernel version support 'attach' ?"); + ret = unshare(CLONE_NEWNS); + if (ret < 0) { + SYSERROR("failed to unshare mount namespace"); return -1; } - for (i = 0; i < size; i++) { - snprintf(path, MAXPATHLEN, "/proc/%d/ns/%s", pid, ns[i]); - fd[i] = open(path, O_RDONLY); - if (fd[i] < 0) { - SYSERROR("failed to open '%s'", path); - return -1; - } + /* assume /proc is always mounted, so remount it */ + ret = umount2("/proc", MNT_DETACH); + if (ret < 0) { + SYSERROR("failed to unmount /proc"); + return -1; } - for (i = 0; i < size; i++) { - if (setns(fd[i], 0)) { - SYSERROR("failed to set namespace '%s'", ns[i]); + ret = mount("none", "/proc", "proc", 0, NULL); + if (ret < 0) { + SYSERROR("failed to remount /proc"); + return -1; + } + + /* try to umount /sys - if it's not a mount point, + * we'll get EINVAL, then we ignore it because it + * may not have been mounted in the first place + */ + ret = umount2("/sys", MNT_DETACH); + if (ret < 0 && errno != EINVAL) { + SYSERROR("failed to unmount /sys"); + return -1; + } else if (ret == 0) { + /* remount it */ + ret = mount("none", "/sys", "sysfs", 0, NULL); + if (ret < 0) { + SYSERROR("failed to remount /sys"); return -1; } - - close(fd[i]); } return 0; @@ -278,3 +256,801 @@ return 0; } + +int lxc_attach_set_environment(enum lxc_attach_env_policy_t policy, char** extra_env, char** extra_keep) +{ + if (policy == LXC_ATTACH_CLEAR_ENV) { + char **extra_keep_store = NULL; + int path_kept = 0; + + if (extra_keep) { + size_t count, i; + + for (count = 0; extra_keep[count]; count++); + + extra_keep_store = calloc(count, sizeof(char *)); + if (!extra_keep_store) { + SYSERROR("failed to allocate memory for storing current " + "environment variable values that will be kept"); + return -1; + } + for (i = 0; i < count; i++) { + char *v = getenv(extra_keep[i]); + if (v) { + extra_keep_store[i] = strdup(v); + if (!extra_keep_store[i]) { + SYSERROR("failed to allocate memory for storing current " + "environment variable values that will be kept"); + while (i > 0) + free(extra_keep_store[--i]); + free(extra_keep_store); + return -1; + } + if (strcmp(extra_keep[i], "PATH") == 0) + path_kept = 1; + } + /* calloc sets entire array to zero, so we don't + * need an else */ + } + } + + if (clearenv()) { + char **p; + SYSERROR("failed to clear environment"); + if (extra_keep_store) { + for (p = extra_keep_store; *p; p++) + free(*p); + free(extra_keep_store); + } + return -1; + } + + if (extra_keep_store) { + size_t i; + for (i = 0; extra_keep[i]; i++) { + if (extra_keep_store[i]) + setenv(extra_keep[i], extra_keep_store[i], 1); + free(extra_keep_store[i]); + } + free(extra_keep_store); + } + + /* always set a default path; shells and execlp tend + * to be fine without it, but there is a disturbing + * number of C programs out there that just assume + * that getenv("PATH") is never NULL and then die a + * painful segfault death. */ + if (!path_kept) { +#ifdef HAVE_CONFSTR + size_t n; + char *path_env; + + n = confstr(_CS_PATH, NULL, 0); + path_env = malloc(n); + if (path_env) { + confstr(_CS_PATH, path_env, n); + setenv("PATH", path_env, 1); + free(path_env); + } + /* don't error out, this is just an extra service */ +#else + setenv("PATH", "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", 1); +#endif + } + } + + if (putenv("container=lxc")) { + SYSERROR("failed to set environment variable"); + return -1; + } + + /* set extra environment variables */ + if (extra_env) { + for (; *extra_env; extra_env++) { + /* duplicate the string, just to be on + * the safe side, because putenv does not + * do it for us */ + char *p = strdup(*extra_env); + /* we just assume the user knows what they + * are doing, so we don't do any checks */ + if (!p) { + SYSERROR("failed to allocate memory for additional environment " + "variables"); + return -1; + } + putenv(p); + } + } + + return 0; +} + +char *lxc_attach_getpwshell(uid_t uid) +{ + /* local variables */ + pid_t pid; + int pipes[2]; + int ret; + int fd; + char *result = NULL; + + /* we need to fork off a process that runs the + * getent program, and we need to capture its + * output, so we use a pipe for that purpose + */ + ret = pipe(pipes); + if (ret < 0) + return NULL; + + pid = fork(); + if (pid < 0) { + close(pipes[0]); + close(pipes[1]); + return NULL; + } + + if (pid) { + /* parent process */ + FILE *pipe_f; + char *line = NULL; + size_t line_bufsz = 0; + int found = 0; + int status; + + close(pipes[1]); + + pipe_f = fdopen(pipes[0], "r"); + while (getline(&line, &line_bufsz, pipe_f) != -1) { + char *token; + char *saveptr = NULL; + long value; + char *endptr = NULL; + int i; + + /* if we already found something, just continue + * to read until the pipe doesn't deliver any more + * data, but don't modify the existing data + * structure + */ + if (found) + continue; + + /* trim line on the right hand side */ + for (i = strlen(line); i > 0 && (line[i - 1] == '\n' || line[i - 1] == '\r'); --i) + line[i - 1] = '\0'; + + /* split into tokens: first user name */ + token = strtok_r(line, ":", &saveptr); + if (!token) + continue; + /* next: dummy password field */ + token = strtok_r(NULL, ":", &saveptr); + if (!token) + continue; + /* next: user id */ + token = strtok_r(NULL, ":", &saveptr); + value = token ? strtol(token, &endptr, 10) : 0; + if (!token || !endptr || *endptr || value == LONG_MIN || value == LONG_MAX) + continue; + /* dummy sanity check: user id matches */ + if ((uid_t) value != uid) + continue; + /* skip fields: gid, gecos, dir, go to next field 'shell' */ + for (i = 0; i < 4; i++) { + token = strtok_r(NULL, ":", &saveptr); + if (!token) + break; + } + if (!token) + continue; + if (result) + free(result); + result = strdup(token); + + /* sanity check that there are no fields after that */ + token = strtok_r(NULL, ":", &saveptr); + if (token) + continue; + + found = 1; + } + + free(line); + fclose(pipe_f); + again: + if (waitpid(pid, &status, 0) < 0) { + if (errno == EINTR) + goto again; + return NULL; + } + + /* some sanity checks: if anything even hinted at going + * wrong: we can't be sure we have a valid result, so + * we assume we don't + */ + + if (!WIFEXITED(status)) + return NULL; + + if (WEXITSTATUS(status) != 0) + return NULL; + + if (!found) + return NULL; + + return result; + } else { + /* child process */ + char uid_buf[32]; + char *arguments[] = { + "getent", + "passwd", + uid_buf, + NULL + }; + + close(pipes[0]); + + /* we want to capture stdout */ + dup2(pipes[1], 1); + close(pipes[1]); + + /* get rid of stdin/stderr, so we try to associate it + * with /dev/null + */ + fd = open("/dev/null", O_RDWR); + if (fd < 0) { + close(0); + close(2); + } else { + dup2(fd, 0); + dup2(fd, 2); + close(fd); + } + + /* finish argument list */ + ret = snprintf(uid_buf, sizeof(uid_buf), "%ld", (long) uid); + if (ret <= 0) + exit(-1); + + /* try to run getent program */ + (void) execvp("getent", arguments); + exit(-1); + } +} + +void lxc_attach_get_init_uidgid(uid_t* init_uid, gid_t* init_gid) +{ + FILE *proc_file; + char proc_fn[MAXPATHLEN]; + char *line = NULL; + size_t line_bufsz = 0; + int ret; + long value = -1; + uid_t uid = (uid_t)-1; + gid_t gid = (gid_t)-1; + + /* read capabilities */ + snprintf(proc_fn, MAXPATHLEN, "/proc/%d/status", 1); + + proc_file = fopen(proc_fn, "r"); + if (!proc_file) + return; + + while (getline(&line, &line_bufsz, proc_file) != -1) { + /* format is: real, effective, saved set user, fs + * we only care about real uid + */ + ret = sscanf(line, "Uid: %ld", &value); + if (ret != EOF && ret > 0) { + uid = (uid_t) value; + } else { + ret = sscanf(line, "Gid: %ld", &value); + if (ret != EOF && ret > 0) + gid = (gid_t) value; + } + if (uid != (uid_t)-1 && gid != (gid_t)-1) + break; + } + + fclose(proc_file); + free(line); + + /* only override arguments if we found something */ + if (uid != (uid_t)-1) + *init_uid = uid; + if (gid != (gid_t)-1) + *init_gid = gid; + + /* TODO: we should also parse supplementary groups and use + * setgroups() to set them */ +} + +struct attach_clone_payload { + int ipc_socket; + lxc_attach_options_t* options; + struct lxc_proc_context_info* init_ctx; + lxc_attach_exec_t exec_function; + void* exec_payload; +}; + +static int attach_child_main(void* data); + +/* help the optimizer along if it doesn't know that exit always exits */ +#define rexit(c) do { int __c = (c); exit(__c); return __c; } while(0) + +/* define default options if no options are supplied by the user */ +static lxc_attach_options_t attach_static_default_options = LXC_ATTACH_OPTIONS_DEFAULT; + +int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t exec_function, void* exec_payload, lxc_attach_options_t* options, pid_t* attached_process) +{ + int ret, status; + pid_t init_pid, pid, attached_pid; + struct lxc_proc_context_info *init_ctx; + char* cwd; + char* new_cwd; + int ipc_sockets[2]; + + if (!options) + options = &attach_static_default_options; + + init_pid = lxc_cmd_get_init_pid(name, lxcpath); + if (init_pid < 0) { + ERROR("failed to get the init pid"); + return -1; + } + + init_ctx = lxc_proc_get_context_info(init_pid); + if (!init_ctx) { + ERROR("failed to get context of the init process, pid = %ld", (long)init_pid); + return -1; + } + + cwd = getcwd(NULL, 0); + + /* determine which namespaces the container was created with + * by asking lxc-start, if necessary + */ + if (options->namespaces == -1) { + options->namespaces = lxc_cmd_get_clone_flags(name, lxcpath); + /* call failed */ + if (options->namespaces == -1) { + ERROR("failed to automatically determine the " + "namespaces which the container unshared"); + free(cwd); + free(init_ctx->aa_profile); + free(init_ctx); + return -1; + } + } + + /* create a socket pair for IPC communication; set SOCK_CLOEXEC in order + * to make sure we don't irritate other threads that want to fork+exec away + * + * IMPORTANT: if the initial process is multithreaded and another call + * just fork()s away without exec'ing directly after, the socket fd will + * exist in the forked process from the other thread and any close() in + * our own child process will not really cause the socket to close properly, + * potentiall causing the parent to hang. + * + * For this reason, while IPC is still active, we have to use shutdown() + * if the child exits prematurely in order to signal that the socket + * is closed and cannot assume that the child exiting will automatically + * do that. + * + * IPC mechanism: (X is receiver) + * initial process intermediate attached + * X <--- send pid of + * attached proc, + * then exit + * send 0 ------------------------------------> X + * [do initialization] + * X <------------------------------------ send 1 + * [add to cgroup, ...] + * send 2 ------------------------------------> X + * close socket close socket + * run program + */ + ret = socketpair(PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0, ipc_sockets); + if (ret < 0) { + SYSERROR("could not set up required IPC mechanism for attaching"); + free(cwd); + free(init_ctx->aa_profile); + free(init_ctx); + return -1; + } + + /* create intermediate subprocess, three reasons: + * 1. runs all pthread_atfork handlers and the + * child will no longer be threaded + * (we can't properly setns() in a threaded process) + * 2. we can't setns() in the child itself, since + * we want to make sure we are properly attached to + * the pidns + * 3. also, the initial thread has to put the attached + * process into the cgroup, which we can only do if + * we didn't already setns() (otherwise, user + * namespaces will hate us) + */ + pid = fork(); + + if (pid < 0) { + SYSERROR("failed to create first subprocess"); + free(cwd); + free(init_ctx->aa_profile); + free(init_ctx); + return -1; + } + + if (pid) { + pid_t to_cleanup_pid = pid; + int expected = 0; + + /* inital thread, we close the socket that is for the + * subprocesses + */ + close(ipc_sockets[1]); + free(cwd); + + /* get pid from intermediate process */ + ret = lxc_read_nointr_expect(ipc_sockets[0], &attached_pid, sizeof(attached_pid), NULL); + if (ret <= 0) { + if (ret != 0) + ERROR("error using IPC to receive pid of attached process"); + goto cleanup_error; + } + + /* reap intermediate process */ + ret = wait_for_pid(pid); + if (ret < 0) + goto cleanup_error; + + /* we will always have to reap the grandchild now */ + to_cleanup_pid = attached_pid; + + /* tell attached process it may start initializing */ + status = 0; + ret = lxc_write_nointr(ipc_sockets[0], &status, sizeof(status)); + if (ret <= 0) { + ERROR("error using IPC to notify attached process for initialization (0)"); + goto cleanup_error; + } + + /* wait for the attached process to finish initializing */ + expected = 1; + ret = lxc_read_nointr_expect(ipc_sockets[0], &status, sizeof(status), &expected); + if (ret <= 0) { + if (ret != 0) + ERROR("error using IPC to receive notification from attached process (1)"); + goto cleanup_error; + } + + /* attach to cgroup, if requested */ + if (options->attach_flags & LXC_ATTACH_MOVE_TO_CGROUP) { + ret = lxc_cgroup_attach(attached_pid, name, lxcpath); + if (ret < 0) { + ERROR("could not move attached process %ld to cgroup of container", (long)attached_pid); + goto cleanup_error; + } + } + + /* tell attached process we're done */ + status = 2; + ret = lxc_write_nointr(ipc_sockets[0], &status, sizeof(status)); + if (ret <= 0) { + ERROR("error using IPC to notify attached process for initialization (2)"); + goto cleanup_error; + } + + /* now shut down communication with child, we're done */ + shutdown(ipc_sockets[0], SHUT_RDWR); + close(ipc_sockets[0]); + free(init_ctx->aa_profile); + free(init_ctx); + + /* we're done, the child process should now execute whatever + * it is that the user requested. The parent can now track it + * with waitpid() or similar. + */ + + *attached_process = attached_pid; + return 0; + + cleanup_error: + /* first shut down the socket, then wait for the pid, + * otherwise the pid we're waiting for may never exit + */ + shutdown(ipc_sockets[0], SHUT_RDWR); + close(ipc_sockets[0]); + if (to_cleanup_pid) + (void) wait_for_pid(to_cleanup_pid); + free(init_ctx->aa_profile); + free(init_ctx); + return -1; + } + + /* first subprocess begins here, we close the socket that is for the + * initial thread + */ + close(ipc_sockets[0]); + + /* attach now, create another subprocess later, since pid namespaces + * only really affect the children of the current process + */ + ret = lxc_attach_to_ns(init_pid, options->namespaces); + if (ret < 0) { + ERROR("failed to enter the namespace"); + shutdown(ipc_sockets[1], SHUT_RDWR); + rexit(-1); + } + + /* attach succeeded, try to cwd */ + if (options->initial_cwd) + new_cwd = options->initial_cwd; + else + new_cwd = cwd; + ret = chdir(new_cwd); + if (ret < 0) + WARN("could not change directory to '%s'", new_cwd); + free(cwd); + + /* now create the real child process */ + { + struct attach_clone_payload payload = { + .ipc_socket = ipc_sockets[1], + .options = options, + .init_ctx = init_ctx, + .exec_function = exec_function, + .exec_payload = exec_payload + }; + /* We use clone_parent here to make this subprocess a direct child of + * the initial process. Then this intermediate process can exit and + * the parent can directly track the attached process. + */ + pid = lxc_clone(attach_child_main, &payload, CLONE_PARENT); + } + + /* shouldn't happen, clone() should always return positive pid */ + if (pid <= 0) { + SYSERROR("failed to create subprocess"); + shutdown(ipc_sockets[1], SHUT_RDWR); + rexit(-1); + } + + /* tell grandparent the pid of the pid of the newly created child */ + ret = lxc_write_nointr(ipc_sockets[1], &pid, sizeof(pid)); + if (ret != sizeof(pid)) { + /* if this really happens here, this is very unfortunate, since the + * parent will not know the pid of the attached process and will + * not be able to wait for it (and we won't either due to CLONE_PARENT) + * so the parent won't be able to reap it and the attached process + * will remain a zombie + */ + ERROR("error using IPC to notify main process of pid of the attached process"); + shutdown(ipc_sockets[1], SHUT_RDWR); + rexit(-1); + } + + /* the rest is in the hands of the initial and the attached process */ + rexit(0); +} + +int attach_child_main(void* data) +{ + struct attach_clone_payload* payload = (struct attach_clone_payload*)data; + int ipc_socket = payload->ipc_socket; + lxc_attach_options_t* options = payload->options; + struct lxc_proc_context_info* init_ctx = payload->init_ctx; +#if HAVE_SYS_PERSONALITY_H + long new_personality; +#endif + int ret; + int status; + int expected; + long flags; + int fd; + uid_t new_uid; + gid_t new_gid; + + /* wait for the initial thread to signal us that it's ready + * for us to start initializing + */ + expected = 0; + status = -1; + ret = lxc_read_nointr_expect(ipc_socket, &status, sizeof(status), &expected); + if (ret <= 0) { + ERROR("error using IPC to receive notification from initial process (0)"); + shutdown(ipc_socket, SHUT_RDWR); + rexit(-1); + } + + /* load apparmor profile */ + if ((options->namespaces & CLONE_NEWNS) && (options->attach_flags & LXC_ATTACH_APPARMOR)) { + ret = attach_apparmor(init_ctx->aa_profile); + if (ret < 0) { + shutdown(ipc_socket, SHUT_RDWR); + rexit(-1); + } + } + + /* A description of the purpose of this functionality is + * provided in the lxc-attach(1) manual page. We have to + * remount here and not in the parent process, otherwise + * /proc may not properly reflect the new pid namespace. + */ + if (!(options->namespaces & CLONE_NEWNS) && (options->attach_flags & LXC_ATTACH_REMOUNT_PROC_SYS)) { + ret = lxc_attach_remount_sys_proc(); + if (ret < 0) { + shutdown(ipc_socket, SHUT_RDWR); + rexit(-1); + } + } + + /* now perform additional attachments*/ +#if HAVE_SYS_PERSONALITY_H + if (options->personality < 0) + new_personality = init_ctx->personality; + else + new_personality = options->personality; + + if (options->attach_flags & LXC_ATTACH_SET_PERSONALITY) { + ret = personality(new_personality); + if (ret < 0) { + SYSERROR("could not ensure correct architecture"); + shutdown(ipc_socket, SHUT_RDWR); + rexit(-1); + } + } +#endif + + if (options->attach_flags & LXC_ATTACH_DROP_CAPABILITIES) { + ret = lxc_attach_drop_privs(init_ctx); + if (ret < 0) { + ERROR("could not drop privileges"); + shutdown(ipc_socket, SHUT_RDWR); + rexit(-1); + } + } + + /* always set the environment (specify (LXC_ATTACH_KEEP_ENV, NULL, NULL) if you want this to be a no-op) */ + ret = lxc_attach_set_environment(options->env_policy, options->extra_env_vars, options->extra_keep_env); + if (ret < 0) { + ERROR("could not set initial environment for attached process"); + shutdown(ipc_socket, SHUT_RDWR); + rexit(-1); + } + + /* set user / group id */ + new_uid = 0; + new_gid = 0; + /* ignore errors, we will fall back to root in that case + * (/proc was not mounted etc.) + */ + if (options->namespaces & CLONE_NEWUSER) + lxc_attach_get_init_uidgid(&new_uid, &new_gid); + + if (options->uid != (uid_t)-1) + new_uid = options->uid; + if (options->gid != (gid_t)-1) + new_gid = options->gid; + + /* try to set the uid/gid combination */ + if ((new_gid != 0 || options->namespaces & CLONE_NEWUSER) && setgid(new_gid)) { + SYSERROR("switching to container gid"); + shutdown(ipc_socket, SHUT_RDWR); + rexit(-1); + } + if ((new_uid != 0 || options->namespaces & CLONE_NEWUSER) && setuid(new_uid)) { + SYSERROR("switching to container uid"); + shutdown(ipc_socket, SHUT_RDWR); + rexit(-1); + } + + /* tell initial process it may now put us into the cgroups */ + status = 1; + ret = lxc_write_nointr(ipc_socket, &status, sizeof(status)); + if (ret != sizeof(status)) { + ERROR("error using IPC to notify initial process for initialization (1)"); + shutdown(ipc_socket, SHUT_RDWR); + rexit(-1); + } + + /* wait for the initial thread to signal us that it has done + * everything for us when it comes to cgroups etc. + */ + expected = 2; + status = -1; + ret = lxc_read_nointr_expect(ipc_socket, &status, sizeof(status), &expected); + if (ret <= 0) { + ERROR("error using IPC to receive final notification from initial process (2)"); + shutdown(ipc_socket, SHUT_RDWR); + rexit(-1); + } + + shutdown(ipc_socket, SHUT_RDWR); + close(ipc_socket); + free(init_ctx->aa_profile); + free(init_ctx); + + /* The following is done after the communication socket is + * shut down. That way, all errors that might (though + * unlikely) occur up until this point will have their messages + * printed to the original stderr (if logging is so configured) + * and not the fd the user supplied, if any. + */ + + /* fd handling for stdin, stdout and stderr; + * ignore errors here, user may want to make sure + * the fds are closed, for example */ + if (options->stdin_fd >= 0 && options->stdin_fd != 0) + dup2(options->stdin_fd, 0); + if (options->stdout_fd >= 0 && options->stdout_fd != 1) + dup2(options->stdout_fd, 1); + if (options->stderr_fd >= 0 && options->stderr_fd != 2) + dup2(options->stderr_fd, 2); + + /* close the old fds */ + if (options->stdin_fd > 2) + close(options->stdin_fd); + if (options->stdout_fd > 2) + close(options->stdout_fd); + if (options->stderr_fd > 2) + close(options->stderr_fd); + + /* try to remove CLOEXEC flag from stdin/stdout/stderr, + * but also here, ignore errors */ + for (fd = 0; fd <= 2; fd++) { + flags = fcntl(fd, F_GETFL); + if (flags < 0) + continue; + if (flags & FD_CLOEXEC) + fcntl(fd, F_SETFL, flags & ~FD_CLOEXEC); + } + + /* we're done, so we can now do whatever the user intended us to do */ + rexit(payload->exec_function(payload->exec_payload)); +} + +int lxc_attach_run_command(void* payload) +{ + lxc_attach_command_t* cmd = (lxc_attach_command_t*)payload; + + execvp(cmd->program, cmd->argv); + SYSERROR("failed to exec '%s'", cmd->program); + return -1; +} + +int lxc_attach_run_shell(void* payload) +{ + uid_t uid; + struct passwd *passwd; + char *user_shell; + + /* ignore payload parameter */ + (void)payload; + + uid = getuid(); + passwd = getpwuid(uid); + + /* this probably happens because of incompatible nss + * implementations in host and container (remember, this + * code is still using the host's glibc but our mount + * namespace is in the container) + * we may try to get the information by spawning a + * [getent passwd uid] process and parsing the result + */ + if (!passwd) + user_shell = lxc_attach_getpwshell(uid); + else + user_shell = passwd->pw_shell; + + if (user_shell) + execlp(user_shell, user_shell, NULL); + + /* executed if either no passwd entry or execvp fails, + * we will fall back on /bin/sh as a default shell + */ + execlp("/bin/sh", "/bin/sh", NULL); + SYSERROR("failed to exec shell"); + return -1; +} diff -Nru lxc-0.8.0~rc1/src/lxc/attach.h lxc-1.0.0~alpha1/src/lxc/attach.h --- lxc-0.8.0~rc1/src/lxc/attach.h 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/attach.h 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,31 +18,32 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _attach_h #define _attach_h #include - -struct lxc_proc_cgroup_info { - char *subsystems; - char *cgroup; -}; +#include "attach_options.h" struct lxc_proc_context_info { + char *aa_profile; unsigned long personality; unsigned long long capability_mask; - struct lxc_proc_cgroup_info* cgroups; - int cgroups_count; }; extern struct lxc_proc_context_info *lxc_proc_get_context_info(pid_t pid); -extern void lxc_proc_free_context_info(struct lxc_proc_context_info *info); -extern int lxc_attach_proc_to_cgroups(pid_t pid, struct lxc_proc_context_info *ctx); -extern int lxc_attach_to_ns(pid_t other_pid); +extern int lxc_attach_to_ns(pid_t other_pid, int which); +extern int lxc_attach_remount_sys_proc(); extern int lxc_attach_drop_privs(struct lxc_proc_context_info *ctx); +extern int lxc_attach_set_environment(enum lxc_attach_env_policy_t policy, char** extra_env, char** extra_keep); + +extern char *lxc_attach_getpwshell(uid_t uid); + +extern void lxc_attach_get_init_uidgid(uid_t* init_uid, gid_t* init_gid); + +extern int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t exec_function, void* exec_payload, lxc_attach_options_t* options, pid_t* attached_process); #endif diff -Nru lxc-0.8.0~rc1/src/lxc/attach_options.h lxc-1.0.0~alpha1/src/lxc/attach_options.h --- lxc-0.8.0~rc1/src/lxc/attach_options.h 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/attach_options.h 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,120 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _LXC_ATTACH_OPTIONS_H +#define _LXC_ATTACH_OPTIONS_H + +#include + +typedef enum lxc_attach_env_policy_t { + LXC_ATTACH_KEEP_ENV, + LXC_ATTACH_CLEAR_ENV +} lxc_attach_env_policy_t; + +enum { + /* the following are on by default: */ + LXC_ATTACH_MOVE_TO_CGROUP = 0x00000001, + LXC_ATTACH_DROP_CAPABILITIES = 0x00000002, + LXC_ATTACH_SET_PERSONALITY = 0x00000004, + LXC_ATTACH_APPARMOR = 0x00000008, + + /* the following are off by default */ + LXC_ATTACH_REMOUNT_PROC_SYS = 0x00010000, + + /* we have 16 bits for things that are on by default + * and 16 bits that are off by default, that should + * be sufficient to keep binary compatibility for + * a while + */ + LXC_ATTACH_DEFAULT = 0x0000FFFF +}; + +typedef struct lxc_attach_options_t lxc_attach_options_t; +typedef int (*lxc_attach_exec_t)(void* payload); + +struct lxc_attach_options_t { + /* any combination of the above enum */ + int attach_flags; + /* the namespaces to attach to (CLONE_NEW... flags) */ + int namespaces; + /* initial personality, -1 to autodetect + * (may be ignored if lxc is compiled w/o personality support) */ + long personality; + + /* inital current directory, use NULL to use cwd + * (might not exist in container, then / will be + * used because of kernel defaults) + */ + char* initial_cwd; + + /* the uid and gid to attach to, + * -1 for default (init uid/gid for userns containers, + * otherwise or if detection fails 0/0) + */ + uid_t uid; + gid_t gid; + + /* environment handling */ + lxc_attach_env_policy_t env_policy; + char** extra_env_vars; + char** extra_keep_env; + + /* file descriptors for stdin, stdout and stderr, + * dup2() will be used before calling exec_function, + * (assuming not 0, 1 and 2 are specified) and the + * original fds are closed before passing control + * over. Any O_CLOEXEC flag will be removed after + * that + */ + int stdin_fd; + int stdout_fd; + int stderr_fd; +}; + +#define LXC_ATTACH_OPTIONS_DEFAULT \ + { \ + /* .attach_flags = */ LXC_ATTACH_DEFAULT, \ + /* .namespaces = */ -1, \ + /* .personality = */ -1, \ + /* .initial_cwd = */ NULL, \ + /* .uid = */ (uid_t)-1, \ + /* .gid = */ (gid_t)-1, \ + /* .env_policy = */ LXC_ATTACH_KEEP_ENV, \ + /* .extra_env_vars = */ NULL, \ + /* .extra_keep_env = */ NULL, \ + /* .stdin_fd = */ 0, 1, 2 \ + } + +typedef struct lxc_attach_command_t { + char* program; /* the program to run (passed to execvp) */ + char** argv; /* the argv pointer of that program, including the program itself in argv[0] */ +} lxc_attach_command_t; + +/* default execution functions: + * run_command: pointer to lxc_attach_command_t + * run_shell: no payload, will be ignored + */ +extern int lxc_attach_run_command(void* payload); +extern int lxc_attach_run_shell(void* payload); + +#endif diff -Nru lxc-0.8.0~rc1/src/lxc/bdev.c lxc-1.0.0~alpha1/src/lxc/bdev.c --- lxc-0.8.0~rc1/src/lxc/bdev.c 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/bdev.c 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,2070 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * this is all just a first shot for experiment. If we go this route, much + * shoudl change. bdev should be a directory with per-bdev file. Things which + * I'm doing by calling out to userspace should sometimes be done through + * libraries like liblvm2 + */ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "lxc.h" +#include "config.h" +#include "conf.h" +#include "bdev.h" +#include "log.h" +#include "error.h" +#include "utils.h" +#include "namespace.h" +#include "parse.h" +#include "utils.h" + +#ifndef BLKGETSIZE64 +#define BLKGETSIZE64 _IOR(0x12,114,size_t) +#endif + +#ifndef LO_FLAGS_AUTOCLEAR +#define LO_FLAGS_AUTOCLEAR 4 +#endif + +lxc_log_define(bdev, lxc); + +static int do_rsync(const char *src, const char *dest) +{ + // call out to rsync + pid_t pid; + char *s; + size_t l; + + pid = fork(); + if (pid < 0) + return -1; + if (pid > 0) + return wait_for_pid(pid); + l = strlen(src) + 2; + s = malloc(l); + if (!s) + exit(1); + strcpy(s, src); + s[l-2] = '/'; + s[l-1] = '\0'; + + execlp("rsync", "rsync", "-a", s, dest, (char *)NULL); + exit(1); +} + +/* + * return block size of dev->src + */ +static int blk_getsize(struct bdev *bdev, unsigned long *size) +{ + int fd, ret; + char *path = bdev->src; + + if (strcmp(bdev->type, "loop") == 0) + path = bdev->src + 5; + + fd = open(path, O_RDONLY); + if (fd < 0) + return -1; + ret = ioctl(fd, BLKGETSIZE64, size); + close(fd); + return ret; +} + +/* + * These are copied from conf.c. However as conf.c will be moved to using + * the callback system, they can be pulled from there eventually, so we + * don't need to pollute utils.c with these low level functions + */ +static int find_fstype_cb(char* buffer, void *data) +{ + struct cbarg { + const char *rootfs; + const char *target; + int mntopt; + } *cbarg = data; + + char *fstype; + + /* we don't try 'nodev' entries */ + if (strstr(buffer, "nodev")) + return 0; + + fstype = buffer; + fstype += lxc_char_left_gc(fstype, strlen(fstype)); + fstype[lxc_char_right_gc(fstype, strlen(fstype))] = '\0'; + + DEBUG("trying to mount '%s'->'%s' with fstype '%s'", + cbarg->rootfs, cbarg->target, fstype); + + if (mount(cbarg->rootfs, cbarg->target, fstype, cbarg->mntopt, NULL)) { + DEBUG("mount failed with error: %s", strerror(errno)); + return 0; + } + + INFO("mounted '%s' on '%s', with fstype '%s'", + cbarg->rootfs, cbarg->target, fstype); + + return 1; +} + +static int mount_unknow_fs(const char *rootfs, const char *target, int mntopt) +{ + int i; + + struct cbarg { + const char *rootfs; + const char *target; + int mntopt; + } cbarg = { + .rootfs = rootfs, + .target = target, + .mntopt = mntopt, + }; + + /* + * find the filesystem type with brute force: + * first we check with /etc/filesystems, in case the modules + * are auto-loaded and fall back to the supported kernel fs + */ + char *fsfile[] = { + "/etc/filesystems", + "/proc/filesystems", + }; + + for (i = 0; i < sizeof(fsfile)/sizeof(fsfile[0]); i++) { + + int ret; + + if (access(fsfile[i], F_OK)) + continue; + + ret = lxc_file_for_each_line(fsfile[i], find_fstype_cb, &cbarg); + if (ret < 0) { + ERROR("failed to parse '%s'", fsfile[i]); + return -1; + } + + if (ret) + return 0; + } + + ERROR("failed to determine fs type for '%s'", rootfs); + return -1; +} + +static int do_mkfs(const char *path, const char *fstype) +{ + pid_t pid; + + if ((pid = fork()) < 0) { + ERROR("error forking"); + return -1; + } + if (pid > 0) + return wait_for_pid(pid); + + // If the file is not a block device, we don't want mkfs to ask + // us about whether to proceed. + close(0); + close(1); + close(2); + open("/dev/zero", O_RDONLY); + open("/dev/null", O_RDWR); + open("/dev/null", O_RDWR); + execlp("mkfs", "mkfs", "-t", fstype, path, NULL); + exit(1); +} + +static char *linkderef(char *path, char *dest) +{ + struct stat sbuf; + ssize_t ret; + + ret = stat(path, &sbuf); + if (ret < 0) + return NULL; + if (!S_ISLNK(sbuf.st_mode)) + return path; + ret = readlink(path, dest, MAXPATHLEN); + if (ret < 0) { + SYSERROR("error reading link %s", path); + return NULL; + } else if (ret >= MAXPATHLEN) { + ERROR("link in %s too long", path); + return NULL; + } + dest[ret] = '\0'; + return dest; +} + +/* + * Given a bdev (presumably blockdev-based), detect the fstype + * by trying mounting (in a private mntns) it. + * @bdev: bdev to investigate + * @type: preallocated char* in which to write the fstype + * @len: length of passed in char* + * Returns length of fstype, of -1 on error + */ +static int detect_fs(struct bdev *bdev, char *type, int len) +{ + int p[2], ret; + size_t linelen; + pid_t pid; + FILE *f; + char *sp1, *sp2, *sp3, *line = NULL; + char *srcdev; + + if (!bdev || !bdev->src || !bdev->dest) + return -1; + + srcdev = bdev->src; + if (strcmp(bdev->type, "loop") == 0) + srcdev = bdev->src + 5; + + if (pipe(p) < 0) + return -1; + if ((pid = fork()) < 0) + return -1; + if (pid > 0) { + int status; + close(p[1]); + memset(type, 0, len); + ret = read(p[0], type, len-1); + close(p[0]); + if (ret < 0) { + SYSERROR("error reading from pipe"); + wait(&status); + return -1; + } else if (ret == 0) { + ERROR("child exited early - fstype not found"); + wait(&status); + return -1; + } + wait(&status); + type[len-1] = '\0'; + INFO("detected fstype %s for %s", type, srcdev); + return ret; + } + + if (unshare(CLONE_NEWNS) < 0) + exit(1); + + ret = mount_unknow_fs(srcdev, bdev->dest, 0); + if (ret < 0) { + ERROR("failed mounting %s onto %s to detect fstype", srcdev, bdev->dest); + exit(1); + } + // if symlink, get the real dev name + char devpath[MAXPATHLEN]; + char *l = linkderef(srcdev, devpath); + if (!l) + exit(1); + f = fopen("/proc/self/mounts", "r"); + if (!f) + exit(1); + while (getline(&line, &linelen, f) != -1) { + sp1 = index(line, ' '); + if (!sp1) + exit(1); + *sp1 = '\0'; + if (strcmp(line, l)) + continue; + sp2 = index(sp1+1, ' '); + if (!sp2) + exit(1); + *sp2 = '\0'; + sp3 = index(sp2+1, ' '); + if (!sp3) + exit(1); + *sp3 = '\0'; + sp2++; + if (write(p[1], sp2, strlen(sp2)) != strlen(sp2)) + exit(1); + exit(0); + } + exit(1); +} + +struct bdev_type { + char *name; + struct bdev_ops *ops; +}; + +static int is_dir(const char *path) +{ + struct stat statbuf; + int ret = stat(path, &statbuf); + if (ret == 0 && S_ISDIR(statbuf.st_mode)) + return 1; + return 0; +} + +static int dir_detect(const char *path) +{ + if (strncmp(path, "dir:", 4) == 0) + return 1; // take their word for it + if (is_dir(path)) + return 1; + return 0; +} + +// +// XXXXXXX plain directory bind mount ops +// +static int dir_mount(struct bdev *bdev) +{ + if (strcmp(bdev->type, "dir")) + return -22; + if (!bdev->src || !bdev->dest) + return -22; + return mount(bdev->src, bdev->dest, "bind", MS_BIND | MS_REC, NULL); +} + +static int dir_umount(struct bdev *bdev) +{ + if (strcmp(bdev->type, "dir")) + return -22; + if (!bdev->src || !bdev->dest) + return -22; + return umount(bdev->dest); +} + +/* the bulk of this needs to become a common helper */ +static char *dir_new_path(char *src, const char *oldname, const char *name, + const char *oldpath, const char *lxcpath) +{ + char *ret, *p, *p2; + int l1, l2, nlen; + + nlen = strlen(src) + 1; + l1 = strlen(oldpath); + p = src; + /* if src starts with oldpath, look for oldname only after + * that path */ + if (strncmp(src, oldpath, l1) == 0) { + p += l1; + nlen += (strlen(lxcpath) - l1); + } + l2 = strlen(oldname); + while ((p = strstr(p, oldname)) != NULL) { + p += l2; + nlen += strlen(name) - l2; + } + + ret = malloc(nlen); + if (!ret) + return NULL; + + p = ret; + if (strncmp(src, oldpath, l1) == 0) { + p += sprintf(p, "%s", lxcpath); + src += l1; + } + + while ((p2 = strstr(src, oldname)) != NULL) { + strncpy(p, src, p2-src); // copy text up to oldname + p += p2-src; // move target pointer (p) + p += sprintf(p, "%s", name); // print new name in place of oldname + src = p2 + l2; // move src to end of oldname + } + sprintf(p, "%s", src); // copy the rest of src + return ret; +} + +/* + * for a simple directory bind mount, we substitute the old container + * name and paths for the new + */ +static int dir_clonepaths(struct bdev *orig, struct bdev *new, const char *oldname, + const char *cname, const char *oldpath, const char *lxcpath, int snap, + unsigned long newsize) +{ + int len, ret; + + if (snap) { + ERROR("directories cannot be snapshotted. Try overlayfs."); + return -1; + } + + if (!orig->dest || !orig->src) + return -1; + + len = strlen(lxcpath) + strlen(cname) + strlen("rootfs") + 3; + new->src = malloc(len); + if (!new->src) + return -1; + ret = snprintf(new->src, len, "%s/%s/rootfs", lxcpath, cname); + if (ret < 0 || ret >= len) + return -1; + if ((new->dest = strdup(new->src)) == NULL) + return -1; + + return 0; +} + +static int dir_destroy(struct bdev *orig) +{ + if (!lxc_rmdir_onedev(orig->src)) + return -1; + return 0; +} + +static int dir_create(struct bdev *bdev, const char *dest, const char *n, + struct bdev_specs *specs) +{ + bdev->src = strdup(dest); + bdev->dest = strdup(dest); + if (!bdev->src || !bdev->dest) { + ERROR("Out of memory"); + return -1; + } + + if (mkdir_p(bdev->src, 0755) < 0) { + ERROR("Error creating %s\n", bdev->src); + return -1; + } + if (mkdir_p(bdev->dest, 0755) < 0) { + ERROR("Error creating %s\n", bdev->dest); + return -1; + } + + return 0; +} + +struct bdev_ops dir_ops = { + .detect = &dir_detect, + .mount = &dir_mount, + .umount = &dir_umount, + .clone_paths = &dir_clonepaths, + .destroy = &dir_destroy, + .create = &dir_create, +}; + + +// +// XXXXXXX zfs ops +// There are two ways we could do this. We could always specify the +// 'zfs device' (i.e. tank/lxc lxc/container) as rootfs. But instead +// (at least right now) we have lxc-create specify $lxcpath/$lxcname/rootfs +// as the mountpoint, so that it is always mounted. +// +// That means 'mount' is really never needed and could be noop, but for the +// sake of flexibility let's always bind-mount. +// + +static int zfs_list_entry(const char *path, char *output, size_t inlen) +{ + FILE *f; + int found=0; + + if ((f = popen("zfs list 2> /dev/null", "r")) == NULL) { + SYSERROR("popen failed"); + return 0; + } + while (fgets(output, inlen, f)) { + if (strstr(output, path)) { + found = 1; + break; + } + } + (void) pclose(f); + + return found; +} + +static int zfs_detect(const char *path) +{ + char *output = malloc(LXC_LOG_BUFFER_SIZE); + int found; + + if (!output) { + ERROR("out of memory"); + return 0; + } + found = zfs_list_entry(path, output, LXC_LOG_BUFFER_SIZE); + free(output); + return found; +} + +static int zfs_mount(struct bdev *bdev) +{ + if (strcmp(bdev->type, "zfs")) + return -22; + if (!bdev->src || !bdev->dest) + return -22; + return mount(bdev->src, bdev->dest, "bind", MS_BIND | MS_REC, NULL); +} + +static int zfs_umount(struct bdev *bdev) +{ + if (strcmp(bdev->type, "zfs")) + return -22; + if (!bdev->src || !bdev->dest) + return -22; + return umount(bdev->dest); +} + +static int zfs_clone(const char *opath, const char *npath, const char *oname, + const char *nname, const char *lxcpath, int snapshot) +{ + // use the 'zfs list | grep opath' entry to get the zfsroot + char output[MAXPATHLEN], option[MAXPATHLEN], *p; + const char *zfsroot = output; + int ret; + pid_t pid; + + if (zfs_list_entry(opath, output, MAXPATHLEN)) { + // zfsroot is output up to ' ' + if ((p = index(output, ' ')) == NULL) + return -1; + *p = '\0'; + if ((p = strrchr(output, '/')) == NULL) + return -1; + *p = '\0'; + } else + zfsroot = default_zfs_root(); + + ret = snprintf(option, MAXPATHLEN, "-omountpoint=%s/%s/rootfs", + lxcpath, nname); + if (ret < 0 || ret >= MAXPATHLEN) + return -1; + + // zfs create -omountpoint=$lxcpath/$lxcname $zfsroot/$nname + if (!snapshot) { + if ((pid = fork()) < 0) + return -1; + if (!pid) { + char dev[MAXPATHLEN]; + ret = snprintf(dev, MAXPATHLEN, "%s/%s", zfsroot, nname); + if (ret < 0 || ret >= MAXPATHLEN) + exit(1); + execlp("zfs", "zfs", "create", option, dev, NULL); + exit(1); + } + return wait_for_pid(pid); + } else { + // if snapshot, do + // 'zfs snapshot zfsroot/oname@nname + // zfs clone zfsroot/oname@nname zfsroot/nname + char path1[MAXPATHLEN], path2[MAXPATHLEN]; + + ret = snprintf(path1, MAXPATHLEN, "%s/%s@%s", zfsroot, + oname, nname); + if (ret < 0 || ret >= MAXPATHLEN) + return -1; + (void) snprintf(path2, MAXPATHLEN, "%s/%s", zfsroot, nname); + + // if the snapshot exists, delete it + if ((pid = fork()) < 0) + return -1; + if (!pid) { + execlp("zfs", "zfs", "destroy", path1, NULL); + exit(1); + } + // it probably doesn't exist so destroy probably will fail. + (void) wait_for_pid(pid); + + // run first (snapshot) command + if ((pid = fork()) < 0) + return -1; + if (!pid) { + execlp("zfs", "zfs", "snapshot", path1, NULL); + exit(1); + } + if (wait_for_pid(pid) < 0) + return -1; + + // run second (clone) command + if ((pid = fork()) < 0) + return -1; + if (!pid) { + execlp("zfs", "zfs", "clone", option, path1, path2, NULL); + exit(1); + } + return wait_for_pid(pid); + } +} + +static int zfs_clonepaths(struct bdev *orig, struct bdev *new, const char *oldname, + const char *cname, const char *oldpath, const char *lxcpath, int snap, + unsigned long newsize) +{ + int len, ret; + + if (!orig->src || !orig->dest) + return -1; + + if (snap && strcmp(orig->type, "zfs")) { + ERROR("zfs snapshot from %s backing store is not supported", + orig->type); + return -1; + } + + len = strlen(lxcpath) + strlen(cname) + strlen("rootfs") + 3; + new->src = malloc(len); + if (!new->src) + return -1; + ret = snprintf(new->src, len, "%s/%s/rootfs", lxcpath, cname); + if (ret < 0 || ret >= len) + return -1; + if ((new->dest = strdup(new->src)) == NULL) + return -1; + + return zfs_clone(orig->src, new->src, oldname, cname, lxcpath, snap); +} + +/* + * TODO: detect whether this was a clone, and if so then also delete the + * snapshot it was based on, so that we don't hold the original + * container busy. + */ +static int zfs_destroy(struct bdev *orig) +{ + pid_t pid; + char output[MAXPATHLEN], *p; + + if ((pid = fork()) < 0) + return -1; + if (pid) + return wait_for_pid(pid); + + if (!zfs_list_entry(orig->src, output, MAXPATHLEN)) { + ERROR("Error: zfs entry for %s not found", orig->src); + return -1; + } + + // zfs mount is output up to ' ' + if ((p = index(output, ' ')) == NULL) + return -1; + *p = '\0'; + + execlp("zfs", "zfs", "destroy", output, NULL); + exit(1); +} + +static int zfs_create(struct bdev *bdev, const char *dest, const char *n, + struct bdev_specs *specs) +{ + const char *zfsroot; + char option[MAXPATHLEN]; + int ret; + pid_t pid; + + if (!specs || !specs->u.zfs.zfsroot) + zfsroot = default_zfs_root(); + else + zfsroot = specs->u.zfs.zfsroot; + + if (!(bdev->dest = strdup(dest))) { + ERROR("No mount target specified or out of memory"); + return -1; + } + if (!(bdev->src = strdup(bdev->dest))) { + ERROR("out of memory"); + return -1; + } + + ret = snprintf(option, MAXPATHLEN, "-omountpoint=%s", bdev->dest); + if (ret < 0 || ret >= MAXPATHLEN) + return -1; + if ((pid = fork()) < 0) + return -1; + if (pid) + return wait_for_pid(pid); + + char dev[MAXPATHLEN]; + ret = snprintf(dev, MAXPATHLEN, "%s/%s", zfsroot, n); + if (ret < 0 || ret >= MAXPATHLEN) + exit(1); + execlp("zfs", "zfs", "create", option, dev, NULL); + exit(1); +} + +struct bdev_ops zfs_ops = { + .detect = &zfs_detect, + .mount = &zfs_mount, + .umount = &zfs_umount, + .clone_paths = &zfs_clonepaths, + .destroy = &zfs_destroy, + .create = &zfs_create, +}; + +// +// LVM ops +// + +/* + * Look at /sys/dev/block/maj:min/dm/uuid. If it contains the hardcoded LVM + * prefix "LVM-", then this is an lvm2 LV + */ +static int lvm_detect(const char *path) +{ + char devp[MAXPATHLEN], buf[4]; + FILE *fout; + int ret; + struct stat statbuf; + + if (strncmp(path, "lvm:", 4) == 0) + return 1; // take their word for it + + ret = stat(path, &statbuf); + if (ret != 0) + return 0; + if (!S_ISBLK(statbuf.st_mode)) + return 0; + + ret = snprintf(devp, MAXPATHLEN, "/sys/dev/block/%d:%d/dm/uuid", + major(statbuf.st_rdev), minor(statbuf.st_rdev)); + if (ret < 0 || ret >= MAXPATHLEN) { + ERROR("lvm uuid pathname too long"); + return 0; + } + fout = fopen(devp, "r"); + if (!fout) + return 0; + ret = fread(buf, 1, 4, fout); + fclose(fout); + if (ret != 4 || strncmp(buf, "LVM-", 4) != 0) + return 0; + return 1; +} + +static int lvm_mount(struct bdev *bdev) +{ + if (strcmp(bdev->type, "lvm")) + return -22; + if (!bdev->src || !bdev->dest) + return -22; + /* if we might pass in data sometime, then we'll have to enrich + * mount_unknow_fs */ + return mount_unknow_fs(bdev->src, bdev->dest, 0); +} + +static int lvm_umount(struct bdev *bdev) +{ + if (strcmp(bdev->type, "lvm")) + return -22; + if (!bdev->src || !bdev->dest) + return -22; + return umount(bdev->dest); +} + +/* + * path must be '/dev/$vg/$lv', $vg must be an existing VG, and $lv must + * not yet exist. This function will attempt to create /dev/$vg/$lv of + * size $size. + */ +static int do_lvm_create(const char *path, unsigned long size) +{ + int ret, pid; + char sz[24], *pathdup, *vg, *lv; + + if ((pid = fork()) < 0) { + SYSERROR("failed fork"); + return -1; + } + if (pid > 0) + return wait_for_pid(pid); + + // lvcreate default size is in M, not bytes. + ret = snprintf(sz, 24, "%lu", size/1000000); + if (ret < 0 || ret >= 24) + exit(1); + + pathdup = strdup(path); + if (!pathdup) + exit(1); + lv = strrchr(pathdup, '/'); + if (!lv) { + free(pathdup); + exit(1); + } + *lv = '\0'; + lv++; + vg = strrchr(pathdup, '/'); + if (!vg) + exit(1); + vg++; + execlp("lvcreate", "lvcreate", "-L", sz, vg, "-n", lv, (char *)NULL); + free(pathdup); + exit(1); +} + +static int lvm_snapshot(const char *orig, const char *path, unsigned long size) +{ + int ret, pid; + char sz[24], *pathdup, *lv; + + if ((pid = fork()) < 0) { + SYSERROR("failed fork"); + return -1; + } + if (pid > 0) + return wait_for_pid(pid); + // lvcreate default size is in M, not bytes. + ret = snprintf(sz, 24, "%lu", size/1000000); + if (ret < 0 || ret >= 24) + exit(1); + + pathdup = strdup(path); + if (!pathdup) + exit(1); + lv = strrchr(pathdup, '/'); + if (!lv) { + free(pathdup); + exit(1); + } + *lv = '\0'; + lv++; + + ret = execlp("lvcreate", "lvcreate", "-s", "-L", sz, "-n", lv, orig, (char *)NULL); + free(pathdup); + exit(1); +} + +// this will return 1 for physical disks, qemu-nbd, loop, etc +// right now only lvm is a block device +static int is_blktype(struct bdev *b) +{ + if (strcmp(b->type, "lvm") == 0) + return 1; + return 0; +} + +static int lvm_clonepaths(struct bdev *orig, struct bdev *new, const char *oldname, + const char *cname, const char *oldpath, const char *lxcpath, int snap, + unsigned long newsize) +{ + char fstype[100]; + unsigned long size = newsize; + int len, ret; + + if (!orig->src || !orig->dest) + return -1; + + if (strcmp(orig->type, "lvm")) { + const char *vg; + + if (snap) { + ERROR("LVM snapshot from %s backing store is not supported", + orig->type); + return -1; + } + vg = default_lvm_vg(); + len = strlen("/dev/") + strlen(vg) + strlen(cname) + 2; + if ((new->src = malloc(len)) == NULL) + return -1; + ret = snprintf(new->src, len, "/dev/%s/%s", vg, cname); + if (ret < 0 || ret >= len) + return -1; + } else { + new->src = dir_new_path(orig->src, oldname, cname, oldpath, lxcpath); + if (!new->src) + return -1; + } + + if (orig->data) { + new->data = strdup(orig->data); + if (!new->data) + return -1; + } + + len = strlen(lxcpath) + strlen(cname) + strlen("rootfs") + 3; + new->dest = malloc(len); + if (!new->dest) + return -1; + ret = snprintf(new->dest, len, "%s/%s/rootfs", lxcpath, cname); + if (ret < 0 || ret >= len) + return -1; + if (mkdir_p(new->dest, 0755) < 0) + return -1; + + if (is_blktype(orig)) { + if (!newsize && blk_getsize(orig, &size) < 0) { + ERROR("Error getting size of %s", orig->src); + return -1; + } + if (detect_fs(orig, fstype, 100) < 0) { + INFO("could not find fstype for %s, using ext3", orig->src); + return -1; + } + } else { + sprintf(fstype, "ext3"); + if (!newsize) + size = 1000000000; // default to 1G + } + + if (snap) { + if (lvm_snapshot(orig->src, new->src, size) < 0) { + ERROR("could not create %s snapshot of %s", new->src, orig->src); + return -1; + } + } else { + if (do_lvm_create(new->src, size) < 0) { + ERROR("Error creating new lvm blockdev"); + return -1; + } + if (do_mkfs(new->src, fstype) < 0) { + ERROR("Error creating filesystem type %s on %s", fstype, + new->src); + return -1; + } + } + + return 0; +} + +static int lvm_destroy(struct bdev *orig) +{ + pid_t pid; + + if ((pid = fork()) < 0) + return -1; + if (!pid) { + execlp("lvremove", "lvremove", "-f", orig->src, NULL); + exit(1); + } + return wait_for_pid(pid); +} + +#define DEFAULT_FS_SIZE 1024000000 +#define DEFAULT_FSTYPE "ext3" +static int lvm_create(struct bdev *bdev, const char *dest, const char *n, + struct bdev_specs *specs) +{ + const char *vg, *fstype, *lv = n; + unsigned long sz; + int ret, len; + + if (!specs) + return -1; + + vg = specs->u.lvm.vg; + if (!vg) + vg = default_lvm_vg(); + + /* /dev/$vg/$lv */ + if (specs->u.lvm.lv) + lv = specs->u.lvm.lv; + len = strlen(vg) + strlen(lv) + 7; + bdev->src = malloc(len); + if (!bdev->src) + return -1; + + ret = snprintf(bdev->src, len, "/dev/%s/%s", vg, lv); + if (ret < 0 || ret >= len) + return -1; + + // lvm.fssize is in bytes. + sz = specs->u.lvm.fssize; + if (!sz) + sz = DEFAULT_FS_SIZE; + + INFO("Error creating new lvm blockdev %s size %lu", bdev->src, sz); + if (do_lvm_create(bdev->src, sz) < 0) { + ERROR("Error creating new lvm blockdev %s size %lu", bdev->src, sz); + return -1; + } + + fstype = specs->u.lvm.fstype; + if (!fstype) + fstype = DEFAULT_FSTYPE; + if (do_mkfs(bdev->src, fstype) < 0) { + ERROR("Error creating filesystem type %s on %s", fstype, + bdev->src); + return -1; + } + if (!(bdev->dest = strdup(dest))) + return -1; + + if (mkdir_p(bdev->dest, 0755) < 0) { + ERROR("Error creating %s\n", bdev->dest); + return -1; + } + + return 0; +} + +struct bdev_ops lvm_ops = { + .detect = &lvm_detect, + .mount = &lvm_mount, + .umount = &lvm_umount, + .clone_paths = &lvm_clonepaths, + .destroy = &lvm_destroy, + .create = &lvm_create, +}; + +// +// btrfs ops +// + +struct btrfs_ioctl_space_info { + unsigned long long flags; + unsigned long long total_bytes; + unsigned long long used_bytes; +}; + +struct btrfs_ioctl_space_args { + unsigned long long space_slots; + unsigned long long total_spaces; + struct btrfs_ioctl_space_info spaces[0]; +}; + +#define BTRFS_IOCTL_MAGIC 0x94 +#define BTRFS_IOC_SUBVOL_GETFLAGS _IOR(BTRFS_IOCTL_MAGIC, 25, unsigned long long) +#define BTRFS_IOC_SPACE_INFO _IOWR(BTRFS_IOCTL_MAGIC, 20, \ + struct btrfs_ioctl_space_args) + +static bool is_btrfs_fs(const char *path) +{ + int fd, ret; + struct btrfs_ioctl_space_args sargs; + + // make sure this is a btrfs filesystem + fd = open(path, O_RDONLY); + if (fd < 0) + return false; + sargs.space_slots = 0; + sargs.total_spaces = 0; + ret = ioctl(fd, BTRFS_IOC_SPACE_INFO, &sargs); + close(fd); + if (ret < 0) + return false; + + return true; +} + +static int btrfs_detect(const char *path) +{ + struct stat st; + int ret; + + if (!is_btrfs_fs(path)) + return 0; + + // and make sure it's a subvolume. + ret = stat(path, &st); + if (ret < 0) + return 0; + + if (st.st_ino == 256 && S_ISDIR(st.st_mode)) + return 1; + + return 0; +} + +static int btrfs_mount(struct bdev *bdev) +{ + if (strcmp(bdev->type, "btrfs")) + return -22; + if (!bdev->src || !bdev->dest) + return -22; + return mount(bdev->src, bdev->dest, "bind", MS_BIND | MS_REC, NULL); +} + +static int btrfs_umount(struct bdev *bdev) +{ + if (strcmp(bdev->type, "btrfs")) + return -22; + if (!bdev->src || !bdev->dest) + return -22; + return umount(bdev->dest); +} + +#define BTRFS_SUBVOL_NAME_MAX 4039 +#define BTRFS_PATH_NAME_MAX 4087 + +struct btrfs_ioctl_vol_args { + signed long long fd; + char name[BTRFS_PATH_NAME_MAX + 1]; +}; + +#define BTRFS_IOCTL_MAGIC 0x94 +#define BTRFS_IOC_SUBVOL_CREATE_V2 _IOW(BTRFS_IOCTL_MAGIC, 24, \ + struct btrfs_ioctl_vol_args_v2) +#define BTRFS_IOC_SNAP_CREATE_V2 _IOW(BTRFS_IOCTL_MAGIC, 23, \ + struct btrfs_ioctl_vol_args_v2) +#define BTRFS_IOC_SUBVOL_CREATE _IOW(BTRFS_IOCTL_MAGIC, 14, \ + struct btrfs_ioctl_vol_args) +#define BTRFS_IOC_SNAP_DESTROY _IOW(BTRFS_IOCTL_MAGIC, 15, \ + struct btrfs_ioctl_vol_args) + +#define BTRFS_QGROUP_INHERIT_SET_LIMITS (1ULL << 0) + +struct btrfs_ioctl_vol_args_v2 { + signed long long fd; + unsigned long long transid; + unsigned long long flags; + union { + struct { + unsigned long long size; + //struct btrfs_qgroup_inherit *qgroup_inherit; + void *qgroup_inherit; + }; + unsigned long long unused[4]; + }; + char name[BTRFS_SUBVOL_NAME_MAX + 1]; +}; + +static int btrfs_subvolume_create(const char *path) +{ + int ret, fd = -1; + struct btrfs_ioctl_vol_args args; + char *p, *newfull = strdup(path); + + if (!newfull) { + ERROR("Error: out of memory"); + return -1; + } + + p = strrchr(newfull, '/'); + if (!p) { + ERROR("bad path: %s", path); + return -1; + } + *p = '\0'; + + if ((fd = open(newfull, O_RDONLY)) < 0) { + ERROR("Error opening %s", newfull); + free(newfull); + return -1; + } + + memset(&args, 0, sizeof(args)); + strncpy(args.name, p+1, BTRFS_SUBVOL_NAME_MAX); + args.name[BTRFS_SUBVOL_NAME_MAX-1] = 0; + ret = ioctl(fd, BTRFS_IOC_SUBVOL_CREATE, &args); + INFO("btrfs: snapshot create ioctl returned %d", ret); + + free(newfull); + close(fd); + return ret; +} + +static int btrfs_snapshot(const char *orig, const char *new) +{ + int fd = -1, fddst = -1, ret = -1; + struct btrfs_ioctl_vol_args_v2 args; + char *newdir, *newname, *newfull = NULL; + + newfull = strdup(new); + if (!newfull) { + ERROR("Error: out of memory"); + goto out; + } + // make sure the directory doesn't already exist + if (rmdir(newfull) < 0 && errno != -ENOENT) { + SYSERROR("Error removing empty new rootfs"); + goto out; + } + newname = basename(newfull); + newdir = dirname(newfull); + fd = open(orig, O_RDONLY); + if (fd < 0) { + SYSERROR("Error opening original rootfs %s", orig); + goto out; + } + fddst = open(newdir, O_RDONLY); + if (fddst < 0) { + SYSERROR("Error opening new container dir %s", newdir); + goto out; + } + + memset(&args, 0, sizeof(args)); + args.fd = fd; + strncpy(args.name, newname, BTRFS_SUBVOL_NAME_MAX); + args.name[BTRFS_SUBVOL_NAME_MAX-1] = 0; + ret = ioctl(fddst, BTRFS_IOC_SNAP_CREATE_V2, &args); + INFO("btrfs: snapshot create ioctl returned %d", ret); + +out: + if (fddst != -1) + close(fddst); + if (fd != -1) + close(fd); + if (newfull) + free(newfull); + return ret; +} + +static int btrfs_clonepaths(struct bdev *orig, struct bdev *new, const char *oldname, + const char *cname, const char *oldpath, const char *lxcpath, int snap, + unsigned long newsize) +{ + if (!orig->dest || !orig->src) + return -1; + + if (strcmp(orig->type, "btrfs")) { + int len, ret; + if (snap) { + ERROR("btrfs snapshot from %s backing store is not supported", + orig->type); + return -1; + } + len = strlen(lxcpath) + strlen(cname) + strlen("rootfs") + 3; + new->src = malloc(len); + if (!new->src) + return -1; + ret = snprintf(new->src, len, "%s/%s/rootfs", lxcpath, cname); + if (ret < 0 || ret >= len) + return -1; + } else { + // in case rootfs is in custom path, reuse it + if ((new->src = dir_new_path(orig->src, oldname, cname, oldpath, lxcpath)) == NULL) + return -1; + + } + + if ((new->dest = strdup(new->src)) == NULL) + return -1; + + if (orig->data && (new->data = strdup(orig->data)) == NULL) + return -1; + + if (snap) + return btrfs_snapshot(orig->dest, new->dest); + + if (rmdir(new->dest) < 0 && errno != -ENOENT) { + SYSERROR("removing %s\n", new->dest); + return -1; + } + + return btrfs_subvolume_create(new->dest); +} + +static int btrfs_destroy(struct bdev *orig) +{ + int ret, fd = -1; + struct btrfs_ioctl_vol_args args; + char *path = orig->src; + char *p, *newfull = strdup(path); + + if (!newfull) { + ERROR("Error: out of memory"); + return -1; + } + + p = strrchr(newfull, '/'); + if (!p) { + ERROR("bad path: %s", path); + return -1; + } + *p = '\0'; + + if ((fd = open(newfull, O_RDONLY)) < 0) { + ERROR("Error opening %s", newfull); + free(newfull); + return -1; + } + + memset(&args, 0, sizeof(args)); + strncpy(args.name, p+1, BTRFS_SUBVOL_NAME_MAX); + args.name[BTRFS_SUBVOL_NAME_MAX-1] = 0; + ret = ioctl(fd, BTRFS_IOC_SNAP_DESTROY, &args); + INFO("btrfs: snapshot create ioctl returned %d", ret); + + free(newfull); + close(fd); + return ret; +} + +static int btrfs_create(struct bdev *bdev, const char *dest, const char *n, + struct bdev_specs *specs) +{ + bdev->src = strdup(dest); + bdev->dest = strdup(dest); + if (!bdev->src || !bdev->dest) + return -1; + return btrfs_subvolume_create(bdev->dest); +} + +struct bdev_ops btrfs_ops = { + .detect = &btrfs_detect, + .mount = &btrfs_mount, + .umount = &btrfs_umount, + .clone_paths = &btrfs_clonepaths, + .destroy = &btrfs_destroy, + .create = &btrfs_create, +}; + +// +// loopback dev ops +// +static int loop_detect(const char *path) +{ + if (strncmp(path, "loop:", 5) == 0) + return 1; + return 0; +} + +static int find_free_loopdev(int *retfd, char *namep) +{ + struct dirent dirent, *direntp; + struct loop_info64 lo; + DIR *dir; + int fd = -1; + + if (!(dir = opendir("/dev"))) { + SYSERROR("Error opening /dev"); + return -1; + } + while (!readdir_r(dir, &dirent, &direntp)) { + + if (!direntp) + break; + if (strncmp(direntp->d_name, "loop", 4) != 0) + continue; + if ((fd = openat(dirfd(dir), direntp->d_name, O_RDWR)) < 0) + continue; + if (ioctl(fd, LOOP_GET_STATUS64, &lo) == 0 || errno != ENXIO) { + close(fd); + fd = -1; + continue; + } + // We can use this fd + snprintf(namep, 100, "/dev/%s", direntp->d_name); + break; + } + closedir(dir); + if (fd == -1) { + ERROR("No loop device found"); + return -1; + } + + *retfd = fd; + return 0; +} + +static int loop_mount(struct bdev *bdev) +{ + int lfd, ffd = -1, ret = -1; + struct loop_info64 lo; + char loname[100]; + + if (strcmp(bdev->type, "loop")) + return -22; + if (!bdev->src || !bdev->dest) + return -22; + if (find_free_loopdev(&lfd, loname) < 0) + return -22; + + if ((ffd = open(bdev->src + 5, O_RDWR)) < 0) { + SYSERROR("Error opening backing file %s\n", bdev->src); + goto out; + } + + if (ioctl(lfd, LOOP_SET_FD, ffd) < 0) { + SYSERROR("Error attaching backing file to loop dev"); + goto out; + } + memset(&lo, 0, sizeof(lo)); + lo.lo_flags = LO_FLAGS_AUTOCLEAR; + if (ioctl(lfd, LOOP_SET_STATUS64, &lo) < 0) { + SYSERROR("Error setting autoclear on loop dev\n"); + goto out; + } + + ret = mount_unknow_fs(loname, bdev->dest, 0); + if (ret < 0) + ERROR("Error mounting %s\n", bdev->src); + else + bdev->lofd = lfd; + +out: + if (ffd > -1) + close(ffd); + if (ret < 0) { + close(lfd); + bdev->lofd = -1; + } + return ret; +} + +static int loop_umount(struct bdev *bdev) +{ + int ret; + + if (strcmp(bdev->type, "loop")) + return -22; + if (!bdev->src || !bdev->dest) + return -22; + ret = umount(bdev->dest); + if (bdev->lofd >= 0) { + close(bdev->lofd); + bdev->lofd = -1; + } + return ret; +} + +static int do_loop_create(const char *path, unsigned long size, const char *fstype) +{ + int fd; + // create the new loopback file. + fd = creat(path, S_IRUSR|S_IWUSR); + if (fd < 0) + return -1; + if (lseek(fd, size, SEEK_SET) < 0) { + SYSERROR("Error seeking to set new loop file size"); + close(fd); + return -1; + } + if (write(fd, "1", 1) != 1) { + SYSERROR("Error creating new loop file"); + close(fd); + return -1; + } + if (close(fd) < 0) { + SYSERROR("Error closing new loop file"); + return -1; + } + + // create an fs in the loopback file + if (do_mkfs(path, fstype) < 0) { + ERROR("Error creating filesystem type %s on %s", fstype, + path); + return -1; + } + + return 0; +} + +/* + * No idea what the original blockdev will be called, but the copy will be + * called $lxcpath/$lxcname/rootdev + */ +static int loop_clonepaths(struct bdev *orig, struct bdev *new, const char *oldname, + const char *cname, const char *oldpath, const char *lxcpath, int snap, + unsigned long newsize) +{ + char fstype[100]; + unsigned long size = newsize; + int len, ret; + char *srcdev; + + if (snap) { + ERROR("loop devices cannot be snapshotted."); + return -1; + } + + if (!orig->dest || !orig->src) + return -1; + + len = strlen(lxcpath) + strlen(cname) + strlen("rootdev") + 3; + srcdev = alloca(len); + ret = snprintf(srcdev, len, "%s/%s/rootdev", lxcpath, cname); + if (ret < 0 || ret >= len) + return -1; + + new->src = malloc(len + 5); + if (!new->src) + return -1; + ret = snprintf(new->src, len + 5, "loop:%s", srcdev); + if (ret < 0 || ret >= len + 5) + return -1; + + new->dest = malloc(len); + if (!new->dest) + return -1; + ret = snprintf(new->dest, len, "%s/%s/rootfs", lxcpath, cname); + if (ret < 0 || ret >= len) + return -1; + + // it's tempting to say: if orig->src == loopback and !newsize, then + // copy the loopback file. However, we'd have to make sure to + // correctly keep holes! So punt for now. + + if (is_blktype(orig)) { + if (!newsize && blk_getsize(orig, &size) < 0) { + ERROR("Error getting size of %s", orig->src); + return -1; + } + if (detect_fs(orig, fstype, 100) < 0) { + INFO("could not find fstype for %s, using %s", orig->src, + DEFAULT_FSTYPE); + return -1; + } + } else { + sprintf(fstype, "%s", DEFAULT_FSTYPE); + if (!newsize) + size = DEFAULT_FS_SIZE; // default to 1G + } + return do_loop_create(srcdev, size, fstype); +} + +static int loop_create(struct bdev *bdev, const char *dest, const char *n, + struct bdev_specs *specs) +{ + const char *fstype; + unsigned long sz; + int ret, len; + char *srcdev; + + if (!specs) + return -1; + + // dest is passed in as $lxcpath / $lxcname / rootfs + // srcdev will be: $lxcpath / $lxcname / rootdev + // src will be 'loop:$srcdev' + len = strlen(dest) + 2; + srcdev = alloca(len); + + ret = snprintf(srcdev, len, "%s", dest); + if (ret < 0 || ret >= len) + return -1; + sprintf(srcdev + len - 4, "dev"); + + bdev->src = malloc(len + 5); + if (!bdev->src) + return -1; + ret = snprintf(bdev->src, len + 5, "loop:%s", srcdev); + if (ret < 0 || ret >= len + 5) + return -1; + + sz = specs->u.loop.fssize; + if (!sz) + sz = DEFAULT_FS_SIZE; + + fstype = specs->u.loop.fstype; + if (!fstype) + fstype = DEFAULT_FSTYPE; + + if (!(bdev->dest = strdup(dest))) + return -1; + + if (mkdir_p(bdev->dest, 0755) < 0) { + ERROR("Error creating %s\n", bdev->dest); + return -1; + } + + return do_loop_create(srcdev, sz, fstype); +} + +static int loop_destroy(struct bdev *orig) +{ + return unlink(orig->src + 5); +} + +struct bdev_ops loop_ops = { + .detect = &loop_detect, + .mount = &loop_mount, + .umount = &loop_umount, + .clone_paths = &loop_clonepaths, + .destroy = &loop_destroy, + .create = &loop_create, +}; + +// +// overlayfs ops +// + +static int overlayfs_detect(const char *path) +{ + if (strncmp(path, "overlayfs:", 10) == 0) + return 1; // take their word for it + return 0; +} + +// +// XXXXXXX plain directory bind mount ops +// +static int overlayfs_mount(struct bdev *bdev) +{ + char *options, *dup, *lower, *upper; + int len; + int ret; + + if (strcmp(bdev->type, "overlayfs")) + return -22; + if (!bdev->src || !bdev->dest) + return -22; + + // separately mount it first + // mount -t overlayfs -oupperdir=${upper},lowerdir=${lower} lower dest + dup = alloca(strlen(bdev->src)+1); + strcpy(dup, bdev->src); + if (!(lower = index(dup, ':'))) + return -22; + if (!(upper = index(++lower, ':'))) + return -22; + *upper = '\0'; + upper++; + + // TODO We should check whether bdev->src is a blockdev, and if so + // but for now, only support overlays of a basic directory + + len = strlen(lower) + strlen(upper) + strlen("upperdir=,lowerdir=") + 1; + options = alloca(len); + ret = snprintf(options, len, "upperdir=%s,lowerdir=%s", upper, lower); + if (ret < 0 || ret >= len) + return -1; + ret = mount(lower, bdev->dest, "overlayfs", MS_MGC_VAL, options); + if (ret < 0) + SYSERROR("overlayfs: error mounting %s onto %s options %s", + lower, bdev->dest, options); + else + INFO("overlayfs: mounted %s onto %s options %s", + lower, bdev->dest, options); + return ret; +} + +static int overlayfs_umount(struct bdev *bdev) +{ + if (strcmp(bdev->type, "overlayfs")) + return -22; + if (!bdev->src || !bdev->dest) + return -22; + return umount(bdev->dest); +} + +static int overlayfs_clonepaths(struct bdev *orig, struct bdev *new, const char *oldname, + const char *cname, const char *oldpath, const char *lxcpath, int snap, + unsigned long newsize) +{ + if (!snap) { + ERROR("overlayfs is only for snapshot clones"); + return -22; + } + + if (!orig->src || !orig->dest) + return -1; + + new->dest = dir_new_path(orig->dest, oldname, cname, oldpath, lxcpath); + if (!new->dest) + return -1; + if (mkdir_p(new->dest, 0755) < 0) + return -1; + + if (strcmp(orig->type, "dir") == 0) { + char *delta; + int ret, len; + + // if we have /var/lib/lxc/c2/rootfs, then delta will be + // /var/lib/lxc/c2/delta0 + delta = strdup(new->dest); + if (!delta) { + return -1; + } + if (strlen(delta) < 6) { + free(delta); + return -22; + } + strcpy(&delta[strlen(delta)-6], "delta0"); + if ((ret = mkdir(delta, 0755)) < 0) { + SYSERROR("error: mkdir %s", delta); + free(delta); + return -1; + } + + // the src will be 'overlayfs:lowerdir:upperdir' + len = strlen(delta) + strlen(orig->src) + 12; + new->src = malloc(len); + if (!new->src) { + free(delta); + return -ENOMEM; + } + ret = snprintf(new->src, len, "overlayfs:%s:%s", orig->src, delta); + free(delta); + if (ret < 0 || ret >= len) + return -ENOMEM; + } else if (strcmp(orig->type, "overlayfs") == 0) { + // What exactly do we want to do here? + // I think we want to use the original lowerdir, with a + // private delta which is originally rsynced from the + // original delta + char *osrc, *odelta, *nsrc, *ndelta; + int len, ret; + if (!(osrc = strdup(orig->src))) + return -22; + nsrc = index(osrc, ':') + 1; + if (nsrc != osrc + 10 || (odelta = index(nsrc, ':')) == NULL) { + free(osrc); + return -22; + } + *odelta = '\0'; + odelta++; + ndelta = dir_new_path(odelta, oldname, cname, oldpath, lxcpath); + if (!ndelta) { + free(osrc); + return -ENOMEM; + } + if (do_rsync(odelta, ndelta) < 0) { + free(osrc); + free(ndelta); + ERROR("copying overlayfs delta"); + return -1; + } + len = strlen(nsrc) + strlen(ndelta) + 12; + new->src = malloc(len); + if (!new->src) { + free(osrc); + free(ndelta); + return -ENOMEM; + } + ret = snprintf(new->src, len, "overlayfs:%s:%s", nsrc, ndelta); + free(osrc); + free(ndelta); + if (ret < 0 || ret >= len) + return -ENOMEM; + } else { + ERROR("overlayfs clone of %s container is not yet supported", + orig->type); + // Note, supporting this will require overlayfs_mount supporting + // mounting of the underlay. No big deal, just needs to be done. + return -1; + } + + return 0; +} + +int overlayfs_destroy(struct bdev *orig) +{ + char *upper; + + if (strncmp(orig->src, "overlayfs:", 10) != 0) + return -22; + upper = index(orig->src + 10, ':'); + if (!upper) + return -22; + upper++; + return lxc_rmdir_onedev(upper); +} + +/* + * to say 'lxc-create -t ubuntu -n o1 -B overlayfs' means you want + * $lxcpath/$lxcname/rootfs to have the created container, while all + * changes after starting the container are written to + * $lxcpath/$lxcname/delta0 + */ +static int overlayfs_create(struct bdev *bdev, const char *dest, const char *n, + struct bdev_specs *specs) +{ + char *delta; + int ret, len = strlen(dest), newlen; + + if (len < 8 || strcmp(dest+len-7, "/rootfs") != 0) + return -1; + + if (!(bdev->dest = strdup(dest))) { + ERROR("Out of memory"); + return -1; + } + + delta = alloca(strlen(dest)+1); + strcpy(delta, dest); + strcpy(delta+len-6, "delta0"); + + if (mkdir_p(delta, 0755) < 0) { + ERROR("Error creating %s\n", delta); + return -1; + } + + /* overlayfs:lower:upper */ + newlen = (2 * len) + strlen("overlayfs:") + 2; + bdev->src = malloc(newlen); + if (!bdev->src) { + ERROR("Out of memory"); + return -1; + } + ret = snprintf(bdev->src, newlen, "overlayfs:%s:%s", dest, delta); + if (ret < 0 || ret >= newlen) + return -1; + + if (mkdir_p(bdev->dest, 0755) < 0) { + ERROR("Error creating %s\n", bdev->dest); + return -1; + } + + return 0; +} + +struct bdev_ops overlayfs_ops = { + .detect = &overlayfs_detect, + .mount = &overlayfs_mount, + .umount = &overlayfs_umount, + .clone_paths = &overlayfs_clonepaths, + .destroy = &overlayfs_destroy, + .create = &overlayfs_create, +}; + +struct bdev_type bdevs[] = { + {.name = "zfs", .ops = &zfs_ops,}, + {.name = "lvm", .ops = &lvm_ops,}, + {.name = "btrfs", .ops = &btrfs_ops,}, + {.name = "dir", .ops = &dir_ops,}, + {.name = "overlayfs", .ops = &overlayfs_ops,}, + {.name = "loop", .ops = &loop_ops,}, +}; + +static const size_t numbdevs = sizeof(bdevs) / sizeof(struct bdev_type); + +void bdev_put(struct bdev *bdev) +{ + if (bdev->data) + free(bdev->data); + if (bdev->src) + free(bdev->src); + if (bdev->dest) + free(bdev->dest); + free(bdev); +} + +struct bdev *bdev_get(const char *type) +{ + int i; + struct bdev *bdev; + + for (i=0; iops = bdevs[i].ops; + bdev->type = bdevs[i].name; + return bdev; +} + +struct bdev *bdev_init(const char *src, const char *dst, const char *data) +{ + int i; + struct bdev *bdev; + + for (i=0; idetect(src); + if (r) + break; + } + + if (i == numbdevs) + return NULL; + bdev = malloc(sizeof(struct bdev)); + if (!bdev) + return NULL; + memset(bdev, 0, sizeof(struct bdev)); + bdev->ops = bdevs[i].ops; + bdev->type = bdevs[i].name; + if (data) + bdev->data = strdup(data); + if (src) + bdev->src = strdup(src); + if (dst) + bdev->dest = strdup(dst); + + return bdev; +} + +/* + * If we're not snaphotting, then bdev_copy becomes a simple case of mount + * the original, mount the new, and rsync the contents. + */ +struct bdev *bdev_copy(const char *src, const char *oldname, const char *cname, + const char *oldpath, const char *lxcpath, const char *bdevtype, + int snap, const char *bdevdata, unsigned long newsize, + int *needs_rdep) +{ + struct bdev *orig, *new; + pid_t pid; + + /* if the container name doesn't show up in the rootfs path, then + * we don't know how to come up with a new name + */ + if (strstr(src, oldname) == NULL) { + ERROR("original rootfs path %s doesn't include container name %s", + src, oldname); + return NULL; + } + + orig = bdev_init(src, NULL, NULL); + if (!orig) { + ERROR("failed to detect blockdev type for %s\n", src); + return NULL; + } + + if (!orig->dest) { + int ret; + orig->dest = malloc(MAXPATHLEN); + if (!orig->dest) { + ERROR("out of memory"); + bdev_put(orig); + return NULL; + } + ret = snprintf(orig->dest, MAXPATHLEN, "%s/%s/rootfs", oldpath, oldname); + if (ret < 0 || ret >= MAXPATHLEN) { + ERROR("rootfs path too long"); + bdev_put(orig); + return NULL; + } + } + + /* + * If newtype is NULL and snapshot is set, then use overlayfs + */ + if (!bdevtype && snap && strcmp(orig->type , "dir") == 0) + bdevtype = "overlayfs"; + + *needs_rdep = 0; + if (bdevtype && strcmp(orig->type, "dir") == 0 && + strcmp(bdevtype, "overlayfs") == 0) + *needs_rdep = 1; + + new = bdev_get(bdevtype ? bdevtype : orig->type); + if (!new) { + ERROR("no such block device type: %s", bdevtype ? bdevtype : orig->type); + bdev_put(orig); + return NULL; + } + + if (new->ops->clone_paths(orig, new, oldname, cname, oldpath, lxcpath, snap, newsize) < 0) { + ERROR("failed getting pathnames for cloned storage: %s\n", src); + bdev_put(orig); + bdev_put(new); + return NULL; + } + + pid = fork(); + if (pid < 0) { + SYSERROR("fork"); + bdev_put(orig); + bdev_put(new); + return NULL; + } + + if (pid > 0) { + int ret = wait_for_pid(pid); + bdev_put(orig); + if (ret < 0) { + bdev_put(new); + return NULL; + } + return new; + } + + if (unshare(CLONE_NEWNS) < 0) { + SYSERROR("unshare CLONE_NEWNS"); + exit(1); + } + if (snap) + exit(0); + + // If not a snapshot, copy the fs. + if (orig->ops->mount(orig) < 0) { + ERROR("failed mounting %s onto %s\n", src, orig->dest); + exit(1); + } + if (new->ops->mount(new) < 0) { + ERROR("failed mounting %s onto %s\n", new->src, new->dest); + exit(1); + } + if (do_rsync(orig->dest, new->dest) < 0) { + ERROR("rsyncing %s to %s\n", orig->src, new->src); + exit(1); + } + // don't bother umounting, ns exit will do that + + exit(0); +} + +static struct bdev * do_bdev_create(const char *dest, const char *type, + const char *cname, struct bdev_specs *specs) +{ + struct bdev *bdev = bdev_get(type); + if (!bdev) { + return NULL; + } + + if (bdev->ops->create(bdev, dest, cname, specs) < 0) { + bdev_put(bdev); + return NULL; + } + + return bdev; +} + +/* + * bdev_create: + * Create a backing store for a container. + * If successfull, return a struct bdev *, with the bdev mounted and ready + * for use. Before completing, the caller will need to call the + * umount operation and bdev_put(). + * @dest: the mountpoint (i.e. /var/lib/lxc/$name/rootfs) + * @type: the bdevtype (dir, btrfs, zfs, etc) + * @cname: the container name + * @specs: details about the backing store to create, like fstype + */ +struct bdev *bdev_create(const char *dest, const char *type, + const char *cname, struct bdev_specs *specs) +{ + struct bdev *bdev; + char *best_options[] = {"btrfs", "zfs", "lvm", "dir", NULL}; + + if (!type) + return do_bdev_create(dest, "dir", cname, specs); + + if (strcmp(type, "best") == 0) { + int i; + // try for the best backing store type, according to our + // opinionated preferences + for (i=0; best_options[i]; i++) { + if ((bdev = do_bdev_create(dest, best_options[i], cname, specs))) + return bdev; + } + return NULL; // 'dir' should never fail, so this shouldn't happen + } + + // -B lvm,dir + if (index(type, ',') != NULL) { + char *dup = alloca(strlen(type)+1), *saveptr, *token; + strcpy(dup, type); + for (token = strtok_r(dup, ",", &saveptr); token; + token = strtok_r(NULL, ",", &saveptr)) { + if ((bdev = do_bdev_create(dest, token, cname, specs))) + return bdev; + } + } + + return do_bdev_create(dest, type, cname, specs); +} + +char *overlayfs_getlower(char *p) +{ + char *p1 = index(p, ':'); + if (p1) + *p1 = '\0'; + return p; +} diff -Nru lxc-0.8.0~rc1/src/lxc/bdev.h lxc-1.0.0~alpha1/src/lxc/bdev.h --- lxc-0.8.0~rc1/src/lxc/bdev.h 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/bdev.h 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,138 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __LXC_BDEV_H +#define __LXC_BDEV_H +/* blockdev operations for: + * dir, raw, btrfs, overlayfs, aufs, lvm, loop, zfs + * someday: qemu-nbd, qcow2, qed + */ + +#include "config.h" +#include "lxccontainer.h" + +struct bdev; + +/* + * specifications for how to create a new backing store + */ +struct bdev_specs { + union { + struct { + char *zfsroot; + } zfs; + struct { + char *vg; + char *lv; + char *fstype; + unsigned long fssize; // fs size in bytes + } lvm; + struct { + char *fstype; + unsigned long fssize; // fs size in bytes + } loop; + } u; +}; + +struct bdev_ops { + /* detect whether path is of this bdev type */ + int (*detect)(const char *path); + // mount requires src and dest to be set. + int (*mount)(struct bdev *bdev); + int (*umount)(struct bdev *bdev); + int (*destroy)(struct bdev *bdev); + int (*create)(struct bdev *bdev, const char *dest, const char *n, + struct bdev_specs *specs); + /* given original mount, rename the paths for cloned container */ + int (*clone_paths)(struct bdev *orig, struct bdev *new, const char *oldname, + const char *cname, const char *oldpath, const char *lxcpath, + int snap, unsigned long newsize); +}; + +/* + * When lxc-start (conf.c) is mounting a rootfs, then src will be the + * 'lxc.rootfs' value, dest will be mount dir (i.e. $libdir/lxc) When clone + * or create is doing so, then dest will be $lxcpath/$lxcname/rootfs, since + * we may need to rsync from one to the other. + * data is so far unused. + */ +struct bdev { + struct bdev_ops *ops; + char *type; + char *src; + char *dest; + char *data; + // turn the following into a union if need be + // lofd is the open fd for the mounted loopback file + int lofd; +}; + +char *overlayfs_getlower(char *p); + +/* + * Instantiate a bdev object. The src is used to determine which blockdev + * type this should be. The dst and data are optional, and will be used + * in case of mount/umount. + * + * Optionally, src can be 'dir:/var/lib/lxc/c1' or 'lvm:/dev/lxc/c1'. For + * other backing stores, this will allow additional options. In particular, + * "overlayfs:/var/lib/lxc/canonical/rootfs:/var/lib/lxc/c1/delta" will mean + * use /var/lib/lxc/canonical/rootfs as lower dir, and /var/lib/lxc/c1/delta + * as the upper, writeable layer. + */ +struct bdev *bdev_init(const char *src, const char *dst, const char *data); + +struct bdev *bdev_copy(const char *src, const char *oldname, const char *cname, + const char *oldpath, const char *lxcpath, const char *bdevtype, + int snap, const char *bdevdata, unsigned long newsize, + int *needs_rdep); +struct bdev *bdev_create(const char *dest, const char *type, + const char *cname, struct bdev_specs *specs); +void bdev_put(struct bdev *bdev); + +/* define constants if the kernel/glibc headers don't define them */ +#ifndef MS_DIRSYNC +#define MS_DIRSYNC 128 +#endif + +#ifndef MS_REC +#define MS_REC 16384 +#endif + +#ifndef MNT_DETACH +#define MNT_DETACH 2 +#endif + +#ifndef MS_SLAVE +#define MS_SLAVE (1<<19) +#endif + +#ifndef MS_RELATIME +#define MS_RELATIME (1 << 21) +#endif + +#ifndef MS_STRICTATIME +#define MS_STRICTATIME (1 << 24) +#endif + +#endif diff -Nru lxc-0.8.0~rc1/src/lxc/caps.c lxc-1.0.0~alpha1/src/lxc/caps.c --- lxc-0.8.0~rc1/src/lxc/caps.c 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/caps.c 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,7 +18,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #define _GNU_SOURCE @@ -27,12 +27,20 @@ #include #include #include -#include +#include +#include "config.h" #include "log.h" lxc_log_define(lxc_caps, lxc); +#if HAVE_SYS_CAPABILITY_H +#include + +#ifndef PR_CAPBSET_READ +#define PR_CAPBSET_READ 23 +#endif + int lxc_caps_reset(void) { cap_t cap = cap_init(); @@ -108,8 +116,13 @@ ret = cap_get_flag(caps, cap, CAP_PERMITTED, &flag); if (ret) { - ERROR("failed to cap_get_flag: %m"); - goto out; + if (errno == EINVAL) { + INFO("Last supported cap was %d\n", cap-1); + break; + } else { + ERROR("failed to cap_get_flag: %m"); + goto out; + } } ret = cap_set_flag(caps, CAP_EFFECTIVE, 1, &cap, flag); @@ -214,41 +227,4 @@ return last_cap; } -/* - * check if we have the caps needed to start a container. returns 1 on - * success, 0 on error. (I'd prefer this be a bool, but am afraid that - * might fail to build on some distros). - */ -int lxc_caps_check(void) -{ - uid_t uid = getuid(); - cap_t caps; - cap_flag_value_t value; - int i, ret; - - cap_value_t needed_caps[] = { CAP_SYS_ADMIN, CAP_NET_ADMIN, CAP_SETUID, CAP_SETGID }; - -#define NUMCAPS ((int) (sizeof(needed_caps) / sizeof(cap_t))) - - if (!uid) - return 1; - - caps = cap_get_proc(); - if (!caps) { - ERROR("failed to cap_get_proc: %m"); - return 0; - } - - for (i=0; i + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,42 +18,64 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "config.h" + #ifndef _caps_h #define _caps_h +#if HAVE_SYS_CAPABILITY_H extern int lxc_caps_reset(void); extern int lxc_caps_down(void); extern int lxc_caps_up(void); extern int lxc_caps_init(void); -extern int lxc_caps_check(void); extern int lxc_caps_last_cap(void); +#else +static inline int lxc_caps_reset(void) { + return 0; +} +static inline int lxc_caps_down(void) { + return 0; +} +static inline int lxc_caps_up(void) { + return 0; +} +static inline int lxc_caps_init(void) { + return 0; +} + +static inline int lxc_caps_last_cap(void) { + return 0; +} +#endif #define lxc_priv(__lxc_function) \ ({ \ - int __ret, __ret2, __errno = 0; \ + __label__ out; \ + int __ret, __ret2, ___errno = 0; \ __ret = lxc_caps_up(); \ if (__ret) \ - goto __out; \ + goto out; \ __ret = __lxc_function; \ if (__ret) \ - __errno = errno; \ + ___errno = errno; \ __ret2 = lxc_caps_down(); \ - __out: __ret ? errno = __errno,__ret : __ret2; \ + out: __ret ? errno = ___errno,__ret : __ret2; \ }) -#define lxc_unpriv(__lxc_function) \ +#define lxc_unpriv(__lxc_function) \ ({ \ - int __ret, __ret2, __errno = 0; \ + __label__ out; \ + int __ret, __ret2, ___errno = 0; \ __ret = lxc_caps_down(); \ if (__ret) \ - goto __out; \ + goto out; \ __ret = __lxc_function; \ if (__ret) \ - __errno = errno; \ + ___errno = errno; \ __ret2 = lxc_caps_up(); \ - __out: __ret ? errno = __errno,__ret : __ret2; \ + out: __ret ? errno = ___errno,__ret : __ret2; \ }) #endif diff -Nru lxc-0.8.0~rc1/src/lxc/cgroup.c lxc-1.0.0~alpha1/src/lxc/cgroup.c --- lxc-0.8.0~rc1/src/lxc/cgroup.c 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/cgroup.c 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,18 +18,18 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #define _GNU_SOURCE #include #undef _GNU_SOURCE #include #include -#include #include #include #include #include +#include #include #include #include @@ -39,109 +39,85 @@ #include "error.h" #include "config.h" +#include "commands.h" +#include "list.h" +#include "conf.h" #include #include #include -lxc_log_define(lxc_cgroup, lxc); - -#define MTAB "/proc/mounts" - -enum { - CGROUP_NS_CGROUP = 1, - CGROUP_CLONE_CHILDREN, -}; - -static char *hasmntopt_multiple(struct mntent *mntent, const char *options) -{ - const char *ptr = options; - const char *ptr2 = strchr(options, ','); - char *result; - - while (ptr2 != NULL) { - char *option = strndup(ptr, ptr2 - ptr); - if (!option) { - SYSERROR("Temporary memory allocation error"); - return NULL; - } +#if IS_BIONIC +#include <../include/lxcmntent.h> +#else +#include +#endif - result = hasmntopt(mntent, option); - free(option); +#ifndef HAVE_GETLINE +#ifdef HAVE_FGETLN +#include <../include/getline.h> +#endif +#endif - if (!result) { - return NULL; - } +lxc_log_define(lxc_cgroup, lxc); - ptr = ptr2 + 1; - ptr2 = strchr(ptr, ','); - } +#define MTAB "/proc/mounts" - /* for multiple mount options, the return value is basically NULL - * or non-NULL, so this should suffice for our purposes */ - return hasmntopt(mntent, ptr); -} +/* In the case of a bind mount, there could be two long pathnames in the + * mntent plus options so use large enough buffer size + */ +#define LARGE_MAXPATHLEN 4 * MAXPATHLEN -/* - * get_init_cgroup: get the cgroup init is in. - * dsg: preallocated buffer to put the output in - * subsystem: the exact cgroup subsystem to look up - * mntent: a mntent (from getmntent) whose mntopts contains the - * subsystem to look up. - * - * subsystem and mntent can both be NULL, in which case we return - * the first entry in /proc/1/cgroup. - * - * Returns a pointer to the answer, which may be "". +/* Check if a mount is a cgroup hierarchy for any subsystem. + * Return the first subsystem found (or NULL if none). */ -static char *get_init_cgroup(const char *subsystem, struct mntent *mntent, - char *dsg) +static char *mount_has_subsystem(const struct mntent *mntent) { FILE *f; - char *c, *c2; + char *c, *ret = NULL; char line[MAXPATHLEN]; - *dsg = '\0'; - f = fopen("/proc/1/cgroup", "r"); + /* read the list of subsystems from the kernel */ + f = fopen("/proc/cgroups", "r"); if (!f) - return dsg; + return 0; + + /* skip the first line, which contains column headings */ + if (!fgets(line, MAXPATHLEN, f)) { + fclose(f); + return 0; + } while (fgets(line, MAXPATHLEN, f)) { - c = index(line, ':'); + c = strchr(line, '\t'); if (!c) continue; - c++; - c2 = index(c, ':'); - if (!c2) - continue; - *c2 = '\0'; - c2++; - if (!subsystem && !mntent) - goto good; - if (subsystem && strcmp(c, subsystem) != 0) - continue; - if (mntent && !hasmntopt(mntent, c)) - continue; -good: - DEBUG("get_init_cgroup: found init cgroup for subsys %s at %s\n", - subsystem, c2); - strncpy(dsg, c2, MAXPATHLEN); - c = &dsg[strlen(dsg)-1]; - if (*c == '\n') - *c = '\0'; - goto found; + *c = '\0'; + + ret = hasmntopt(mntent, line); + if (ret) + break; } -found: fclose(f); - return dsg; + return ret; } -static int get_cgroup_mount(const char *subsystem, char *mnt) +/* + * Determine mountpoint for a cgroup subsystem. + * @dest: a passed-in buffer of at least size MAXPATHLEN into which the path + * is copied. + * @subsystem: cgroup subsystem (i.e. freezer) + * + * Returns true on success, false on error. + */ +bool get_subsys_mount(char *dest, const char *subsystem) { - struct mntent *mntent; - char initcgroup[MAXPATHLEN]; + struct mntent mntent_r; FILE *file = NULL; + int ret; + bool retv = false; + char buf[LARGE_MAXPATHLEN] = {0}; file = setmntent(MTAB, "r"); if (!file) { @@ -149,278 +125,991 @@ return -1; } - while ((mntent = getmntent(file))) { - - if (strcmp(mntent->mnt_type, "cgroup")) + while ((getmntent_r(file, &mntent_r, buf, sizeof(buf)))) { + if (strcmp(mntent_r.mnt_type, "cgroup")) continue; - if (!subsystem || hasmntopt_multiple(mntent, subsystem)) { - int ret; - ret = snprintf(mnt, MAXPATHLEN, "%s%s/lxc", - mntent->mnt_dir, - get_init_cgroup(subsystem, NULL, - initcgroup)); - if (ret < 0 || ret >= MAXPATHLEN) - goto fail; - fclose(file); - DEBUG("using cgroup mounted at '%s'", mnt); - return 0; + + if (subsystem) { + if (!hasmntopt(&mntent_r, subsystem)) + continue; + } else { + if (!mount_has_subsystem(&mntent_r)) + continue; } + + ret = snprintf(dest, MAXPATHLEN, "%s", mntent_r.mnt_dir); + if (ret < 0 || ret >= MAXPATHLEN) + goto fail; + + retv = true; + goto out; }; fail: DEBUG("Failed to find cgroup for %s\n", subsystem ? subsystem : "(NULL)"); - - fclose(file); - - return -1; +out: + endmntent(file); + return retv; } -int lxc_ns_is_mounted(void) +/* + * is_in_cgroup: check whether pid is found in the passed-in cgroup tasks + * file. + * @path: in full path to a cgroup tasks file + * Note that in most cases the file will simply not exist, which is ok - it + * just means that's not our cgroup. + */ +static bool is_in_cgroup(pid_t pid, char *path) { - static char buf[MAXPATHLEN]; + int cmppid; + FILE *f = fopen(path, "r"); + char *line = NULL; + size_t sz = 0; - return (get_cgroup_mount("ns", buf) == 0); + if (!f) + return false; + while (getline(&line, &sz, f) != -1) { + if (sscanf(line, "%d", &cmppid) == 1 && cmppid == pid) { + fclose(f); + free(line); + return true; + } + } + fclose(f); + if (line) + free(line); + return false; } -static int get_cgroup_flags(struct mntent *mntent) +/* + * lxc_cgroup_path_get: Get the absolute pathname for a cgroup + * file for a running container. + * + * @subsystem : subsystem of interest (e.g. "freezer"). If NULL, then + * the first cgroup entry in mtab will be used. + * @name : name of container to connect to + * @lxcpath : the lxcpath in which the container is running + * + * This is the exported function, which determines cgpath from the + * lxc-start of the @name container running in @lxcpath. + * + * Returns path on success, NULL on error. The caller must free() + * the returned path. + */ +char *lxc_cgroup_path_get(const char *subsystem, const char *name, + const char *lxcpath) { - int flags = 0; + char *cgpath, *cgp, path[MAXPATHLEN], *pathp, *p; + pid_t initpid = lxc_cmd_get_init_pid(name, lxcpath); + int ret; + if (initpid < 0) + return NULL; - if (hasmntopt(mntent, "ns")) - flags |= CGROUP_NS_CGROUP; + cgpath = lxc_cmd_get_cgroup_path(name, lxcpath, subsystem); + if (!cgpath) + return NULL; - if (hasmntopt(mntent, "clone_children")) - flags |= CGROUP_CLONE_CHILDREN; + if (!get_subsys_mount(path, subsystem)) + return NULL; - DEBUG("cgroup %s has flags 0x%x", mntent->mnt_dir, flags); - return flags; + pathp = path + strlen(path); + /* + * find a mntpt where i have the subsystem mounted, then find + * a subset cgpath under that which has pid in it. + * + * If d->mntpt is '/a/b/c/d', and the mountpoint is /x/y/z, + * then look for ourselves in: + * /x/y/z/a/b/c/d/tasks + * /x/y/z/b/c/d/tasks + * /x/y/z/c/d/tasks + * /x/y/z/d/tasks + * /x/y/z/tasks + */ + cgp = cgpath; + while (cgp[0]) { + ret = snprintf(pathp, MAXPATHLEN - (pathp - path), "%s/tasks", cgp); + if (ret < 0 || ret >= MAXPATHLEN) + return NULL; + if (!is_in_cgroup(initpid, path)) { + // does not exist, try the next one + cgp = index(cgp+1, '/'); + if (!cgp) + break; + continue; + } + break; + } + if (!cgp || !*cgp) { + // try just the path + ret = snprintf(pathp, MAXPATHLEN - (pathp - path), "/tasks"); + if (ret < 0 || ret >= MAXPATHLEN) + return NULL; + if (!is_in_cgroup(initpid, path)) { + return NULL; + } + return strdup("/"); + } + // path still has 'tasks' on the end, drop it + if ((p = strrchr(path, '/')) != NULL) + *p = '\0'; + return strdup(path); } -static int cgroup_rename_nsgroup(const char *mnt, const char *name, pid_t pid) +/* + * do_cgroup_set: Write a value into a cgroup file + * + * @path : absolute path to cgroup file + * @value : value to write into file + * + * Returns 0 on success, < 0 on error. + */ +static int do_cgroup_set(const char *path, const char *value) { - char oldname[MAXPATHLEN]; - - snprintf(oldname, MAXPATHLEN, "%s/%d", mnt, pid); + int fd, ret; - if (rename(oldname, name)) { - SYSERROR("failed to rename cgroup %s->%s", oldname, name); + if ((fd = open(path, O_WRONLY)) < 0) { + SYSERROR("open %s : %s", path, strerror(errno)); return -1; } - DEBUG("'%s' renamed to '%s'", oldname, name); + if ((ret = write(fd, value, strlen(value))) < 0) { + close(fd); + SYSERROR("write %s : %s", path, strerror(errno)); + return ret; + } + if ((ret = close(fd)) < 0) { + SYSERROR("close %s : %s", path, strerror(errno)); + return ret; + } return 0; } -static int cgroup_enable_clone_children(const char *path) +static int in_subsys_list(const char *s, const char *list) { - FILE *f; - int ret = 0; + char *token, *str, *saveptr = NULL; - f = fopen(path, "w"); - if (!f) { - SYSERROR("failed to open '%s'", path); - return -1; + if (!list || !s) + return 0; + + str = alloca(strlen(list)+1); + strcpy(str, list); + for (; (token = strtok_r(str, ",", &saveptr)); str = NULL) { + if (strcmp(s, token) == 0) + return 1; } - if (fprintf(f, "1") < 1) { - ERROR("failed to write flag to '%s'", path); - ret = -1; + return 0; +} + +static char *cgroup_get_subsys_abspath(struct lxc_handler *handler, const char *subsys) +{ + struct cgroup_desc *d; + + for (d = handler->cgroup; d; d = d->next) { + if (in_subsys_list(subsys, d->subsystems)) + return d->curcgroup; } - fclose(f); + return NULL; +} +static bool cgroup_devices_has_deny(struct lxc_handler *h, char *v) +{ + char *cgabspath, path[MAXPATHLEN]; + FILE *f; + char *line = NULL; + size_t len = 0; + bool ret = true; + int r; + + // XXX FIXME if users could use something other than 'lxc.devices.deny = a'. + // not sure they ever do, but they *could* + // right now, I'm assuming they do NOT + if (strcmp(v, "a") && strcmp(v, "a *:* rwm")) + return false; + cgabspath = cgroup_get_subsys_abspath(h, "devices"); + if (!cgabspath) + return false; + + r = snprintf(path, MAXPATHLEN, "%s/devices.list", cgabspath); + if (r < 0 || r >= MAXPATHLEN) { + ERROR("pathname too long for devices.list"); + return false; + } + + if (!(f = fopen(path, "r"))) + return false; + + while (getline(&line, &len, f) != -1) { + size_t len = strlen(line); + if (len > 0 && line[len-1] == '\n') + line[len-1] = '\0'; + if (strcmp(line, "a *:* rwm") == 0) { + ret = false; + goto out; + } + } + +out: + fclose(f); + if (line) + free(line); return ret; } -int lxc_cgroup_attach(const char *path, pid_t pid) +static bool cgroup_devices_has_allow(struct lxc_handler *h, char *v) { + char *cgabspath, path[MAXPATHLEN]; + int r; + bool ret = false; FILE *f; - char tasks[MAXPATHLEN]; - int ret = 0; + char *line = NULL; + size_t len = 0; + + cgabspath = cgroup_get_subsys_abspath(h, "devices"); + if (!cgabspath) + return false; + + r = snprintf(path, MAXPATHLEN, "%s/devices.list", cgabspath); + if (r < 0 || r >= MAXPATHLEN) { + ERROR("pathname too long to for devices.list"); + return false; + } + + if (!(f = fopen(path, "r"))) + return false; + + while (getline(&line, &len, f) != -1) { + if (len < 1) + goto out; + if (line[len-1] == '\n') + line[len-1] = '\0'; + if (strcmp(line, "a *:* rwm") == 0 || strcmp(line, v) == 0) { + ret = true; + goto out; + } + } + +out: + if (line) + free(line); + fclose(f); + return ret; +} + +/* + * lxc_cgroup_set_bypath: Write a value into a cgroup file + * + * @cgrelpath : a container's relative cgroup path (e.g. "lxc/c1") + * @filename : the cgroup file to write (e.g. "freezer.state") + * @value : value to write into file + * + * Returns 0 on success, < 0 on error. + */ +int lxc_cgroup_set_value(struct lxc_handler *handler, const char *filename, + const char *value) +{ + char *cgabspath, path[MAXPATHLEN], *p; + int ret; - snprintf(tasks, MAXPATHLEN, "%s/tasks", path); + ret = snprintf(path, MAXPATHLEN, "%s", filename); + if (ret < 0 || ret >= MAXPATHLEN) + return -1; + if ((p = index(path, '.')) != NULL) + *p = '\0'; + cgabspath = cgroup_get_subsys_abspath(handler, path); + if (!cgabspath) + return -1; - f = fopen(tasks, "w"); - if (!f) { - SYSERROR("failed to open '%s'", tasks); + ret = snprintf(path, MAXPATHLEN, "%s/%s", cgabspath, filename); + if (ret < 0 || ret >= MAXPATHLEN) { + ERROR("pathname too long to set cgroup value %s to %s", + filename, value); return -1; } - if (fprintf(f, "%d", pid) <= 0) { - SYSERROR("failed to write pid '%d' to '%s'", pid, tasks); + return do_cgroup_set(path, value); +} + +/* + * lxc_cgroup_set: Write a value into a cgroup file + * + * @name : name of container to connect to + * @filename : the cgroup file to write (e.g. "freezer.state") + * @value : value to write into file + * @lxcpath : the lxcpath in which the container is running + * + * Returns 0 on success, < 0 on error. + */ +int lxc_cgroup_set(const char *name, const char *filename, const char *value, + const char *lxcpath) +{ + int ret; + char *cgabspath; + char path[MAXPATHLEN]; + char *subsystem = alloca(strlen(filename)+1), *p; + strcpy(subsystem, filename); + + if ((p = index(subsystem, '.')) != NULL) + *p = '\0'; + + cgabspath = lxc_cgroup_path_get(subsystem, name, lxcpath); + if (!cgabspath) + return -1; + + ret = snprintf(path, MAXPATHLEN, "%s/%s", cgabspath, filename); + if (ret < 0 || ret >= MAXPATHLEN) { + ERROR("pathname too long"); ret = -1; + goto out; } - fclose(f); + ret = do_cgroup_set(path, value); +out: + free(cgabspath); return ret; } /* - * rename cgname, which is under cgparent, to a new name starting - * with 'cgparent/dead'. That way cgname can be reused. Return - * 0 on success, -1 on failure. + * lxc_cgroup_get: Read value from a cgroup file + * + * @name : name of container to connect to + * @filename : the cgroup file to read (e.g. "freezer.state") + * @value : a pre-allocated buffer to copy the answer into + * @len : the length of pre-allocated @value + * @lxcpath : the lxcpath in which the container is running + * + * Returns the number of bytes read on success, < 0 on error + * + * If you pass in NULL value or 0 len, the return value will be the size of + * the file, and @value will not contain the contents. + * + * Note that we can't get the file size quickly through stat or lseek. + * Therefore if you pass in len > 0 but less than the file size, your only + * indication will be that the return value will be equal to the passed-in ret. + * We will not return the actual full file size. */ -int try_to_move_cgname(char *cgparent, char *cgname) +int lxc_cgroup_get(const char *name, const char *filename, char *value, + size_t len, const char *lxcpath) { - char *newdir; + int fd, ret; + char *cgabspath; + char path[MAXPATHLEN]; + char *subsystem = alloca(strlen(filename)+1), *p; - /* tempnam problems don't matter here - cgroupfs will prevent - * duplicates if we race, and we'll just fail at that (unlikely) - * point - */ + strcpy(subsystem, filename); - newdir = tempnam(cgparent, "dead"); - if (!newdir) - return -1; - if (rename(cgname, newdir)) + if ((p = index(subsystem, '.')) != NULL) + *p = '\0'; + + cgabspath = lxc_cgroup_path_get(subsystem, name, lxcpath); + if (!cgabspath) return -1; - WARN("non-empty cgroup %s renamed to %s, please manually inspect it\n", - cgname, newdir); - return 0; + ret = snprintf(path, MAXPATHLEN, "%s/%s", cgabspath, filename); + if (ret < 0 || ret >= MAXPATHLEN) { + ERROR("pathname too long"); + ret = -1; + goto out; + } + + fd = open(path, O_RDONLY); + if (fd < 0) { + ERROR("open %s : %s", path, strerror(errno)); + ret = -1; + goto out; + } + + if (!len || !value) { + char buf[100]; + int count = 0; + while ((ret = read(fd, buf, 100)) > 0) + count += ret; + if (ret >= 0) + ret = count; + } else { + memset(value, 0, len); + ret = read(fd, value, len); + } + + if (ret < 0) + ERROR("read %s : %s", path, strerror(errno)); + + close(fd); +out: + free(cgabspath); + return ret; } -/* - * create a cgroup for the container in a particular subsystem. - */ -static int lxc_one_cgroup_create(const char *name, - struct mntent *mntent, pid_t pid) +int lxc_cgroup_nrtasks(struct lxc_handler *handler) { - char cginit[MAXPATHLEN], cgname[MAXPATHLEN], cgparent[MAXPATHLEN]; - char clonechild[MAXPATHLEN]; - char initcgroup[MAXPATHLEN]; - int flags, ret; - - /* cgparent is the parent dir, /sys/fs/cgroup///lxc */ - /* (remember get_init_cgroup() returns a path starting with '/') */ - /* cgname is the full name, /sys/fs/cgroup///lxc/name */ - ret = snprintf(cginit, MAXPATHLEN, "%s%s", mntent->mnt_dir, - get_init_cgroup(NULL, mntent, initcgroup)); - if (ret < 0 || ret >= MAXPATHLEN) { - SYSERROR("Failed creating pathname for init's cgroup (%d)\n", ret); + char path[MAXPATHLEN]; + int pid, ret; + FILE *file; + + if (!handler->cgroup) return -1; - } - ret = snprintf(cgparent, MAXPATHLEN, "%s/lxc", cginit); + /* XXX Should we use a specific subsystem rather than the first one we + * found (handler->cgroup->curcgroup)? */ + ret = snprintf(path, MAXPATHLEN, "%s/tasks", handler->cgroup->curcgroup); if (ret < 0 || ret >= MAXPATHLEN) { - SYSERROR("Failed creating pathname for cgroup parent (%d)\n", ret); + ERROR("pathname too long"); return -1; } - ret = snprintf(cgname, MAXPATHLEN, "%s/%s", cgparent, name); - if (ret < 0 || ret >= MAXPATHLEN) { - SYSERROR("Failed creating pathname for cgroup (%d)\n", ret); + + file = fopen(path, "r"); + if (!file) { + SYSERROR("fopen '%s' failed", path); return -1; } - flags = get_cgroup_flags(mntent); + ret = 0; + while (fscanf(file, "%d", &pid) != EOF) + ret++; + + fclose(file); + return ret; +} + +static int subsys_lists_match(const char *list1, const char *list2) +{ + char *token, *str, *saveptr = NULL; - /* Do we have the deprecated ns_cgroup subsystem? */ - if (flags & CGROUP_NS_CGROUP) { - WARN("using deprecated ns_cgroup"); - return cgroup_rename_nsgroup(cgparent, cgname, pid); + if (!list1 || !list2) + return 0; + + if (strlen(list1) != strlen(list2)) + return 0; + + str = alloca(strlen(list1)+1); + strcpy(str, list1); + for (; (token = strtok_r(str, ",", &saveptr)); str = NULL) { + if (in_subsys_list(token, list2) == 0) + return 0; } - ret = snprintf(clonechild, MAXPATHLEN, "%s/cgroup.clone_children", - cginit); - if (ret < 0 || ret >= MAXPATHLEN) { - SYSERROR("Failed creating pathname for clone_children (%d)\n", ret); - return -1; + return 1; +} + +static void set_clone_children(struct mntent *m) +{ + char path[MAXPATHLEN]; + FILE *fout; + int ret; + + if (!in_subsys_list("cpuset", m->mnt_opts)) + return; + ret = snprintf(path, MAXPATHLEN, "%s/cgroup.clone_children", m->mnt_dir); + if (ret < 0 || ret > MAXPATHLEN) + return; + fout = fopen(path, "w"); + if (!fout) + return; + fprintf(fout, "1\n"); + fclose(fout); +} + +static bool have_visited(char *opts, char *visited, char *all_subsystems) +{ + char *str, *s = NULL, *token; + + str = alloca(strlen(opts)+1); + strcpy(str, opts); + for (; (token = strtok_r(str, ",", &s)); str = NULL) { + if (!in_subsys_list(token, all_subsystems)) + continue; + if (visited && in_subsys_list(token, visited)) + return true; } - /* we check if the kernel has clone_children, at this point if there - * no clone_children neither ns_cgroup, that means the cgroup is mounted - * without the ns_cgroup and it has not the compatibility flag - */ - if (access(clonechild, F_OK)) { - ERROR("no ns_cgroup option specified"); - return -1; + return false; +} + +static bool is_in_desclist(struct cgroup_desc *d, char *opts, char *all_subsystems) +{ + while (d) { + if (have_visited(opts, d->subsystems, all_subsystems)) + return true; + d = d->next; } + return false; +} - /* enable the clone_children flag of the cgroup */ - if (cgroup_enable_clone_children(clonechild)) { - SYSERROR("failed to enable 'clone_children flag"); - return -1; +static char *record_visited(char *opts, char *all_subsystems) +{ + char *s = NULL, *token, *str; + int oldlen = 0, newlen, toklen; + char *visited = NULL; + + str = alloca(strlen(opts)+1); + strcpy(str, opts); + for (; (token = strtok_r(str, ",", &s)); str = NULL) { + if (!in_subsys_list(token, all_subsystems)) + continue; + toklen = strlen(token); + newlen = oldlen + toklen + 1; // ',' + token or token + '\0' + visited = realloc(visited, newlen); + if (!visited) + return (char *)-ENOMEM; + if (oldlen) + strcat(visited, ","); + else + *visited = '\0'; + strcat(visited, token); + oldlen = newlen; } - /* if /sys/fs/cgroup///lxc does not exist, create it */ - if (access(cgparent, F_OK) && mkdir(cgparent, 0755)) { - SYSERROR("failed to create '%s' directory", cgparent); - return -1; + return visited; +} + +static char *get_all_subsystems(void) +{ + FILE *f; + char *line = NULL, *ret = NULL; + size_t len; + int first = 1; + + /* read the list of subsystems from the kernel */ + f = fopen("/proc/cgroups", "r"); + if (!f) + return NULL; + + while (getline(&line, &len, f) != -1) { + char *c; + int oldlen, newlen, inc; + + /* skip the first line */ + if (first) { + first=0; + continue; + } + + c = strchr(line, '\t'); + if (!c) + continue; + *c = '\0'; + + oldlen = ret ? strlen(ret) : 0; + newlen = oldlen + strlen(line) + 2; + ret = realloc(ret, newlen); + if (!ret) + goto out; + inc = snprintf(ret + oldlen, newlen, ",%s", line); + if (inc < 0 || inc >= newlen) { + free(ret); + ret = NULL; + goto out; + } } - /* - * There is a previous cgroup. Try to delete it. If that fails - * (i.e. it is not empty) try to move it out of the way. - */ - if (!access(cgname, F_OK) && rmdir(cgname)) { - if (try_to_move_cgname(cgparent, cgname)) { - SYSERROR("failed to remove previous cgroup '%s'", cgname); - return -1; +out: + if (line) + free(line); + fclose(f); + return ret; +} + +/* + * /etc/lxc/lxc.conf can contain lxc.cgroup.use = entries. + * If any of those are present, then lxc will ONLY consider + * cgroup filesystems mounted at one of the listed entries. + */ +static char *get_cgroup_uselist() +{ + FILE *f; + char *line = NULL, *ret = NULL; + size_t sz = 0, retsz = 0, newsz; + + if ((f = fopen(LXC_GLOBAL_CONF, "r")) == NULL) + return NULL; + while (getline(&line, &sz, f) != -1) { + char *p = line; + while (*p && isblank(*p)) + p++; + if (strncmp(p, "lxc.cgroup.use", 14) != 0) + continue; + p = index(p, '='); + if (!p) + continue; + p++; + while (*p && isblank(*p)) + p++; + if (strlen(p) < 1) + continue; + newsz = retsz + strlen(p); + if (retsz == 0) + newsz += 1; // for trailing \0 + // the last line in the file could lack \n + if (p[strlen(p)-1] != '\n') + newsz += 1; + ret = realloc(ret, newsz); + if (!ret) { + ERROR("Out of memory reading cgroup uselist"); + fclose(f); + free(line); + return (char *)-ENOMEM; } + if (retsz == 0) + strcpy(ret, p); + else + strcat(ret, p); + if (p[strlen(p)-1] != '\n') + ret[newsz-2] = '\0'; + ret[newsz-1] = '\0'; + retsz = newsz; } - /* Let's create the cgroup */ - if (mkdir(cgname, 0755)) { - SYSERROR("failed to create '%s' directory", cgname); - return -1; + if (line) + free(line); + return ret; +} + +static bool is_in_uselist(char *uselist, struct mntent *m) +{ + char *p; + if (!uselist) + return true; + if (!*uselist) + return false; + while (*uselist) { + p = index(uselist, '\n'); + if (strncmp(m->mnt_dir, uselist, p - uselist) == 0) + return true; + uselist = p+1; } + return false; +} - /* Let's add the pid to the 'tasks' file */ - if (lxc_cgroup_attach(cgname, pid)) { - SYSERROR("failed to attach pid '%d' to '%s'", pid, cgname); - rmdir(cgname); - return -1; +static bool find_real_cgroup(struct cgroup_desc *d, char *path) +{ + FILE *f; + char *line = NULL, *p, *p2; + int ret = 0; + size_t len; + + if ((f = fopen("/proc/self/cgroup", "r")) == NULL) { + SYSERROR("Error opening /proc/self/cgroups"); + return false; + } + + // If there is no subsystem, ignore the mount. Note we may want + // to change this, so that unprivileged users can use a unbound + // cgroup mount to arrange their container tasks. + if (!d->subsystems) { + fclose(f); + return false; } + while (getline(&line, &len, f) != -1) { + if (!(p = index(line, ':'))) + continue; + if (!(p2 = index(++p, ':'))) + continue; + *p2 = '\0'; + // remove trailing newlines + if (*(p2 + 1) && p2[strlen(p2 + 1)] == '\n') + p2[strlen(p2 + 1)] = '\0'; + // in case of multiple mounts it may be more correct to + // insist all subsystems be the same + if (subsys_lists_match(p, d->subsystems)) + goto found; + } - INFO("created cgroup '%s'", cgname); + if (line) + free(line); + fclose(f); + return false;; - return 0; +found: + fclose(f); + ret = snprintf(path, MAXPATHLEN, "%s", p2+1); + if (ret < 0 || ret >= MAXPATHLEN) { + free(line); + return false; + } + free(line); + return true; } + /* - * for each mounted cgroup, create a cgroup for the container + * for a given cgroup mount entry, and a to-be-created container, + * 1. Figure out full path of the cgroup we are currently in, + * 2. Find a new free cgroup which is $path / $lxc_name with an + * optional '-$n' where n is an ever-increasing integer. */ -int lxc_cgroup_create(const char *name, pid_t pid) +static char *find_free_cgroup(struct cgroup_desc *d, const char *lxc_name) { - struct mntent *mntent; - FILE *file = NULL; - int err = -1; - int found = 0; + char tail[20], cgpath[MAXPATHLEN], *cgp, path[MAXPATHLEN]; + int i = 0, ret; + size_t l; + + if (!find_real_cgroup(d, cgpath)) { + ERROR("Failed to find current cgroup"); + return NULL; + } + /* + * If d->mntpt is '/a/b/c/d', and the mountpoint is /x/y/z, + * then look for ourselves in: + * /x/y/z/a/b/c/d/tasks + * /x/y/z/b/c/d/tasks + * /x/y/z/c/d/tasks + * /x/y/z/d/tasks + * /x/y/z/tasks + */ + cgp = cgpath; + while (cgp[0]) { + ret = snprintf(path, MAXPATHLEN, "%s%s/tasks", d->mntpt, cgp); + if (ret < 0 || ret >= MAXPATHLEN) + return NULL; + if (!is_in_cgroup(getpid(), path)) { + // does not exist, try the next one + cgp = index(cgp+1, '/'); + if (!cgp) + break; + continue; + } + break; + } + if (!cgp || !*cgp) { + // try just the path + ret = snprintf(path, MAXPATHLEN, "%s/tasks", d->mntpt); + if (ret < 0 || ret >= MAXPATHLEN) + return NULL; + if (!is_in_cgroup(getpid(), path)) + return NULL; + } + // found it + // path has '/tasks' at end, drop that + if (!(cgp = strrchr(path, '/'))) { + ERROR("Got nonsensical path name %s\n", path); + return NULL; + } + *cgp = '\0'; + + if (strlen(path) + strlen(lxc_name) + 20 > MAXPATHLEN) { + ERROR("Error: cgroup path too long"); + return NULL; + } + tail[0] = '\0'; + while (1) { + struct stat sb; + int freebytes = MAXPATHLEN - (cgp - path); + + if (i) { + ret = snprintf(tail, 20, "-%d", i); + if (ret < 0 || ret >= 20) + return NULL; + } + ret = snprintf(cgp, freebytes, "/%s%s", lxc_name, tail); + if (ret < 0 || ret >= freebytes) + return NULL; + if (stat(path, &sb) == -1) + break; + i++; + } + + l = strlen(cgpath); + ret = snprintf(cgpath + l, MAXPATHLEN - l, "/%s%s", lxc_name, tail); + if (ret < 0 || ret >= (MAXPATHLEN - l)) { + ERROR("Out of memory"); + return NULL; + } + if ((d->realcgroup = strdup(cgpath)) == NULL) { + ERROR("Out of memory"); + return NULL; + } + l = strlen(d->realcgroup); + if (l > 0 && d->realcgroup[l-1] == '\n') + d->realcgroup[l-1] = '\0'; + return strdup(path); +} + +/* + * For a new container, find a cgroup path which is unique in all cgroup mounts. + * I.e. if r1 is already running, then /lxc/r1-1 may be used. + * + * @lxcgroup: the cgroup 'group' the contaienr should run in. By default, this + * is just 'lxc'. Admins may wish to group some containers into other groups, + * i.e. 'build', to take advantage of cgroup hierarchy to simplify group + * administration. Also, unprivileged users who are placed into a cgroup by + * libcgroup_pam will be using that cgroup rather than the system-wide 'lxc' + * group. + * @name: the name of the container + * + * The chosen cgpath is returned as a strdup'd string. The caller will have to + * free that eventually, however the lxc monitor will keep that string so as to + * return it in response to a LXC_COMMAND_CGROUP query. + * + * Note the path is relative to cgroup mounts. I.e. if the freezer subsystem + * is at /sys/fs/cgroup/freezer, and this fn returns '/lxc/r1', then the + * freezer cgroup's full path will be /sys/fs/cgroup/freezer/lxc/r1/. + * + * Races won't be determintal, you'll just end up with leftover unused cgroups + */ +struct cgroup_desc *lxc_cgroup_path_create(const char *name) +{ + struct cgroup_desc *retdesc = NULL, *newdesc = NULL; + FILE *file = NULL; + struct mntent mntent_r; + char buf[LARGE_MAXPATHLEN] = {0}; + char *all_subsystems = get_all_subsystems(); + char *cgroup_uselist = get_cgroup_uselist(); + + if (cgroup_uselist == (char *)-ENOMEM) { + if (all_subsystems) + free(all_subsystems); + return NULL; + } + if (!all_subsystems) { + ERROR("failed to get a list of all cgroup subsystems"); + if (cgroup_uselist) + free(cgroup_uselist); + return NULL; + } file = setmntent(MTAB, "r"); if (!file) { SYSERROR("failed to open %s", MTAB); - return -1; + free(all_subsystems); + if (cgroup_uselist) + free(cgroup_uselist); + return NULL; } - while ((mntent = getmntent(file))) { + while ((getmntent_r(file, &mntent_r, buf, sizeof(buf)))) { - DEBUG("checking '%s' (%s)", mntent->mnt_dir, mntent->mnt_type); + if (strcmp(mntent_r.mnt_type, "cgroup")) + continue; - if (!strcmp(mntent->mnt_type, "cgroup")) { + if (cgroup_uselist && !is_in_uselist(cgroup_uselist, &mntent_r)) + continue; - INFO("[%d] found cgroup mounted at '%s',opts='%s'", - ++found, mntent->mnt_dir, mntent->mnt_opts); + /* make sure we haven't checked this subsystem already */ + if (is_in_desclist(retdesc, mntent_r.mnt_opts, all_subsystems)) + continue; - err = lxc_one_cgroup_create(name, mntent, pid); - if (err) - goto out; + if (!(newdesc = malloc(sizeof(struct cgroup_desc)))) { + ERROR("Out of memory reading cgroups"); + goto fail; + } + newdesc->subsystems = record_visited(mntent_r.mnt_opts, all_subsystems); + if (newdesc->subsystems == (char *)-ENOMEM) { + ERROR("Out of memory recording cgroup subsystems"); + free(newdesc); + newdesc = NULL; + goto fail; + } + if (!newdesc->subsystems) { + free(newdesc); + newdesc = NULL; + continue; + } + newdesc->mntpt = strdup(mntent_r.mnt_dir); + newdesc->realcgroup = NULL; + newdesc->curcgroup = find_free_cgroup(newdesc, name); + if (!newdesc->mntpt || !newdesc->curcgroup) { + ERROR("Out of memory reading cgroups"); + goto fail; } - }; - if (!found) - ERROR("No cgroup mounted on the system"); + set_clone_children(&mntent_r); + + if (mkdir(newdesc->curcgroup, 0755)) { + ERROR("Error creating cgroup %s", newdesc->curcgroup); + goto fail; + } + newdesc->next = retdesc; + retdesc = newdesc; + } -out: endmntent(file); - return err; + free(all_subsystems); + if (cgroup_uselist) + free(cgroup_uselist); + return retdesc; + +fail: + endmntent(file); + free(all_subsystems); + if (cgroup_uselist) + free(cgroup_uselist); + if (newdesc) { + if (newdesc->mntpt) + free(newdesc->mntpt); + if (newdesc->subsystems) + free(newdesc->subsystems); + if (newdesc->curcgroup) + free(newdesc->curcgroup); + if (newdesc->realcgroup) + free(newdesc->realcgroup); + free(newdesc); + } + while (retdesc) { + struct cgroup_desc *t = retdesc; + retdesc = retdesc->next; + if (t->mntpt) + free(t->mntpt); + if (t->subsystems) + free(t->subsystems); + if (t->curcgroup) + free(t->curcgroup); + if (t->realcgroup) + free(t->realcgroup); + free(t); + + } + return NULL; +} + +static bool lxc_cgroup_enter_one(const char *dir, int pid) +{ + char path[MAXPATHLEN]; + int ret; + FILE *fout; + + ret = snprintf(path, MAXPATHLEN, "%s/tasks", dir); + if (ret < 0 || ret >= MAXPATHLEN) { + ERROR("Error entering cgroup"); + return false; + } + fout = fopen(path, "w"); + if (!fout) { + SYSERROR("Error entering cgroup"); + return false; + } + if (fprintf(fout, "%d\n", (int)pid) < 0) { + ERROR("Error writing pid to %s to enter cgroup", path); + fclose(fout); + return false; + } + if (fclose(fout) < 0) { + SYSERROR("Error writing pid to %s to enter cgroup", path); + return false; + } + + return true; } -int recursive_rmdir(char *dirname) +int lxc_cgroup_enter(struct cgroup_desc *cgroups, pid_t pid) +{ + while (cgroups) { + if (!cgroups->subsystems) + goto next; + + if (!lxc_cgroup_enter_one(cgroups->curcgroup, pid)) + return -1; +next: + cgroups = cgroups->next; + } + return 0; +} + +static int cgroup_rmdir(char *dirname) { struct dirent dirent, *direntp; DIR *dir; @@ -435,20 +1124,25 @@ while (!readdir_r(dir, &dirent, &direntp)) { struct stat mystat; + int rc; if (!direntp) break; if (!strcmp(direntp->d_name, ".") || - !strcmp(direntp->d_name, "..")) + !strcmp(direntp->d_name, "..")) continue; - snprintf(pathname, MAXPATHLEN, "%s/%s", dirname, direntp->d_name); + rc = snprintf(pathname, MAXPATHLEN, "%s/%s", dirname, direntp->d_name); + if (rc < 0 || rc >= MAXPATHLEN) { + ERROR("pathname too long"); + continue; + } ret = stat(pathname, &mystat); if (ret) continue; if (S_ISDIR(mystat.st_mode)) - recursive_rmdir(pathname); + cgroup_rmdir(pathname); } ret = rmdir(dirname); @@ -456,170 +1150,177 @@ if (closedir(dir)) ERROR("failed to close directory"); return ret; - - -} - -int lxc_one_cgroup_destroy(struct mntent *mntent, const char *name) -{ - char cgname[MAXPATHLEN], initcgroup[MAXPATHLEN]; - char *cgmnt = mntent->mnt_dir; - - snprintf(cgname, MAXPATHLEN, "%s%s/lxc/%s", cgmnt, - get_init_cgroup(NULL, mntent, initcgroup), name); - DEBUG("destroying %s\n", cgname); - if (recursive_rmdir(cgname)) { - SYSERROR("failed to remove cgroup '%s'", cgname); - return -1; - } - - DEBUG("'%s' unlinked", cgname); - - return 0; } /* * for each mounted cgroup, destroy the cgroup for the container */ -int lxc_cgroup_destroy(const char *name) -{ - struct mntent *mntent; - FILE *file = NULL; - int ret, err = -1; - - file = setmntent(MTAB, "r"); - if (!file) { - SYSERROR("failed to open %s", MTAB); - return -1; - } - - while ((mntent = getmntent(file))) { - if (!strcmp(mntent->mnt_type, "cgroup")) { - ret = lxc_one_cgroup_destroy(mntent, name); - if (ret) { - fclose(file); - return ret; - } - err = 0; - } - } - - fclose(file); - - return err; -} -/* - * lxc_cgroup_path_get: put into *path the pathname for - * %subsystem and cgroup %name. If %subsystem is NULL, then - * the first mounted cgroup will be used (for nr_tasks) - */ -int lxc_cgroup_path_get(char **path, const char *subsystem, const char *name) +void lxc_cgroup_destroy_desc(struct cgroup_desc *cgroups) { - static char buf[MAXPATHLEN]; - static char retbuf[MAXPATHLEN]; - - /* what lxc_cgroup_set calls subsystem is actually the filename, i.e. - 'devices.allow'. So for our purposee we trim it */ - if (subsystem) { - snprintf(retbuf, MAXPATHLEN, "%s", subsystem); - char *s = index(retbuf, '.'); - if (s) - *s = '\0'; - DEBUG("%s: called for subsys %s name %s\n", __func__, retbuf, name); + while (cgroups) { + struct cgroup_desc *next = cgroups->next; + if (cgroup_rmdir(cgroups->curcgroup) < 0) + SYSERROR("Error removing cgroup directory %s", cgroups->curcgroup); + free(cgroups->mntpt); + free(cgroups->subsystems); + free(cgroups->curcgroup); + free(cgroups->realcgroup); + free(cgroups); + cgroups = next; } - if (get_cgroup_mount(subsystem ? retbuf : NULL, buf)) { - ERROR("cgroup is not mounted"); - return -1; - } - - snprintf(retbuf, MAXPATHLEN, "%s/%s", buf, name); - - DEBUG("%s: returning %s for subsystem %s", __func__, retbuf, subsystem); - - *path = retbuf; - return 0; } -int lxc_cgroup_set(const char *name, const char *filename, const char *value) +int lxc_cgroup_attach(pid_t pid, const char *name, const char *lxcpath) { - int fd, ret; + FILE *f; + char *line = NULL, ret = 0; + size_t len = 0; + int first = 1; char *dirpath; - char path[MAXPATHLEN]; - ret = lxc_cgroup_path_get(&dirpath, filename, name); - if (ret) + /* read the list of subsystems from the kernel */ + f = fopen("/proc/cgroups", "r"); + if (!f) return -1; - snprintf(path, MAXPATHLEN, "%s/%s", dirpath, filename); + while (getline(&line, &len, f) != -1) { + char *c; - fd = open(path, O_WRONLY); - if (fd < 0) { - ERROR("open %s : %s", path, strerror(errno)); - return -1; - } + /* skip the first line */ + if (first) { + first=0; + continue; + } - ret = write(fd, value, strlen(value)); - if (ret < 0) { - ERROR("write %s : %s", path, strerror(errno)); - goto out; + c = strchr(line, '\t'); + if (!c) + continue; + *c = '\0'; + dirpath = lxc_cgroup_path_get(line, name, lxcpath); + if (!dirpath) + continue; + + INFO("joining pid %d to cgroup %s", pid, dirpath); + if (!lxc_cgroup_enter_one(dirpath, pid)) { + ERROR("Failed joining %d to %s\n", pid, dirpath); + ret = -1; + continue; + } } - ret = 0; -out: - close(fd); + if (line) + free(line); + fclose(f); return ret; } -int lxc_cgroup_get(const char *name, const char *filename, - char *value, size_t len) +bool is_in_subcgroup(int pid, const char *subsystem, struct cgroup_desc *d) { - int fd, ret = -1; - char *dirpath; - char path[MAXPATHLEN]; + char filepath[MAXPATHLEN], *line = NULL, v1[MAXPATHLEN], v2[MAXPATHLEN]; + FILE *f; + int ret, junk; + size_t sz = 0, l1, l2; + char *end = index(subsystem, '.'); + int len = end ? (end - subsystem) : strlen(subsystem); + const char *cgpath = NULL; + + while (d) { + if (in_subsys_list("devices", d->subsystems)) { + cgpath = d->realcgroup; + l1 = strlen(cgpath); + break; + } + d = d->next; + } + if (!d) + return false; - ret = lxc_cgroup_path_get(&dirpath, filename, name); - if (ret) - return -1; + ret = snprintf(filepath, MAXPATHLEN, "/proc/%d/cgroup", pid); + if (ret < 0 || ret >= MAXPATHLEN) + return false; + if ((f = fopen(filepath, "r")) == NULL) + return false; + while (getline(&line, &sz, f) != -1) { + // nr:subsystem:path + v2[0] = v2[1] = '\0'; + ret = sscanf(line, "%d:%[^:]:%s", &junk, v1, v2); + if (ret != 3) { + fclose(f); + free(line); + return false; + } + len = end ? end - subsystem : strlen(subsystem); + if (strncmp(v1, subsystem, len) != 0) + continue; + // v2 will start with '/', skip it by using v2+1 + // we must be in SUBcgroup, so make sure l2 > l1 + l2 = strlen(v2+1); + if (l2 > l1 && strncmp(v2+1, cgpath, l1) == 0) { + fclose(f); + free(line); + return true; + } + } + fclose(f); + if (line) + free(line); + return false; +} - snprintf(path, MAXPATHLEN, "%s/%s", dirpath, filename); +char *cgroup_get_subsys_path(struct lxc_handler *handler, const char *subsys) +{ + struct cgroup_desc *d; - fd = open(path, O_RDONLY); - if (fd < 0) { - ERROR("open %s : %s", path, strerror(errno)); - return -1; + for (d = handler->cgroup; d; d = d->next) { + if (in_subsys_list(subsys, d->subsystems)) + return d->realcgroup; } - ret = read(fd, value, len); - if (ret < 0) - ERROR("read %s : %s", path, strerror(errno)); - - close(fd); - return ret; + return NULL; } -int lxc_cgroup_nrtasks(const char *name) +static int _setup_cgroup(struct lxc_handler *h, struct lxc_list *cgroups, + int devices) { - char *dpath; - char path[MAXPATHLEN]; - int pid, ret, count = 0; - FILE *file; - - ret = lxc_cgroup_path_get(&dpath, NULL, name); - if (ret) - return -1; - - snprintf(path, MAXPATHLEN, "%s/tasks", dpath); + struct lxc_list *iterator; + struct lxc_cgroup *cg; + int ret = -1; + + if (lxc_list_empty(cgroups)) + return 0; + + lxc_list_for_each(iterator, cgroups) { + cg = iterator->elem; + + if (devices == !strncmp("devices", cg->subsystem, 7)) { + if (strcmp(cg->subsystem, "devices.deny") == 0 && + cgroup_devices_has_deny(h, cg->value)) + continue; + if (strcmp(cg->subsystem, "devices.allow") == 0 && + cgroup_devices_has_allow(h, cg->value)) + continue; + if (lxc_cgroup_set_value(h, cg->subsystem, cg->value)) { + ERROR("Error setting %s to %s for %s\n", + cg->subsystem, cg->value, h->name); + goto out; + } + } - file = fopen(path, "r"); - if (!file) { - SYSERROR("fopen '%s' failed", path); - return -1; + DEBUG("cgroup '%s' set to '%s'", cg->subsystem, cg->value); } - while (fscanf(file, "%d", &pid) != EOF) - count++; + ret = 0; + INFO("cgroup has been setup"); +out: + return ret; +} - fclose(file); +int setup_cgroup_devices(struct lxc_handler *h, struct lxc_list *cgroups) +{ + return _setup_cgroup(h, cgroups, 1); +} - return count; +int setup_cgroup(struct lxc_handler *h, struct lxc_list *cgroups) +{ + return _setup_cgroup(h, cgroups, 0); } diff -Nru lxc-0.8.0~rc1/src/lxc/cgroup.h lxc-1.0.0~alpha1/src/lxc/cgroup.h --- lxc-0.8.0~rc1/src/lxc/cgroup.h 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/cgroup.h 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,18 +18,40 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _cgroup_h #define _cgroup_h +#include -#define MAXPRIOLEN 24 +/* + * cgroup_desc: describe a container's cgroup membership + */ +struct cgroup_desc { + char *mntpt; /* where this is mounted */ + char *subsystems; /* comma-separated list of subsystems, or NULL */ + char *curcgroup; /* task's current cgroup, full pathanme */ + char *realcgroup; /* the cgroup as known in /proc/self/cgroup */ + struct cgroup_desc *next; +}; struct lxc_handler; -extern int lxc_cgroup_create(const char *name, pid_t pid); -extern int lxc_cgroup_destroy(const char *name); -extern int lxc_cgroup_path_get(char **path, const char *subsystem, const char *name); -extern int lxc_cgroup_nrtasks(const char *name); -extern int lxc_cgroup_attach(const char *path, pid_t pid); -extern int lxc_ns_is_mounted(void); +extern void lxc_cgroup_destroy_desc(struct cgroup_desc *cgroups); +extern char *lxc_cgroup_path_get(const char *subsystem, const char *name, + const char *lxcpath); +extern int lxc_cgroup_nrtasks(struct lxc_handler *handler); +struct cgroup_desc *lxc_cgroup_path_create(const char *name); +extern int lxc_cgroup_enter(struct cgroup_desc *cgroups, pid_t pid); +extern int lxc_cgroup_attach(pid_t pid, const char *name, const char *lxcpath); +extern char *cgroup_path_get(const char *subsystem, const char *cgpath); +extern bool get_subsys_mount(char *dest, const char *subsystem); +extern bool is_in_subcgroup(int pid, const char *subsystem, struct cgroup_desc *d); +/* + * Called by commands.c by a container's monitor to find out the + * container's cgroup path in a specific subsystem + */ +extern char *cgroup_get_subsys_path(struct lxc_handler *handler, const char *subsys); +struct lxc_list; +extern int setup_cgroup(struct lxc_handler *h, struct lxc_list *cgroups); +extern int setup_cgroup_devices(struct lxc_handler *h, struct lxc_list *cgroups); #endif diff -Nru lxc-0.8.0~rc1/src/lxc/checkpoint.c lxc-1.0.0~alpha1/src/lxc/checkpoint.c --- lxc-0.8.0~rc1/src/lxc/checkpoint.c 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/checkpoint.c 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,7 +18,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include diff -Nru lxc-0.8.0~rc1/src/lxc/commands.c lxc-1.0.0~alpha1/src/lxc/commands.c --- lxc-0.8.0~rc1/src/lxc/commands.c 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/commands.c 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2009 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,7 +18,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include @@ -30,167 +30,707 @@ #include #include #include +#include +#include #include +#include #include #include /* for struct lxc_handler */ +#include #include "commands.h" +#include "console.h" +#include "confile.h" #include "mainloop.h" #include "af_unix.h" #include "config.h" /* - * This file provides the different functions to have the client - * and the server to communicate + * This file provides the different functions for clients to + * query/command the server. The client is typically some lxc + * tool and the server is typically the container (ie. lxc-start). * - * Each command is transactional, the client send a request to - * the server and the server answer the request with a message + * Each command is transactional, the clients send a request to + * the server and the server answers the request with a message * giving the request's status (zero or a negative errno value). + * Both the request and response may contain addtional data. * * Each command is wrapped in a ancillary message in order to pass * a credential making possible to the server to check if the client * is allowed to ask for this command or not. * + * IMPORTANTLY: Note that semantics for current commands are fixed. If you + * wish to make any changes to how, say, LXC_CMD_GET_CONFIG_ITEM works by + * adding information to the end of cmd.data, then you must introduce a new + * LXC_CMD_GET_CONFIG_ITEM_V2 define with a new number. You may wish to + * also mark LXC_CMD_GET_CONFIG_ITEM deprecated in commands.h. + * + * This is necessary in order to avoid having a newly compiled lxc command + * communicating with a running (old) monitor from crashing the running + * container. */ lxc_log_define(lxc_commands, lxc); -#define abstractname LXCPATH "/%s/command" - -static int receive_answer(int sock, struct lxc_answer *answer) +static int fill_sock_name(char *path, int len, const char *name, + const char *inpath) { + const char *lxcpath = NULL; int ret; - ret = lxc_af_unix_recv_fd(sock, &answer->fd, answer, sizeof(*answer)); - if (ret < 0) - ERROR("failed to receive answer for the command"); + if (!inpath) { + lxcpath = default_lxc_path(); + if (!lxcpath) { + ERROR("Out of memory getting lxcpath"); + return -1; + } + } + ret = snprintf(path, len, "%s/%s/command", lxcpath ? lxcpath : inpath, name); + + if (ret < 0 || ret >= len) { + ERROR("Name too long"); + return -1; + } + return 0; +} + +static const char *lxc_cmd_str(lxc_cmd_t cmd) +{ + static const char *cmdname[LXC_CMD_MAX] = { + [LXC_CMD_CONSOLE] = "console", + [LXC_CMD_STOP] = "stop", + [LXC_CMD_GET_STATE] = "get_state", + [LXC_CMD_GET_INIT_PID] = "get_init_pid", + [LXC_CMD_GET_CLONE_FLAGS] = "get_clone_flags", + [LXC_CMD_GET_CGROUP] = "get_cgroup", + [LXC_CMD_GET_CONFIG_ITEM] = "get_config_item", + }; + + if (cmd < 0 || cmd >= LXC_CMD_MAX) + return "Unknown cmd"; + return cmdname[cmd]; +} + +/* + * lxc_cmd_rsp_recv: Receive a response to a command + * + * @sock : the socket connected to the container + * @cmd : command to put response in + * + * Returns the size of the response message or < 0 on failure + * + * Note that if the command response datalen > 0, then data is + * a malloc()ed buffer and should be free()ed by the caller. If + * the response data is <= a void * worth of data, it will be + * stored directly in data and datalen will be 0. + * + * As a special case, the response for LXC_CMD_CONSOLE is created + * here as it contains an fd for the master pty passed through the + * unix socket. + */ +static int lxc_cmd_rsp_recv(int sock, struct lxc_cmd_rr *cmd) +{ + int ret,rspfd; + struct lxc_cmd_rsp *rsp = &cmd->rsp; + + ret = lxc_af_unix_recv_fd(sock, &rspfd, rsp, sizeof(*rsp)); + if (ret < 0) { + ERROR("command %s failed to receive response", + lxc_cmd_str(cmd->req.cmd)); + return -1; + } + + if (cmd->req.cmd == LXC_CMD_CONSOLE) { + struct lxc_cmd_console_rsp_data *rspdata; + + /* recv() returns 0 bytes when a tty cannot be allocated, + * rsp->ret is < 0 when the peer permission check failed + */ + if (ret == 0 || rsp->ret < 0) + return 0; + + rspdata = malloc(sizeof(*rspdata)); + if (!rspdata) { + ERROR("command %s couldn't allocate response buffer", + lxc_cmd_str(cmd->req.cmd)); + return -1; + } + rspdata->masterfd = rspfd; + rspdata->ttynum = PTR_TO_INT(rsp->data); + rsp->data = rspdata; + } + + if (rsp->datalen == 0) + return ret; + if (rsp->datalen > LXC_CMD_DATA_MAX) { + ERROR("command %s response data %d too long", + lxc_cmd_str(cmd->req.cmd), rsp->datalen); + errno = EFBIG; + return -1; + } + + rsp->data = malloc(rsp->datalen); + if (!rsp->data) { + ERROR("command %s unable to allocate response buffer", + lxc_cmd_str(cmd->req.cmd)); + return -1; + } + ret = recv(sock, rsp->data, rsp->datalen, 0); + if (ret != rsp->datalen) { + ERROR("command %s failed to receive response data", + lxc_cmd_str(cmd->req.cmd)); + if (ret >= 0) + ret = -1; + } return ret; } -static int __lxc_command(const char *name, struct lxc_command *command, - int *stopped, int stay_connected) +/* + * lxc_cmd_rsp_send: Send a command response + * + * @fd : file descriptor of socket to send response on + * @rsp : response to send + * + * Returns 0 on success, < 0 on failure + */ +static int lxc_cmd_rsp_send(int fd, struct lxc_cmd_rsp *rsp) +{ + int ret; + + ret = send(fd, rsp, sizeof(*rsp), 0); + if (ret != sizeof(*rsp)) { + ERROR("failed to send command response %d %s", ret, + strerror(errno)); + return -1; + } + + if (rsp->datalen > 0) { + ret = send(fd, rsp->data, rsp->datalen, 0); + if (ret != rsp->datalen) { + WARN("failed to send command response data %d %s", ret, + strerror(errno)); + return -1; + } + } + return 0; +} + +/* + * lxc_cmd: Connect to the specified running container, send it a command + * request and collect the response + * + * @name : name of container to connect to + * @cmd : command with initialized reqest to send + * @stopped : output indicator if the container was not running + * @lxcpath : the lxcpath in which the container is running + * + * Returns the size of the response message on success, < 0 on failure + * + * Note that there is a special case for LXC_CMD_CONSOLE. For this command + * the fd cannot be closed because it is used as a placeholder to indicate + * that a particular tty slot is in use. The fd is also used as a signal to + * the container that when the caller dies or closes the fd, the container + * will notice the fd on its side of the socket in its mainloop select and + * then free the slot with lxc_cmd_fd_cleanup(). The socket fd will be + * returned in the cmd response structure. + */ +static int lxc_cmd(const char *name, struct lxc_cmd_rr *cmd, int *stopped, + const char *lxcpath) { int sock, ret = -1; char path[sizeof(((struct sockaddr_un *)0)->sun_path)] = { 0 }; char *offset = &path[1]; + int len; + int stay_connected = cmd->req.cmd == LXC_CMD_CONSOLE; - sprintf(offset, abstractname, name); - - sock = lxc_af_unix_connect(path); - if (sock < 0 && errno == ECONNREFUSED) { - *stopped = 1; + len = sizeof(path)-1; + if (fill_sock_name(offset, len, name, lxcpath)) return -1; - } + sock = lxc_af_unix_connect(path); if (sock < 0) { - SYSERROR("failed to connect to '@%s'", offset); + if (errno == ECONNREFUSED) + *stopped = 1; + else + SYSERROR("command %s failed to connect to '@%s'", + lxc_cmd_str(cmd->req.cmd), offset); return -1; } - ret = lxc_af_unix_send_credential(sock, &command->request, - sizeof(command->request)); - if (ret < 0) { - SYSERROR("failed to send request to '@%s'", offset); + ret = lxc_af_unix_send_credential(sock, &cmd->req, sizeof(cmd->req)); + if (ret != sizeof(cmd->req)) { + SYSERROR("command %s failed to send req to '@%s' %d", + lxc_cmd_str(cmd->req.cmd), offset, ret); + if (ret >=0) + ret = -1; goto out; } - if (ret != sizeof(command->request)) { - SYSERROR("message partially sent to '@%s'", offset); - goto out; + if (cmd->req.datalen > 0) { + ret = send(sock, cmd->req.data, cmd->req.datalen, 0); + if (ret != cmd->req.datalen) { + SYSERROR("command %s failed to send request data to '@%s' %d", + lxc_cmd_str(cmd->req.cmd), offset, ret); + if (ret >=0) + ret = -1; + goto out; + } } - ret = receive_answer(sock, &command->answer); + ret = lxc_cmd_rsp_recv(sock, cmd); out: - if (!stay_connected || ret < 0) + if (!stay_connected || ret <= 0) close(sock); + if (stay_connected && ret > 0) + cmd->rsp.ret = sock; return ret; } -extern int lxc_command(const char *name, - struct lxc_command *command, int *stopped) +/* Implentations of the commands and their callbacks */ + +/* + * lxc_cmd_get_init_pid: Get pid of the container's init process + * + * @name : name of container to connect to + * @lxcpath : the lxcpath in which the container is running + * + * Returns the pid on success, < 0 on failure + */ +pid_t lxc_cmd_get_init_pid(const char *name, const char *lxcpath) +{ + int ret, stopped = 0; + struct lxc_cmd_rr cmd = { + .req = { .cmd = LXC_CMD_GET_INIT_PID }, + }; + + ret = lxc_cmd(name, &cmd, &stopped, lxcpath); + if (ret < 0) + return ret; + + return PTR_TO_INT(cmd.rsp.data); +} + +static int lxc_cmd_get_init_pid_callback(int fd, struct lxc_cmd_req *req, + struct lxc_handler *handler) +{ + struct lxc_cmd_rsp rsp = { .data = INT_TO_PTR(handler->pid) }; + + return lxc_cmd_rsp_send(fd, &rsp); +} + +/* + * lxc_cmd_get_clone_flags: Get clone flags container was spawned with + * + * @name : name of container to connect to + * @lxcpath : the lxcpath in which the container is running + * + * Returns the clone flags on success, < 0 on failure + */ +int lxc_cmd_get_clone_flags(const char *name, const char *lxcpath) +{ + int ret, stopped = 0; + struct lxc_cmd_rr cmd = { + .req = { .cmd = LXC_CMD_GET_CLONE_FLAGS }, + }; + + ret = lxc_cmd(name, &cmd, &stopped, lxcpath); + if (ret < 0) + return ret; + + return PTR_TO_INT(cmd.rsp.data); +} + +static int lxc_cmd_get_clone_flags_callback(int fd, struct lxc_cmd_req *req, + struct lxc_handler *handler) { - return __lxc_command(name, command, stopped, 0); + struct lxc_cmd_rsp rsp = { .data = INT_TO_PTR(handler->clone_flags) }; + + return lxc_cmd_rsp_send(fd, &rsp); } -extern int lxc_command_connected(const char *name, - struct lxc_command *command, int *stopped) +extern char *cgroup_get_subsys_path(struct lxc_handler *handler, const char *subsys); +/* + * lxc_cmd_get_cgroup_path: Calculate a container's cgroup path for a + * particular subsystem. This is the cgroup path relative to the root + * of the cgroup filesystem. + * + * @name : name of container to connect to + * @lxcpath : the lxcpath in which the container is running + * @subsystem : the subsystem being asked about + * + * Returns the path on success, NULL on failure. The caller must free() the + * returned path. + */ +char *lxc_cmd_get_cgroup_path(const char *name, const char *lxcpath, + const char *subsystem) { - return __lxc_command(name, command, stopped, 1); + int ret, stopped = 0; + struct lxc_cmd_rr cmd = { + .req = { + .cmd = LXC_CMD_GET_CGROUP, + .datalen = strlen(subsystem)+1, + .data = subsystem, + }, + }; + + ret = lxc_cmd(name, &cmd, &stopped, lxcpath); + if (ret < 0) + return NULL; + + if (!ret) { + WARN("'%s' has stopped before sending its state", name); + return NULL; + } + + if (cmd.rsp.ret < 0 || cmd.rsp.datalen < 0) { + ERROR("command %s failed for '%s': %s", + lxc_cmd_str(cmd.req.cmd), name, + strerror(-cmd.rsp.ret)); + return NULL; + } + + return cmd.rsp.data; } +static int lxc_cmd_get_cgroup_callback(int fd, struct lxc_cmd_req *req, + struct lxc_handler *handler) +{ + struct lxc_cmd_rsp rsp; + char *path; + + if (req->datalen < 1) + return -1; + + path = cgroup_get_subsys_path(handler, req->data); + if (!path) + return -1; + rsp.datalen = strlen(path) + 1, + rsp.data = path; + rsp.ret = 0; + + return lxc_cmd_rsp_send(fd, &rsp); +} -pid_t get_init_pid(const char *name) +/* + * lxc_cmd_get_config_item: Get config item the running container + * + * @name : name of container to connect to + * @item : the configuration item to retrieve (ex: lxc.network.0.veth.pair) + * @lxcpath : the lxcpath in which the container is running + * + * Returns the item on success, NULL on failure. The caller must free() the + * returned item. + */ +char *lxc_cmd_get_config_item(const char *name, const char *item, + const char *lxcpath) { - struct lxc_command command = { - .request = { .type = LXC_COMMAND_PID }, + int ret, stopped = 0; + struct lxc_cmd_rr cmd = { + .req = { .cmd = LXC_CMD_GET_CONFIG_ITEM, + .data = item, + .datalen = strlen(item)+1, + }, }; + ret = lxc_cmd(name, &cmd, &stopped, lxcpath); + if (ret < 0) + return NULL; + + if (cmd.rsp.ret == 0) + return cmd.rsp.data; + return NULL; +} + +static int lxc_cmd_get_config_item_callback(int fd, struct lxc_cmd_req *req, + struct lxc_handler *handler) +{ + int cilen; + struct lxc_cmd_rsp rsp; + char *cidata; + + memset(&rsp, 0, sizeof(rsp)); + cilen = lxc_get_config_item(handler->conf, req->data, NULL, 0); + if (cilen <= 0) + goto err1; + + cidata = alloca(cilen + 1); + if (lxc_get_config_item(handler->conf, req->data, cidata, cilen + 1) != cilen) + goto err1; + cidata[cilen] = '\0'; + rsp.data = cidata; + rsp.datalen = cilen + 1; + rsp.ret = 0; + goto out; + +err1: + rsp.ret = -1; +out: + return lxc_cmd_rsp_send(fd, &rsp); +} + +/* + * lxc_cmd_get_state: Get current state of the container + * + * @name : name of container to connect to + * @lxcpath : the lxcpath in which the container is running + * + * Returns the state on success, < 0 on failure + */ +lxc_state_t lxc_cmd_get_state(const char *name, const char *lxcpath) +{ int ret, stopped = 0; + struct lxc_cmd_rr cmd = { + .req = { .cmd = LXC_CMD_GET_STATE } + }; - ret = lxc_command(name, &command, &stopped); + ret = lxc_cmd(name, &cmd, &stopped, lxcpath); if (ret < 0 && stopped) + return STOPPED; + + if (ret < 0) + return -1; + + if (!ret) { + WARN("'%s' has stopped before sending its state", name); return -1; + } + + DEBUG("'%s' is in '%s' state", name, + lxc_state2str(PTR_TO_INT(cmd.rsp.data))); + return PTR_TO_INT(cmd.rsp.data); +} + +static int lxc_cmd_get_state_callback(int fd, struct lxc_cmd_req *req, + struct lxc_handler *handler) +{ + struct lxc_cmd_rsp rsp = { .data = INT_TO_PTR(handler->state) }; + + return lxc_cmd_rsp_send(fd, &rsp); +} +/* + * lxc_cmd_stop: Stop the container previously started with lxc_start. All + * the processes running inside this container will be killed. + * + * @name : name of container to connect to + * @lxcpath : the lxcpath in which the container is running + * + * Returns 0 on success, < 0 on failure + */ +int lxc_cmd_stop(const char *name, const char *lxcpath) +{ + int ret, stopped = 0; + struct lxc_cmd_rr cmd = { + .req = { .cmd = LXC_CMD_STOP }, + }; + + ret = lxc_cmd(name, &cmd, &stopped, lxcpath); if (ret < 0) { - ERROR("failed to send command"); + if (stopped) { + INFO("'%s' is already stopped", name); + return 0; + } return -1; } - if (command.answer.ret) { - ERROR("failed to retrieve the init pid: %s", - strerror(-command.answer.ret)); + /* we do not expect any answer, because we wait for the connection to be + * closed + */ + if (ret > 0) { + ERROR("failed to stop '%s': %s", name, strerror(-cmd.rsp.ret)); return -1; } - return command.answer.pid; + INFO("'%s' has stopped", name); + return 0; +} + +static int lxc_cmd_stop_callback(int fd, struct lxc_cmd_req *req, + struct lxc_handler *handler) +{ + struct lxc_cmd_rsp rsp; + int ret; + int stopsignal = SIGKILL; + + if (handler->conf->stopsignal) + stopsignal = handler->conf->stopsignal; + memset(&rsp, 0, sizeof(rsp)); + rsp.ret = kill(handler->pid, stopsignal); + if (!rsp.ret) { + char *path = cgroup_get_subsys_path(handler, "freezer"); + if (!path) { + ERROR("container %s:%s is not in a freezer cgroup", + handler->lxcpath, handler->name); + return 0; + } + ret = lxc_unfreeze_bypath(path); + if (!ret) + return 0; + + ERROR("failed to unfreeze container"); + rsp.ret = ret; + } + + return lxc_cmd_rsp_send(fd, &rsp); +} + +/* + * lxc_cmd_console_winch: To process as if a SIGWINCH were received + * + * @name : name of container to connect to + * @lxcpath : the lxcpath in which the container is running + * + * Returns 0 on success, < 0 on failure + */ +int lxc_cmd_console_winch(const char *name, const char *lxcpath) +{ + int ret, stopped = 0; + struct lxc_cmd_rr cmd = { + .req = { .cmd = LXC_CMD_CONSOLE_WINCH }, + }; + + ret = lxc_cmd(name, &cmd, &stopped, lxcpath); + if (ret < 0) + return ret; + + return 0; +} + +static int lxc_cmd_console_winch_callback(int fd, struct lxc_cmd_req *req, + struct lxc_handler *handler) +{ + struct lxc_cmd_rsp rsp = { .data = 0 }; + + lxc_console_sigwinch(SIGWINCH); + return lxc_cmd_rsp_send(fd, &rsp); +} + +/* + * lxc_cmd_console: Open an fd to a tty in the container + * + * @name : name of container to connect to + * @ttynum : in: the tty to open or -1 for next available + * : out: the tty allocated + * @fd : out: file descriptor for master side of pty + * @lxcpath : the lxcpath in which the container is running + * + * Returns fd holding tty allocated on success, < 0 on failure + */ +int lxc_cmd_console(const char *name, int *ttynum, int *fd, const char *lxcpath) +{ + int ret, stopped = 0; + struct lxc_cmd_console_rsp_data *rspdata; + struct lxc_cmd_rr cmd = { + .req = { .cmd = LXC_CMD_CONSOLE, .data = INT_TO_PTR(*ttynum) }, + }; + + ret = lxc_cmd(name, &cmd, &stopped, lxcpath); + if (ret < 0) + return ret; + + if (cmd.rsp.ret < 0) { + ERROR("console access denied: %s", strerror(-cmd.rsp.ret)); + ret = -1; + goto out; + } + + if (ret == 0) { + ERROR("console %d invalid,busy or all consoles busy", *ttynum); + ret = -1; + goto out; + } + + rspdata = cmd.rsp.data; + if (rspdata->masterfd < 0) { + ERROR("unable to allocate fd for tty %d", rspdata->ttynum); + goto out; + } + + ret = cmd.rsp.ret; /* sock fd */ + *fd = rspdata->masterfd; + *ttynum = rspdata->ttynum; + INFO("tty %d allocated fd %d sock %d", rspdata->ttynum, *fd, ret); +out: + free(cmd.rsp.data); + return ret; +} + +static int lxc_cmd_console_callback(int fd, struct lxc_cmd_req *req, + struct lxc_handler *handler) +{ + int ttynum = PTR_TO_INT(req->data); + int masterfd; + struct lxc_cmd_rsp rsp; + + masterfd = lxc_console_allocate(handler->conf, fd, &ttynum); + if (masterfd < 0) + goto out_close; + + memset(&rsp, 0, sizeof(rsp)); + rsp.data = INT_TO_PTR(ttynum); + if (lxc_af_unix_send_fd(fd, masterfd, &rsp, sizeof(rsp)) < 0) { + ERROR("failed to send tty to client"); + lxc_console_free(handler->conf, fd); + goto out_close; + } + + return 0; + +out_close: + /* special indicator to lxc_cmd_handler() to close the fd and do + * related cleanup + */ + return 1; } -extern void lxc_console_remove_fd(int, struct lxc_tty_info *); -extern int lxc_console_callback(int, struct lxc_request *, struct lxc_handler *); -extern int lxc_stop_callback(int, struct lxc_request *, struct lxc_handler *); -extern int lxc_state_callback(int, struct lxc_request *, struct lxc_handler *); -extern int lxc_pid_callback(int, struct lxc_request *, struct lxc_handler *); -static int trigger_command(int fd, struct lxc_request *request, + +static int lxc_cmd_process(int fd, struct lxc_cmd_req *req, struct lxc_handler *handler) { - typedef int (*callback)(int, struct lxc_request *, struct lxc_handler *); + typedef int (*callback)(int, struct lxc_cmd_req *, struct lxc_handler *); - callback cb[LXC_COMMAND_MAX] = { - [LXC_COMMAND_TTY] = lxc_console_callback, - [LXC_COMMAND_STOP] = lxc_stop_callback, - [LXC_COMMAND_STATE] = lxc_state_callback, - [LXC_COMMAND_PID] = lxc_pid_callback, + callback cb[LXC_CMD_MAX] = { + [LXC_CMD_CONSOLE] = lxc_cmd_console_callback, + [LXC_CMD_CONSOLE_WINCH] = lxc_cmd_console_winch_callback, + [LXC_CMD_STOP] = lxc_cmd_stop_callback, + [LXC_CMD_GET_STATE] = lxc_cmd_get_state_callback, + [LXC_CMD_GET_INIT_PID] = lxc_cmd_get_init_pid_callback, + [LXC_CMD_GET_CLONE_FLAGS] = lxc_cmd_get_clone_flags_callback, + [LXC_CMD_GET_CGROUP] = lxc_cmd_get_cgroup_callback, + [LXC_CMD_GET_CONFIG_ITEM] = lxc_cmd_get_config_item_callback, }; - if (request->type < 0 || request->type >= LXC_COMMAND_MAX) + if (req->cmd < 0 || req->cmd >= LXC_CMD_MAX) { + ERROR("bad cmd %d recieved", req->cmd); return -1; - - return cb[request->type](fd, request, handler); + } + return cb[req->cmd](fd, req, handler); } -static void command_fd_cleanup(int fd, struct lxc_handler *handler, +static void lxc_cmd_fd_cleanup(int fd, struct lxc_handler *handler, struct lxc_epoll_descr *descr) { - lxc_console_remove_fd(fd, &handler->conf->tty_info); + lxc_console_free(handler->conf, fd); lxc_mainloop_del_handler(descr, fd); close(fd); } -static int command_handler(int fd, void *data, struct lxc_epoll_descr *descr) +static int lxc_cmd_handler(int fd, void *data, struct lxc_epoll_descr *descr) { int ret; - struct lxc_request request; + struct lxc_cmd_req req; struct lxc_handler *handler = data; - ret = lxc_af_unix_rcv_credential(fd, &request, sizeof(request)); + ret = lxc_af_unix_rcv_credential(fd, &req, sizeof(req)); if (ret == -EACCES) { /* we don't care for the peer, just send and close */ - struct lxc_answer answer = { .ret = ret }; - send(fd, &answer, sizeof(answer), 0); + struct lxc_cmd_rsp rsp = { .ret = ret }; + + lxc_cmd_rsp_send(fd, &rsp); goto out_close; } @@ -204,12 +744,32 @@ goto out_close; } - if (ret != sizeof(request)) { + if (ret != sizeof(req)) { WARN("partial request, ignored"); + ret = -1; + goto out_close; + } + + if (req.datalen > LXC_CMD_DATA_MAX) { + ERROR("cmd data length %d too large", req.datalen); + ret = -1; goto out_close; } - ret = trigger_command(fd, &request, handler); + if (req.datalen > 0) { + void *reqdata; + + reqdata = alloca(req.datalen); + ret = recv(fd, reqdata, req.datalen, 0); + if (ret != req.datalen) { + WARN("partial request, ignored"); + ret = -1; + goto out_close; + } + req.data = reqdata; + } + + ret = lxc_cmd_process(fd, &req, handler); if (ret) { /* this is not an error, but only a request to close fd */ ret = 0; @@ -219,12 +779,11 @@ out: return ret; out_close: - command_fd_cleanup(fd, handler, descr); + lxc_cmd_fd_cleanup(fd, handler, descr); goto out; } -static int incoming_command_handler(int fd, void *data, - struct lxc_epoll_descr *descr) +static int lxc_cmd_accept(int fd, void *data, struct lxc_epoll_descr *descr) { int opt = 1, ret = -1, connection; @@ -245,7 +804,7 @@ goto out_close; } - ret = lxc_mainloop_add_handler(descr, connection, command_handler, data); + ret = lxc_mainloop_add_handler(descr, connection, lxc_cmd_handler, data); if (ret) { ERROR("failed to add handler"); goto out_close; @@ -259,15 +818,17 @@ goto out; } -extern int lxc_command_mainloop_add(const char *name, - struct lxc_epoll_descr *descr, - struct lxc_handler *handler) +int lxc_cmd_init(const char *name, struct lxc_handler *handler, + const char *lxcpath) { - int ret, fd; + int fd; char path[sizeof(((struct sockaddr_un *)0)->sun_path)] = { 0 }; char *offset = &path[1]; + int len; - sprintf(offset, abstractname, name); + len = sizeof(path)-1; + if (fill_sock_name(offset, len, name, lxcpath)) + return -1; fd = lxc_af_unix_open(path, SOCK_STREAM, 0); if (fd < 0) { @@ -286,8 +847,17 @@ return -1; } - ret = lxc_mainloop_add_handler(descr, fd, incoming_command_handler, - handler); + handler->conf->maincmd_fd = fd; + return 0; +} + +int lxc_cmd_mainloop_add(const char *name, + struct lxc_epoll_descr *descr, + struct lxc_handler *handler) +{ + int ret, fd = handler->conf->maincmd_fd; + + ret = lxc_mainloop_add_handler(descr, fd, lxc_cmd_accept, handler); if (ret) { ERROR("failed to add handler for command socket"); close(fd); diff -Nru lxc-0.8.0~rc1/src/lxc/commands.h lxc-1.0.0~alpha1/src/lxc/commands.h --- lxc-0.8.0~rc1/src/lxc/commands.h 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/commands.h 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2009 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,47 +18,75 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ + #ifndef __commands_h #define __commands_h -enum { - LXC_COMMAND_TTY, - LXC_COMMAND_STOP, - LXC_COMMAND_STATE, - LXC_COMMAND_PID, - LXC_COMMAND_MAX, -}; +#include "state.h" + +#define LXC_CMD_DATA_MAX (MAXPATHLEN*2) -struct lxc_request { - int type; - int data; +/* https://developer.gnome.org/glib/2.28/glib-Type-Conversion-Macros.html */ +#define INT_TO_PTR(n) ((void *) (long) (n)) +#define PTR_TO_INT(p) ((int) (long) (p)) + +typedef enum { + LXC_CMD_CONSOLE, + LXC_CMD_CONSOLE_WINCH, + LXC_CMD_STOP, + LXC_CMD_GET_STATE, + LXC_CMD_GET_INIT_PID, + LXC_CMD_GET_CLONE_FLAGS, + LXC_CMD_GET_CGROUP, + LXC_CMD_GET_CONFIG_ITEM, + LXC_CMD_MAX, +} lxc_cmd_t; + +struct lxc_cmd_req { + lxc_cmd_t cmd; + int datalen; + const void *data; }; -struct lxc_answer { - int fd; +struct lxc_cmd_rsp { int ret; /* 0 on success, -errno on failure */ - pid_t pid; + int datalen; + void *data; }; -struct lxc_command { - struct lxc_request request; - struct lxc_answer answer; +struct lxc_cmd_rr { + struct lxc_cmd_req req; + struct lxc_cmd_rsp rsp; }; -extern pid_t get_init_pid(const char *name); - -extern int lxc_command(const char *name, struct lxc_command *command, - int *stopped); +struct lxc_cmd_console_rsp_data { + int masterfd; + int ttynum; +}; -extern int lxc_command_connected(const char *name, struct lxc_command *command, - int *stopped); +extern int lxc_cmd_console_winch(const char *name, const char *lxcpath); +extern int lxc_cmd_console(const char *name, int *ttynum, int *fd, + const char *lxcpath); +/* + * Get the 'real' cgroup path (as seen in /proc/self/cgroup) for a container + * for a particular subsystem + */ +extern char *lxc_cmd_get_cgroup_path(const char *name, const char *lxcpath, + const char *subsystem); +extern int lxc_cmd_get_clone_flags(const char *name, const char *lxcpath); +extern char *lxc_cmd_get_config_item(const char *name, const char *item, const char *lxcpath); +extern pid_t lxc_cmd_get_init_pid(const char *name, const char *lxcpath); +extern lxc_state_t lxc_cmd_get_state(const char *name, const char *lxcpath); +extern int lxc_cmd_stop(const char *name, const char *lxcpath); struct lxc_epoll_descr; struct lxc_handler; -extern int lxc_command_mainloop_add(const char *name, struct lxc_epoll_descr *descr, +extern int lxc_cmd_init(const char *name, struct lxc_handler *handler, + const char *lxcpath); +extern int lxc_cmd_mainloop_add(const char *name, struct lxc_epoll_descr *descr, struct lxc_handler *handler); -#endif +#endif /* __commands_h */ diff -Nru lxc-0.8.0~rc1/src/lxc/conf.c lxc-1.0.0~alpha1/src/lxc/conf.c --- lxc-0.8.0~rc1/src/lxc/conf.c 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/conf.c 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,7 +18,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #define _GNU_SOURCE #include @@ -28,10 +28,22 @@ #include #include #include -#include #include #include +#include +#include + +#if HAVE_IFADDRS_H +#include +#else +#include <../include/ifaddrs.h> +#endif + +#if HAVE_PTY_H #include +#else +#include <../include/openpty.h> +#endif #include @@ -43,8 +55,6 @@ #include #include #include -#include -#include #include #include @@ -61,34 +71,36 @@ #include "log.h" #include "lxc.h" /* for lxc_cgroup_set() */ #include "caps.h" /* for lxc_caps_last_cap() */ +#include "bdev.h" -lxc_log_define(lxc_conf, lxc); - -#define MAXHWLEN 18 -#define MAXINDEXLEN 20 -#define MAXMTULEN 16 -#define MAXLINELEN 128 - -#ifndef MS_DIRSYNC -#define MS_DIRSYNC 128 +#if HAVE_APPARMOR +#include #endif -#ifndef MS_REC -#define MS_REC 16384 +#if HAVE_SYS_CAPABILITY_H +#include #endif -#ifndef MNT_DETACH -#define MNT_DETACH 2 +#if HAVE_SYS_PERSONALITY_H +#include #endif -#ifndef MS_RELATIME -#define MS_RELATIME (1 << 21) +#if IS_BIONIC +#include <../include/lxcmntent.h> +#else +#include #endif -#ifndef MS_STRICTATIME -#define MS_STRICTATIME (1 << 24) -#endif +#include "lxcseccomp.h" + +lxc_log_define(lxc_conf, lxc); + +#define MAXHWLEN 18 +#define MAXINDEXLEN 20 +#define MAXMTULEN 16 +#define MAXLINELEN 128 +#if HAVE_SYS_CAPABILITY_H #ifndef CAP_SETFCAP #define CAP_SETFCAP 31 #endif @@ -100,12 +112,51 @@ #ifndef CAP_MAC_ADMIN #define CAP_MAC_ADMIN 33 #endif +#endif #ifndef PR_CAPBSET_DROP #define PR_CAPBSET_DROP 24 #endif +#ifndef LO_FLAGS_AUTOCLEAR +#define LO_FLAGS_AUTOCLEAR 4 +#endif + +/* Define pivot_root() if missing from the C library */ +#ifndef HAVE_PIVOT_ROOT +static int pivot_root(const char * new_root, const char * put_old) +{ +#ifdef __NR_pivot_root +return syscall(__NR_pivot_root, new_root, put_old); +#else +errno = ENOSYS; +return -1; +#endif +} +#else extern int pivot_root(const char * new_root, const char * put_old); +#endif + +/* Define sethostname() if missing from the C library */ +#ifndef HAVE_SETHOSTNAME +static int sethostname(const char * name, size_t len) +{ +#ifdef __NR_sethostname +return syscall(__NR_sethostname, name, len); +#else +errno = ENOSYS; +return -1; +#endif +} +#endif + +/* Define __S_ISTYPE if missing from the C library */ +#ifndef __S_ISTYPE +#define __S_ISTYPE(mode, mask) (((mode) & S_IFMT) == (mask)) +#endif + +char *lxchook_names[NUM_LXC_HOOKS] = { + "pre-start", "pre-mount", "mount", "autodev", "start", "post-stop", "clone" }; typedef int (*instanciate_cb)(struct lxc_handler *, struct lxc_netdev *); @@ -134,6 +185,20 @@ [LXC_NET_EMPTY] = instanciate_empty, }; +static int shutdown_veth(struct lxc_handler *, struct lxc_netdev *); +static int shutdown_macvlan(struct lxc_handler *, struct lxc_netdev *); +static int shutdown_vlan(struct lxc_handler *, struct lxc_netdev *); +static int shutdown_phys(struct lxc_handler *, struct lxc_netdev *); +static int shutdown_empty(struct lxc_handler *, struct lxc_netdev *); + +static instanciate_cb netdev_deconf[LXC_NET_MAXCONFTYPE + 1] = { + [LXC_NET_VETH] = shutdown_veth, + [LXC_NET_MACVLAN] = shutdown_macvlan, + [LXC_NET_VLAN] = shutdown_vlan, + [LXC_NET_PHYS] = shutdown_phys, + [LXC_NET_EMPTY] = shutdown_empty, +}; + static struct mount_opt mount_opt[] = { { "defaults", 0, 0 }, { "ro", 0, MS_RDONLY }, @@ -163,6 +228,7 @@ { NULL, 0, 0 }, }; +#if HAVE_SYS_CAPABILITY_H static struct caps_opt caps_opt[] = { { "chown", CAP_CHOWN }, { "dac_override", CAP_DAC_OVERRIDE }, @@ -209,23 +275,129 @@ { "wake_alarm", CAP_WAKE_ALARM }, #endif }; +#else +static struct caps_opt caps_opt[] = {}; +#endif -static int run_script(const char *name, const char *section, - const char *script, ...) +static char padchar[] = +"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + +static char *mkifname(char *template) +{ + char *name = NULL; + int i = 0; + FILE *urandom; + unsigned int seed; + struct ifaddrs *ifaddr, *ifa; + int ifexists = 0; + + /* Get all the network interfaces */ + getifaddrs(&ifaddr); + + /* Initialize the random number generator */ + urandom = fopen ("/dev/urandom", "r"); + if (urandom != NULL) { + if (fread (&seed, sizeof(seed), 1, urandom) <= 0) + seed = time(0); + fclose(urandom); + } + else + seed = time(0); + +#ifndef HAVE_RAND_R + srand(seed); +#endif + + /* Generate random names until we find one that doesn't exist */ + while(1) { + ifexists = 0; + name = strdup(template); + + if (name == NULL) + return NULL; + + for (i = 0; i < strlen(name); i++) { + if (name[i] == 'X') { +#ifdef HAVE_RAND_R + name[i] = padchar[rand_r(&seed) % (strlen(padchar) - 1)]; +#else + name[i] = padchar[rand() % (strlen(padchar) - 1)]; +#endif + } + } + + for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { + if (strcmp(ifa->ifa_name, name) == 0) { + ifexists = 1; + break; + } + } + + if (ifexists == 0) + break; + + free(name); + } + + freeifaddrs(ifaddr); + return name; +} + +static int run_buffer(char *buffer) { - int ret; FILE *f; - char *buffer, *p, *output; + char *output; + int ret; + + f = popen(buffer, "r"); + if (!f) { + SYSERROR("popen failed"); + return -1; + } + + output = malloc(LXC_LOG_BUFFER_SIZE); + if (!output) { + ERROR("failed to allocate memory for script output"); + pclose(f); + return -1; + } + + while(fgets(output, LXC_LOG_BUFFER_SIZE, f)) + DEBUG("script output: %s", output); + + free(output); + + ret = pclose(f); + if (ret == -1) { + SYSERROR("Script exited on error"); + return -1; + } else if (WIFEXITED(ret) && WEXITSTATUS(ret) != 0) { + ERROR("Script exited with status %d", WEXITSTATUS(ret)); + return -1; + } else if (WIFSIGNALED(ret)) { + ERROR("Script terminated by signal %d (%s)", WTERMSIG(ret), + strsignal(WTERMSIG(ret))); + return -1; + } + + return 0; +} + +static int run_script_argv(const char *name, const char *section, + const char *script, const char *hook, const char *lxcpath, + char **argsin) +{ + int ret, i; + char *buffer; size_t size = 0; - va_list ap; INFO("Executing script '%s' for container '%s', config section '%s'", script, name, section); - va_start(ap, script); - while ((p = va_arg(ap, char *))) - size += strlen(p) + 1; - va_end(ap); + for (i=0; argsin && argsin[i]; i++) + size += strlen(argsin[i]) + 1; + + size += strlen(hook) + 1; size += strlen(script); size += strlen(name); @@ -241,36 +413,76 @@ return -1; } - ret = sprintf(buffer, "%s %s %s", script, name, section); + ret = snprintf(buffer, size, "%s %s %s %s", script, name, section, hook); + if (ret < 0 || ret >= size) { + ERROR("Script name too long"); + return -1; + } + + for (i=0; argsin && argsin[i]; i++) { + int len = size-ret; + int rc; + rc = snprintf(buffer + ret, len, " %s", argsin[i]); + if (rc < 0 || rc >= len) { + ERROR("Script args too long"); + return -1; + } + ret += rc; + } + + return run_buffer(buffer); +} + +static int run_script(const char *name, const char *section, + const char *script, ...) +{ + int ret; + char *buffer, *p; + size_t size = 0; + va_list ap; + + INFO("Executing script '%s' for container '%s', config section '%s'", + script, name, section); va_start(ap, script); while ((p = va_arg(ap, char *))) - ret += sprintf(buffer + ret, " %s", p); + size += strlen(p) + 1; va_end(ap); - f = popen(buffer, "r"); - if (!f) { - SYSERROR("popen failed"); + size += strlen(script); + size += strlen(name); + size += strlen(section); + size += 3; + + if (size > INT_MAX) return -1; - } - output = malloc(LXC_LOG_BUFFER_SIZE); - if (!output) { - ERROR("failed to allocate memory for script output"); + buffer = alloca(size); + if (!buffer) { + ERROR("failed to allocate memory"); return -1; } - while(fgets(output, LXC_LOG_BUFFER_SIZE, f)) - DEBUG("script output: %s", output); - - free(output); - - if (pclose(f)) { - ERROR("Script exited on error"); + ret = snprintf(buffer, size, "%s %s %s", script, name, section); + if (ret < 0 || ret >= size) { + ERROR("Script name too long"); return -1; } - return 0; + va_start(ap, script); + while ((p = va_arg(ap, char *))) { + int len = size-ret; + int rc; + rc = snprintf(buffer + ret, len, " %s", p); + if (rc < 0 || rc >= len) { + ERROR("Script args too long"); + return -1; + } + ret += rc; + } + va_end(ap); + + return run_buffer(buffer); } static int find_fstype_cb(char* buffer, void *data) @@ -391,7 +603,7 @@ { struct dirent dirent, *direntp; struct loop_info64 loinfo; - int ret = -1, fd = -1; + int ret = -1, fd = -1, rc; DIR *dir; char path[MAXPATHLEN]; @@ -415,7 +627,10 @@ if (strncmp(direntp->d_name, "loop", 4)) continue; - sprintf(path, "/dev/%s", direntp->d_name); + rc = snprintf(path, MAXPATHLEN, "/dev/%s", direntp->d_name); + if (rc < 0 || rc >= MAXPATHLEN) + continue; + fd = open(path, O_RDWR); if (fd < 0) continue; @@ -428,6 +643,7 @@ if (errno != ENXIO) { WARN("unexpected error for ioctl on '%s': %m", direntp->d_name); + close(fd); continue; } @@ -452,6 +668,54 @@ return mount_unknow_fs(rootfs, target, 0); } +/* + * pin_rootfs + * if rootfs is a directory, then open ${rootfs}.hold for writing for the + * duration of the container run, to prevent the container from marking the + * underlying fs readonly on shutdown. + * return -1 on error. + * return -2 if nothing needed to be pinned. + * return an open fd (>=0) if we pinned it. + */ +int pin_rootfs(const char *rootfs) +{ + char absrootfs[MAXPATHLEN]; + char absrootfspin[MAXPATHLEN]; + struct stat s; + int ret, fd; + + if (rootfs == NULL || strlen(rootfs) == 0) + return -2; + + if (!realpath(rootfs, absrootfs)) { + INFO("failed to get real path for '%s', not pinning", rootfs); + return -2; + } + + if (access(absrootfs, F_OK)) { + SYSERROR("'%s' is not accessible", absrootfs); + return -1; + } + + if (stat(absrootfs, &s)) { + SYSERROR("failed to stat '%s'", absrootfs); + return -1; + } + + if (!S_ISDIR(s.st_mode)) + return -2; + + ret = snprintf(absrootfspin, MAXPATHLEN, "%s%s", absrootfs, ".hold"); + if (ret >= MAXPATHLEN) { + SYSERROR("pathname too long for rootfs hold file"); + return -1; + } + + fd = open(absrootfspin, O_CREAT | O_RDWR, S_IWUSR|S_IRUSR); + INFO("opened %s as fd %d\n", absrootfspin, fd); + return fd; +} + static int mount_rootfs(const char *rootfs, const char *target) { char absrootfs[MAXPATHLEN]; @@ -532,7 +796,7 @@ } if (ttydir) { /* create dev/lxc/tty%d" */ - snprintf(lxcpath, sizeof(lxcpath), "%s/dev/%s/tty%d", + ret = snprintf(lxcpath, sizeof(lxcpath), "%s/dev/%s/tty%d", rootfs->mount, ttydir, i + 1); if (ret >= sizeof(lxcpath)) { ERROR("pathname too long for ttys"); @@ -543,7 +807,8 @@ SYSERROR("error creating %s\n", lxcpath); return -1; } - close(ret); + if (ret >= 0) + close(ret); ret = unlink(path); if (ret && errno != ENOENT) { SYSERROR("error unlinking %s\n", path); @@ -556,13 +821,26 @@ continue; } - snprintf(lxcpath, sizeof(lxcpath), "%s/tty%d", ttydir, i+1); + ret = snprintf(lxcpath, sizeof(lxcpath), "%s/tty%d", ttydir, i+1); + if (ret >= sizeof(lxcpath)) { + ERROR("tty pathname too long"); + return -1; + } ret = symlink(lxcpath, path); if (ret) { SYSERROR("failed to create symlink for tty %d\n", i+1); return -1; } } else { + /* If we populated /dev, then we need to create /dev/ttyN */ + if (access(path, F_OK)) { + ret = creat(path, 0660); + if (ret==-1) { + SYSERROR("error creating %s\n", path); + /* this isn't fatal, continue */ + } else + close(ret); + } if (mount(pty_info->name, path, "none", MS_BIND, 0)) { WARN("failed to mount '%s'->'%s'", pty_info->name, path); @@ -579,7 +857,7 @@ static int setup_rootfs_pivot_root_cb(char *buffer, void *data) { struct lxc_list *mountlist, *listentry, *iterator; - char *pivotdir, *mountpoint, *mountentry; + char *pivotdir, *mountpoint, *mountentry, *saveptr = NULL; int found; void **cbparm; @@ -590,12 +868,12 @@ pivotdir = cbparm[1]; /* parse entry, first field is mountname, ignore */ - mountpoint = strtok(mountentry, " "); + mountpoint = strtok_r(mountentry, " ", &saveptr); if (!mountpoint) return -1; /* second field is mountpoint */ - mountpoint = strtok(NULL, " "); + mountpoint = strtok_r(NULL, " ", &saveptr); if (!mountpoint) return -1; @@ -624,6 +902,7 @@ listentry->elem = strdup(mountpoint); if (!listentry->elem) { SYSERROR("strdup failed"); + free(listentry); return -1; } lxc_list_add_tail(mountlist, listentry); @@ -635,14 +914,19 @@ { char path[MAXPATHLEN]; void *cbparm[2]; - struct lxc_list mountlist, *iterator; + struct lxc_list mountlist, *iterator, *next; int ok, still_mounted, last_still_mounted; + int rc; /* read and parse /proc/mounts in old root fs */ lxc_list_init(&mountlist); /* oldrootfs is on the top tree directory now */ - snprintf(path, sizeof(path), "/%s", oldrootfs); + rc = snprintf(path, sizeof(path), "/%s", oldrootfs); + if (rc >= sizeof(path)) { + ERROR("rootfs name too long"); + return -1; + } cbparm[0] = &mountlist; cbparm[1] = strdup(path); @@ -651,7 +935,11 @@ return -1; } - snprintf(path, sizeof(path), "%s/proc/mounts", oldrootfs); + rc = snprintf(path, sizeof(path), "%s/proc/mounts", oldrootfs); + if (rc >= sizeof(path)) { + ERROR("container proc/mounts name too long"); + return -1; + } ok = lxc_file_for_each_line(path, setup_rootfs_pivot_root_cb, &cbparm); @@ -666,7 +954,7 @@ last_still_mounted = still_mounted; still_mounted = 0; - lxc_list_for_each(iterator, &mountlist) { + lxc_list_for_each_safe(iterator, &mountlist, next) { /* umount normally */ if (!umount(iterator->elem)) { @@ -705,6 +993,7 @@ { char path[MAXPATHLEN]; int remove_pivotdir = 0; + int rc; /* change into new root fs */ if (chdir(rootfs)) { @@ -713,10 +1002,14 @@ } if (!pivotdir) - pivotdir = "mnt"; + pivotdir = "lxc_putold"; /* compute the full path to pivotdir under rootfs */ - snprintf(path, sizeof(path), "%s/%s", rootfs, pivotdir); + rc = snprintf(path, sizeof(path), "%s/%s", rootfs, pivotdir); + if (rc >= sizeof(path)) { + ERROR("pivot dir name too long"); + return -1; + } if (access(path, F_OK)) { @@ -756,71 +1049,281 @@ return 0; } -static int setup_rootfs(const struct lxc_rootfs *rootfs) +/* + * Do we want to add options for max size of /dev and a file to + * specify which devices to create? + */ +static int mount_autodev(char *root) { - if (!rootfs->path) - return 0; + int ret; + char path[MAXPATHLEN]; - if (access(rootfs->mount, F_OK)) { - SYSERROR("failed to access to '%s', check it is present", - rootfs->mount); + INFO("Mounting /dev under %s\n", root); + ret = snprintf(path, MAXPATHLEN, "%s/dev", root); + if (ret < 0 || ret > MAXPATHLEN) + return -1; + ret = mount("none", path, "tmpfs", 0, "size=100000"); + if (ret) { + SYSERROR("Failed to mount /dev at %s\n", root); return -1; } - - if (mount_rootfs(rootfs->path, rootfs->mount)) { - ERROR("failed to mount rootfs"); + ret = snprintf(path, MAXPATHLEN, "%s/dev/pts", root); + if (ret < 0 || ret >= MAXPATHLEN) + return -1; + ret = mkdir(path, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); + if (ret) { + SYSERROR("Failed to create /dev/pts in container"); return -1; } - DEBUG("mounted '%s' on '%s'", rootfs->path, rootfs->mount); - + INFO("Mounted /dev under %s\n", root); return 0; } -int setup_pivot_root(const struct lxc_rootfs *rootfs) +struct lxc_devs { + char *name; + mode_t mode; + int maj; + int min; +}; + +struct lxc_devs lxc_devs[] = { + { "null", S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO, 1, 3 }, + { "zero", S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO, 1, 5 }, + { "full", S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO, 1, 7 }, + { "urandom", S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO, 1, 9 }, + { "random", S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO, 1, 8 }, + { "tty", S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO, 5, 0 }, + { "console", S_IFCHR | S_IRUSR | S_IWUSR, 5, 1 }, +}; + +static int setup_autodev(char *root) { - if (!rootfs->path) - return 0; + int ret; + struct lxc_devs *d; + char path[MAXPATHLEN]; + int i; + mode_t cmask; - if (setup_rootfs_pivot_root(rootfs->mount, rootfs->pivot)) { - ERROR("failed to setup pivot root"); + INFO("Creating initial consoles under %s/dev\n", root); + + ret = snprintf(path, MAXPATHLEN, "%s/dev", root); + if (ret < 0 || ret >= MAXPATHLEN) { + ERROR("Error calculating container /dev location"); return -1; } + INFO("Populating /dev under %s\n", root); + cmask = umask(S_IXUSR | S_IXGRP | S_IXOTH); + for (i = 0; i < sizeof(lxc_devs) / sizeof(lxc_devs[0]); i++) { + d = &lxc_devs[i]; + ret = snprintf(path, MAXPATHLEN, "%s/dev/%s", root, d->name); + if (ret < 0 || ret >= MAXPATHLEN) + return -1; + ret = mknod(path, d->mode, makedev(d->maj, d->min)); + if (ret && errno != EEXIST) { + SYSERROR("Error creating %s\n", d->name); + return -1; + } + } + umask(cmask); + + INFO("Populated /dev under %s\n", root); return 0; } -static int setup_pts(int pts) +/* + * Detect whether / is mounted MS_SHARED. The only way I know of to + * check that is through /proc/self/mountinfo. + * I'm only checking for /. If the container rootfs or mount location + * is MS_SHARED, but not '/', then you're out of luck - figuring that + * out would be too much work to be worth it. + */ +#define LINELEN 4096 +int detect_shared_rootfs(void) { - char target[PATH_MAX]; + char buf[LINELEN], *p; + FILE *f; + int i; + char *p2; - if (!pts) + f = fopen("/proc/self/mountinfo", "r"); + if (!f) return 0; + while ((p = fgets(buf, LINELEN, f))) { + INFO("looking at .%s.", p); + for (p = buf, i=0; p && i < 4; i++) + p = index(p+1, ' '); + if (!p) + continue; + p2 = index(p+1, ' '); + if (!p2) + continue; + *p2 = '\0'; + INFO("now p is .%s.", p); + if (strcmp(p+1, "/") == 0) { + // this is '/'. is it shared? + p = index(p2+1, ' '); + if (p && strstr(p, "shared:")) { + fclose(f); + return 1; + } + } + } + fclose(f); + return 0; +} - if (!access("/dev/pts/ptmx", F_OK) && umount("/dev/pts")) { - SYSERROR("failed to umount 'dev/pts'"); +/* + * I'll forgive you for asking whether all of this is needed :) The + * answer is yes. + * pivot_root will fail if the new root, the put_old dir, or the parent + * of current->fs->root are MS_SHARED. (parent of current->fs_root may + * or may not be current->fs_root - if we assumed it always was, we could + * just mount --make-rslave /). So, + * 1. mount a tiny tmpfs to be parent of current->fs->root. + * 2. make that MS_SLAVE + * 3. make a 'root' directory under that + * 4. mount --rbind / under the $tinyroot/root. + * 5. make that rslave + * 6. chdir and chroot into $tinyroot/root + * 7. $tinyroot will be unmounted by our parent in start.c + */ +static int chroot_into_slave(struct lxc_conf *conf) +{ + char path[MAXPATHLEN]; + const char *destpath = conf->rootfs.mount; + int ret; + + if (mount(destpath, destpath, NULL, MS_BIND, 0)) { + SYSERROR("failed to mount %s bind", destpath); return -1; } - - if (mount("devpts", "/dev/pts", "devpts", MS_MGC_VAL, - "newinstance,ptmxmode=0666")) { - SYSERROR("failed to mount a new instance of '/dev/pts'"); + if (mount("", destpath, NULL, MS_SLAVE, 0)) { + SYSERROR("failed to make %s slave", destpath); return -1; } - - if (access("/dev/ptmx", F_OK)) { - if (!symlink("/dev/pts/ptmx", "/dev/ptmx")) - goto out; - SYSERROR("failed to symlink '/dev/pts/ptmx'->'/dev/ptmx'"); + if (mount("none", destpath, "tmpfs", 0, "size=10000")) { + SYSERROR("Failed to mount tmpfs / at %s", destpath); return -1; } - - if (realpath("/dev/ptmx", target) && !strcmp(target, "/dev/pts/ptmx")) - goto out; - - /* fallback here, /dev/pts/ptmx exists just mount bind */ - if (mount("/dev/pts/ptmx", "/dev/ptmx", "none", MS_BIND, 0)) { - SYSERROR("mount failed '/dev/pts/ptmx'->'/dev/ptmx'"); + ret = snprintf(path, MAXPATHLEN, "%s/root", destpath); + if (ret < 0 || ret >= MAXPATHLEN) { + ERROR("out of memory making root path"); + return -1; + } + if (mkdir(path, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { + SYSERROR("Failed to create /dev/pts in container"); + return -1; + } + if (mount("/", path, NULL, MS_BIND|MS_REC, 0)) { + SYSERROR("Failed to rbind mount / to %s", path); + return -1; + } + if (mount("", destpath, NULL, MS_SLAVE|MS_REC, 0)) { + SYSERROR("Failed to make tmp-/ at %s rslave", path); + return -1; + } + if (chdir(path)) { + SYSERROR("Failed to chdir into tmp-/"); + return -1; + } + if (chroot(path)) { + SYSERROR("Failed to chroot into tmp-/"); + return -1; + } + INFO("Chrooted into tmp-/ at %s\n", path); + return 0; +} + +static int setup_rootfs(struct lxc_conf *conf) +{ + const struct lxc_rootfs *rootfs = &conf->rootfs; + + if (!rootfs->path) { + if (mount("", "/", NULL, MS_SLAVE|MS_REC, 0)) { + SYSERROR("Failed to make / rslave"); + return -1; + } + return 0; + } + + if (access(rootfs->mount, F_OK)) { + SYSERROR("failed to access to '%s', check it is present", + rootfs->mount); + return -1; + } + + if (detect_shared_rootfs()) { + if (chroot_into_slave(conf)) { + ERROR("Failed to chroot into slave /"); + return -1; + } + } + + // First try mounting rootfs using a bdev + struct bdev *bdev = bdev_init(rootfs->path, rootfs->mount, NULL); + if (bdev && bdev->ops->mount(bdev) == 0) { + bdev_put(bdev); + DEBUG("mounted '%s' on '%s'", rootfs->path, rootfs->mount); + return 0; + } + if (bdev) + bdev_put(bdev); + if (mount_rootfs(rootfs->path, rootfs->mount)) { + ERROR("failed to mount rootfs"); + return -1; + } + + DEBUG("mounted '%s' on '%s'", rootfs->path, rootfs->mount); + + return 0; +} + +int setup_pivot_root(const struct lxc_rootfs *rootfs) +{ + if (!rootfs->path) + return 0; + + if (setup_rootfs_pivot_root(rootfs->mount, rootfs->pivot)) { + ERROR("failed to setup pivot root"); + return -1; + } + + return 0; +} + +static int setup_pts(int pts) +{ + char target[PATH_MAX]; + + if (!pts) + return 0; + + if (!access("/dev/pts/ptmx", F_OK) && umount("/dev/pts")) { + SYSERROR("failed to umount 'dev/pts'"); + return -1; + } + + if (mount("devpts", "/dev/pts", "devpts", MS_MGC_VAL, + "newinstance,ptmxmode=0666")) { + SYSERROR("failed to mount a new instance of '/dev/pts'"); + return -1; + } + + if (access("/dev/ptmx", F_OK)) { + if (!symlink("/dev/pts/ptmx", "/dev/ptmx")) + goto out; + SYSERROR("failed to symlink '/dev/pts/ptmx'->'/dev/ptmx'"); + return -1; + } + + if (realpath("/dev/ptmx", target) && !strcmp(target, "/dev/pts/ptmx")) + goto out; + + /* fallback here, /dev/pts/ptmx exists just mount bind */ + if (mount("/dev/pts/ptmx", "/dev/ptmx", "none", MS_BIND, 0)) { + SYSERROR("mount failed '/dev/pts/ptmx'->'/dev/ptmx'"); return -1; } @@ -832,6 +1335,7 @@ static int setup_personality(int persona) { + #if HAVE_SYS_PERSONALITY_H if (persona == -1) return 0; @@ -841,6 +1345,7 @@ } INFO("set personality to '0x%x'", persona); + #endif return 0; } @@ -863,8 +1368,8 @@ return 0; } - if (console->peer == -1) { - INFO("no console output required"); + if (console->master < 0) { + INFO("no console"); return 0; } @@ -926,10 +1431,11 @@ SYSERROR("error %d creating %s\n", errno, lxcpath); return -1; } - close(ret); + if (ret >= 0) + close(ret); - if (console->peer == -1) { - INFO("no console output required"); + if (console->master < 0) { + INFO("no console"); return 0; } @@ -939,7 +1445,11 @@ } /* create symlink from rootfs/dev/console to 'lxc/console' */ - snprintf(lxcpath, sizeof(lxcpath), "%s/console", ttydir); + ret = snprintf(lxcpath, sizeof(lxcpath), "%s/console", ttydir); + if (ret >= sizeof(lxcpath)) { + ERROR("lxc/console path too long"); + return -1; + } ret = symlink(lxcpath, path); if (ret) { SYSERROR("failed to create symlink for console"); @@ -964,29 +1474,31 @@ return setup_ttydir_console(rootfs, console, ttydir); } -static int setup_cgroup(const char *name, struct lxc_list *cgroups) +static int setup_kmsg(const struct lxc_rootfs *rootfs, + const struct lxc_console *console) { - struct lxc_list *iterator; - struct lxc_cgroup *cg; - int ret = -1; + char kpath[MAXPATHLEN]; + int ret; - if (lxc_list_empty(cgroups)) + if (!rootfs->path) return 0; + ret = snprintf(kpath, sizeof(kpath), "%s/dev/kmsg", rootfs->mount); + if (ret < 0 || ret >= sizeof(kpath)) + return -1; - lxc_list_for_each(iterator, cgroups) { - - cg = iterator->elem; - - if (lxc_cgroup_set(name, cg->subsystem, cg->value)) - goto out; + ret = unlink(kpath); + if (ret && errno != ENOENT) { + SYSERROR("error unlinking %s\n", kpath); + return -1; + } - DEBUG("cgroup '%s' set to '%s'", cg->subsystem, cg->value); + ret = symlink("console", kpath); + if (ret) { + SYSERROR("failed to create symlink for kmsg"); + return -1; } - ret = 0; - INFO("cgroup has been setup"); -out: - return ret; + return 0; } static void parse_mntopt(char *opt, unsigned long *flags, char **data) @@ -1091,37 +1603,73 @@ ret = mount_entry(mntent->mnt_fsname, mntent->mnt_dir, mntent->mnt_type, mntflags, mntdata); + if (hasmntopt(mntent, "optional") != NULL) + ret = 0; + free(mntdata); return ret; } static int mount_entry_on_absolute_rootfs(struct mntent *mntent, - const struct lxc_rootfs *rootfs) + const struct lxc_rootfs *rootfs, + const char *lxc_name) { char *aux; char path[MAXPATHLEN]; unsigned long mntflags; char *mntdata; - int ret = 0; + int r, ret = 0, offset; + const char *lxcpath; if (parse_mntopts(mntent->mnt_opts, &mntflags, &mntdata) < 0) { ERROR("failed to parse mount option '%s'", mntent->mnt_opts); return -1; } + lxcpath = default_lxc_path(); + if (!lxcpath) { + ERROR("Out of memory"); + return -1; + } + + /* if rootfs->path is a blockdev path, allow container fstab to + * use $lxcpath/CN/rootfs as the target prefix */ + r = snprintf(path, MAXPATHLEN, "%s/%s/rootfs", lxcpath, lxc_name); + if (r < 0 || r >= MAXPATHLEN) + goto skipvarlib; + + aux = strstr(mntent->mnt_dir, path); + if (aux) { + offset = strlen(path); + goto skipabs; + } + +skipvarlib: aux = strstr(mntent->mnt_dir, rootfs->path); if (!aux) { WARN("ignoring mount point '%s'", mntent->mnt_dir); goto out; } + offset = strlen(rootfs->path); + +skipabs: + + r = snprintf(path, MAXPATHLEN, "%s/%s", rootfs->mount, + aux + offset); + if (r < 0 || r >= MAXPATHLEN) { + WARN("pathnme too long for '%s'", mntent->mnt_dir); + ret = -1; + goto out; + } - snprintf(path, MAXPATHLEN, "%s/%s", rootfs->mount, - aux + strlen(rootfs->path)); ret = mount_entry(mntent->mnt_fsname, path, mntent->mnt_type, mntflags, mntdata); + if (hasmntopt(mntent, "optional") != NULL) + ret = 0; + out: free(mntdata); return ret; @@ -1141,17 +1689,25 @@ } /* relative to root mount point */ - snprintf(path, sizeof(path), "%s/%s", rootfs, mntent->mnt_dir); + ret = snprintf(path, sizeof(path), "%s/%s", rootfs, mntent->mnt_dir); + if (ret >= sizeof(path)) { + ERROR("path name too long"); + return -1; + } ret = mount_entry(mntent->mnt_fsname, path, mntent->mnt_type, mntflags, mntdata); + if (hasmntopt(mntent, "optional") != NULL) + ret = 0; + free(mntdata); return ret; } -static int mount_file_entries(const struct lxc_rootfs *rootfs, FILE *file) +static int mount_file_entries(const struct lxc_rootfs *rootfs, FILE *file, + const char *lxc_name) { struct mntent *mntent; int ret = -1; @@ -1172,7 +1728,7 @@ continue; } - if (mount_entry_on_absolute_rootfs(mntent, rootfs)) + if (mount_entry_on_absolute_rootfs(mntent, rootfs, lxc_name)) goto out; } @@ -1183,7 +1739,8 @@ return ret; } -static int setup_mount(const struct lxc_rootfs *rootfs, const char *fstab) +static int setup_mount(const struct lxc_rootfs *rootfs, const char *fstab, + const char *lxc_name) { FILE *file; int ret; @@ -1197,13 +1754,14 @@ return -1; } - ret = mount_file_entries(rootfs, file); + ret = mount_file_entries(rootfs, file, lxc_name); endmntent(file); return ret; } -static int setup_mount_entries(const struct lxc_rootfs *rootfs, struct lxc_list *mount) +static int setup_mount_entries(const struct lxc_rootfs *rootfs, struct lxc_list *mount, + const char *lxc_name) { FILE *file; struct lxc_list *iterator; @@ -1223,7 +1781,7 @@ rewind(file); - ret = mount_file_entries(rootfs, file); + ret = mount_file_entries(rootfs, file, lxc_name); fclose(file); return ret; @@ -1280,7 +1838,76 @@ } - DEBUG("capabilities has been setup"); + DEBUG("capabilities have been setup"); + + return 0; +} + +static int dropcaps_except(struct lxc_list *caps) +{ + struct lxc_list *iterator; + char *keep_entry; + char *ptr; + int i, capid; + int numcaps = lxc_caps_last_cap() + 1; + INFO("found %d capabilities\n", numcaps); + + if (numcaps <= 0 || numcaps > 200) + return -1; + + // caplist[i] is 1 if we keep capability i + int *caplist = alloca(numcaps * sizeof(int)); + memset(caplist, 0, numcaps * sizeof(int)); + + lxc_list_for_each(iterator, caps) { + + keep_entry = iterator->elem; + + capid = -1; + + for (i = 0; i < sizeof(caps_opt)/sizeof(caps_opt[0]); i++) { + + if (strcmp(keep_entry, caps_opt[i].name)) + continue; + + capid = caps_opt[i].value; + break; + } + + if (capid < 0) { + /* try to see if it's numeric, so the user may specify + * capabilities that the running kernel knows about but + * we don't */ + capid = strtol(keep_entry, &ptr, 10); + if (!ptr || *ptr != '\0' || + capid == LONG_MIN || capid == LONG_MAX) + /* not a valid number */ + capid = -1; + else if (capid > lxc_caps_last_cap()) + /* we have a number but it's not a valid + * capability */ + capid = -1; + } + + if (capid < 0) { + ERROR("unknown capability %s", keep_entry); + return -1; + } + + DEBUG("drop capability '%s' (%d)", keep_entry, capid); + + caplist[capid] = 1; + } + for (i=0; iipv6_gateway_auto) { char buf[INET6_ADDRSTRLEN]; - inet_ntop(AF_INET, netdev->ipv6_gateway, buf, sizeof(buf)); + inet_ntop(AF_INET6, netdev->ipv6_gateway, buf, sizeof(buf)); ERROR("tried to set autodetected ipv6 gateway '%s'", buf); } return -1; @@ -1534,6 +2161,21 @@ return 0; } +void lxc_rename_phys_nics_on_shutdown(struct lxc_conf *conf) +{ + int i; + + INFO("running to reset %d nic names", conf->num_savednics); + for (i=0; inum_savednics; i++) { + struct saved_nic *s = &conf->saved_nics[i]; + INFO("resetting nic %d to %s\n", s->ifindex, s->orig_name); + lxc_netdev_rename_by_index(s->ifindex, s->orig_name); + free(s->orig_name); + } + conf->num_savednics = 0; + free(conf->saved_nics); +} + static int setup_private_host_hw_addr(char *veth1) { struct ifreq ifr; @@ -1569,9 +2211,12 @@ return 0; } +static char *default_rootfs_mount = LXCROOTFSMOUNT; + struct lxc_conf *lxc_conf_init(void) { struct lxc_conf *new; + int i; new = malloc(sizeof(*new)); if (!new) { @@ -1580,17 +2225,40 @@ } memset(new, 0, sizeof(*new)); + new->loglevel = LXC_LOG_PRIORITY_NOTSET; new->personality = -1; + new->console.log_path = NULL; + new->console.log_fd = -1; new->console.path = NULL; new->console.peer = -1; + new->console.peerpty.busy = -1; + new->console.peerpty.master = -1; + new->console.peerpty.slave = -1; new->console.master = -1; new->console.slave = -1; new->console.name[0] = '\0'; - new->rootfs.mount = LXCROOTFSMOUNT; + new->maincmd_fd = -1; + new->rootfs.mount = strdup(default_rootfs_mount); + if (!new->rootfs.mount) { + ERROR("lxc_conf_init : %m"); + free(new); + return NULL; + } + new->kmsg = 1; lxc_list_init(&new->cgroup); lxc_list_init(&new->network); lxc_list_init(&new->mount_list); lxc_list_init(&new->caps); + lxc_list_init(&new->keepcaps); + lxc_list_init(&new->id_map); + for (i=0; ihooks[i]); +#if HAVE_APPARMOR + new->aa_profile = NULL; +#endif +#if HAVE_APPARMOR /* || HAVE_SMACK || HAVE_SELINUX */ + new->lsm_umount_proc = 0; +#endif return new; } @@ -1604,12 +2272,18 @@ if (netdev->priv.veth_attr.pair) veth1 = netdev->priv.veth_attr.pair; else { - snprintf(veth1buf, sizeof(veth1buf), "vethXXXXXX"); - veth1 = mktemp(veth1buf); + err = snprintf(veth1buf, sizeof(veth1buf), "vethXXXXXX"); + if (err >= sizeof(veth1buf)) { /* can't *really* happen, but... */ + ERROR("veth1 name too long"); + return -1; + } + veth1 = mkifname(veth1buf); + /* store away for deconf */ + memcpy(netdev->priv.veth_attr.veth1, veth1, IFNAMSIZ); } snprintf(veth2buf, sizeof(veth2buf), "vethXXXXXX"); - veth2 = mktemp(veth2buf); + veth2 = mkifname(veth2buf); if (!strlen(veth1) || !strlen(veth2)) { ERROR("failed to allocate a temporary name"); @@ -1682,6 +2356,25 @@ return -1; } +static int shutdown_veth(struct lxc_handler *handler, struct lxc_netdev *netdev) +{ + char *veth1; + int err; + + if (netdev->priv.veth_attr.pair) + veth1 = netdev->priv.veth_attr.pair; + else + veth1 = netdev->priv.veth_attr.veth1; + + if (netdev->downscript) { + err = run_script(handler->name, "net", netdev->downscript, + "down", "veth", veth1, (char*) NULL); + if (err) + return -1; + } + return 0; +} + static int instanciate_macvlan(struct lxc_handler *handler, struct lxc_netdev *netdev) { char peerbuf[IFNAMSIZ], *peer; @@ -1692,9 +2385,11 @@ return -1; } - snprintf(peerbuf, sizeof(peerbuf), "mcXXXXXX"); + err = snprintf(peerbuf, sizeof(peerbuf), "mcXXXXXX"); + if (err >= sizeof(peerbuf)) + return -1; - peer = mktemp(peerbuf); + peer = mkifname(peerbuf); if (!strlen(peer)) { ERROR("failed to make a temporary name"); return -1; @@ -1728,6 +2423,20 @@ return 0; } +static int shutdown_macvlan(struct lxc_handler *handler, struct lxc_netdev *netdev) +{ + int err; + + if (netdev->downscript) { + err = run_script(handler->name, "net", netdev->downscript, + "down", "macvlan", netdev->link, + (char*) NULL); + if (err) + return -1; + } + return 0; +} + /* XXX: merge with instanciate_macvlan */ static int instanciate_vlan(struct lxc_handler *handler, struct lxc_netdev *netdev) { @@ -1739,7 +2448,11 @@ return -1; } - snprintf(peer, sizeof(peer), "vlan%d", netdev->priv.vlan_attr.vid); + err = snprintf(peer, sizeof(peer), "vlan%d", netdev->priv.vlan_attr.vid); + if (err >= sizeof(peer)) { + ERROR("peer name too long"); + return -1; + } err = lxc_vlan_create(netdev->link, peer, netdev->priv.vlan_attr.vid); if (err) { @@ -1761,6 +2474,11 @@ return 0; } +static int shutdown_vlan(struct lxc_handler *handler, struct lxc_netdev *netdev) +{ + return 0; +} + static int instanciate_phys(struct lxc_handler *handler, struct lxc_netdev *netdev) { if (!netdev->link) { @@ -1785,6 +2503,19 @@ return 0; } +static int shutdown_phys(struct lxc_handler *handler, struct lxc_netdev *netdev) +{ + int err; + + if (netdev->downscript) { + err = run_script(handler->name, "net", netdev->downscript, + "down", "phys", netdev->link, (char*) NULL); + if (err) + return -1; + } + return 0; +} + static int instanciate_empty(struct lxc_handler *handler, struct lxc_netdev *netdev) { netdev->ifindex = 0; @@ -1798,6 +2529,19 @@ return 0; } +static int shutdown_empty(struct lxc_handler *handler, struct lxc_netdev *netdev) +{ + int err; + + if (netdev->downscript) { + err = run_script(handler->name, "net", netdev->downscript, + "down", "empty", (char*) NULL); + if (err) + return -1; + } + return 0; +} + int lxc_create_network(struct lxc_handler *handler) { struct lxc_list *network = &handler->conf->network; @@ -1824,28 +2568,32 @@ return 0; } -void lxc_delete_network(struct lxc_list *network) +void lxc_delete_network(struct lxc_handler *handler) { + struct lxc_list *network = &handler->conf->network; struct lxc_list *iterator; struct lxc_netdev *netdev; lxc_list_for_each(iterator, network) { netdev = iterator->elem; - if (netdev->ifindex == 0) - continue; - if (netdev->type == LXC_NET_PHYS) { + if (netdev->ifindex != 0 && netdev->type == LXC_NET_PHYS) { if (lxc_netdev_rename_by_index(netdev->ifindex, netdev->link)) WARN("failed to rename to the initial name the " \ "netdev '%s'", netdev->link); continue; } + if (netdev_deconf[netdev->type](handler, netdev)) { + WARN("failed to destroy netdev"); + } + /* Recent kernel remove the virtual interfaces when the network * namespace is destroyed but in case we did not moved the * interface to the network namespace, we have to destroy it */ - if (lxc_netdev_delete_by_index(netdev->ifindex)) + if (netdev->ifindex != 0 && + lxc_netdev_delete_by_index(netdev->ifindex)) WARN("failed to remove interface '%s'", netdev->name); } } @@ -1877,6 +2625,73 @@ return 0; } +static int write_id_mapping(enum idtype idtype, pid_t pid, const char *buf, + size_t buf_size) +{ + char path[PATH_MAX]; + int ret, closeret; + FILE *f; + + ret = snprintf(path, PATH_MAX, "/proc/%d/%cid_map", pid, idtype == ID_TYPE_UID ? 'u' : 'g'); + if (ret < 0 || ret >= PATH_MAX) { + fprintf(stderr, "%s: path name too long", __func__); + return -E2BIG; + } + f = fopen(path, "w"); + if (!f) { + perror("open"); + return -EINVAL; + } + ret = fwrite(buf, buf_size, 1, f); + if (ret < 0) + SYSERROR("writing id mapping"); + closeret = fclose(f); + if (closeret) + SYSERROR("writing id mapping"); + return ret < 0 ? ret : closeret; +} + +int lxc_map_ids(struct lxc_list *idmap, pid_t pid) +{ + struct lxc_list *iterator; + struct id_map *map; + int ret = 0; + enum idtype type; + char *buf = NULL, *pos; + + for(type = ID_TYPE_UID; type <= ID_TYPE_GID; type++) { + int left, fill; + + pos = buf; + lxc_list_for_each(iterator, idmap) { + /* The kernel only takes <= 4k for writes to /proc//[ug]id_map */ + if (!buf) + buf = pos = malloc(4096); + if (!buf) + return -ENOMEM; + + map = iterator->elem; + if (map->idtype == type) { + left = 4096 - (pos - buf); + fill = snprintf(pos, left, "%lu %lu %lu\n", + map->nsid, map->hostid, map->range); + if (fill <= 0 || fill >= left) + SYSERROR("snprintf failed, too many mappings"); + pos += fill; + } + } + if (pos == buf) // no mappings were found + continue; + ret = write_id_mapping(type, pid, buf, pos-buf); + if (ret) + break; + } + + if (buf) + free(buf); + return ret; +} + int lxc_find_gateway_addresses(struct lxc_handler *handler) { struct lxc_list *network = &handler->conf->network; @@ -1985,8 +2800,99 @@ tty_info->nbtty = 0; } -int lxc_setup(const char *name, struct lxc_conf *lxc_conf) +/* + * given a host uid, return the ns uid if it is mapped. + * if it is not mapped, return the original host id. + */ +static int shiftid(struct lxc_conf *c, int uid, enum idtype w) { + struct lxc_list *iterator; + struct id_map *map; + int low, high; + + lxc_list_for_each(iterator, &c->id_map) { + map = iterator->elem; + if (map->idtype != w) + continue; + + low = map->nsid; + high = map->nsid + map->range; + if (uid < low || uid >= high) + continue; + + return uid - low + map->hostid; + } + + return uid; +} + +/* + * Take a pathname for a file created on the host, and map the uid and gid + * into the container if needed. (Used for ttys) + */ +static int uid_shift_file(char *path, struct lxc_conf *c) +{ + struct stat statbuf; + int newuid, newgid; + + if (stat(path, &statbuf)) { + SYSERROR("stat(%s)", path); + return -1; + } + + newuid = shiftid(c, statbuf.st_uid, ID_TYPE_UID); + newgid = shiftid(c, statbuf.st_gid, ID_TYPE_GID); + if (newuid != statbuf.st_uid || newgid != statbuf.st_gid) { + DEBUG("chowning %s from %d:%d to %d:%d\n", path, (int)statbuf.st_uid, (int)statbuf.st_gid, newuid, newgid); + if (chown(path, newuid, newgid)) { + SYSERROR("chown(%s)", path); + return -1; + } + } + return 0; +} + +int uid_shift_ttys(int pid, struct lxc_conf *conf) +{ + int i, ret; + struct lxc_tty_info *tty_info = &conf->tty_info; + char path[MAXPATHLEN]; + char *ttydir = conf->ttydir; + + if (!conf->rootfs.path) + return 0; + /* first the console */ + ret = snprintf(path, sizeof(path), "/proc/%d/root/dev/%s/console", pid, ttydir ? ttydir : ""); + if (ret < 0 || ret >= sizeof(path)) { + ERROR("console path too long\n"); + return -1; + } + if (uid_shift_file(path, conf)) { + DEBUG("Failed to chown the console %s.\n", path); + return -1; + } + for (i=0; i< tty_info->nbtty; i++) { + ret = snprintf(path, sizeof(path), "/proc/%d/root/dev/%s/tty%d", + pid, ttydir ? ttydir : "", i + 1); + if (ret < 0 || ret >= sizeof(path)) { + ERROR("pathname too long for ttys"); + return -1; + } + if (uid_shift_file(path, conf)) { + DEBUG("Failed to chown pty %s.\n", path); + return -1; + } + } + + return 0; +} + +int lxc_setup(const char *name, struct lxc_conf *lxc_conf, const char *lxcpath) +{ +#if HAVE_APPARMOR /* || HAVE_SMACK || HAVE_SELINUX */ + int mounted; +#endif + if (setup_utsname(lxc_conf->utsname)) { ERROR("failed to setup the utsname for '%s'", name); return -1; @@ -1997,36 +2903,83 @@ return -1; } - if (setup_rootfs(&lxc_conf->rootfs)) { + if (run_lxc_hooks(name, "pre-mount", lxc_conf, lxcpath, NULL)) { + ERROR("failed to run pre-mount hooks for container '%s'.", name); + return -1; + } + + if (setup_rootfs(lxc_conf)) { ERROR("failed to setup rootfs for '%s'", name); return -1; } - if (setup_mount(&lxc_conf->rootfs, lxc_conf->fstab)) { + if (lxc_conf->autodev) { + if (mount_autodev(lxc_conf->rootfs.mount)) { + ERROR("failed to mount /dev in the container"); + return -1; + } + } + + if (setup_mount(&lxc_conf->rootfs, lxc_conf->fstab, name)) { ERROR("failed to setup the mounts for '%s'", name); return -1; } - if (setup_mount_entries(&lxc_conf->rootfs, &lxc_conf->mount_list)) { + if (!lxc_list_empty(&lxc_conf->mount_list) && setup_mount_entries(&lxc_conf->rootfs, &lxc_conf->mount_list, name)) { ERROR("failed to setup the mount entries for '%s'", name); return -1; } - if (setup_cgroup(name, &lxc_conf->cgroup)) { - ERROR("failed to setup the cgroups for '%s'", name); + if (run_lxc_hooks(name, "mount", lxc_conf, lxcpath, NULL)) { + ERROR("failed to run mount hooks for container '%s'.", name); return -1; } - if (setup_console(&lxc_conf->rootfs, &lxc_conf->console, lxc_conf->ttydir)) { + if (lxc_conf->autodev) { + if (run_lxc_hooks(name, "autodev", lxc_conf, lxcpath, NULL)) { + ERROR("failed to run autodev hooks for container '%s'.", name); + return -1; + } + if (setup_autodev(lxc_conf->rootfs.mount)) { + ERROR("failed to populate /dev in the container"); + return -1; + } + } + + if (!lxc_conf->is_execute && setup_console(&lxc_conf->rootfs, &lxc_conf->console, lxc_conf->ttydir)) { ERROR("failed to setup the console for '%s'", name); return -1; } - if (setup_tty(&lxc_conf->rootfs, &lxc_conf->tty_info, lxc_conf->ttydir)) { + if (lxc_conf->kmsg) { + if (setup_kmsg(&lxc_conf->rootfs, &lxc_conf->console)) // don't fail + ERROR("failed to setup kmsg for '%s'", name); + } + + if (!lxc_conf->is_execute && setup_tty(&lxc_conf->rootfs, &lxc_conf->tty_info, lxc_conf->ttydir)) { ERROR("failed to setup the ttys for '%s'", name); return -1; } +#if HAVE_APPARMOR /* || HAVE_SMACK || HAVE_SELINUX */ + INFO("rootfs path is .%s., mount is .%s.", lxc_conf->rootfs.path, + lxc_conf->rootfs.mount); + if (lxc_conf->rootfs.path == NULL || strlen(lxc_conf->rootfs.path) == 0) { + if (mount("proc", "/proc", "proc", 0, NULL)) { + SYSERROR("Failed mounting /proc, proceeding"); + mounted = 0; + } else + mounted = 1; + } else + mounted = lsm_mount_proc_if_needed(lxc_conf->rootfs.path, lxc_conf->rootfs.mount); + if (mounted == -1) { + SYSERROR("failed to mount /proc in the container."); + return -1; + } else if (mounted == 1) { + lxc_conf->lsm_umount_proc = 1; + } +#endif + if (setup_pivot_root(&lxc_conf->rootfs)) { ERROR("failed to set rootfs for '%s'", name); return -1; @@ -2042,12 +2995,331 @@ return -1; } - if (setup_caps(&lxc_conf->caps)) { - ERROR("failed to drop capabilities"); - return -1; + if (lxc_list_empty(&lxc_conf->id_map)) { + if (!lxc_list_empty(&lxc_conf->keepcaps)) { + if (!lxc_list_empty(&lxc_conf->caps)) { + ERROR("Simultaneously requested dropping and keeping caps"); + return -1; + } + if (dropcaps_except(&lxc_conf->keepcaps)) { + ERROR("failed to keep requested caps\n"); + return -1; + } + } else if (setup_caps(&lxc_conf->caps)) { + ERROR("failed to drop capabilities"); + return -1; + } } NOTICE("'%s' is setup.", name); return 0; } + +int run_lxc_hooks(const char *name, char *hook, struct lxc_conf *conf, + const char *lxcpath, char *argv[]) +{ + int which = -1; + struct lxc_list *it; + + if (strcmp(hook, "pre-start") == 0) + which = LXCHOOK_PRESTART; + else if (strcmp(hook, "pre-mount") == 0) + which = LXCHOOK_PREMOUNT; + else if (strcmp(hook, "mount") == 0) + which = LXCHOOK_MOUNT; + else if (strcmp(hook, "autodev") == 0) + which = LXCHOOK_AUTODEV; + else if (strcmp(hook, "start") == 0) + which = LXCHOOK_START; + else if (strcmp(hook, "post-stop") == 0) + which = LXCHOOK_POSTSTOP; + else if (strcmp(hook, "clone") == 0) + which = LXCHOOK_CLONE; + else + return -1; + lxc_list_for_each(it, &conf->hooks[which]) { + int ret; + char *hookname = it->elem; + ret = run_script_argv(name, "lxc", hookname, hook, lxcpath, argv); + if (ret) + return ret; + } + return 0; +} + +static void lxc_remove_nic(struct lxc_list *it) +{ + struct lxc_netdev *netdev = it->elem; + struct lxc_list *it2,*next; + + lxc_list_del(it); + + if (netdev->link) + free(netdev->link); + if (netdev->name) + free(netdev->name); + if (netdev->upscript) + free(netdev->upscript); + if (netdev->hwaddr) + free(netdev->hwaddr); + if (netdev->mtu) + free(netdev->mtu); + if (netdev->ipv4_gateway) + free(netdev->ipv4_gateway); + if (netdev->ipv6_gateway) + free(netdev->ipv6_gateway); + lxc_list_for_each_safe(it2, &netdev->ipv4, next) { + lxc_list_del(it2); + free(it2->elem); + free(it2); + } + lxc_list_for_each_safe(it2, &netdev->ipv6, next) { + lxc_list_del(it2); + free(it2->elem); + free(it2); + } + free(netdev); + free(it); +} + +/* we get passed in something like '0', '0.ipv4' or '1.ipv6' */ +int lxc_clear_nic(struct lxc_conf *c, const char *key) +{ + char *p1; + int ret, idx, i; + struct lxc_list *it; + struct lxc_netdev *netdev; + + p1 = index(key, '.'); + if (!p1 || *(p1+1) == '\0') + p1 = NULL; + + ret = sscanf(key, "%d", &idx); + if (ret != 1) return -1; + if (idx < 0) + return -1; + + i = 0; + lxc_list_for_each(it, &c->network) { + if (i == idx) + break; + i++; + } + if (i < idx) // we don't have that many nics defined + return -1; + + if (!it || !it->elem) + return -1; + + netdev = it->elem; + + if (!p1) { + lxc_remove_nic(it); + } else if (strcmp(p1, "ipv4") == 0) { + struct lxc_list *it2,*next; + lxc_list_for_each_safe(it2, &netdev->ipv4, next) { + lxc_list_del(it2); + free(it2->elem); + free(it2); + } + } else if (strcmp(p1, "ipv6") == 0) { + struct lxc_list *it2,*next; + lxc_list_for_each_safe(it2, &netdev->ipv6, next) { + lxc_list_del(it2); + free(it2->elem); + free(it2); + } + } else if (strcmp(p1, "link") == 0) { + if (netdev->link) { + free(netdev->link); + netdev->link = NULL; + } + } else if (strcmp(p1, "name") == 0) { + if (netdev->name) { + free(netdev->name); + netdev->name = NULL; + } + } else if (strcmp(p1, "script.up") == 0) { + if (netdev->upscript) { + free(netdev->upscript); + netdev->upscript = NULL; + } + } else if (strcmp(p1, "hwaddr") == 0) { + if (netdev->hwaddr) { + free(netdev->hwaddr); + netdev->hwaddr = NULL; + } + } else if (strcmp(p1, "mtu") == 0) { + if (netdev->mtu) { + free(netdev->mtu); + netdev->mtu = NULL; + } + } else if (strcmp(p1, "ipv4_gateway") == 0) { + if (netdev->ipv4_gateway) { + free(netdev->ipv4_gateway); + netdev->ipv4_gateway = NULL; + } + } else if (strcmp(p1, "ipv6_gateway") == 0) { + if (netdev->ipv6_gateway) { + free(netdev->ipv6_gateway); + netdev->ipv6_gateway = NULL; + } + } + else return -1; + + return 0; +} + +int lxc_clear_config_network(struct lxc_conf *c) +{ + struct lxc_list *it,*next; + lxc_list_for_each_safe(it, &c->network, next) { + lxc_remove_nic(it); + } + return 0; +} + +int lxc_clear_config_caps(struct lxc_conf *c) +{ + struct lxc_list *it,*next; + + lxc_list_for_each_safe(it, &c->caps, next) { + lxc_list_del(it); + free(it->elem); + free(it); + } + return 0; +} + +int lxc_clear_idmaps(struct lxc_conf *c) +{ + struct lxc_list *it, *next; + + lxc_list_for_each_safe(it, &c->id_map, next) { + lxc_list_del(it); + free(it->elem); + free(it); + } + return 0; +} + +int lxc_clear_config_keepcaps(struct lxc_conf *c) +{ + struct lxc_list *it,*next; + + lxc_list_for_each_safe(it, &c->keepcaps, next) { + lxc_list_del(it); + free(it->elem); + free(it); + } + return 0; +} + +int lxc_clear_cgroups(struct lxc_conf *c, const char *key) +{ + struct lxc_list *it,*next; + bool all = false; + const char *k = key + 11; + + if (strcmp(key, "lxc.cgroup") == 0) + all = true; + + lxc_list_for_each_safe(it, &c->cgroup, next) { + struct lxc_cgroup *cg = it->elem; + if (!all && strcmp(cg->subsystem, k) != 0) + continue; + lxc_list_del(it); + free(cg->subsystem); + free(cg->value); + free(cg); + free(it); + } + return 0; +} + +int lxc_clear_mount_entries(struct lxc_conf *c) +{ + struct lxc_list *it,*next; + + lxc_list_for_each_safe(it, &c->mount_list, next) { + lxc_list_del(it); + free(it->elem); + free(it); + } + return 0; +} + +int lxc_clear_hooks(struct lxc_conf *c, const char *key) +{ + struct lxc_list *it,*next; + bool all = false, done = false; + const char *k = key + 9; + int i; + + if (strcmp(key, "lxc.hook") == 0) + all = true; + + for (i=0; ihooks[i], next) { + lxc_list_del(it); + free(it->elem); + free(it); + } + done = true; + } + } + + if (!done) { + ERROR("Invalid hook key: %s", key); + return -1; + } + return 0; +} + +void lxc_clear_saved_nics(struct lxc_conf *conf) +{ + int i; + + if (!conf->num_savednics) + return; + for (i=0; i < conf->num_savednics; i++) + free(conf->saved_nics[i].orig_name); + conf->saved_nics = 0; + free(conf->saved_nics); +} + +void lxc_conf_free(struct lxc_conf *conf) +{ + if (!conf) + return; + if (conf->console.path) + free(conf->console.path); + if (conf->rootfs.mount) + free(conf->rootfs.mount); + if (conf->rootfs.path) + free(conf->rootfs.path); + if (conf->utsname) + free(conf->utsname); + if (conf->ttydir) + free(conf->ttydir); + if (conf->fstab) + free(conf->fstab); + if (conf->rcfile) + free(conf->rcfile); + lxc_clear_config_network(conf); +#if HAVE_APPARMOR + if (conf->aa_profile) + free(conf->aa_profile); +#endif + lxc_seccomp_free(conf); + lxc_clear_config_caps(conf); + lxc_clear_config_keepcaps(conf); + lxc_clear_cgroups(conf, "lxc.cgroup"); + lxc_clear_hooks(conf, "lxc.hook"); + lxc_clear_mount_entries(conf); + lxc_clear_saved_nics(conf); + lxc_clear_idmaps(conf); + free(conf); +} diff -Nru lxc-0.8.0~rc1/src/lxc/conf.h lxc-1.0.0~alpha1/src/lxc/conf.h --- lxc-0.8.0~rc1/src/lxc/conf.h 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/conf.h 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,19 +18,27 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _conf_h #define _conf_h +#include "config.h" + #include +#include #include +#include #include #include #include /* for lxc_handler */ +#if HAVE_SCMP_FILTER_CTX +typedef void * scmp_filter_ctx; +#endif + enum { LXC_NET_EMPTY, LXC_NET_VETH, @@ -76,13 +84,14 @@ struct ifla_veth { char *pair; /* pair name */ + char veth1[IFNAMSIZ]; /* needed for deconf */ }; struct ifla_vlan { uint flags; uint fmask; - ushort vid; - ushort pad; + unsigned short vid; + unsigned short pad; }; struct ifla_macvlan { @@ -103,6 +112,7 @@ * @ipv4 : a list of ipv4 addresses to be set on the network device * @ipv6 : a list of ipv6 addresses to be set on the network device * @upscript : a script filename to be executed during interface configuration + * @downscript : a script filename to be executed during interface destruction */ struct lxc_netdev { int type; @@ -120,6 +130,7 @@ struct in6_addr *ipv6_gateway; bool ipv6_gateway_auto; char *upscript; + char *downscript; }; /* @@ -133,6 +144,26 @@ char *value; }; +enum idtype { + ID_TYPE_UID, + ID_TYPE_GID +}; + +/* + * id_map is an id map entry. Form in confile is: + * lxc.id_map = u 0 9800 100 + * lxc.id_map = u 1000 9900 100 + * lxc.id_map = g 0 9800 100 + * lxc.id_map = g 1000 9900 100 + * meaning the container can use uids and gids 0-99 and 1000-1099, + * with [ug]id 0 mapping to [ug]id 9800 on the host, and [ug]id 1000 to + * [ug]id 9900 on the host. + */ +struct id_map { + enum idtype idtype; + unsigned long hostid, nsid, range; +}; + /* * Defines a structure containing a pty information for * virtualizing a tty @@ -157,6 +188,8 @@ struct lxc_pty_info *pty_info; }; +struct lxc_tty_state; + /* * Defines the structure to store the console information * @peer : the file descriptor put/get console traffic @@ -166,9 +199,14 @@ int slave; int master; int peer; + struct lxc_pty_info peerpty; + struct lxc_epoll_descr *descr; char *path; + char *log_path; + int log_fd; char name[MAXPATHLEN]; struct termios *tios; + struct lxc_tty_state *tty_state; }; /* @@ -194,12 +232,27 @@ * @network : network configuration * @utsname : container utsname * @fstab : path to a fstab file format - * @caps : list of the capabilities + * @caps : list of the capabilities to drop + * @keepcaps : list of the capabilities to keep * @tty_info : tty data * @console : console data * @ttydir : directory (under /dev) in which to create console and ttys +#if HAVE_APPARMOR + * @aa_profile : apparmor profile to switch to +#endif */ +enum lxchooks { + LXCHOOK_PRESTART, LXCHOOK_PREMOUNT, LXCHOOK_MOUNT, LXCHOOK_AUTODEV, + LXCHOOK_START, LXCHOOK_POSTSTOP, LXCHOOK_CLONE, NUM_LXC_HOOKS}; +extern char *lxchook_names[NUM_LXC_HOOKS]; + +struct saved_nic { + int ifindex; + char *orig_name; +}; + struct lxc_conf { + int is_execute; char *fstab; int tty; int pts; @@ -208,32 +261,83 @@ int personality; struct utsname *utsname; struct lxc_list cgroup; + struct lxc_list id_map; struct lxc_list network; + struct saved_nic *saved_nics; + int num_savednics; struct lxc_list mount_list; struct lxc_list caps; + struct lxc_list keepcaps; struct lxc_tty_info tty_info; struct lxc_console console; struct lxc_rootfs rootfs; char *ttydir; int close_all_fds; + struct lxc_list hooks[NUM_LXC_HOOKS]; +#if HAVE_APPARMOR + char *aa_profile; +#endif + +#if HAVE_APPARMOR /* || HAVE_SELINUX || HAVE_SMACK */ + int lsm_umount_proc; +#endif + char *seccomp; // filename with the seccomp rules +#if HAVE_SCMP_FILTER_CTX + scmp_filter_ctx *seccomp_ctx; +#endif + int maincmd_fd; + int autodev; // if 1, mount and fill a /dev at start + int stopsignal; // signal used to stop container + int kmsg; // if 1, create /dev/kmsg symlink + char *rcfile; // Copy of the top level rcfile we read + + // Logfile and logleve can be set in a container config file. + // Those function as defaults. The defaults can be overriden + // by command line. However we don't want the command line + // specified values to be saved on c->save_config(). So we + // store the config file specified values here. + char *logfile; // the logfile as specifed in config + int loglevel; // loglevel as specifed in config (if any) }; +int run_lxc_hooks(const char *name, char *hook, struct lxc_conf *conf, + const char *lxcpath, char *argv[]); + +extern int detect_shared_rootfs(void); + /* * Initialize the lxc configuration structure */ extern struct lxc_conf *lxc_conf_init(void); +extern void lxc_conf_free(struct lxc_conf *conf); + +extern int pin_rootfs(const char *rootfs); extern int lxc_create_network(struct lxc_handler *handler); -extern void lxc_delete_network(struct lxc_list *networks); +extern void lxc_delete_network(struct lxc_handler *handler); extern int lxc_assign_network(struct lxc_list *networks, pid_t pid); +extern int lxc_map_ids(struct lxc_list *idmap, pid_t pid); extern int lxc_find_gateway_addresses(struct lxc_handler *handler); extern int lxc_create_tty(const char *name, struct lxc_conf *conf); extern void lxc_delete_tty(struct lxc_tty_info *tty_info); +extern int lxc_clear_config_network(struct lxc_conf *c); +extern int lxc_clear_nic(struct lxc_conf *c, const char *key); +extern int lxc_clear_config_caps(struct lxc_conf *c); +extern int lxc_clear_config_keepcaps(struct lxc_conf *c); +extern int lxc_clear_cgroups(struct lxc_conf *c, const char *key); +extern int lxc_clear_mount_entries(struct lxc_conf *c); +extern int lxc_clear_hooks(struct lxc_conf *c, const char *key); + +extern int uid_shift_ttys(int pid, struct lxc_conf *conf); + /* * Configure the container from inside */ -extern int lxc_setup(const char *name, struct lxc_conf *lxc_conf); +extern int lxc_setup(const char *name, struct lxc_conf *lxc_conf, + const char *lxcpath); + +extern void lxc_rename_phys_nics_on_shutdown(struct lxc_conf *conf); #endif diff -Nru lxc-0.8.0~rc1/src/lxc/confile.c lxc-1.0.0~alpha1/src/lxc/confile.c --- lxc-0.8.0~rc1/src/lxc/confile.c 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/confile.c 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,79 +18,107 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#define _GNU_SOURCE #include #include #include #include #include #include -#include +#include +#include #include #include #include #include -#include #include #include #include #include "parse.h" +#include "config.h" #include "confile.h" #include "utils.h" #include #include +#include "network.h" -lxc_log_define(lxc_confile, lxc); - -static int config_personality(const char *, char *, struct lxc_conf *); -static int config_pts(const char *, char *, struct lxc_conf *); -static int config_tty(const char *, char *, struct lxc_conf *); -static int config_ttydir(const char *, char *, struct lxc_conf *); -static int config_cgroup(const char *, char *, struct lxc_conf *); -static int config_mount(const char *, char *, struct lxc_conf *); -static int config_rootfs(const char *, char *, struct lxc_conf *); -static int config_rootfs_mount(const char *, char *, struct lxc_conf *); -static int config_pivotdir(const char *, char *, struct lxc_conf *); -static int config_utsname(const char *, char *, struct lxc_conf *); -static int config_network_type(const char *, char *, struct lxc_conf *); -static int config_network_flags(const char *, char *, struct lxc_conf *); -static int config_network_link(const char *, char *, struct lxc_conf *); -static int config_network_name(const char *, char *, struct lxc_conf *); -static int config_network_veth_pair(const char *, char *, struct lxc_conf *); -static int config_network_macvlan_mode(const char *, char *, struct lxc_conf *); -static int config_network_hwaddr(const char *, char *, struct lxc_conf *); -static int config_network_vlan_id(const char *, char *, struct lxc_conf *); -static int config_network_mtu(const char *, char *, struct lxc_conf *); -static int config_network_ipv4(const char *, char *, struct lxc_conf *); -static int config_network_ipv4_gateway(const char *, char *, struct lxc_conf *); -static int config_network_script(const char *, char *, struct lxc_conf *); -static int config_network_ipv6(const char *, char *, struct lxc_conf *); -static int config_network_ipv6_gateway(const char *, char *, struct lxc_conf *); -static int config_cap_drop(const char *, char *, struct lxc_conf *); -static int config_console(const char *, char *, struct lxc_conf *); +#if HAVE_SYS_PERSONALITY_H +#include +#endif -typedef int (*config_cb)(const char *, char *, struct lxc_conf *); +lxc_log_define(lxc_confile, lxc); -struct config { - char *name; - config_cb cb; -}; +static int config_personality(const char *, const char *, struct lxc_conf *); +static int config_pts(const char *, const char *, struct lxc_conf *); +static int config_tty(const char *, const char *, struct lxc_conf *); +static int config_ttydir(const char *, const char *, struct lxc_conf *); +static int config_kmsg(const char *, const char *, struct lxc_conf *); +#if HAVE_APPARMOR +static int config_aa_profile(const char *, const char *, struct lxc_conf *); +#endif +static int config_cgroup(const char *, const char *, struct lxc_conf *); +static int config_idmap(const char *, const char *, struct lxc_conf *); +static int config_loglevel(const char *, const char *, struct lxc_conf *); +static int config_logfile(const char *, const char *, struct lxc_conf *); +static int config_mount(const char *, const char *, struct lxc_conf *); +static int config_rootfs(const char *, const char *, struct lxc_conf *); +static int config_rootfs_mount(const char *, const char *, struct lxc_conf *); +static int config_pivotdir(const char *, const char *, struct lxc_conf *); +static int config_utsname(const char *, const char *, struct lxc_conf *); +static int config_hook(const char *, const char *, struct lxc_conf *lxc_conf); +static int config_network_type(const char *, const char *, struct lxc_conf *); +static int config_network_flags(const char *, const char *, struct lxc_conf *); +static int config_network_link(const char *, const char *, struct lxc_conf *); +static int config_network_name(const char *, const char *, struct lxc_conf *); +static int config_network_veth_pair(const char *, const char *, struct lxc_conf *); +static int config_network_macvlan_mode(const char *, const char *, struct lxc_conf *); +static int config_network_hwaddr(const char *, const char *, struct lxc_conf *); +static int config_network_vlan_id(const char *, const char *, struct lxc_conf *); +static int config_network_mtu(const char *, const char *, struct lxc_conf *); +static int config_network_ipv4(const char *, const char *, struct lxc_conf *); +static int config_network_ipv4_gateway(const char *, const char *, struct lxc_conf *); +static int config_network_script(const char *, const char *, struct lxc_conf *); +static int config_network_ipv6(const char *, const char *, struct lxc_conf *); +static int config_network_ipv6_gateway(const char *, const char *, struct lxc_conf *); +static int config_cap_drop(const char *, const char *, struct lxc_conf *); +static int config_cap_keep(const char *, const char *, struct lxc_conf *); +static int config_console(const char *, const char *, struct lxc_conf *); +static int config_seccomp(const char *, const char *, struct lxc_conf *); +static int config_includefile(const char *, const char *, struct lxc_conf *); +static int config_network_nic(const char *, const char *, struct lxc_conf *); +static int config_autodev(const char *, const char *, struct lxc_conf *); +static int config_stopsignal(const char *, const char *, struct lxc_conf *); -static struct config config[] = { +static struct lxc_config_t config[] = { { "lxc.arch", config_personality }, { "lxc.pts", config_pts }, { "lxc.tty", config_tty }, { "lxc.devttydir", config_ttydir }, + { "lxc.kmsg", config_kmsg }, +#if HAVE_APPARMOR + { "lxc.aa_profile", config_aa_profile }, +#endif { "lxc.cgroup", config_cgroup }, + { "lxc.id_map", config_idmap }, + { "lxc.loglevel", config_loglevel }, + { "lxc.logfile", config_logfile }, { "lxc.mount", config_mount }, { "lxc.rootfs.mount", config_rootfs_mount }, { "lxc.rootfs", config_rootfs }, { "lxc.pivotdir", config_pivotdir }, { "lxc.utsname", config_utsname }, + { "lxc.hook.pre-start", config_hook }, + { "lxc.hook.pre-mount", config_hook }, + { "lxc.hook.mount", config_hook }, + { "lxc.hook.autodev", config_hook }, + { "lxc.hook.start", config_hook }, + { "lxc.hook.post-stop", config_hook }, + { "lxc.hook.clone", config_hook }, { "lxc.network.type", config_network_type }, { "lxc.network.flags", config_network_flags }, { "lxc.network.link", config_network_link }, @@ -98,6 +126,7 @@ { "lxc.network.macvlan.mode", config_network_macvlan_mode }, { "lxc.network.veth.pair", config_network_veth_pair }, { "lxc.network.script.up", config_network_script }, + { "lxc.network.script.down", config_network_script }, { "lxc.network.hwaddr", config_network_hwaddr }, { "lxc.network.mtu", config_network_mtu }, { "lxc.network.vlan.id", config_network_vlan_id }, @@ -105,13 +134,47 @@ { "lxc.network.ipv4", config_network_ipv4 }, { "lxc.network.ipv6.gateway", config_network_ipv6_gateway }, { "lxc.network.ipv6", config_network_ipv6 }, + /* config_network_nic must come after all other 'lxc.network.*' entries */ + { "lxc.network.", config_network_nic }, { "lxc.cap.drop", config_cap_drop }, + { "lxc.cap.keep", config_cap_keep }, { "lxc.console", config_console }, + { "lxc.seccomp", config_seccomp }, + { "lxc.include", config_includefile }, + { "lxc.autodev", config_autodev }, + { "lxc.stopsignal", config_stopsignal }, }; -static const size_t config_size = sizeof(config)/sizeof(struct config); +struct signame { + int num; + char *name; +}; + +struct signame signames[] = { + { SIGHUP, "HUP" }, + { SIGINT, "INT" }, + { SIGQUIT, "QUIT" }, + { SIGILL, "ILL" }, + { SIGABRT, "ABRT" }, + { SIGFPE, "FPE" }, + { SIGKILL, "KILL" }, + { SIGSEGV, "SEGV" }, + { SIGPIPE, "PIPE" }, + { SIGALRM, "ALRM" }, + { SIGTERM, "TERM" }, + { SIGUSR1, "USR1" }, + { SIGUSR2, "USR2" }, + { SIGCHLD, "CHLD" }, + { SIGCONT, "CONT" }, + { SIGSTOP, "STOP" }, + { SIGTSTP, "TSTP" }, + { SIGTTIN, "TTIN" }, + { SIGTTOU, "TTOU" }, +}; -static struct config *getconfig(const char *key) +static const size_t config_size = sizeof(config)/sizeof(struct lxc_config_t); + +extern struct lxc_config_t *lxc_getconfig(const char *key) { int i; @@ -122,7 +185,77 @@ return NULL; } -static int config_network_type(const char *key, char *value, +#define strprint(str, inlen, ...) \ + do { \ + len = snprintf(str, inlen, ##__VA_ARGS__); \ + if (len < 0) { SYSERROR("snprintf"); return -1; }; \ + fulllen += len; \ + if (inlen > 0) { \ + if (str) str += len; \ + inlen -= len; \ + if (inlen < 0) inlen = 0; \ + } \ + } while (0); + +int lxc_listconfigs(char *retv, int inlen) +{ + int i, fulllen = 0, len; + + if (!retv) + inlen = 0; + else + memset(retv, 0, inlen); + for (i = 0; i < config_size; i++) { + char *s = config[i].name; + if (s[strlen(s)-1] == '.') + continue; + strprint(retv, inlen, "%s\n", s); + } + return fulllen; +} + +/* + * config entry is something like "lxc.network.0.ipv4" + * the key 'lxc.network.' was found. So we make sure next + * comes an integer, find the right callback (by rewriting + * the key), and call it. + */ +static int config_network_nic(const char *key, const char *value, + struct lxc_conf *lxc_conf) +{ + char *copy = strdup(key), *p; + int ret = -1; + struct lxc_config_t *config; + + if (!copy) { + SYSERROR("failed to allocate memory"); + return -1; + } + /* + * ok we know that to get here we've got "lxc.network." + * and it isn't any of the other network entries. So + * after the second . should come an integer (# of defined + * nic) followed by a valid entry. + */ + if (*(key+12) < '0' || *(key+12) > '9') + goto out; + p = index(key+12, '.'); + if (!p) + goto out; + strcpy(copy+12, p+1); + config = lxc_getconfig(copy); + if (!config) { + ERROR("unknown key %s", key); + goto out; + } + ret = config->cb(key, value, lxc_conf); + +out: + free(copy); + return ret; +} + +static int config_network_type(const char *key, const char *value, struct lxc_conf *lxc_conf) { struct lxc_list *network = &lxc_conf->network; @@ -142,6 +275,7 @@ list = malloc(sizeof(*list)); if (!list) { SYSERROR("failed to allocate memory"); + free(netdev); return -1; } @@ -179,10 +313,90 @@ return 0; } +/* + * if you have p="lxc.network.0.link", pass it p+12 + * to get back '0' (the index of the nic) + */ +static int get_network_netdev_idx(const char *key) +{ + int ret, idx; + + if (*key < '0' || *key > '9') + return -1; + ret = sscanf(key, "%d", &idx); + if (ret != 1) + return -1; + return idx; +} + +/* + * if you have p="lxc.network.0", pass this p+12 and it will return + * the netdev of the first configured nic + */ +static struct lxc_netdev *get_netdev_from_key(const char *key, + struct lxc_list *network) +{ + int i = 0, idx = get_network_netdev_idx(key); + struct lxc_netdev *netdev = NULL; + struct lxc_list *it; + if (idx == -1) + return NULL; + lxc_list_for_each(it, network) { + if (idx == i++) { + netdev = it->elem; + break; + } + } + return netdev; +} + +extern int lxc_list_nicconfigs(struct lxc_conf *c, const char *key, + char *retv, int inlen) +{ + struct lxc_netdev *netdev; + int fulllen = 0, len; + + netdev = get_netdev_from_key(key+12, &c->network); + if (!netdev) + return -1; + + if (!retv) + inlen = 0; + else + memset(retv, 0, inlen); + + strprint(retv, inlen, "script.up\n"); + if (netdev->type != LXC_NET_EMPTY) { + strprint(retv, inlen, "flags\n"); + strprint(retv, inlen, "link\n"); + strprint(retv, inlen, "name\n"); + strprint(retv, inlen, "hwaddr\n"); + strprint(retv, inlen, "mtu\n"); + strprint(retv, inlen, "ipv6\n"); + strprint(retv, inlen, "ipv6_gateway\n"); + strprint(retv, inlen, "ipv4\n"); + strprint(retv, inlen, "ipv4_gateway\n"); + } + switch(netdev->type) { + case LXC_NET_VETH: + strprint(retv, inlen, "veth.pair\n"); + break; + case LXC_NET_MACVLAN: + strprint(retv, inlen, "macvlan.mode\n"); + break; + case LXC_NET_VLAN: + strprint(retv, inlen, "vlan.id\n"); + break; + case LXC_NET_PHYS: + break; + } + return fulllen; +} + static struct lxc_netdev *network_netdev(const char *key, const char *value, struct lxc_list *network) { - struct lxc_netdev *netdev; + struct lxc_netdev *netdev = NULL; if (lxc_list_empty(network)) { ERROR("network is not created for '%s' = '%s' option", @@ -190,7 +404,11 @@ return NULL; } - netdev = lxc_list_last_elem(network); + if (get_network_netdev_idx(key+12) == -1) + netdev = lxc_list_last_elem(network); + else + netdev = get_netdev_from_key(key+12, network); + if (!netdev) { ERROR("no network device defined for '%s' = '%s' option", key, value); @@ -200,10 +418,11 @@ return netdev; } -static int network_ifname(char **valuep, char *value) +static int network_ifname(char **valuep, const char *value) { if (strlen(value) >= IFNAMSIZ) { - ERROR("invalid interface name: %s", value); + ERROR("interface name '%s' too long (>%d)\n", + value, IFNAMSIZ - 1); return -1; } @@ -228,7 +447,7 @@ # define MACVLAN_MODE_BRIDGE 4 #endif -static int macvlan_mode(int *valuep, char *value) +static int macvlan_mode(int *valuep, const char *value) { struct mc_mode { char *name; @@ -252,7 +471,7 @@ return -1; } -static int config_network_flags(const char *key, char *value, +static int config_network_flags(const char *key, const char *value, struct lxc_conf *lxc_conf) { struct lxc_netdev *netdev; @@ -266,7 +485,7 @@ return 0; } -static int config_network_link(const char *key, char *value, +static int config_network_link(const char *key, const char *value, struct lxc_conf *lxc_conf) { struct lxc_netdev *netdev; @@ -278,7 +497,7 @@ return network_ifname(&netdev->link, value); } -static int config_network_name(const char *key, char *value, +static int config_network_name(const char *key, const char *value, struct lxc_conf *lxc_conf) { struct lxc_netdev *netdev; @@ -290,7 +509,7 @@ return network_ifname(&netdev->name, value); } -static int config_network_veth_pair(const char *key, char *value, +static int config_network_veth_pair(const char *key, const char *value, struct lxc_conf *lxc_conf) { struct lxc_netdev *netdev; @@ -302,7 +521,7 @@ return network_ifname(&netdev->priv.veth_attr.pair, value); } -static int config_network_macvlan_mode(const char *key, char *value, +static int config_network_macvlan_mode(const char *key, const char *value, struct lxc_conf *lxc_conf) { struct lxc_netdev *netdev; @@ -314,25 +533,29 @@ return macvlan_mode(&netdev->priv.macvlan_attr.mode, value); } -static int config_network_hwaddr(const char *key, char *value, +static int config_network_hwaddr(const char *key, const char *value, struct lxc_conf *lxc_conf) { struct lxc_netdev *netdev; + char *hwaddr; netdev = network_netdev(key, value, &lxc_conf->network); if (!netdev) return -1; - netdev->hwaddr = strdup(value); - if (!netdev->hwaddr) { + hwaddr = strdup(value); + if (!hwaddr) { SYSERROR("failed to dup string '%s'", value); return -1; } + if (netdev->hwaddr) + free(netdev->hwaddr); + netdev->hwaddr = hwaddr; return 0; } -static int config_network_vlan_id(const char *key, char *value, +static int config_network_vlan_id(const char *key, const char *value, struct lxc_conf *lxc_conf) { struct lxc_netdev *netdev; @@ -347,25 +570,29 @@ return 0; } -static int config_network_mtu(const char *key, char *value, +static int config_network_mtu(const char *key, const char *value, struct lxc_conf *lxc_conf) { struct lxc_netdev *netdev; + char *mtu; netdev = network_netdev(key, value, &lxc_conf->network); if (!netdev) return -1; - netdev->mtu = strdup(value); - if (!netdev->mtu) { + mtu = strdup(value); + if (!mtu) { SYSERROR("failed to dup string '%s'", value); return -1; } + if (netdev->mtu) + free(netdev->mtu); + netdev->mtu = mtu; return 0; } -static int config_network_ipv4(const char *key, char *value, +static int config_network_ipv4(const char *key, const char *value, struct lxc_conf *lxc_conf) { struct lxc_netdev *netdev; @@ -387,13 +614,20 @@ list = malloc(sizeof(*list)); if (!list) { SYSERROR("failed to allocate memory"); + free(inetdev); return -1; } lxc_list_init(list); list->elem = inetdev; - addr = value; + addr = strdup(value); + if (!addr) { + ERROR("no address specified"); + free(inetdev); + free(list); + return -1; + } cursor = strstr(addr, " "); if (cursor) { @@ -407,18 +641,19 @@ prefix = slash + 1; } - if (!addr) { - ERROR("no address specified"); - return -1; - } - if (!inet_pton(AF_INET, addr, &inetdev->addr)) { SYSERROR("invalid ipv4 address: %s", value); + free(inetdev); + free(addr); + free(list); return -1; } if (bcast && !inet_pton(AF_INET, bcast, &inetdev->bcast)) { SYSERROR("invalid ipv4 broadcast address: %s", value); + free(inetdev); + free(list); + free(addr); return -1; } @@ -435,12 +670,13 @@ htonl(INADDR_BROADCAST >> inetdev->prefix); } - lxc_list_add(&netdev->ipv4, list); + lxc_list_add_tail(&netdev->ipv4, list); + free(addr); return 0; } -static int config_network_ipv4_gateway(const char *key, char *value, +static int config_network_ipv4_gateway(const char *key, const char *value, struct lxc_conf *lxc_conf) { struct lxc_netdev *netdev; @@ -458,6 +694,7 @@ if (!value) { ERROR("no ipv4 gateway address specified"); + free(gw); return -1; } @@ -467,6 +704,7 @@ } else { if (!inet_pton(AF_INET, value, gw)) { SYSERROR("invalid ipv4 gateway address: %s", value); + free(gw); return -1; } @@ -477,13 +715,13 @@ return 0; } -static int config_network_ipv6(const char *key, char *value, +static int config_network_ipv6(const char *key, const char *value, struct lxc_conf *lxc_conf) { struct lxc_netdev *netdev; struct lxc_inet6dev *inet6dev; struct lxc_list *list; - char *slash; + char *slash,*valdup; char *netmask; netdev = network_netdev(key, value, &lxc_conf->network); @@ -500,46 +738,52 @@ list = malloc(sizeof(*list)); if (!list) { SYSERROR("failed to allocate memory"); + free(inet6dev); return -1; } lxc_list_init(list); list->elem = inet6dev; + valdup = strdup(value); + if (!valdup) { + ERROR("no address specified"); + free(list); + free(inet6dev); + return -1; + } + inet6dev->prefix = 64; - slash = strstr(value, "/"); + slash = strstr(valdup, "/"); if (slash) { *slash = '\0'; netmask = slash + 1; inet6dev->prefix = atoi(netmask); } - if (!inet_pton(AF_INET6, value, &inet6dev->addr)) { - SYSERROR("invalid ipv6 address: %s", value); + if (!inet_pton(AF_INET6, valdup, &inet6dev->addr)) { + SYSERROR("invalid ipv6 address: %s", valdup); + free(list); + free(inet6dev); + free(valdup); return -1; } - lxc_list_add(&netdev->ipv6, list); + lxc_list_add_tail(&netdev->ipv6, list); + free(valdup); return 0; } -static int config_network_ipv6_gateway(const char *key, char *value, +static int config_network_ipv6_gateway(const char *key, const char *value, struct lxc_conf *lxc_conf) { struct lxc_netdev *netdev; - struct in6_addr *gw; netdev = network_netdev(key, value, &lxc_conf->network); if (!netdev) return -1; - gw = malloc(sizeof(*gw)); - if (!gw) { - SYSERROR("failed to allocate ipv6 gateway address"); - return -1; - } - if (!value) { ERROR("no ipv6 gateway address specified"); return -1; @@ -549,8 +793,17 @@ netdev->ipv6_gateway = NULL; netdev->ipv6_gateway_auto = true; } else { + struct in6_addr *gw; + + gw = malloc(sizeof(*gw)); + if (!gw) { + SYSERROR("failed to allocate ipv6 gateway address"); + return -1; + } + if (!inet_pton(AF_INET6, value, gw)) { SYSERROR("invalid ipv6 gateway address: %s", value); + free(gw); return -1; } @@ -561,7 +814,7 @@ return 0; } -static int config_network_script(const char *key, char *value, +static int config_network_script(const char *key, const char *value, struct lxc_conf *lxc_conf) { struct lxc_netdev *netdev; @@ -575,16 +828,83 @@ SYSERROR("failed to dup string '%s'", value); return -1; } - if (strcmp(key, "lxc.network.script.up") == 0) { + if (strstr(key, "script.up") != NULL) { netdev->upscript = copy; return 0; } + if (strcmp(key, "lxc.network.script.down") == 0) { + netdev->downscript = copy; + return 0; + } SYSERROR("Unknown key: %s", key); free(copy); return -1; } -static int config_personality(const char *key, char *value, +static int add_hook(struct lxc_conf *lxc_conf, int which, char *hook) +{ + struct lxc_list *hooklist; + + hooklist = malloc(sizeof(*hooklist)); + if (!hooklist) { + free(hook); + return -1; + } + hooklist->elem = hook; + lxc_list_add_tail(&lxc_conf->hooks[which], hooklist); + return 0; +} + +static int config_seccomp(const char *key, const char *value, + struct lxc_conf *lxc_conf) +{ + char *path; + + if (lxc_conf->seccomp) { + ERROR("seccomp already defined"); + return -1; + } + path = strdup(value); + if (!path) { + SYSERROR("failed to strdup '%s': %m", value); + return -1; + } + + if (lxc_conf->seccomp) + free(lxc_conf->seccomp); + lxc_conf->seccomp = path; + + return 0; +} + +static int config_hook(const char *key, const char *value, + struct lxc_conf *lxc_conf) +{ + char *copy = strdup(value); + if (!copy) { + SYSERROR("failed to dup string '%s'", value); + return -1; + } + if (strcmp(key, "lxc.hook.pre-start") == 0) + return add_hook(lxc_conf, LXCHOOK_PRESTART, copy); + else if (strcmp(key, "lxc.hook.pre-mount") == 0) + return add_hook(lxc_conf, LXCHOOK_PREMOUNT, copy); + else if (strcmp(key, "lxc.hook.autodev") == 0) + return add_hook(lxc_conf, LXCHOOK_AUTODEV, copy); + else if (strcmp(key, "lxc.hook.mount") == 0) + return add_hook(lxc_conf, LXCHOOK_MOUNT, copy); + else if (strcmp(key, "lxc.hook.start") == 0) + return add_hook(lxc_conf, LXCHOOK_START, copy); + else if (strcmp(key, "lxc.hook.post-stop") == 0) + return add_hook(lxc_conf, LXCHOOK_POSTSTOP, copy); + else if (strcmp(key, "lxc.hook.clone") == 0) + return add_hook(lxc_conf, LXCHOOK_CLONE, copy); + SYSERROR("Unknown key: %s", key); + free(copy); + return -1; +} + +static int config_personality(const char *key, const const char *value, struct lxc_conf *lxc_conf) { signed long personality = lxc_config_parse_arch(value); @@ -597,7 +917,8 @@ return 0; } -static int config_pts(const char *key, char *value, struct lxc_conf *lxc_conf) +static int config_pts(const char *key, const char *value, + struct lxc_conf *lxc_conf) { int maxpts = atoi(value); @@ -606,7 +927,8 @@ return 0; } -static int config_tty(const char *key, char *value, struct lxc_conf *lxc_conf) +static int config_tty(const char *key, const char *value, + struct lxc_conf *lxc_conf) { int nbtty = atoi(value); @@ -615,7 +937,7 @@ return 0; } -static int config_ttydir(const char *key, char *value, +static int config_ttydir(const char *key, const char *value, struct lxc_conf *lxc_conf) { char *path; @@ -628,12 +950,149 @@ return -1; } + if (lxc_conf->ttydir) + free(lxc_conf->ttydir); lxc_conf->ttydir = path; return 0; } -static int config_cgroup(const char *key, char *value, struct lxc_conf *lxc_conf) +static int config_kmsg(const char *key, const char *value, + struct lxc_conf *lxc_conf) +{ + int v = atoi(value); + + lxc_conf->kmsg = v; + + return 0; +} + +#if HAVE_APPARMOR +static int config_aa_profile(const char *key, const char *value, + struct lxc_conf *lxc_conf) +{ + char *path; + + if (!value || strlen(value) == 0) + return 0; + path = strdup(value); + if (!path) { + SYSERROR("failed to strdup '%s': %m", value); + return -1; + } + + if (lxc_conf->aa_profile) + free(lxc_conf->aa_profile); + lxc_conf->aa_profile = path; + + return 0; +} +#endif + +static int config_logfile(const char *key, const char *value, + struct lxc_conf *lxc_conf) +{ + // store these values in the lxc_conf, and then try to set for + // actual current logging. + if (lxc_conf->logfile) + free(lxc_conf->logfile); + lxc_conf->logfile = strdup(value); + return lxc_log_set_file(value); +} + +static int config_loglevel(const char *key, const char *value, + struct lxc_conf *lxc_conf) +{ + int newlevel; + + if (!value || strlen(value) == 0) + return 0; + + if (lxc_log_get_level() != LXC_LOG_PRIORITY_NOTSET) { + DEBUG("Log level already set - ignoring new value"); + return 0; + } + if (value[0] >= '0' && value[0] <= '9') + newlevel = atoi(value); + else + newlevel = lxc_log_priority_to_int(value); + // store these values in the lxc_conf, and then try to set for + // actual current logging. + lxc_conf->loglevel = newlevel; + return lxc_log_set_level(newlevel); +} + +static int config_autodev(const char *key, const char *value, + struct lxc_conf *lxc_conf) +{ + int v = atoi(value); + + lxc_conf->autodev = v; + + return 0; +} + +static int sig_num(const char *sig) +{ + int n; + char *endp = NULL; + + errno = 0; + n = strtol(sig, &endp, 10); + if (sig == endp || n < 0 || errno != 0) + return -1; + return n; +} + +static int rt_sig_num(const char *signame) +{ + int sig_n = 0; + int rtmax = 0; + + if (strncasecmp(signame, "max-", 4) == 0) { + rtmax = 1; + } + signame += 4; + if (!isdigit(*signame)) + return -1; + sig_n = sig_num(signame); + sig_n = rtmax ? SIGRTMAX - sig_n : SIGRTMIN + sig_n; + if (sig_n > SIGRTMAX || sig_n < SIGRTMIN) + return -1; + return sig_n; +} + +static int sig_parse(const char *signame) { + int n; + + if (isdigit(*signame)) { + return sig_num(signame); + } else if (strncasecmp(signame, "sig", 3) == 0) { + signame += 3; + if (strncasecmp(signame, "rt", 2) == 0) + return rt_sig_num(signame + 2); + for (n = 0; n < sizeof(signames) / sizeof((signames)[0]); n++) { + if (strcasecmp (signames[n].name, signame) == 0) + return signames[n].num; + } + } + return -1; +} + +static int config_stopsignal(const char *key, const char *value, + struct lxc_conf *lxc_conf) +{ + int sig_n = sig_parse(value); + + if (sig_n < 0) + return -1; + lxc_conf->stopsignal = sig_n; + + return 0; +} + +static int config_cgroup(const char *key, const char *value, + struct lxc_conf *lxc_conf) { char *token = "lxc.cgroup."; char *subkey; @@ -691,23 +1150,93 @@ return -1; } -static int config_fstab(const char *key, char *value, struct lxc_conf *lxc_conf) +static int config_idmap(const char *key, const char *value, struct lxc_conf *lxc_conf) { + char *token = "lxc.id_map"; + char *subkey; + struct lxc_list *idmaplist = NULL; + struct id_map *idmap = NULL; + unsigned long hostid, nsid, range; + char type; + int ret; + + subkey = strstr(key, token); + + if (!subkey) + return -1; + + if (!strlen(subkey)) + return -1; + + idmaplist = malloc(sizeof(*idmaplist)); + if (!idmaplist) + goto out; + + idmap = malloc(sizeof(*idmap)); + if (!idmap) + goto out; + memset(idmap, 0, sizeof(*idmap)); + + idmaplist->elem = idmap; + + lxc_list_add_tail(&lxc_conf->id_map, idmaplist); + + ret = sscanf(value, "%c %lu %lu %lu", &type, &nsid, &hostid, &range); + if (ret != 4) + goto out; + INFO("read uid map: type %c nsid %lu hostid %lu range %lu", type, nsid, hostid, range); + if (type == 'u') + idmap->idtype = ID_TYPE_UID; + else if (type == 'g') + idmap->idtype = ID_TYPE_GID; + else + goto out; + idmap->hostid = hostid; + idmap->nsid = nsid; + idmap->range = range; + + return 0; + +out: + if (idmaplist) + free(idmaplist); + + if (idmap) { + free(idmap); + } + + return -1; +} + +static int config_path_item(const char *key, const char *value, + struct lxc_conf *lxc_conf, char **conf_item) +{ + char *valdup; if (strlen(value) >= MAXPATHLEN) { ERROR("%s path is too long", value); return -1; } - lxc_conf->fstab = strdup(value); - if (!lxc_conf->fstab) { + valdup = strdup(value); + if (!valdup) { SYSERROR("failed to duplicate string %s", value); return -1; } + if (*conf_item) + free(*conf_item); + *conf_item = valdup; return 0; } -static int config_mount(const char *key, char *value, struct lxc_conf *lxc_conf) +static int config_fstab(const char *key, const char *value, + struct lxc_conf *lxc_conf) +{ + return config_path_item(key, value, lxc_conf, &lxc_conf->fstab); +} + +static int config_mount(const char *key, const char *value, + struct lxc_conf *lxc_conf) { char *fstab_token = "lxc.mount"; char *token = "lxc.mount.entry"; @@ -734,8 +1263,10 @@ return -1; mntelem = strdup(value); - if (!mntelem) + if (!mntelem) { + free(mntlist); return -1; + } mntlist->elem = mntelem; lxc_list_add_tail(&lxc_conf->mount_list, mntlist); @@ -743,10 +1274,56 @@ return 0; } -static int config_cap_drop(const char *key, char *value, +static int config_cap_keep(const char *key, const char *value, + struct lxc_conf *lxc_conf) +{ + char *keepcaps, *keepptr, *sptr, *token; + struct lxc_list *keeplist; + int ret = -1; + + if (!strlen(value)) + return -1; + + keepcaps = strdup(value); + if (!keepcaps) { + SYSERROR("failed to dup '%s'", value); + return -1; + } + + /* in case several capability keep is specified in a single line + * split these caps in a single element for the list */ + for (keepptr = keepcaps;;keepptr = NULL) { + token = strtok_r(keepptr, " \t", &sptr); + if (!token) { + ret = 0; + break; + } + + keeplist = malloc(sizeof(*keeplist)); + if (!keeplist) { + SYSERROR("failed to allocate keepcap list"); + break; + } + + keeplist->elem = strdup(token); + if (!keeplist->elem) { + SYSERROR("failed to dup '%s'", token); + free(keeplist); + break; + } + + lxc_list_add_tail(&lxc_conf->keepcaps, keeplist); + } + + free(keepcaps); + + return ret; +} + +static int config_cap_drop(const char *key, const char *value, struct lxc_conf *lxc_conf) { - char *dropcaps, *sptr, *token; + char *dropcaps, *dropptr, *sptr, *token; struct lxc_list *droplist; int ret = -1; @@ -761,13 +1338,12 @@ /* in case several capability drop is specified in a single line * split these caps in a single element for the list */ - for (;;) { - token = strtok_r(dropcaps, " \t", &sptr); + for (dropptr = dropcaps;;dropptr = NULL) { + token = strtok_r(dropptr, " \t", &sptr); if (!token) { ret = 0; break; } - dropcaps = NULL; droplist = malloc(sizeof(*droplist)); if (!droplist) { @@ -790,7 +1366,7 @@ return ret; } -static int config_console(const char *key, char *value, +static int config_console(const char *key, const char *value, struct lxc_conf *lxc_conf) { char *path; @@ -801,60 +1377,39 @@ return -1; } + if (lxc_conf->console.path) + free(lxc_conf->console.path); lxc_conf->console.path = path; return 0; } -static int config_rootfs(const char *key, char *value, struct lxc_conf *lxc_conf) +static int config_includefile(const char *key, const char *value, + struct lxc_conf *lxc_conf) { - if (strlen(value) >= MAXPATHLEN) { - ERROR("%s path is too long", value); - return -1; - } - - lxc_conf->rootfs.path = strdup(value); - if (!lxc_conf->rootfs.path) { - SYSERROR("failed to duplicate string %s", value); - return -1; - } - - return 0; + return lxc_config_read(value, lxc_conf); } -static int config_rootfs_mount(const char *key, char *value, struct lxc_conf *lxc_conf) +static int config_rootfs(const char *key, const char *value, + struct lxc_conf *lxc_conf) { - if (strlen(value) >= MAXPATHLEN) { - ERROR("%s path is too long", value); - return -1; - } - - lxc_conf->rootfs.mount = strdup(value); - if (!lxc_conf->rootfs.mount) { - SYSERROR("failed to duplicate string '%s'", value); - return -1; - } - - return 0; + return config_path_item(key, value, lxc_conf, &lxc_conf->rootfs.path); } -static int config_pivotdir(const char *key, char *value, struct lxc_conf *lxc_conf) +static int config_rootfs_mount(const char *key, const char *value, + struct lxc_conf *lxc_conf) { - if (strlen(value) >= MAXPATHLEN) { - ERROR("%s path is too long", value); - return -1; - } - - lxc_conf->rootfs.pivot = strdup(value); - if (!lxc_conf->rootfs.pivot) { - SYSERROR("failed to duplicate string %s", value); - return -1; - } + return config_path_item(key, value, lxc_conf, &lxc_conf->rootfs.mount); +} - return 0; +static int config_pivotdir(const char *key, const char *value, + struct lxc_conf *lxc_conf) +{ + return config_path_item(key, value, lxc_conf, &lxc_conf->rootfs.pivot); } -static int config_utsname(const char *key, char *value, struct lxc_conf *lxc_conf) +static int config_utsname(const char *key, const char *value, + struct lxc_conf *lxc_conf) { struct utsname *utsname; @@ -867,10 +1422,13 @@ if (strlen(value) >= sizeof(utsname->nodename)) { ERROR("node name '%s' is too long", utsname->nodename); + free(utsname); return -1; } strcpy(utsname->nodename, value); + if (lxc_conf->utsname) + free(lxc_conf->utsname); lxc_conf->utsname = utsname; return 0; @@ -878,7 +1436,7 @@ static int parse_line(char *buffer, void *data) { - struct config *config; + struct lxc_config_t *config; char *line, *linep; char *dot; char *key; @@ -923,9 +1481,9 @@ value += lxc_char_left_gc(value, strlen(value)); value[lxc_char_right_gc(value, strlen(value))] = '\0'; - config = getconfig(key); + config = lxc_getconfig(key); if (!config) { - ERROR("unknow key %s", key); + ERROR("unknown key %s", key); goto out; } @@ -943,6 +1501,13 @@ int lxc_config_read(const char *file, struct lxc_conf *conf) { + if( access(file, R_OK) == -1 ) { + return -1; + } + /* Catch only the top level config file name in the structure */ + if( ! conf->rcfile ) { + conf->rcfile = strdup( file ); + } return lxc_file_for_each_line(file, parse_line, conf); } @@ -961,7 +1526,7 @@ int lxc_config_define_load(struct lxc_list *defines, struct lxc_conf *conf) { - struct lxc_list *it; + struct lxc_list *it,*next; int ret = 0; lxc_list_for_each(it, defines) { @@ -970,7 +1535,7 @@ break; } - lxc_list_for_each(it, defines) { + lxc_list_for_each_safe(it, defines, next) { lxc_list_del(it); free(it); } @@ -980,6 +1545,7 @@ signed long lxc_config_parse_arch(const char *arch) { + #if HAVE_SYS_PERSONALITY_H struct per_name { char *name; unsigned long per; @@ -997,6 +1563,483 @@ if (!strcmp(pername[i].name, arch)) return pername[i].per; } + #endif + + return -1; +} + +static int lxc_get_conf_int(struct lxc_conf *c, char *retv, int inlen, int v) +{ + if (!retv) + inlen = 0; + else + memset(retv, 0, inlen); + return snprintf(retv, inlen, "%d", v); +} + +static int lxc_get_arch_entry(struct lxc_conf *c, char *retv, int inlen) +{ + int fulllen = 0; + + if (!retv) + inlen = 0; + else + memset(retv, 0, inlen); + + #if HAVE_SYS_PERSONALITY_H + int len = 0; + + switch(c->personality) { + case PER_LINUX32: strprint(retv, inlen, "x86"); break; + case PER_LINUX: strprint(retv, inlen, "x86_64"); break; + default: break; + } + #endif + + return fulllen; +} + +/* + * If you ask for a specific cgroup value, i.e. lxc.cgroup.devices.list, + * then just the value(s) will be printed. Since there still could be + * more than one, it is newline-separated. + * (Maybe that's ambigous, since some values, i.e. devices.list, will + * already have newlines?) + * If you ask for 'lxc.cgroup", then all cgroup entries will be printed, + * in 'lxc.cgroup.subsystem.key = value' format. + */ +static int lxc_get_cgroup_entry(struct lxc_conf *c, char *retv, int inlen, + const char *key) +{ + int fulllen = 0, len; + int all = 0; + struct lxc_list *it; + + if (!retv) + inlen = 0; + else + memset(retv, 0, inlen); + + if (strcmp(key, "all") == 0) + all = 1; + + lxc_list_for_each(it, &c->cgroup) { + struct lxc_cgroup *cg = it->elem; + if (all) { + strprint(retv, inlen, "lxc.cgroup.%s = %s\n", cg->subsystem, cg->value); + } else if (strcmp(cg->subsystem, key) == 0) { + strprint(retv, inlen, "%s\n", cg->value); + } + } + return fulllen; +} + +static int lxc_get_item_hooks(struct lxc_conf *c, char *retv, int inlen, + const char *key) +{ + char *subkey; + int len, fulllen = 0, found = -1; + struct lxc_list *it; + int i; + + /* "lxc.hook.mount" */ + subkey = index(key, '.'); + if (subkey) subkey = index(subkey+1, '.'); + if (!subkey) + return -1; + subkey++; + if (!*subkey) + return -1; + for (i=0; ihooks[found]) { + strprint(retv, inlen, "%s\n", (char *)it->elem); + } + return fulllen; +} + +static int lxc_get_item_cap_drop(struct lxc_conf *c, char *retv, int inlen) +{ + int len, fulllen = 0; + struct lxc_list *it; + + if (!retv) + inlen = 0; + else + memset(retv, 0, inlen); + + lxc_list_for_each(it, &c->caps) { + strprint(retv, inlen, "%s\n", (char *)it->elem); + } + return fulllen; +} + +static int lxc_get_item_cap_keep(struct lxc_conf *c, char *retv, int inlen) +{ + int len, fulllen = 0; + struct lxc_list *it; + + if (!retv) + inlen = 0; + else + memset(retv, 0, inlen); + + lxc_list_for_each(it, &c->keepcaps) { + strprint(retv, inlen, "%s\n", (char *)it->elem); + } + return fulllen; +} + +static int lxc_get_mount_entries(struct lxc_conf *c, char *retv, int inlen) +{ + int len, fulllen = 0; + struct lxc_list *it; + + if (!retv) + inlen = 0; + else + memset(retv, 0, inlen); + + lxc_list_for_each(it, &c->mount_list) { + strprint(retv, inlen, "%s\n", (char *)it->elem); + } + return fulllen; +} + +/* + * lxc.network.0.XXX, where XXX can be: name, type, link, flags, type, + * macvlan.mode, veth.pair, vlan, ipv4, ipv6, upscript, hwaddr, mtu, + * ipv4_gateway, ipv6_gateway. ipvX_gateway can return 'auto' instead + * of an address. ipv4 and ipv6 return lists (newline-separated). + * things like veth.pair return '' if invalid (i.e. if called for vlan + * type). + */ +static int lxc_get_item_nic(struct lxc_conf *c, char *retv, int inlen, + const char *key) +{ + char *p1; + int len, fulllen = 0; + struct lxc_netdev *netdev; + + if (!retv) + inlen = 0; + else + memset(retv, 0, inlen); + + p1 = index(key, '.'); + if (!p1 || *(p1+1) == '\0') return -1; + p1++; + + netdev = get_netdev_from_key(key, &c->network); + if (!netdev) + return -1; + if (strcmp(p1, "name") == 0) { + if (netdev->name) + strprint(retv, inlen, "%s", netdev->name); + } else if (strcmp(p1, "type") == 0) { + strprint(retv, inlen, "%s", lxc_net_type_to_str(netdev->type)); + } else if (strcmp(p1, "link") == 0) { + if (netdev->link) + strprint(retv, inlen, "%s", netdev->link); + } else if (strcmp(p1, "flags") == 0) { + if (netdev->flags & IFF_UP) + strprint(retv, inlen, "up"); + } else if (strcmp(p1, "upscript") == 0) { + if (netdev->upscript) + strprint(retv, inlen, "%s", netdev->upscript); + } else if (strcmp(p1, "hwaddr") == 0) { + if (netdev->hwaddr) + strprint(retv, inlen, "%s", netdev->hwaddr); + } else if (strcmp(p1, "mtu") == 0) { + if (netdev->mtu) + strprint(retv, inlen, "%s", netdev->mtu); + } else if (strcmp(p1, "macvlan.mode") == 0) { + if (netdev->type == LXC_NET_MACVLAN) { + const char *mode; + switch (netdev->priv.macvlan_attr.mode) { + case MACVLAN_MODE_PRIVATE: mode = "private"; break; + case MACVLAN_MODE_VEPA: mode = "vepa"; break; + case MACVLAN_MODE_BRIDGE: mode = "bridge"; break; + default: mode = "(invalid)"; break; + } + strprint(retv, inlen, "%s", mode); + } + } else if (strcmp(p1, "veth.pair") == 0) { + if (netdev->type == LXC_NET_VETH) { + strprint(retv, inlen, "%s", + netdev->priv.veth_attr.pair ? + netdev->priv.veth_attr.pair : + netdev->priv.veth_attr.veth1); + } + } else if (strcmp(p1, "vlan") == 0) { + if (netdev->type == LXC_NET_VLAN) { + strprint(retv, inlen, "%d", netdev->priv.vlan_attr.vid); + } + } else if (strcmp(p1, "ipv4_gateway") == 0) { + if (netdev->ipv4_gateway_auto) { + strprint(retv, inlen, "auto"); + } else if (netdev->ipv4_gateway) { + char buf[INET_ADDRSTRLEN]; + inet_ntop(AF_INET, netdev->ipv4_gateway, buf, sizeof(buf)); + strprint(retv, inlen, "%s", buf); + } + } else if (strcmp(p1, "ipv4") == 0) { + struct lxc_list *it2; + lxc_list_for_each(it2, &netdev->ipv4) { + struct lxc_inetdev *i = it2->elem; + char buf[INET_ADDRSTRLEN]; + inet_ntop(AF_INET, &i->addr, buf, sizeof(buf)); + strprint(retv, inlen, "%s\n", buf); + } + } else if (strcmp(p1, "ipv6_gateway") == 0) { + if (netdev->ipv6_gateway_auto) { + strprint(retv, inlen, "auto"); + } else if (netdev->ipv6_gateway) { + char buf[INET_ADDRSTRLEN]; + inet_ntop(AF_INET, netdev->ipv6_gateway, buf, sizeof(buf)); + strprint(retv, inlen, "%s", buf); + } + } else if (strcmp(p1, "ipv6") == 0) { + struct lxc_list *it2; + lxc_list_for_each(it2, &netdev->ipv6) { + struct lxc_inetdev *i = it2->elem; + char buf[INET_ADDRSTRLEN]; + inet_ntop(AF_INET6, &i->addr, buf, sizeof(buf)); + strprint(retv, inlen, "%s\n", buf); + } + } + return fulllen; +} + +static int lxc_get_item_network(struct lxc_conf *c, char *retv, int inlen) +{ + int len, fulllen = 0; + struct lxc_list *it; + + if (!retv) + inlen = 0; + else + memset(retv, 0, inlen); + + lxc_list_for_each(it, &c->network) { + struct lxc_netdev *n = it->elem; + const char *t = lxc_net_type_to_str(n->type); + strprint(retv, inlen, "%s\n", t ? t : "(invalid)"); + } + return fulllen; +} + +int lxc_get_config_item(struct lxc_conf *c, const char *key, char *retv, + int inlen) +{ + const char *v = NULL; + + if (strcmp(key, "lxc.mount.entry") == 0) + return lxc_get_mount_entries(c, retv, inlen); + else if (strcmp(key, "lxc.mount") == 0) + v = c->fstab; + else if (strcmp(key, "lxc.tty") == 0) + return lxc_get_conf_int(c, retv, inlen, c->tty); + else if (strcmp(key, "lxc.pts") == 0) + return lxc_get_conf_int(c, retv, inlen, c->pts); + else if (strcmp(key, "lxc.devttydir") == 0) + v = c->ttydir; + else if (strcmp(key, "lxc.arch") == 0) + return lxc_get_arch_entry(c, retv, inlen); +#if HAVE_APPARMOR + else if (strcmp(key, "lxc.aa_profile") == 0) + v = c->aa_profile; +#endif + else if (strcmp(key, "lxc.logfile") == 0) + v = lxc_log_get_file(); + else if (strcmp(key, "lxc.loglevel") == 0) + v = lxc_log_priority_to_string(lxc_log_get_level()); + else if (strcmp(key, "lxc.cgroup") == 0) // all cgroup info + return lxc_get_cgroup_entry(c, retv, inlen, "all"); + else if (strncmp(key, "lxc.cgroup.", 11) == 0) // specific cgroup info + return lxc_get_cgroup_entry(c, retv, inlen, key + 11); + else if (strcmp(key, "lxc.utsname") == 0) + v = c->utsname ? c->utsname->nodename : NULL; + else if (strcmp(key, "lxc.console") == 0) + v = c->console.path; + else if (strcmp(key, "lxc.rootfs.mount") == 0) + v = c->rootfs.mount; + else if (strcmp(key, "lxc.rootfs") == 0) + v = c->rootfs.path; + else if (strcmp(key, "lxc.pivotdir") == 0) + v = c->rootfs.pivot; + else if (strcmp(key, "lxc.cap.drop") == 0) + return lxc_get_item_cap_drop(c, retv, inlen); + else if (strcmp(key, "lxc.cap.keep") == 0) + return lxc_get_item_cap_keep(c, retv, inlen); + else if (strncmp(key, "lxc.hook", 8) == 0) + return lxc_get_item_hooks(c, retv, inlen, key); + else if (strcmp(key, "lxc.network") == 0) + return lxc_get_item_network(c, retv, inlen); + else if (strncmp(key, "lxc.network.", 12) == 0) + return lxc_get_item_nic(c, retv, inlen, key + 12); + else return -1; + + if (!v) + return 0; + if (retv && inlen >= strlen(v) + 1) + strncpy(retv, v, strlen(v)+1); + return strlen(v); +} + +int lxc_clear_config_item(struct lxc_conf *c, const char *key) +{ + if (strcmp(key, "lxc.network") == 0) + return lxc_clear_config_network(c); + else if (strncmp(key, "lxc.network.", 12) == 0) + return lxc_clear_nic(c, key + 12); + else if (strcmp(key, "lxc.cap.drop") == 0) + return lxc_clear_config_caps(c); + else if (strcmp(key, "lxc.cap.keep") == 0) + return lxc_clear_config_keepcaps(c); + else if (strncmp(key, "lxc.cgroup", 10) == 0) + return lxc_clear_cgroups(c, key); + else if (strcmp(key, "lxc.mount.entries") == 0) + return lxc_clear_mount_entries(c); + else if (strncmp(key, "lxc.hook", 8) == 0) + return lxc_clear_hooks(c, key); return -1; } + +/* + * writing out a confile. + */ +void write_config(FILE *fout, struct lxc_conf *c) +{ + struct lxc_list *it; + int i; + + if (c->fstab) + fprintf(fout, "lxc.mount = %s\n", c->fstab); + lxc_list_for_each(it, &c->mount_list) { + fprintf(fout, "lxc.mount.entry = %s\n", (char *)it->elem); + } + if (c->tty) + fprintf(fout, "lxc.tty = %d\n", c->tty); + if (c->pts) + fprintf(fout, "lxc.pts = %d\n", c->pts); + if (c->ttydir) + fprintf(fout, "lxc.devttydir = %s\n", c->ttydir); + #if HAVE_SYS_PERSONALITY_H + switch(c->personality) { + case PER_LINUX32: fprintf(fout, "lxc.arch = x86\n"); break; + case PER_LINUX: fprintf(fout, "lxc.arch = x86_64\n"); break; + default: break; + } + #endif +#if HAVE_APPARMOR + if (c->aa_profile) + fprintf(fout, "lxc.aa_profile = %s\n", c->aa_profile); +#endif + if (c->loglevel != LXC_LOG_PRIORITY_NOTSET) + fprintf(fout, "lxc.loglevel = %s\n", lxc_log_priority_to_string(c->loglevel)); + if (c->logfile) + fprintf(fout, "lxc.logfile = %s\n", c->logfile); + lxc_list_for_each(it, &c->cgroup) { + struct lxc_cgroup *cg = it->elem; + fprintf(fout, "lxc.cgroup.%s = %s\n", cg->subsystem, cg->value); + } + if (c->utsname) + fprintf(fout, "lxc.utsname = %s\n", c->utsname->nodename); + lxc_list_for_each(it, &c->network) { + struct lxc_netdev *n = it->elem; + const char *t = lxc_net_type_to_str(n->type); + struct lxc_list *it2; + fprintf(fout, "lxc.network.type = %s\n", t ? t : "(invalid)"); + if (n->flags & IFF_UP) + fprintf(fout, "lxc.network.flags = up\n"); + if (n->link) + fprintf(fout, "lxc.network.link = %s\n", n->link); + if (n->name) + fprintf(fout, "lxc.network.name = %s\n", n->name); + if (n->type == LXC_NET_MACVLAN) { + const char *mode; + switch (n->priv.macvlan_attr.mode) { + case MACVLAN_MODE_PRIVATE: mode = "private"; break; + case MACVLAN_MODE_VEPA: mode = "vepa"; break; + case MACVLAN_MODE_BRIDGE: mode = "bridge"; break; + default: mode = "(invalid)"; break; + } + fprintf(fout, "lxc.network.macvlan.mode = %s\n", mode); + } else if (n->type == LXC_NET_VETH) { + if (n->priv.veth_attr.pair) + fprintf(fout, "lxc.network.veth.pair = %s\n", + n->priv.veth_attr.pair); + } else if (n->type == LXC_NET_VLAN) { + fprintf(fout, "lxc.network.vlan.id = %d\n", n->priv.vlan_attr.vid); + } + if (n->upscript) + fprintf(fout, "lxc.network.script.up = %s\n", n->upscript); + if (n->hwaddr) + fprintf(fout, "lxc.network.hwaddr = %s\n", n->hwaddr); + if (n->mtu) + fprintf(fout, "lxc.network.mtu = %s\n", n->mtu); + if (n->ipv4_gateway_auto) + fprintf(fout, "lxc.network.ipv4.gateway = auto\n"); + else if (n->ipv4_gateway) { + char buf[INET_ADDRSTRLEN]; + inet_ntop(AF_INET, n->ipv4_gateway, buf, sizeof(buf)); + fprintf(fout, "lxc.network.ipv4.gateway = %s\n", buf); + } + lxc_list_for_each(it2, &n->ipv4) { + struct lxc_inetdev *i = it2->elem; + char buf[INET_ADDRSTRLEN]; + inet_ntop(AF_INET, &i->addr, buf, sizeof(buf)); + fprintf(fout, "lxc.network.ipv4 = %s\n", buf); + } + if (n->ipv6_gateway_auto) + fprintf(fout, "lxc.network.ipv6.gateway = auto\n"); + else if (n->ipv6_gateway) { + char buf[INET6_ADDRSTRLEN]; + inet_ntop(AF_INET6, n->ipv6_gateway, buf, sizeof(buf)); + fprintf(fout, "lxc.network.ipv6.gateway = %s\n", buf); + } + lxc_list_for_each(it2, &n->ipv6) { + struct lxc_inet6dev *i = it2->elem; + char buf[INET6_ADDRSTRLEN]; + inet_ntop(AF_INET, &i->addr, buf, sizeof(buf)); + fprintf(fout, "lxc.network.ipv6 = %s\n", buf); + } + } + lxc_list_for_each(it, &c->caps) + fprintf(fout, "lxc.cap.drop = %s\n", (char *)it->elem); + lxc_list_for_each(it, &c->keepcaps) + fprintf(fout, "lxc.cap.keep = %s\n", (char *)it->elem); + lxc_list_for_each(it, &c->id_map) { + struct id_map *idmap = it->elem; + fprintf(fout, "lxc.id_map = %c %lu %lu %lu\n", + idmap->idtype == ID_TYPE_UID ? 'u' : 'g', idmap->nsid, + idmap->hostid, idmap->range); + } + for (i=0; ihooks[i]) + fprintf(fout, "lxc.hook.%s = %s\n", + lxchook_names[i], (char *)it->elem); + } + if (c->console.path) + fprintf(fout, "lxc.console = %s\n", c->console.path); + if (c->rootfs.path) + fprintf(fout, "lxc.rootfs = %s\n", c->rootfs.path); + if (c->rootfs.mount && strcmp(c->rootfs.mount, LXCROOTFSMOUNT) != 0) + fprintf(fout, "lxc.rootfs.mount = %s\n", c->rootfs.mount); + if (c->rootfs.pivot) + fprintf(fout, "lxc.pivotdir = %s\n", c->rootfs.pivot); +} diff -Nru lxc-0.8.0~rc1/src/lxc/confile.h lxc-1.0.0~alpha1/src/lxc/confile.h --- lxc-0.8.0~rc1/src/lxc/confile.h 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/confile.h 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,15 +18,26 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include + #ifndef _confile_h #define _confile_h struct lxc_conf; struct lxc_list; +typedef int (*config_cb)(const char *, const char *, struct lxc_conf *); +struct lxc_config_t { + char *name; + config_cb cb; +}; + +extern struct lxc_config_t *lxc_getconfig(const char *key); +extern int lxc_list_nicconfigs(struct lxc_conf *c, const char *key, char *retv, int inlen); +extern int lxc_listconfigs(char *retv, int inlen); extern int lxc_config_read(const char *file, struct lxc_conf *conf); extern int lxc_config_readline(char *buffer, struct lxc_conf *conf); @@ -37,4 +48,7 @@ /* needed for lxc-attach */ extern signed long lxc_config_parse_arch(const char *arch); +extern int lxc_get_config_item(struct lxc_conf *c, const char *key, char *retv, int inlen); +extern int lxc_clear_config_item(struct lxc_conf *c, const char *key); +extern void write_config(FILE *fout, struct lxc_conf *c); #endif diff -Nru lxc-0.8.0~rc1/src/lxc/console.c lxc-1.0.0~alpha1/src/lxc/console.c --- lxc-0.8.0~rc1/src/lxc/console.c 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/console.c 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,165 +18,561 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include +#include #include #include #include #include #include -#include #include -#include +#include +#include "lxccontainer.h" #include "log.h" #include "conf.h" +#include "config.h" #include "start.h" /* for struct lxc_handler */ #include "caps.h" #include "commands.h" #include "mainloop.h" #include "af_unix.h" +#include "lxclock.h" +#include "utils.h" + +#if HAVE_PTY_H +#include +#else +#include <../include/openpty.h> +#endif lxc_log_define(lxc_console, lxc); -extern int lxc_console(const char *name, int ttynum, int *fd) +static struct lxc_list lxc_ttys; + +typedef void (*sighandler_t)(int); +struct lxc_tty_state +{ + struct lxc_list node; + int stdinfd; + int stdoutfd; + int masterfd; + int escape; + int saw_escape; + const char *winch_proxy; + const char *winch_proxy_lxcpath; + int sigfd; + sigset_t oldmask; +}; + +__attribute__((constructor)) +void lxc_console_init(void) +{ + lxc_list_init(&lxc_ttys); +} + +/* lxc_console_winsz: propagte winsz from one terminal to another + * + * @srcfd : terminal to get size from (typically a slave pty) + * @dstfd : terminal to set size on (typically a master pty) + */ +static void lxc_console_winsz(int srcfd, int dstfd) { - int ret, stopped = 0; - struct lxc_command command = { - .request = { .type = LXC_COMMAND_TTY, .data = ttynum }, - }; + struct winsize wsz; + if (isatty(srcfd) && ioctl(srcfd, TIOCGWINSZ, &wsz) == 0) { + DEBUG("set winsz dstfd:%d cols:%d rows:%d", dstfd, + wsz.ws_col, wsz.ws_row); + ioctl(dstfd, TIOCSWINSZ, &wsz); + } +} - ret = lxc_command_connected(name, &command, &stopped); - if (ret < 0 && stopped) { - ERROR("'%s' is stopped", name); +static void lxc_console_winch(struct lxc_tty_state *ts) +{ + lxc_console_winsz(ts->stdinfd, ts->masterfd); + if (ts->winch_proxy) { + lxc_cmd_console_winch(ts->winch_proxy, + ts->winch_proxy_lxcpath); + } +} + +void lxc_console_sigwinch(int sig) +{ + if (process_lock() == 0) { + struct lxc_list *it; + struct lxc_tty_state *ts; + + lxc_list_for_each(it, &lxc_ttys) { + ts = it->elem; + lxc_console_winch(ts); + } + process_unlock(); + } +} + +static int lxc_console_cb_sigwinch_fd(int fd, void *cbdata, + struct lxc_epoll_descr *descr) +{ + struct signalfd_siginfo siginfo; + struct lxc_tty_state *ts = cbdata; + + if (read(fd, &siginfo, sizeof(siginfo)) < 0) { + ERROR("failed to read signal info"); return -1; } - if (ret < 0) { - ERROR("failed to send command"); + lxc_console_winch(ts); + return 0; +} + +/* + * lxc_console_sigwinch_init: install SIGWINCH handler + * + * @srcfd : src for winsz in SIGWINCH handler + * @dstfd : dst for winsz in SIGWINCH handler + * + * Returns lxc_tty_state structure on success or NULL on failure. The sigfd + * member of the returned lxc_tty_state can be select()/poll()ed/epoll()ed + * on (ie added to a mainloop) for SIGWINCH. + * + * Must be called with process_lock held to protect the lxc_ttys list, or + * from a non-threaded context. + * + * Note that SIGWINCH isn't installed as a classic asychronous handler, + * rather signalfd(2) is used so that we can handle the signal when we're + * ready for it. This avoids deadlocks since a signal handler + * (ie lxc_console_sigwinch()) would need to take the thread mutex to + * prevent lxc_ttys list corruption, but using the fd we can provide the + * tty_state needed to the callback (lxc_console_cb_sigwinch_fd()). + */ +static struct lxc_tty_state *lxc_console_sigwinch_init(int srcfd, int dstfd) +{ + sigset_t mask; + struct lxc_tty_state *ts; + + ts = malloc(sizeof(*ts)); + if (!ts) + return NULL; + + memset(ts, 0, sizeof(*ts)); + ts->stdinfd = srcfd; + ts->masterfd = dstfd; + ts->sigfd = -1; + + /* add tty to list to be scanned at SIGWINCH time */ + lxc_list_add_elem(&ts->node, ts); + lxc_list_add_tail(&lxc_ttys, &ts->node); + + sigemptyset(&mask); + sigaddset(&mask, SIGWINCH); + if (sigprocmask(SIG_BLOCK, &mask, &ts->oldmask)) { + SYSERROR("failed to block SIGWINCH"); + goto err1; + } + + ts->sigfd = signalfd(-1, &mask, 0); + if (ts->sigfd < 0) { + SYSERROR("failed to get signalfd"); + goto err2; + } + + DEBUG("%d got SIGWINCH fd %d", getpid(), ts->sigfd); + goto out; + +err2: + sigprocmask(SIG_SETMASK, &ts->oldmask, NULL); +err1: + lxc_list_del(&ts->node); + free(ts); + ts = NULL; +out: + return ts; +} + +/* + * lxc_console_sigwinch_fini: uninstall SIGWINCH handler + * + * @ts : the lxc_tty_state returned by lxc_console_sigwinch_init + * + * Restore the saved signal handler that was in effect at the time + * lxc_console_sigwinch_init() was called. + * + * Must be called with process_lock held to protect the lxc_ttys list, or + * from a non-threaded context. + */ +static void lxc_console_sigwinch_fini(struct lxc_tty_state *ts) +{ + if (ts->sigfd >= 0) + close(ts->sigfd); + lxc_list_del(&ts->node); + sigprocmask(SIG_SETMASK, &ts->oldmask, NULL); + free(ts); +} + +static int lxc_console_cb_con(int fd, void *data, + struct lxc_epoll_descr *descr) +{ + struct lxc_console *console = (struct lxc_console *)data; + char buf[1024]; + int r,w; + + w = r = read(fd, buf, sizeof(buf)); + if (r < 0) { + SYSERROR("failed to read"); + return 1; + } + + if (!r) { + INFO("console client on fd %d has exited", fd); + lxc_mainloop_del_handler(descr, fd); + close(fd); + return 0; + } + + if (fd == console->peer) + w = write(console->master, buf, r); + + if (fd == console->master) { + if (console->log_fd >= 0) + w = write(console->log_fd, buf, r); + + if (console->peer >= 0) + w = write(console->peer, buf, r); + } + + if (w != r) + WARN("console short write r:%d w:%d", r, w); + return 0; +} + +static void lxc_console_mainloop_add_peer(struct lxc_console *console) +{ + if (console->peer >= 0) { + if (lxc_mainloop_add_handler(console->descr, console->peer, + lxc_console_cb_con, console)) + WARN("console peer not added to mainloop"); + } + + if (console->tty_state) { + if (lxc_mainloop_add_handler(console->descr, + console->tty_state->sigfd, + lxc_console_cb_sigwinch_fd, + console->tty_state)) { + WARN("failed to add to mainloop SIGWINCH handler for '%d'", + console->tty_state->sigfd); + } + } +} + +int lxc_console_mainloop_add(struct lxc_epoll_descr *descr, + struct lxc_handler *handler) +{ + struct lxc_conf *conf = handler->conf; + struct lxc_console *console = &conf->console; + + if (conf->is_execute) { + INFO("no console for lxc-execute."); + return 0; + } + + if (!conf->rootfs.path) { + INFO("no rootfs, no console."); + return 0; + } + + if (console->master < 0) { + INFO("no console"); + return 0; + } + + if (lxc_mainloop_add_handler(descr, console->master, + lxc_console_cb_con, console)) { + ERROR("failed to add to mainloop console handler for '%d'", + console->master); return -1; } - if (!ret) { - ERROR("console denied by '%s'", name); + /* we cache the descr so that we can add an fd to it when someone + * does attach to it in lxc_console_allocate() + */ + console->descr = descr; + lxc_console_mainloop_add_peer(console); + + return 0; +} + +static int setup_tios(int fd, struct termios *oldtios) +{ + struct termios newtios; + + if (!isatty(fd)) { + ERROR("'%d' is not a tty", fd); return -1; } - if (command.answer.ret) { - ERROR("console access denied: %s", - strerror(-command.answer.ret)); + /* Get current termios */ + if (tcgetattr(fd, oldtios)) { + SYSERROR("failed to get current terminal settings"); return -1; } - *fd = command.answer.fd; - if (*fd <0) { - ERROR("unable to allocate fd for tty %d", ttynum); + newtios = *oldtios; + + /* Remove the echo characters and signal reception, the echo + * will be done with master proxying */ + newtios.c_iflag &= ~IGNBRK; + newtios.c_iflag &= BRKINT; + newtios.c_lflag &= ~(ECHO|ICANON|ISIG); + newtios.c_cc[VMIN] = 1; + newtios.c_cc[VTIME] = 0; + + /* Set new attributes */ + if (tcsetattr(fd, TCSAFLUSH, &newtios)) { + ERROR("failed to set new terminal settings"); return -1; } - INFO("tty %d allocated", ttynum); return 0; } -/*---------------------------------------------------------------------------- - * functions used by lxc-start mainloop - * to handle above command request. - *--------------------------------------------------------------------------*/ -extern void lxc_console_remove_fd(int fd, struct lxc_tty_info *tty_info) +static void lxc_console_peer_proxy_free(struct lxc_console *console) { - int i; + if (console->tty_state) { + lxc_console_sigwinch_fini(console->tty_state); + console->tty_state = NULL; + } + close(console->peerpty.master); + close(console->peerpty.slave); + console->peerpty.master = -1; + console->peerpty.slave = -1; + console->peerpty.busy = -1; + console->peerpty.name[0] = '\0'; + console->peer = -1; +} - for (i = 0; i < tty_info->nbtty; i++) { +static int lxc_console_peer_proxy_alloc(struct lxc_console *console, int sockfd) +{ + struct termios oldtermio; + struct lxc_tty_state *ts; - if (tty_info->pty_info[i].busy != fd) - continue; + if (console->master < 0) { + ERROR("console not set up"); + return -1; + } + if (console->peerpty.busy != -1 || console->peer != -1) { + NOTICE("console already in use"); + return -1; + } + if (console->tty_state) { + ERROR("console already has tty_state"); + return -1; + } - tty_info->pty_info[i].busy = 0; + /* this is the proxy pty that will be given to the client, and that + * the real pty master will send to / recv from + */ + if (openpty(&console->peerpty.master, &console->peerpty.slave, + console->peerpty.name, NULL, NULL)) { + SYSERROR("failed to create proxy pty"); + return -1; } - return; + if (setup_tios(console->peerpty.slave, &oldtermio) < 0) + goto err1; + + ts = lxc_console_sigwinch_init(console->peerpty.master, console->master); + if (!ts) + goto err1; + + console->tty_state = ts; + console->peer = console->peerpty.slave; + console->peerpty.busy = sockfd; + lxc_console_mainloop_add_peer(console); + + DEBUG("%d %s peermaster:%d sockfd:%d", getpid(), __FUNCTION__, console->peerpty.master, sockfd); + return 0; + +err1: + lxc_console_peer_proxy_free(console); + return -1; } -extern int lxc_console_callback(int fd, struct lxc_request *request, - struct lxc_handler *handler) +/* lxc_console_allocate: allocate the console or a tty + * + * @conf : the configuration of the container to allocate from + * @sockfd : the socket fd whose remote side when closed, will be an + * indication that the console or tty is no longer in use + * @ttyreq : the tty requested to be opened, -1 for any, 0 for the console + */ +int lxc_console_allocate(struct lxc_conf *conf, int sockfd, int *ttyreq) { - int ttynum = request->data; - struct lxc_tty_info *tty_info = &handler->conf->tty_info; + int masterfd = -1, ttynum; + struct lxc_tty_info *tty_info = &conf->tty_info; + struct lxc_console *console = &conf->console; + + process_lock(); + if (*ttyreq == 0) { + if (lxc_console_peer_proxy_alloc(console, sockfd) < 0) + goto out; + masterfd = console->peerpty.master; + goto out; + } - if (ttynum > 0) { - if (ttynum > tty_info->nbtty) - goto out_close; + if (*ttyreq > 0) { + if (*ttyreq > tty_info->nbtty) + goto out; - if (tty_info->pty_info[ttynum - 1].busy) - goto out_close; + if (tty_info->pty_info[*ttyreq - 1].busy) + goto out; - goto out_send; + /* the requested tty is available */ + ttynum = *ttyreq; + goto out_tty; } - /* fixup index tty1 => [0] */ + /* search for next available tty, fixup index tty1 => [0] */ for (ttynum = 1; ttynum <= tty_info->nbtty && tty_info->pty_info[ttynum - 1].busy; ttynum++); /* we didn't find any available slot for tty */ if (ttynum > tty_info->nbtty) - goto out_close; + goto out; -out_send: - if (lxc_af_unix_send_fd(fd, tty_info->pty_info[ttynum - 1].master, - &ttynum, sizeof(ttynum)) < 0) { - ERROR("failed to send tty to client"); - goto out_close; - } + *ttyreq = ttynum; - tty_info->pty_info[ttynum - 1].busy = fd; +out_tty: + tty_info->pty_info[ttynum - 1].busy = sockfd; + masterfd = tty_info->pty_info[ttynum - 1].master; +out: + process_unlock(); + return masterfd; +} - return 0; +/* lxc_console_free: mark the console or a tty as unallocated, free any + * resources allocated by lxc_console_allocate(). + * + * @conf : the configuration of the container whose tty was closed + * @fd : the socket fd whose remote side was closed, which indicated + * the console or tty is no longer in use. this is used to match + * which console/tty is being freed. + */ +void lxc_console_free(struct lxc_conf *conf, int fd) +{ + int i; + struct lxc_tty_info *tty_info = &conf->tty_info; + struct lxc_console *console = &conf->console; + + process_lock(); + for (i = 0; i < tty_info->nbtty; i++) { + if (tty_info->pty_info[i].busy == fd) + tty_info->pty_info[i].busy = 0; + } -out_close: - /* the close fd and related cleanup will be done by caller */ - return 1; + if (console->peerpty.busy == fd) { + lxc_mainloop_del_handler(console->descr, console->peerpty.slave); + lxc_console_peer_proxy_free(console); + } + process_unlock(); } -static int get_default_console(char **console) +static void lxc_console_peer_default(struct lxc_console *console) { - int fd; + struct lxc_tty_state *ts; + const char *path = console->path; - if (!access("/dev/tty", F_OK)) { + /* if no console was given, try current controlling terminal, there + * won't be one if we were started as a daemon (-d) + */ + if (!path && !access("/dev/tty", F_OK)) { + int fd; fd = open("/dev/tty", O_RDWR); - if (fd > 0) { + if (fd >= 0) { close(fd); - *console = strdup("/dev/tty"); - goto out; + path = "/dev/tty"; } } - if (!access("/dev/null", F_OK)) { - *console = strdup("/dev/null"); + if (!path) goto out; + + DEBUG("opening %s for console peer", path); + console->peer = lxc_unpriv(open(path, O_CLOEXEC | O_RDWR | O_CREAT | + O_APPEND, 0600)); + if (console->peer < 0) + goto out; + + DEBUG("using '%s' as console", path); + + if (!isatty(console->peer)) + return; + + ts = lxc_console_sigwinch_init(console->peer, console->master); + if (!ts) + WARN("Unable to install SIGWINCH"); + console->tty_state = ts; + + lxc_console_winsz(console->peer, console->master); + + console->tios = malloc(sizeof(*console->tios)); + if (!console->tios) { + SYSERROR("failed to allocate memory"); + goto err1; } - ERROR("No suitable default console"); + if (setup_tios(console->peer, console->tios) < 0) + goto err2; + + return; + +err2: + free(console->tios); + console->tios = NULL; +err1: + close(console->peer); + console->peer = -1; out: - return *console ? 0 : -1; + DEBUG("no console peer"); +} + +void lxc_console_delete(struct lxc_console *console) +{ + if (console->tios && console->peer >= 0 && + tcsetattr(console->peer, TCSAFLUSH, console->tios)) + WARN("failed to set old terminal settings"); + free(console->tios); + console->tios = NULL; + + close(console->peer); + console->peer = -1; + + if (console->log_fd >= 0) { + close(console->log_fd); + console->log_fd = -1; + } + + close(console->master); + console->master = -1; + + close(console->slave); + console->slave = -1; } -int lxc_create_console(struct lxc_conf *conf) +int lxc_console_create(struct lxc_conf *conf) { - struct termios tios; struct lxc_console *console = &conf->console; - int fd; - if (!conf->rootfs.path) + if (conf->is_execute) { + INFO("no console for lxc-execute."); return 0; - - if (!console->path && get_default_console(&console->path)) { - ERROR("failed to get default console"); - return -1; } - if (!strcmp(console->path, "none")) + if (!conf->rootfs.path) + return 0; + + if (console->path && !strcmp(console->path, "none")) return 0; if (openpty(&console->master, &console->slave, @@ -195,130 +591,182 @@ goto err; } - fd = lxc_unpriv(open(console->path, O_CLOEXEC | O_RDWR | O_CREAT | - O_APPEND, 0600)); - if (fd < 0) { - SYSERROR("failed to open '%s'", console->path); - goto err; + lxc_console_peer_default(console); + + if (console->log_path) { + console->log_fd = lxc_unpriv(open(console->log_path, + O_CLOEXEC | O_RDWR | + O_CREAT | O_APPEND, 0600)); + if (console->log_fd < 0) { + SYSERROR("failed to open '%s'", console->log_path); + goto err; + } + DEBUG("using '%s' as console log", console->log_path); } - DEBUG("using '%s' as console", console->path); + return 0; + +err: + lxc_console_delete(console); + return -1; +} - console->peer = fd; - if (!isatty(console->peer)) - return 0; - console->tios = malloc(sizeof(tios)); - if (!console->tios) { - SYSERROR("failed to allocate memory"); - goto err; - } +static int lxc_console_cb_tty_stdin(int fd, void *cbdata, + struct lxc_epoll_descr *descr) +{ + struct lxc_tty_state *ts = cbdata; + char c; - /* Get termios */ - if (tcgetattr(console->peer, console->tios)) { - SYSERROR("failed to get current terminal settings"); - goto err_free; + assert(fd == ts->stdinfd); + if (read(ts->stdinfd, &c, 1) < 0) { + SYSERROR("failed to read"); + return 1; } - tios = *console->tios; + /* we want to exit the console with Ctrl+a q */ + if (c == ts->escape && !ts->saw_escape) { + ts->saw_escape = 1; + return 0; + } - /* Remove the echo characters and signal reception, the echo - * will be done below with master proxying */ - tios.c_iflag &= ~IGNBRK; - tios.c_iflag &= BRKINT; - tios.c_lflag &= ~(ECHO|ICANON|ISIG); - tios.c_cc[VMIN] = 1; - tios.c_cc[VTIME] = 0; + if (c == 'q' && ts->saw_escape) + return 1; - /* Set new attributes */ - if (tcsetattr(console->peer, TCSAFLUSH, &tios)) { - ERROR("failed to set new terminal settings"); - goto err_free; + ts->saw_escape = 0; + if (write(ts->masterfd, &c, 1) < 0) { + SYSERROR("failed to write"); + return 1; } return 0; - -err_free: - free(console->tios); -err: - close(console->master); - close(console->slave); - return -1; } -void lxc_delete_console(const struct lxc_console *console) +static int lxc_console_cb_tty_master(int fd, void *cbdata, + struct lxc_epoll_descr *descr) { - if (console->tios && - tcsetattr(console->peer, TCSAFLUSH, console->tios)) - WARN("failed to set old terminal settings"); - close(console->master); - close(console->slave); -} - -static int console_handler(int fd, void *data, struct lxc_epoll_descr *descr) -{ - struct lxc_console *console = (struct lxc_console *)data; + struct lxc_tty_state *ts = cbdata; char buf[1024]; - int r; + int r,w; + assert(fd == ts->masterfd); r = read(fd, buf, sizeof(buf)); if (r < 0) { SYSERROR("failed to read"); return 1; } - if (!r) { - INFO("console client has exited"); - lxc_mainloop_del_handler(descr, fd); - close(fd); - return 0; + w = write(ts->stdoutfd, buf, r); + if (w < 0 || w != r) { + SYSERROR("failed to write"); + return 1; } - /* no output for the console, do nothing */ - if (console->peer == -1) - return 0; - - if (console->peer == fd) - r = write(console->master, buf, r); - else - r = write(console->peer, buf, r); - return 0; } -int lxc_console_mainloop_add(struct lxc_epoll_descr *descr, - struct lxc_handler *handler) +int lxc_console_getfd(struct lxc_container *c, int *ttynum, int *masterfd) { - struct lxc_conf *conf = handler->conf; - struct lxc_console *console = &conf->console; - - if (!conf->rootfs.path) { - INFO("no rootfs, no console."); - return 0; - } + return lxc_cmd_console(c->name, ttynum, masterfd, c->config_path); +} - if (!console->path) { - INFO("no console specified"); - return 0; - } +int lxc_console(struct lxc_container *c, int ttynum, + int stdinfd, int stdoutfd, int stderrfd, + int escape) +{ + int ret, ttyfd, masterfd; + struct lxc_epoll_descr descr; + struct termios oldtios; + struct lxc_tty_state *ts; - if (console->peer == -1) { - INFO("no console will be used"); - return 0; + if (!isatty(stdinfd)) { + ERROR("stdin is not a tty"); + return -1; } - if (lxc_mainloop_add_handler(descr, console->master, - console_handler, console)) { - ERROR("failed to add to mainloop console handler for '%d'", - console->master); + ret = setup_tios(stdinfd, &oldtios); + if (ret) { + ERROR("failed to setup tios"); return -1; } - if (console->peer != -1 && - lxc_mainloop_add_handler(descr, console->peer, - console_handler, console)) - WARN("console input disabled"); + process_lock(); + ttyfd = lxc_cmd_console(c->name, &ttynum, &masterfd, c->config_path); + if (ttyfd < 0) { + ret = ttyfd; + goto err1; + } + + fprintf(stderr, "\n" + "Connected to tty %1$d\n" + "Type to exit the console, " + " to enter Ctrl+%2$c itself\n", + ttynum, 'a' + escape - 1); + + ret = setsid(); + if (ret) + INFO("already group leader"); + + ts = lxc_console_sigwinch_init(stdinfd, masterfd); + if (!ts) { + ret = -1; + goto err2; + } + ts->escape = escape; + ts->winch_proxy = c->name; + ts->winch_proxy_lxcpath = c->config_path; + + lxc_console_winsz(stdinfd, masterfd); + lxc_cmd_console_winch(ts->winch_proxy, ts->winch_proxy_lxcpath); + + ret = lxc_mainloop_open(&descr); + if (ret) { + ERROR("failed to create mainloop"); + goto err3; + } + + ret = lxc_mainloop_add_handler(&descr, ts->sigfd, + lxc_console_cb_sigwinch_fd, ts); + if (ret) { + ERROR("failed to add handler for SIGWINCH fd"); + goto err4; + } + + ret = lxc_mainloop_add_handler(&descr, ts->stdinfd, + lxc_console_cb_tty_stdin, ts); + if (ret) { + ERROR("failed to add handler for stdinfd"); + goto err4; + } + + ret = lxc_mainloop_add_handler(&descr, ts->masterfd, + lxc_console_cb_tty_master, ts); + if (ret) { + ERROR("failed to add handler for masterfd"); + goto err4; + } + + process_unlock(); + ret = lxc_mainloop(&descr, -1); + process_lock(); + if (ret) { + ERROR("mainloop returned an error"); + goto err4; + } + + ret = 0; + +err4: + lxc_mainloop_close(&descr); +err3: + lxc_console_sigwinch_fini(ts); +err2: + close(masterfd); + close(ttyfd); +err1: + tcsetattr(stdinfd, TCSAFLUSH, &oldtios); + process_unlock(); - return 0; + return ret; } diff -Nru lxc-0.8.0~rc1/src/lxc/console.h lxc-1.0.0~alpha1/src/lxc/console.h --- lxc-0.8.0~rc1/src/lxc/console.h 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/console.h 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2010 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,9 +18,21 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -extern int lxc_create_console(struct lxc_conf *); -extern void lxc_delete_console(struct lxc_console *); -extern int lxc_console_mainloop_add(struct lxc_epoll_descr *, struct lxc_handler *); +struct lxc_epoll_descr; +struct lxc_container; + +extern int lxc_console_allocate(struct lxc_conf *conf, int sockfd, int *ttynum); +extern int lxc_console_create(struct lxc_conf *); +extern void lxc_console_delete(struct lxc_console *); +extern void lxc_console_free(struct lxc_conf *conf, int fd); + +extern int lxc_console_mainloop_add(struct lxc_epoll_descr *, struct lxc_handler *); +extern void lxc_console_sigwinch(int sig); +extern int lxc_console(struct lxc_container *c, int ttynum, + int stdinfd, int stdoutfd, int stderrfd, + int escape); +extern int lxc_console_getfd(struct lxc_container *c, int *ttynum, + int *masterfd); diff -Nru lxc-0.8.0~rc1/src/lxc/error.c lxc-1.0.0~alpha1/src/lxc/error.c --- lxc-0.8.0~rc1/src/lxc/error.c 2011-12-11 22:36:28.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/error.c 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,7 +18,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include diff -Nru lxc-0.8.0~rc1/src/lxc/error.h lxc-1.0.0~alpha1/src/lxc/error.h --- lxc-0.8.0~rc1/src/lxc/error.h 2011-12-11 22:36:28.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/error.h 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,7 +18,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __lxc_error_h #define __lxc_error_h diff -Nru lxc-0.8.0~rc1/src/lxc/execute.c lxc-1.0.0~alpha1/src/lxc/execute.c --- lxc-0.8.0~rc1/src/lxc/execute.c 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/execute.c 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,13 +18,16 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include +#include #include #include #include +#include "conf.h" #include "log.h" #include "start.h" @@ -35,22 +38,94 @@ int quiet; }; +/* historically lxc-init has been under /usr/lib/lxc. Now with + * multi-arch it can be under /usr/lib/$ARCH/lxc. Serge thinks + * it makes more sense to put it under /sbin. + * If /usr/lib/$ARCH/lxc exists and is used, then LXCINITDIR will + * point to it. + */ +static char *choose_init(void) +{ + char *retv = malloc(PATH_MAX); + int ret; + struct stat mystat; + if (!retv) + return NULL; + + ret = snprintf(retv, PATH_MAX, LXCINITDIR "/lxc/lxc-init"); + if (ret < 0 || ret >= PATH_MAX) { + ERROR("pathname too long"); + goto out1; + } + + ret = stat(retv, &mystat); + if (ret == 0) + return retv; + + ret = snprintf(retv, PATH_MAX, "/usr/lib/lxc/lxc-init"); + if (ret < 0 || ret >= PATH_MAX) { + ERROR("pathname too long"); + goto out1; + } + ret = stat(retv, &mystat); + if (ret == 0) + return retv; + ret = snprintf(retv, PATH_MAX, "/sbin/lxc-init"); + if (ret < 0 || ret >= PATH_MAX) { + ERROR("pathname too long"); + goto out1; + } + ret = stat(retv, &mystat); + if (ret == 0) + return retv; +out1: + free(retv); + return NULL; +} + static int execute_start(struct lxc_handler *handler, void* data) { int j, i = 0; struct execute_args *my_args = data; char **argv; - int argc = 0; + int argc = 0, argc_add; + char *initpath; while (my_args->argv[argc++]); - argv = malloc((argc + my_args->quiet ? 5 : 4) * sizeof(*argv)); + argc_add = 4; + if (my_args->quiet) + argc_add++; + if (!handler->conf->rootfs.path) { + argc_add += 4; + if (lxc_log_has_valid_level()) + argc_add += 2; + } + + argv = malloc((argc + argc_add) * sizeof(*argv)); if (!argv) - return 1; + goto out1; - argv[i++] = LXCINITDIR "/lxc-init"; + initpath = choose_init(); + if (!initpath) { + ERROR("Failed to find an lxc-init"); + goto out2; + } + argv[i++] = initpath; if (my_args->quiet) argv[i++] = "--quiet"; + if (!handler->conf->rootfs.path) { + argv[i++] = "--name"; + argv[i++] = (char *)handler->name; + argv[i++] = "--lxcpath"; + argv[i++] = (char *)handler->lxcpath; + + if (lxc_log_has_valid_level()) { + argv[i++] = "--logpriority"; + argv[i++] = (char *) + lxc_log_priority_to_string(lxc_log_get_level()); + } + } argv[i++] = "--"; for (j = 0; j < argc; j++) argv[i++] = my_args->argv[j]; @@ -60,6 +135,10 @@ execvp(argv[0], argv); SYSERROR("failed to exec %s", argv[0]); + free(initpath); +out2: + free(argv); +out1: return 1; } @@ -76,7 +155,7 @@ }; int lxc_execute(const char *name, char *const argv[], int quiet, - struct lxc_conf *conf) + struct lxc_conf *conf, const char *lxcpath) { struct execute_args args = { .argv = argv, @@ -86,5 +165,6 @@ if (lxc_check_inherited(conf, -1)) return -1; - return __lxc_start(name, conf, &execute_start_ops, &args); + conf->is_execute = 1; + return __lxc_start(name, conf, &execute_start_ops, &args, lxcpath); } diff -Nru lxc-0.8.0~rc1/src/lxc/freezer.c lxc-1.0.0~alpha1/src/lxc/freezer.c --- lxc-0.8.0~rc1/src/lxc/freezer.c 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/freezer.c 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,7 +18,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #define _GNU_SOURCE #include @@ -32,28 +32,29 @@ #include #include "error.h" +#include "state.h" +#include "monitor.h" #include #include lxc_log_define(lxc_freezer, lxc); -static int freeze_unfreeze(const char *name, int freeze) +static int do_unfreeze(const char *nsgroup, int freeze, const char *name, const char *lxcpath) { - char *nsgroup; char freezer[MAXPATHLEN], *f; char tmpf[32]; int fd, ret; - - ret = lxc_cgroup_path_get(&nsgroup, "freezer", name); - if (ret) - return -1; - snprintf(freezer, MAXPATHLEN, "%s/freezer.state", nsgroup); + ret = snprintf(freezer, MAXPATHLEN, "%s/freezer.state", nsgroup); + if (ret >= MAXPATHLEN) { + ERROR("freezer.state name too long"); + return -1; + } fd = open(freezer, O_RDWR); if (fd < 0) { - SYSERROR("failed to open freezer for '%s'", name); + SYSERROR("failed to open freezer at '%s'", nsgroup); return -1; } @@ -91,7 +92,11 @@ ret = strncmp(f, tmpf, strlen(f)); if (!ret) + { + if (name) + lxc_monitor_send_state(name, freeze ? FROZEN : THAWED, lxcpath); break; /* Success */ + } sleep(1); @@ -113,13 +118,44 @@ return ret; } -int lxc_freeze(const char *name) +static int freeze_unfreeze(const char *name, int freeze, const char *lxcpath) +{ + char *cgabspath; + int ret; + + cgabspath = lxc_cgroup_path_get("freezer", name, lxcpath); + if (!cgabspath) + return -1; + + ret = do_unfreeze(cgabspath, freeze, name, lxcpath); + free(cgabspath); + return ret; +} + +int lxc_freeze(const char *name, const char *lxcpath) { - return freeze_unfreeze(name, 1); + lxc_monitor_send_state(name, FREEZING, lxcpath); + return freeze_unfreeze(name, 1, lxcpath); } -int lxc_unfreeze(const char *name) +int lxc_unfreeze(const char *name, const char *lxcpath) { - return freeze_unfreeze(name, 0); + return freeze_unfreeze(name, 0, lxcpath); } +int lxc_unfreeze_bypath(const char *cgrelpath) +{ + char cgabspath[MAXPATHLEN]; + int len, ret; + + if (!get_subsys_mount(cgabspath, "freezer")) + return -1; + len = strlen(cgabspath); + ret = snprintf(cgabspath+len, MAXPATHLEN-len, "/%s", cgrelpath); + if (ret < 0 || ret >= MAXPATHLEN-len) { + ERROR("freezer path name too long"); + return -1; + } + + return do_unfreeze(cgabspath, 0, NULL, NULL); +} diff -Nru lxc-0.8.0~rc1/src/lxc/genl.c lxc-1.0.0~alpha1/src/lxc/genl.c --- lxc-0.8.0~rc1/src/lxc/genl.c 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/genl.c 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,7 +18,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include @@ -60,45 +60,46 @@ ret = netlink_open(&handler, NETLINK_GENERIC); if (ret) - return ret; + goto out; - ret = nla_put_string((struct nlmsg *)&request->nlmsghdr, + ret = nla_put_string((struct nlmsg *)&request->nlmsghdr, CTRL_ATTR_FAMILY_NAME, family); if (ret) - goto out; + goto out_close; ret = netlink_transaction(&handler, (struct nlmsg *)&request->nlmsghdr, (struct nlmsg *)&reply->nlmsghdr); if (ret < 0) - goto out; + goto out_close; genlmsghdr = NLMSG_DATA(&reply->nlmsghdr); len = reply->nlmsghdr.nlmsg_len; ret = -ENOMSG; if (reply->nlmsghdr.nlmsg_type != GENL_ID_CTRL) - goto out; + goto out_close; if (genlmsghdr->cmd != CTRL_CMD_NEWFAMILY) - goto out; + goto out_close; ret = -EMSGSIZE; len -= NLMSG_LENGTH(GENL_HDRLEN); if (len < 0) - goto out; + goto out_close; attr = (struct nlattr *)GENLMSG_DATA(reply); attr = (struct nlattr *)((char *)attr + NLA_ALIGN(attr->nla_len)); ret = -ENOMSG; if (attr->nla_type != CTRL_ATTR_FAMILY_ID) - goto out; + goto out_close; ret = *(__u16 *) NLA_DATA(attr); +out_close: + netlink_close(&handler); out: genlmsg_free(request); genlmsg_free(reply); - netlink_close(&handler); return ret; } @@ -130,7 +131,7 @@ return netlink_send(&handler->nlh, (struct nlmsg *)&genlmsg->nlmsghdr); } -extern int genetlink_transaction(struct genl_handler *handler, +extern int genetlink_transaction(struct genl_handler *handler, struct genlmsg *request, struct genlmsg *answer) { return netlink_transaction(&handler->nlh, (struct nlmsg *)&request->nlmsghdr, diff -Nru lxc-0.8.0~rc1/src/lxc/genl.h lxc-1.0.0~alpha1/src/lxc/genl.h --- lxc-0.8.0~rc1/src/lxc/genl.h 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/genl.h 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,7 +18,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __genl_h #define __genl_h @@ -30,7 +30,7 @@ #define GENLMSG_DATA(glh) ((void *)(NLMSG_DATA(glh) + GENL_HDRLEN)) /* - * struct genl_handler : the structure which store the netlink handler + * struct genl_handler : the structure which store the netlink handler * and the family number resulting of the auto-generating id family * for the generic netlink protocol * @@ -116,6 +116,6 @@ * * Returns 0 on success, < 0 otherwise */ -int genetlink_transaction(struct genl_handler *handler, +int genetlink_transaction(struct genl_handler *handler, struct genlmsg *request, struct genlmsg *answer); #endif diff -Nru lxc-0.8.0~rc1/src/lxc/legacy/lxc-ls.in lxc-1.0.0~alpha1/src/lxc/legacy/lxc-ls.in --- lxc-0.8.0~rc1/src/lxc/legacy/lxc-ls.in 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/legacy/lxc-ls.in 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,99 @@ +#!/bin/sh + +# +# lxc: linux Container library + +# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +. @DATADIR@/lxc/lxc.functions + +usage() +{ + echo "usage: $(basename $0) [--active] [--] [LS_OPTIONS...]" >&2 +} + +help() { + usage + echo >&2 + echo "List containers existing on the system." >&2 + echo >&2 + echo " --active list active containers" >&2 + echo " LS_OPTIONS ls command options (see \`ls --help')" >&2 +} + +get_parent_cgroup() +{ + parent_cgroup="" + + # Obtain a list of hierarchies that contain one or more subsystems + hierarchies=$(tail -n +2 /proc/cgroups | cut -f 2) + + # Iterate through the list until a suitable hierarchy is found + for hierarchy in $hierarchies; do + # Obtain information about the init process in the hierarchy + fields=$(grep -E "^$hierarchy:" /proc/1/cgroup | head -n 1) + if [ -z "$fields" ]; then continue; fi + fields=${fields#*:} + + # Get a comma-separated list of the hierarchy's subsystems + subsystems=${fields%:*} + + # Get the cgroup of the init process in the hierarchy + init_cgroup=${fields#*:} + + # Get the filesystem mountpoint of the hierarchy + mountpoint=$(awk -v subsysregex="(^|,)$subsystems(,|\$)" \ + '$3 == "cgroup" && $4 ~ subsysregex {print $2}' /proc/self/mounts) + if [ -z "$mountpoint" ]; then continue; fi + + # Return the absolute path to the containers' parent cgroup + # (do not append '/lxc' if the hierarchy contains the 'ns' subsystem) + case ",$subsystems," in + *,ns,*) parent_cgroup="${mountpoint}${init_cgroup%/}";; + *) parent_cgroup="${mountpoint}${init_cgroup%/}/lxc";; + esac + break + done +} + +directory=$(readlink -f "$lxc_path") + +for i in "$@"; do + case $i in + --help) + help; exit;; + --active) + get_parent_cgroup; directory="$parent_cgroup"; shift;; + --) + shift; break;; + *) + break;; + esac +done + +containers="" +if [ ! -z "$directory" ]; then + if [ x"$parent_cgroup" = x ]; then + containers=$(find $directory -mindepth 2 -maxdepth 2 -name config -type f |awk -F "/" '{print $(NF-1)}') + else + containers=$(find $directory -mindepth 1 -maxdepth 1 -type d 2>/dev/null | sed 's:.*/::') + fi + if [ x"$containers" = x ]; then + exit 0 + fi +fi + +cd "$directory" +ls -d $@ -- $containers diff -Nru lxc-0.8.0~rc1/src/lxc/list.h lxc-1.0.0~alpha1/src/lxc/list.h --- lxc-0.8.0~rc1/src/lxc/list.h 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/list.h 2013-09-10 22:22:00.000000000 +0000 @@ -1,3 +1,26 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + #ifndef _list_h #define _list_h @@ -14,6 +37,11 @@ __iterator != __list; \ __iterator = __iterator->next) +#define lxc_list_for_each_safe(__iterator, __list, __next) \ + for (__iterator = (__list)->next, __next = __iterator->next; \ + __iterator != __list; \ + __iterator = __next, __next = __next->next) + static inline void lxc_list_init(struct lxc_list *list) { list->elem = NULL; diff -Nru lxc-0.8.0~rc1/src/lxc/log.c lxc-1.0.0~alpha1/src/lxc/log.c --- lxc-0.8.0~rc1/src/lxc/log.c 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/log.c 2013-09-10 22:22:00.000000000 +0000 @@ -18,7 +18,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include @@ -35,12 +35,19 @@ #include "log.h" #include "caps.h" +#include "utils.h" #define LXC_LOG_PREFIX_SIZE 32 #define LXC_LOG_BUFFER_SIZE 512 int lxc_log_fd = -1; static char log_prefix[LXC_LOG_PREFIX_SIZE] = "lxc"; +static char *log_fname = NULL; +/* command line values for logfile or logpriority should always override + * values from the configuration file or defaults + */ +static int lxc_logfile_specified = 0; +static int lxc_loglevel_specified = 0; lxc_log_define(lxc_log, lxc); @@ -116,10 +123,34 @@ }; /*---------------------------------------------------------------------------*/ -extern void lxc_log_setprefix(const char *prefix) +static int build_dir(const char *name) { - strncpy(log_prefix, prefix, sizeof(log_prefix)); - log_prefix[sizeof(log_prefix) - 1] = 0; + char *n = strdup(name); // because we'll be modifying it + char *p, *e; + int ret; + + if (!n) { + ERROR("Out of memory while creating directory '%s'.", name); + return -1; + } + + e = &n[strlen(n)]; + for (p = n+1; p < e; p++) { + if (*p != '/') + continue; + *p = '\0'; + if (access(n, F_OK)) { + ret = lxc_unpriv(mkdir(n, 0755)); + if (ret && errno != -EEXIST) { + SYSERROR("failed to create directory '%s'.", n); + free(n); + return -1; + } + } + *p = '/'; + } + free(n); + return 0; } /*---------------------------------------------------------------------------*/ @@ -147,13 +178,121 @@ return newfd; } -/*---------------------------------------------------------------------------*/ -extern int lxc_log_init(const char *file, const char *priority, - const char *prefix, int quiet) +/* + * Build the path to the log file + * @name : the name of the container + * @lxcpath : the lxcpath to use as a basename or NULL to use LOGPATH + * Returns malloced path on sucess, or NULL on failure + */ +static char *build_log_path(const char *name, const char *lxcpath) +{ + char *p; + int len, ret, use_dir; + +#if USE_CONFIGPATH_LOGS + use_dir = 1; +#else + use_dir = 0; +#endif + + /* + * If USE_CONFIGPATH_LOGS is true or lxcpath is given, the resulting + * path will be: + * '$logpath' + '/' + '$name' + '/' + '$name' + '.log' + '\0' + * + * If USE_CONFIGPATH_LOGS is false the resulting path will be: + * '$logpath' + '/' + '$name' + '.log' + '\0' + */ + len = strlen(name) + 6; /* 6 == '/' + '.log' + '\0' */ + if (lxcpath) + use_dir = 1; + else + lxcpath = LOGPATH; + + if (use_dir) + len += strlen(lxcpath) + 1 + strlen(name) + 1; /* add "/$container_name/" */ + else + len += strlen(lxcpath) + 1; + p = malloc(len); + if (!p) + return p; + + if (use_dir) + ret = snprintf(p, len, "%s/%s/%s.log", lxcpath, name, name); + else + ret = snprintf(p, len, "%s/%s.log", lxcpath, name); + + if (ret < 0 || ret >= len) { + free(p); + return NULL; + } + return p; +} + +/* + * This can be called: + * 1. when a program calls lxc_log_init with no logfile parameter (in which + * case the default is used). In this case lxc.logfile can override this. + * 2. when a program calls lxc_log_init with a logfile parameter. In this + * case we don't want lxc.logfile to override this. + * 3. When a lxc.logfile entry is found in config file. + */ +static int __lxc_log_set_file(const char *fname, int create_dirs) +{ + if (lxc_log_fd != -1) { + // we are overriding the default. + close(lxc_log_fd); + free(log_fname); + } + +#if USE_CONFIGPATH_LOGS + // we don't build_dir for the default if the default is + // i.e. /var/lib/lxc/$container/$container.log + if (create_dirs) +#endif + if (build_dir(fname)) { + ERROR("failed to create dir for log file \"%s\" : %s", fname, + strerror(errno)); + return -1; + } + + lxc_log_fd = log_open(fname); + if (lxc_log_fd == -1) + return -1; + + log_fname = strdup(fname); + return 0; +} + +static int _lxc_log_set_file(const char *name, const char *lxcpath, int create_dirs) +{ + char *logfile; + int ret; + + logfile = build_log_path(name, lxcpath); + if (!logfile) { + ERROR("could not build log path"); + return -1; + } + ret = __lxc_log_set_file(logfile, create_dirs); + free(logfile); + return ret; +} + +extern int lxc_log_init(const char *name, const char *file, + const char *priority, const char *prefix, int quiet, + const char *lxcpath) { int lxc_priority = LXC_LOG_PRIORITY_ERROR; + int ret; + + if (lxc_log_fd != -1) { + WARN("lxc_log_init called with log already initialized"); + return 0; + } if (priority) { + lxc_loglevel_specified = 1; lxc_priority = lxc_log_priority_to_int(priority); if (lxc_priority == LXC_LOG_PRIORITY_NOTSET) { @@ -169,19 +308,100 @@ lxc_log_category_lxc.appender->next = &log_appender_stderr; if (prefix) - lxc_log_setprefix(prefix); + lxc_log_set_prefix(prefix); if (file) { - int fd; - - fd = log_open(file); - if (fd == -1) { - ERROR("failed to initialize log service"); - return -1; - } + lxc_logfile_specified = 1; + if (strcmp(file, "none") == 0) + return 0; + ret = __lxc_log_set_file(file, 1); + } else { + ret = -1; + + if (!lxcpath) + lxcpath = LOGPATH; + + /* try LOGPATH if lxcpath is the default */ + if (strcmp(lxcpath, default_lxc_path()) == 0) + ret = _lxc_log_set_file(name, NULL, 0); + + /* try in lxcpath */ + if (ret < 0) + ret = _lxc_log_set_file(name, lxcpath, 1); + + /* try LOGPATH in case its writable by the caller */ + if (ret < 0) + ret = _lxc_log_set_file(name, NULL, 0); + } - lxc_log_fd = fd; + /* + * If !file, that is, if the user did not request this logpath, then + * ignore failures and continue logging to console + */ + if (!file && ret != 0) { + INFO("Ignoring failure to open default logfile."); + ret = 0; } + return ret; +} + +/* + * This is called when we read a lxc.loglevel entry in a lxc.conf file. This + * happens after processing command line arguments, which override the .conf + * settings. So only set the level if previously unset. + */ +extern int lxc_log_set_level(int level) +{ + if (lxc_loglevel_specified) + return 0; + if (level < 0 || level >= LXC_LOG_PRIORITY_NOTSET) { + ERROR("invalid log priority %d", level); + return -1; + } + lxc_log_category_lxc.priority = level; return 0; } + +extern int lxc_log_get_level(void) +{ + if (!lxc_loglevel_specified) + return LXC_LOG_PRIORITY_NOTSET; + return lxc_log_category_lxc.priority; +} + +extern bool lxc_log_has_valid_level(void) +{ + int log_level = lxc_log_get_level(); + if (log_level < 0 || log_level >= LXC_LOG_PRIORITY_NOTSET) + return false; + return true; +} + +/* + * This is called when we read a lxc.logfile entry in a lxc.conf file. This + * happens after processing command line arguments, which override the .conf + * settings. So only set the file if previously unset. + */ +extern int lxc_log_set_file(const char *fname) +{ + if (lxc_logfile_specified) + return 0; + return __lxc_log_set_file(fname, 0); +} + +extern const char *lxc_log_get_file(void) +{ + return log_fname; +} + +extern void lxc_log_set_prefix(const char *prefix) +{ + strncpy(log_prefix, prefix, sizeof(log_prefix)); + log_prefix[sizeof(log_prefix) - 1] = 0; +} + +extern const char *lxc_log_get_prefix(void) +{ + return log_prefix; +} diff -Nru lxc-0.8.0~rc1/src/lxc/log.h lxc-1.0.0~alpha1/src/lxc/log.h --- lxc-0.8.0~rc1/src/lxc/log.h 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/log.h 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * Cedric Le Goater * * This library is free software; you can redistribute it and/or @@ -19,7 +19,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _log_h #define _log_h @@ -28,6 +28,7 @@ #include #include #include +#include #ifndef O_CLOEXEC #define O_CLOEXEC 02000000 @@ -41,7 +42,7 @@ #define LXC_LOG_BUFFER_SIZE 512 /* predefined priorities. */ -enum { +enum lxc_loglevel { LXC_LOG_PRIORITY_TRACE, LXC_LOG_PRIORITY_DEBUG, LXC_LOG_PRIORITY_INFO, @@ -172,7 +173,7 @@ } /* - * Helper macro to define log fonctions. + * Helper macro to define log functions. */ #define lxc_log_priority_define(acategory, PRIORITY) \ \ @@ -287,8 +288,15 @@ extern int lxc_log_fd; -extern int lxc_log_init(const char *file, const char *priority, - const char *prefix, int quiet); - -extern void lxc_log_setprefix(const char *a_prefix); +extern int lxc_log_init(const char *name, const char *file, + const char *priority, const char *prefix, int quiet, + const char *lxcpath); + +extern int lxc_log_set_file(const char *fname); +extern int lxc_log_set_level(int level); +extern void lxc_log_set_prefix(const char *prefix); +extern const char *lxc_log_get_file(void); +extern int lxc_log_get_level(void); +extern bool lxc_log_has_valid_level(void); +extern const char *lxc_log_get_prefix(void); #endif diff -Nru lxc-0.8.0~rc1/src/lxc/lxc-checkconfig.in lxc-1.0.0~alpha1/src/lxc/lxc-checkconfig.in --- lxc-0.8.0~rc1/src/lxc/lxc-checkconfig.in 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/lxc-checkconfig.in 2013-09-10 22:22:00.000000000 +0000 @@ -1,16 +1,16 @@ -#!/bin/bash +#!/bin/sh # Allow environment variables to override grep and config : ${CONFIG:=/proc/config.gz} : ${GREP:=zgrep} -SETCOLOR_SUCCESS="echo -en \\033[1;32m" -SETCOLOR_FAILURE="echo -en \\033[1;31m" -SETCOLOR_WARNING="echo -en \\033[1;33m" -SETCOLOR_NORMAL="echo -en \\033[0;39m" +SETCOLOR_SUCCESS="printf \\033[1;32m" +SETCOLOR_FAILURE="printf \\033[1;31m" +SETCOLOR_WARNING="printf \\033[1;33m" +SETCOLOR_NORMAL="printf \\033[0;39m" is_set() { - $GREP -q "$1=[y|m]" $CONFIG + $GREP "$1=[y|m]" $CONFIG > /dev/null return $? } @@ -21,18 +21,18 @@ RES=$? if [ $RES -eq 0 ]; then - $SETCOLOR_SUCCESS && echo -e "enabled" && $SETCOLOR_NORMAL + $SETCOLOR_SUCCESS && echo "enabled" && $SETCOLOR_NORMAL else - if [ ! -z "$mandatory" -a "$mandatory" = yes ]; then - $SETCOLOR_FAILURE && echo -e "required" && $SETCOLOR_NORMAL - else - $SETCOLOR_WARNING && echo -e "missing" && $SETCOLOR_NORMAL - fi + if [ ! -z "$mandatory" -a "$mandatory" = yes ]; then + $SETCOLOR_FAILURE && echo "required" && $SETCOLOR_NORMAL + else + $SETCOLOR_WARNING && echo "missing" && $SETCOLOR_NORMAL + fi fi } if [ ! -f $CONFIG ]; then - echo "Kernel config $CONFIG not found, looking in other places..." + echo "Kernel configuration not found at $CONFIG; searching..." KVER="`uname -r`" HEADERS_CONFIG="/lib/modules/$KVER/build/.config" BOOT_CONFIG="/boot/config-$KVER" @@ -40,15 +40,14 @@ [ -f "${BOOT_CONFIG}" ] && CONFIG=${BOOT_CONFIG} GREP=grep if [ ! -f $CONFIG ]; then - echo - echo "The kernel configuration can not be retrieved." - echo "Please recompile with IKCONFIG_PROC, or" - echo "install the kernel headers, or specify" - echo "the path to the config file with: CONFIG= lxc-checkconfig" - echo + echo "$(basename $0): unable to retrieve kernel configuration" >&2 + echo >&2 + echo "Try recompiling with IKCONFIG_PROC, installing the kernel headers," >&2 + echo "or specifying the kernel configuration path with:" >&2 + echo " CONFIG= $(basename $0)" >&2 exit 1 else - echo "Found kernel config file $CONFIG" + echo "Kernel configuration found at $CONFIG" fi fi @@ -69,40 +68,45 @@ } CGROUP_MNT_PATH=`print_cgroups cgroup /proc/self/mounts | head -1` +KVER_MAJOR=$($GREP '^# Linux' $CONFIG | \ + sed -r 's/.* ([0-9])\.[0-9]{1,2}\.[0-9]{1,3}.*/\1/') +if [ "$KVER_MAJOR" = "2" ]; then +KVER_MINOR=$($GREP '^# Linux' $CONFIG | \ + sed -r 's/.* 2.6.([0-9]{2}).*/\1/') +else +KVER_MINOR=$($GREP '^# Linux' $CONFIG | \ + sed -r 's/.* [0-9]\.([0-9]{1,3})\.[0-9]{1,3}.*/\1/') +fi echo -n "Cgroup: " && is_enabled CONFIG_CGROUPS yes if [ -f $CGROUP_MNT_PATH/cgroup.clone_children ]; then echo -n "Cgroup clone_children flag: " && - $SETCOLOR_SUCCESS && echo -e "enabled" && $SETCOLOR_NORMAL + $SETCOLOR_SUCCESS && echo "enabled" && $SETCOLOR_NORMAL else echo -n "Cgroup namespace: " && is_enabled CONFIG_CGROUP_NS yes fi echo -n "Cgroup device: " && is_enabled CONFIG_CGROUP_DEVICE echo -n "Cgroup sched: " && is_enabled CONFIG_CGROUP_SCHED echo -n "Cgroup cpu account: " && is_enabled CONFIG_CGROUP_CPUACCT -echo -n "Cgroup memory controller: " && is_enabled CONFIG_CGROUP_MEM_RES_CTLR +echo -n "Cgroup memory controller: " +if [ $KVER_MAJOR -ge 3 -a $KVER_MINOR -ge 6 ]; then + is_enabled CONFIG_MEMCG +else + is_enabled CONFIG_CGROUP_MEM_RES_CTLR +fi is_set CONFIG_SMP && echo -n "Cgroup cpuset: " && is_enabled CONFIG_CPUSETS echo echo "--- Misc ---" echo -n "Veth pair device: " && is_enabled CONFIG_VETH echo -n "Macvlan: " && is_enabled CONFIG_MACVLAN echo -n "Vlan: " && is_enabled CONFIG_VLAN_8021Q -KVER_MAJOR=$($GREP '^# Linux' $CONFIG | \ - sed -r 's/.* ([0-9])\.[0-9]{1,2}\.[0-9]{1,3}.*/\1/') -if [[ $KVER_MAJOR == 2 ]]; then -KVER_MINOR=$($GREP '^# Linux' $CONFIG | \ - sed -r 's/.* 2.6.([0-9]{2}).*/\1/') -else -KVER_MINOR=$($GREP '^# Linux' $CONFIG | \ - sed -r 's/.* [0-9]\.([0-9]{1,3})\.[0-9]{1,3}.*/\1/') -fi -echo -n "File capabilities: " && - ( [[ ${KVER_MAJOR} == 2 && ${KVER_MINOR} < 33 ]] && - is_enabled CONFIG_SECURITY_FILE_CAPABILITIES ) || - ( [[ ( ${KVER_MAJOR} == 2 && ${KVER_MINOR} > 32 ) || - ${KVER_MAJOR} > 2 ]] && $SETCOLOR_SUCCESS && - echo -e "enabled" && $SETCOLOR_NORMAL ) +echo -n "File capabilities: " && \ + ( [ "${KVER_MAJOR}" = 2 ] && [ ${KVER_MINOR} -lt 33 ] && \ + is_enabled CONFIG_SECURITY_FILE_CAPABILITIES ) || \ + ( ( [ "${KVER_MAJOR}" = "2" ] && [ ${KVER_MINOR} -gt 32 ] ) || \ + [ ${KVER_MAJOR} -gt 2 ] && $SETCOLOR_SUCCESS && \ + echo "enabled" && $SETCOLOR_NORMAL ) echo echo "Note : Before booting a new kernel, you can check its configuration" diff -Nru lxc-0.8.0~rc1/src/lxc/lxc-clone.in lxc-1.0.0~alpha1/src/lxc/lxc-clone.in --- lxc-0.8.0~rc1/src/lxc/lxc-clone.in 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/lxc-clone.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,280 +0,0 @@ -#!/bin/bash - -# -# lxc: linux Container library - -# Authors: -# Serge Hallyn -# Daniel Lezcano - -# 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 - -set -e - -usage() { - echo "usage: lxc-clone -o -n [-s] [-h] [-L fssize] [-v vgname] [-p lxc_lv_prefix] [-t fstype]" -} - -help() { - usage - echo - echo "creates a lxc system object." - echo - echo "Options:" - echo "orig : name of the original container" - echo "new : name of the new container" - echo "-s : make the new rootfs a snapshot of the original" - echo "fssize : size if creating a new fs. By default, 2G" - echo "vgname : lvm volume group name, lxc by default" - echo "lvprefix : lvm volume name prefix, none by default, e.g. --lvprefix=lxc_ then new lxc lv name will be lxc_newname" - echo "fstype : new container file system type, ext3 by default (only works for non-snapshot lvm)" -} - -shortoptions='ho:n:sL:v:p:t:' -longoptions='help,orig:,name:,snapshot,fssize:,vgname:,lvprefix:,fstype:' -localstatedir=@LOCALSTATEDIR@ -lxc_path=@LXCPATH@ -bindir=@BINDIR@ -snapshot=no -lxc_size=2G -lxc_vg=lxc -lxc_lv_prefix="" -fstype=ext3 - -getopt=$(getopt -o $shortoptions --longoptions $longoptions -- "$@") -if [ $? != 0 ]; then - usage - exit 1; -fi - -eval set -- "$getopt" - -while true; do - case "$1" in - -h|--help) - help - exit 1 - ;; - -s|--snapshot) - shift - snapshot=yes - snapshot_opt="-s" - ;; - -o|--orig) - shift - lxc_orig=$1 - shift - ;; - -L|--fssize) - shift - lxc_size=$1 - shift - ;; - -v|--vgname) - shift - lxc_vg=$1 - shift - ;; - -n|--new) - shift - lxc_new=$1 - shift - ;; - -p|--lvprefix) - shift - lxc_lv_prefix=$1 - shift - ;; - --) - shift - break - ;; - *) - echo $1 - usage - exit 1 - ;; - esac -done - -if [ -z "$lxc_path" ]; then - echo "no configuration path defined !" - exit 1 -fi - -if [ ! -r $lxc_path ]; then - echo "configuration path '$lxc_path' not found" - exit 1 -fi - -if [ -z "$lxc_orig" ]; then - echo "no original container name specified" - usage - exit 1 -fi - -if [ -z "$lxc_new" ]; then - echo "no new container name specified" - usage - exit 1 -fi - -if [ "$(id -u)" != "0" ]; then - echo "This command has to be run as root" - exit 1 -fi - -if [ ! -r $lxc_path ]; then - echo "no configuration path defined !" - exit 1 -fi - -if [ ! -d "$lxc_path/$lxc_orig" ]; then - echo "'$lxc_orig' does not exist" - exit 1 -fi - -if [ -d "$lxc_path/$lxc_new" ]; then - echo "'$lxc_new' already exists" - exit 1 -fi - -mounted=0 -frozen=0 -oldroot=`grep lxc.rootfs $lxc_path/$lxc_orig/config | awk -F= '{ print $2 '}` - -cleanup() { - if [ -b $oldroot ]; then - if [ $mounted -eq 1 ]; then - umount $rootfs || true - fi - lvremove -f $rootdev || true - fi - ${bindir}/lxc-destroy -n $lxc_new || true - if [ $frozen -eq 1 ]; then - lxc-unfreeze -n $lxc_orig - fi - echo aborted - exit 1 -} -trap cleanup SIGHUP SIGINT SIGTERM - -mkdir -p $lxc_path/$lxc_new -hostname=$lxc_new - -echo "Tweaking configuration" -cp $lxc_path/$lxc_orig/config $lxc_path/$lxc_new/config -sed -i '/lxc.utsname/d' $lxc_path/$lxc_new/config -echo "lxc.utsname = $hostname" >> $lxc_path/$lxc_new/config - -grep "lxc.mount =" $lxc_path/$lxc_new/config >/dev/null 2>&1 && { sed -i '/lxc.mount =/d' $lxc_path/$lxc_new/config; echo "lxc.mount = $lxc_path/$lxc_new/fstab" >> $lxc_path/$lxc_new/config; } - -if [ -e $lxc_path/$lxc_orig/fstab ];then - cp $lxc_path/$lxc_orig/fstab $lxc_path/$lxc_new/fstab - sed -i "s@$lxc_path/$lxc_orig@$lxc_path/$lxc_new@" $lxc_path/$lxc_new/fstab -fi - -echo "Copying rootfs..." -rootfs=$lxc_path/$lxc_new/rootfs - -container_running=True -lxc-info -s -n $lxc_orig|grep RUNNING >/dev/null 2>&1 || container_running=False - -sed -i '/lxc.rootfs/d' $lxc_path/$lxc_new/config -oldroot=`grep lxc.rootfs $lxc_path/$lxc_orig/config | awk -F= '{ print $2 '}` -if [ -b $oldroot ]; then - type vgscan || { echo "Please install lvm"; false; } - lvdisplay $oldroot > /dev/null 2>&1 || { echo "non-lvm blockdev cloning not supported"; false; } - lvm=TRUE - # ok, create a snapshot of the lvm device - if [ $container_running = "True" ]; then - lxc-freeze -n $lxc_orig - frozen=1 - fi - lvcreate -s -L $lxc_size -n ${lxc_lv_prefix}${lxc_new}_snapshot $oldroot - if [ $container_running = "True" ]; then - lxc-unfreeze -n $lxc_orig - frozen=0 - fi - if [ $snapshot = "no" ]; then - #mount snapshot - mkdir -p ${rootfs}_snapshot - mount /dev/$lxc_vg/${lxc_lv_prefix}${lxc_new}_snapshot ${rootfs}_snapshot || { echo "failed to mount new rootfs_snapshot"; false; } - #create a new lv - lvcreate -L $lxc_size $lxc_vg -n ${lxc_lv_prefix}$lxc_new - echo "lxc.rootfs = /dev/$lxc_vg/${lxc_lv_prefix}$lxc_new" >> $lxc_path/$lxc_new/config - # and mount it so we can tweak it - mkdir -p $lxc_path/$lxc_new/rootfs - mkfs -t $fstype /dev/$lxc_vg/${lxc_lv_prefix}$lxc_new - mount /dev/$lxc_vg/${lxc_lv_prefix}$lxc_new $rootfs || { echo "failed to mount new rootfs"; false; } - mounted=1 - rsync -ax ${rootfs}_snapshot/ ${rootfs}/ || { echo "copy of data to new lv failed"; false; } - umount ${rootfs}_snapshot - rmdir ${rootfs}_snapshot - lvremove -f $lxc_vg/${lxc_lv_prefix}${lxc_new}_snapshot - else - lvrename $lxc_vg/${lxc_lv_prefix}${lxc_new}_snapshot $lxc_vg/${lxc_lv_prefix}$lxc_new - echo "lxc.rootfs = /dev/$lxc_vg/${lxc_lv_prefix}$lxc_new" >> $lxc_path/$lxc_new/config - # and mount it so we can tweak it - mkdir -p $lxc_path/$lxc_new/rootfs - mount /dev/$lxc_vg/${lxc_lv_prefix}$lxc_new $rootfs || { echo "failed to mount new rootfs"; false; } - mounted=1 - fi - -elif out=$(btrfs subvolume list "$lxc_path/$lxc_orig/rootfs" 2>&1); then - - out=$(btrfs subvolume snapshot "$lxc_path/$lxc_orig/rootfs" "$rootfs" 2>&1) || { echo "failed btrfs snapshot"; false; } - echo "lxc.rootfs = $rootfs" >> "$lxc_path/$lxc_new/config" - -else - if [ $snapshot = "yes" ]; then - echo "Can't snapshot a directory" - cleanup - fi - if [ $container_running = "True" ]; then - lxc-freeze -n $lxc_orig - frozen=1 - fi - mkdir -p $lxc_path/$lxc_new/rootfs/ - rsync -ax $lxc_path/$lxc_orig/rootfs/ $lxc_path/$lxc_new/rootfs/ - echo "lxc.rootfs = $rootfs" >> $lxc_path/$lxc_new/config - if [ $container_running = "True" ]; then - lxc-unfreeze -n $lxc_orig - frozen=0 - fi -fi - -echo "Updating rootfs..." - -# so you can 'ssh $hostname.' or 'ssh $hostname.local' -if [ -f $rootfs/etc/dhcp/dhclient.conf ]; then - sed -i "s/send host-name.*$/send host-name \"$hostname\";/" $rootfs/etc/dhcp/dhclient.conf -fi - -# set the hostname -cat < $rootfs/etc/hostname -$hostname -EOF -# set minimal hosts -cat < $rootfs/etc/hosts -127.0.0.1 localhost $hostname -EOF - -# if this was a block device, then umount it now -if [ $mounted -eq 1 ]; then - umount $rootfs -fi - -echo "'$lxc_new' created" diff -Nru lxc-0.8.0~rc1/src/lxc/lxc-create.in lxc-1.0.0~alpha1/src/lxc/lxc-create.in --- lxc-0.8.0~rc1/src/lxc/lxc-create.in 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/lxc-create.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,318 +0,0 @@ -#!/bin/bash - -# -# lxc: linux Container library - -# Authors: -# Daniel Lezcano - -# 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 - -usage() { - echo "usage: lxc-create -n [-f configuration] [-t template] [-h] [fsopts] -- [template_options]" - echo " fsopts: -B none" - echo " fsopts: -B lvm [--lvname lvname] [--vgname vgname] [--fstype fstype] [--fssize fssize]" - echo " fsopts: -B btrfs" - echo " flag is not necessary, if possible btrfs support will be used" -# echo " fsopts: -B union [--uniontype overlayfs]" -# echo " fsopts: -B loop [--fstype fstype] [--fssize fssize]" -# echo " fsopts: -B qemu-nbd [--type qed|qcow2|raw] [--fstype fstype] [--fssize fssize] # Qemu qed disk format" -} - -help() { - usage - echo - echo "creates a lxc system object." - echo - echo "Options:" - echo "name : name of the container" - echo "configuration: lxc configuration" - echo "template : lxc-template is an accessible template script" - echo - echo "The container backing store can be altered using '-B'. By default it" - echo "is 'none', which is a simple directory tree under /var/lib/lxc//rootfs" - echo "Otherwise, the following option values may be relevant:" - echo "lvname : [for -lvm] name of lv in which to create lv," - echo " container-name by default" - echo "vgname : [for -lvm] name of vg in which to create lv, 'lxc' by default" - echo "fstype : name of filesystem to create, ext4 by default" - echo "fssize : size of filesystem to create, 500M by default" - echo - if [ -z $lxc_template ]; then - echo "for template-specific help, specify a template, for instance:" - echo "lxc-create -t ubuntu -h" - exit 0 - fi - type ${templatedir}/lxc-$lxc_template >/dev/null - echo - echo "template-specific help follows: (these options follow '--')" - if [ $? -eq 0 ]; then - ${templatedir}/lxc-$lxc_template -h - fi -} - -shortoptions='hn:f:t:B:' -longoptions='help,name:,config:,template:,backingstore:,fstype:,lvname:,vgname:,fssize:' -localstatedir=@LOCALSTATEDIR@ -lxc_path=@LXCPATH@ -bindir=@BINDIR@ -libdir=@LIBDIR@ -templatedir=@LXCTEMPLATEDIR@ -backingstore=_unset -fstype=ext4 -fssize=500M -vgname=lxc - -getopt=$(getopt -o $shortoptions --longoptions $longoptions -- "$@") -if [ $? != 0 ]; then - usage - exit 1; -fi - -eval set -- "$getopt" - -while true; do - case "$1" in - -h|--help) - help - exit 1 - ;; - -n|--name) - shift - lxc_name=$1 - shift - ;; - -f|--config) - shift - lxc_config=$1 - shift - ;; - -t|--template) - shift - lxc_template=$1 - shift - ;; - -B|--backingstore) - shift - backingstore=$1 - shift - ;; - --lvname) - shift - lvname=$1 - shift - ;; - --vgname) - shift - vgname=$1 - shift - ;; - --fstype) - shift - fstype=$1 - shift - ;; - --fssize) - shift - fssize=$1 - shift - ;; - --) - shift - break;; - *) - echo $1 - usage - exit 1 - ;; - esac -done - -if [ -z "$lxc_path" ]; then - echo "no configuration path defined !" - exit 1 -fi - -if [ ! -r $lxc_path ]; then - echo "configuration path '$lxc_path' not found" - exit 1 -fi - -if [ -z "$lxc_name" ]; then - echo "no container name specified" - usage - exit 1 -fi - -if [ -z "$lvname" ]; then - lvname="$lxc_name" -fi - -if [ "$(id -u)" != "0" ]; then - echo "This command has to be run as root" - exit 1 -fi - -case "$backingstore" in - lvm|none|btrfs|_unset) :;; - *) echo "'$backingstore' is not known ('none', 'lvm', 'btrfs')" - usage - exit 1 - ;; -esac - -if [ -d "$lxc_path/$lxc_name" ]; then - echo "'$lxc_name' already exists" - exit 1 -fi - -rootfs="$lxc_path/$lxc_name/rootfs" - -if [ "$backingstore" = "_unset" -o "$backingstore" = "btrfs" ]; then -# if no backing store was given, then see if btrfs would work - if which btrfs >/dev/null 2>&1 && - btrfs filesystem df "$lxc_path/" >/dev/null 2>&1; then - backingstore="btrfs" - else - if [ "$backingstore" = "btrfs" ]; then - echo "missing 'btrfs' command or $lxc_path is not btrfs"; - exit 1; - fi - backingstore="none" - fi -fi - -if [ $backingstore = "lvm" ]; then - which vgscan > /dev/null - if [ $? -ne 0 ]; then - echo "vgscan not found. Please install lvm2 package" - exit 1 - fi - grep -q "\<$fstype\>" /proc/filesystems - if [ $? -ne 0 ]; then - echo "$fstype is not listed in /proc/filesystems" - usage - exit 1 - fi - - vgscan | grep -q "Found volume group \"$vgname\"" - if [ $? -ne 0 ]; then - echo "Could not find volume group \"$vgname\"" - usage - exit 1 - fi - - rootdev=/dev/$vgname/$lvname - lvdisplay $rootdev > /dev/null 2>&1 - if [ $? -eq 0 ]; then - echo "backing store already exists: $rootdev" - echo "please delete it (using \"lvremove $rootdev\") and try again" - exit 1 - fi -elif [ "$backingstore" = "btrfs" ]; then - mkdir "$lxc_path/$lxc_name" - if ! out=$(btrfs subvolume create "$rootfs" 2>&1); then - echo "failed to create subvolume in $rootfs: $out"; - exit 1; - fi -fi - -cleanup() { - if [ $backingstore = "lvm" ]; then - umount $rootfs - lvremove -f $rootdev - fi - ${bindir}/lxc-destroy -n $lxc_name - echo aborted - exit 1 -} - -trap cleanup SIGHUP SIGINT SIGTERM - -mkdir -p $lxc_path/$lxc_name - -if [ -z "$lxc_config" ]; then - touch $lxc_path/$lxc_name/config -else - if [ ! -r "$lxc_config" ]; then - echo "'$lxc_config' configuration file not found" - exit 1 - fi - - cp $lxc_config $lxc_path/$lxc_name/config -fi - -# Create the fs as needed -[ -d "$rootfs" ] || mkdir $rootfs -if [ $backingstore = "lvm" ]; then - lvcreate -L $fssize -n $lvname $vgname || exit 1 - udevadm settle - mkfs -t $fstype $rootdev || exit 1 - mount -t $fstype $rootdev $rootfs -fi - -if [ ! -z $lxc_template ]; then - - type ${templatedir}/lxc-$lxc_template >/dev/null - if [ $? -ne 0 ]; then - echo "unknown template '$lxc_template'" - cleanup - fi - - if [ -z "$lxc_config" ]; then - echo - echo "Warning:" - echo "-------" - echo "Usually the template option is called with a configuration" - echo "file option too, mostly to configure the network." - echo "eg. lxc-create -n foo -f lxc.conf -t debian" - echo "The configuration file is often:" - echo - echo "lxc.network.type=macvlan" - echo "lxc.network.link=eth0" - echo "lxc.network.flags=up" - echo - echo "or alternatively:" - echo - echo "lxc.network.type=veth" - echo "lxc.network.link=br0" - echo "lxc.network.flags=up" - echo - echo "For more information look at lxc.conf (5)" - echo - echo "At this point, I assume you know what you do." - echo "Press to continue ..." - read dummy - fi - - ${templatedir}/lxc-$lxc_template --path=$lxc_path/$lxc_name --name=$lxc_name $* - if [ $? -ne 0 ]; then - echo "failed to execute template '$lxc_template'" - cleanup - fi - - echo "'$lxc_template' template installed" -fi - -if [ $backingstore = "lvm" ]; then - echo "Unmounting LVM" - umount $rootfs - - # TODO: make the templates set this right from the start? - sed -i '/lxc.rootfs/d' $lxc_path/$lxc_name/config - echo "lxc.rootfs = $rootdev" >> $lxc_path/$lxc_name/config -fi - -echo "'$lxc_name' created" diff -Nru lxc-0.8.0~rc1/src/lxc/lxc-destroy.in lxc-1.0.0~alpha1/src/lxc/lxc-destroy.in --- lxc-0.8.0~rc1/src/lxc/lxc-destroy.in 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/lxc-destroy.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,110 +0,0 @@ -#!/bin/bash - -# -# lxc: linux Container library - -# Authors: -# Daniel Lezcano - -# 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 - -# -# This script allows to set or remove the capabilities on the lxc tools. -# When the capabilities are set, a non root user can manage the containers. -# - -usage() { - echo "usage: $0 -n [-f]" - echo " -f: if a container is running, stop it first. Default is to abort" -} - -if [ "$(id -u)" != "0" ]; then - echo "This command has to be run as root" - exit 1 -fi - -shortoptions='n:f' -longoptions='name:' -localstatedir=@LOCALSTATEDIR@ -lxc_path=@LXCPATH@ -force=0 - -getopt=$(getopt -o $shortoptions --longoptions $longoptions -- "$@") -if [ $? != 0 ]; then - usage $0 - exit 1; -fi - -eval set -- "$getopt" - -while true; do - case "$1" in - -n|--name) - shift - lxc_name=$1 - shift - ;; - -f) - force=1 - shift - ;; - --) - shift - break;; - *) - echo $1 - usage $0 - exit 1 - ;; - esac -done - -if [ -z "$lxc_name" ]; then - echo "no container name specified" - usage $0 - exit 1 -fi - -if [ ! -d "$lxc_path/$lxc_name" ]; then - echo "'$lxc_name' does not exist" - exit 1 -fi - -# make sure the container isn't running -lxc-info -n $lxc_name 2>/dev/null | grep -q RUNNING -if [ $? -eq 0 ]; then - if [ $force -eq 1 ]; then - lxc-stop -n $lxc_name - else - echo "Container $lxc_name is running, aborting the deletion." - exit 1 - fi -fi - -# Deduce the type of rootfs -# If LVM partition, destroy it. If anything else, ignore it. We'll support -# deletion of others later. -rootdev=`grep lxc.rootfs $lxc_path/$lxc_name/config 2>/dev/null | sed -e 's/^[^/]*/\//'` -if [ ! -z "$rootdev" ]; then - if [ -b "$rootdev" -o -h "$rootdev" ]; then - lvdisplay $rootdev > /dev/null 2>&1 - if [ $? -eq 0 ]; then - echo "removing backing store: $rootdev" - lvremove -f $rootdev - fi - fi -fi -# recursively remove the container to remove old container configuration -rm -rf --one-file-system --preserve-root $lxc_path/$lxc_name diff -Nru lxc-0.8.0~rc1/src/lxc/lxc-device lxc-1.0.0~alpha1/src/lxc/lxc-device --- lxc-0.8.0~rc1/src/lxc/lxc-device 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/lxc-device 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,99 @@ +#!/usr/bin/python3 +# +# lxc-device: Add devices to a running container +# +# This python implementation is based on the work done in the original +# shell implementation done by Serge Hallyn in Ubuntu (and other contributors) +# +# (C) Copyright Canonical Ltd. 2012 +# +# Authors: +# Stéphane Graber +# +# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# + +# NOTE: To remove once the API is stabilized +import warnings +warnings.filterwarnings("ignore", "The python-lxc API isn't yet stable") + +import argparse +import gettext +import lxc +import os +import sys + +_ = gettext.gettext +gettext.textdomain("lxc-device") + +# Begin parsing the command line +parser = argparse.ArgumentParser(description=_("LXC: Manage devices"), + formatter_class=argparse.RawTextHelpFormatter) + +# Global arguments +parser.add_argument("-n", dest="container", metavar="CONTAINER", + help=_("Name of the container to add the device to"), + required=True) + +parser.add_argument("-P", "--lxcpath", dest="lxcpath", metavar="PATH", + help=_("Use specified container path"), default=None) + +# Commands +subparsers = parser.add_subparsers() +subparser_add = subparsers.add_parser('add', help=_('Add a device')) +subparser_add.set_defaults(action="add") + +subparser_add.add_argument(dest="device", metavar="DEVICE", + help=_("Add a device " + "(path to a node or interface name)")) + +subparser_add.add_argument(dest="name", metavar="NAME", nargs="?", + help=_("Use an alternative path or name " + "in the container")) + +args = parser.parse_args() + +# Some basic checks +if not hasattr(args, "action"): + parser.error(_("You must specify an action.")) + +## The user needs to be uid 0 +if not os.geteuid() == 0: + parser.error(_("You must be root to run this script. Try running: sudo %s" + % (sys.argv[0]))) + +## Don't rename if no alternative name +if not args.name: + args.name = args.device + +## Check that the container is ready +container = lxc.Container(args.container, args.lxcpath) + +if not container.running: + parser.error("The container must be running.") + +# Do the work +if args.action == "add": + if os.path.exists("/sys/class/net/%s/" % args.device): + ret = container.add_device_net(args.device, args.name) + else: + ret = container.add_device_node(args.device, args.name) + + if ret: + print("Added '%s' to '%s' as '%s'." % + (args.device, container.name, args.name)) + else: + print("Failed to add '%s' to '%s' as '%s'." % + (args.device, container.name, args.name)) diff -Nru lxc-0.8.0~rc1/src/lxc/lxc-ls lxc-1.0.0~alpha1/src/lxc/lxc-ls --- lxc-0.8.0~rc1/src/lxc/lxc-ls 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/lxc-ls 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,312 @@ +#!/usr/bin/python3 +# +# lxc-ls: List containers +# +# This python implementation is based on the work done in the original +# shell implementation done by Serge Hallyn in Ubuntu (and other contributors) +# +# (C) Copyright Canonical Ltd. 2012 +# +# Authors: +# Stéphane Graber +# +# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# + +# NOTE: To remove once the API is stabilized +import warnings +warnings.filterwarnings("ignore", "The python-lxc API isn't yet stable") + +import argparse +import gettext +import json +import lxc +import os +import re +import subprocess +import sys + +_ = gettext.gettext +gettext.textdomain("lxc-ls") + + +# Functions used later on +def batch(iterable, cols=1): + import math + + length = len(iterable) + lines = math.ceil(length / cols) + + for line in range(lines): + fields = [] + for col in range(cols): + index = line + (col * lines) + if index < length: + fields.append(iterable[index]) + yield fields + + +def getTerminalSize(): + import os + env = os.environ + + def ioctl_GWINSZ(fd): + try: + import fcntl + import termios + import struct + cr = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ, + '1234')) + return cr + except: + return + + cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2) + if not cr: + try: + fd = os.open(os.ctermid(), os.O_RDONLY) + cr = ioctl_GWINSZ(fd) + os.close(fd) + except: + pass + + if not cr: + cr = (env.get('LINES', 25), env.get('COLUMNS', 80)) + + return int(cr[1]), int(cr[0]) + + +def getSubContainers(container, lxcpath): + attach = ['lxc-attach', '-P', lxcpath, '-R', '-s', 'NETWORK|PID', + '-n', container, + '--', sys.argv[0], "--nesting"] + + with open(os.devnull, "w") as fd: + newenv = dict(os.environ) + newenv['NESTED'] = "/proc/1/root/%s" % lxc.default_config_path + sp = subprocess.Popen(attach, stderr=fd, stdout=subprocess.PIPE, + env=newenv, universal_newlines=True) + sp.wait() + out = sp.stdout.read() + if out: + return json.loads(out) + return None + + +# Begin parsing the command line +parser = argparse.ArgumentParser(description=_("LXC: List containers"), + formatter_class=argparse.RawTextHelpFormatter) + +parser.add_argument("-1", dest="one", action="store_true", + help=_("list one container per line (default when piped)")) + +parser.add_argument("-P", "--lxcpath", dest="lxcpath", metavar="PATH", + help=_("Use specified container path"), + default=lxc.default_config_path) + +parser.add_argument("--active", action="store_true", + help=_("list only active containers " + "(same as --running --frozen)")) + +parser.add_argument("--frozen", dest="state", action="append_const", + const="FROZEN", help=_("list only frozen containers")) + +parser.add_argument("--running", dest="state", action="append_const", + const="RUNNING", help=_("list only running containers")) + +parser.add_argument("--stopped", dest="state", action="append_const", + const="STOPPED", help=_("list only stopped containers")) + +parser.add_argument("--fancy", action="store_true", + help=_("use fancy output")) + +parser.add_argument("--fancy-format", type=str, default="name,state,ipv4,ipv6", + help=_("comma separated list of fields to show")) + +parser.add_argument("--nesting", dest="nesting", action="store_true", + help=_("show nested containers")) + +parser.add_argument("filter", metavar='FILTER', type=str, nargs="?", + help=_("regexp to be applied on the container list")) + +args = parser.parse_args() + +# --active is the same as --running --frozen +if args.active: + if not args.state: + args.state = [] + args.state += ["RUNNING", "FROZEN"] + +# If the output is piped, default to --one +if not sys.stdout.isatty(): + args.one = True + +# Set the lookup path for the containers +lxcpath = os.environ.get('NESTED', args.lxcpath) + +# Turn args.fancy_format into a list +args.fancy_format = args.fancy_format.strip().split(",") + +# Basic checks +## The user needs to be uid 0 +if not os.geteuid() == 0 and (args.fancy or args.state): + parser.error(_("You must be root to access advanced container properties. " + "Try running: sudo %s" + % (sys.argv[0]))) + +# List of containers, stored as dictionaries +containers = [] +for container_name in lxc.list_containers(config_path=lxcpath): + entry = {} + entry['name'] = container_name + + # Apply filter + if args.filter and not re.match(args.filter, container_name): + continue + + # Return before grabbing the object (non-root) + if not args.state and not args.fancy and not args.nesting: + containers.append(entry) + continue + + container = lxc.Container(container_name, args.lxcpath) + + # Filter by status + if args.state and container.state not in args.state: + continue + + # Nothing more is needed if we're not printing some fancy output + if not args.fancy and not args.nesting: + containers.append(entry) + continue + + # Some extra field we may want + if 'state' in args.fancy_format or args.nesting: + entry['state'] = container.state + + if 'pid' in args.fancy_format or args.nesting: + entry['pid'] = "-" + if container.init_pid != -1: + entry['pid'] = str(container.init_pid) + + # Get the IPs + for family, protocol in {'inet': 'ipv4', 'inet6': 'ipv6'}.items(): + if protocol in args.fancy_format or args.nesting: + entry[protocol] = "-" + ips = container.get_ips(family=family) + if ips: + entry[protocol] = ", ".join(ips) + + # Append the container + containers.append(entry) + + # Nested containers + if args.nesting: + sub = getSubContainers(container_name, args.lxcpath) + if sub: + for entry in sub: + if 'nesting_parent' not in entry: + entry['nesting_parent'] = [] + entry['nesting_parent'].insert(0, container_name) + entry['nesting_real_name'] = entry.get('nesting_real_name', + entry['name']) + entry['name'] = "%s/%s" % (container_name, entry['name']) + containers += sub + +# Deal with json output: +if 'NESTED' in os.environ: + print(json.dumps(containers)) + sys.exit(0) + +# Print the list +## Standard list with one entry per line +if not args.fancy and args.one: + for container in sorted(containers, + key=lambda container: container['name']): + print(container['name']) + sys.exit(0) + +## Standard list with multiple entries per line +if not args.fancy and not args.one: + # Get the longest name and extra simple list + field_maxlength = 0 + container_names = [] + for container in containers: + if len(container['name']) > field_maxlength: + field_maxlength = len(container['name']) + container_names.append(container['name']) + + # Figure out how many we can put per line + width = getTerminalSize()[0] + + entries = int(width / (field_maxlength + 2)) + if entries == 0: + entries = 1 + + for line in batch(sorted(container_names), entries): + line_format = "" + for index in range(len(line)): + line_format += "{line[%s]:%s}" % (index, field_maxlength + 2) + + print(line_format.format(line=line)) + +## Fancy listing +if args.fancy: + field_maxlength = {} + + # Get the maximum length per field + for field in args.fancy_format: + field_maxlength[field] = len(field) + + for container in containers: + for field in args.fancy_format: + if field == 'name' and 'nesting_real_name' in container: + fieldlen = len(" " * ((len(container['nesting_parent']) - 1) + * 4) + " \_ " + container['nesting_real_name']) + if fieldlen > field_maxlength[field]: + field_maxlength[field] = fieldlen + elif len(container[field]) > field_maxlength[field]: + field_maxlength[field] = len(container[field]) + + # Generate the line format string based on the maximum length and + # a 2 character padding + line_format = "" + index = 0 + for field in args.fancy_format: + line_format += "{fields[%s]:%s}" % (index, field_maxlength[field] + 2) + index += 1 + + # Get the line length minus the padding of the last field + line_length = -2 + for field in field_maxlength: + line_length += field_maxlength[field] + 2 + + # Print header + print(line_format.format(fields=[header.upper() + for header in args.fancy_format])) + print("-" * line_length) + + # Print the entries + for container in sorted(containers, + key=lambda container: container['name']): + fields = [] + for field in args.fancy_format: + if field == 'name' and 'nesting_real_name' in container: + prefix = " " * ((len(container['nesting_parent']) - 1) * 4) + fields.append(prefix + " \_ " + container['nesting_real_name']) + else: + fields.append(container[field]) + + print(line_format.format(fields=fields)) diff -Nru lxc-0.8.0~rc1/src/lxc/lxc-ls.in lxc-1.0.0~alpha1/src/lxc/lxc-ls.in --- lxc-0.8.0~rc1/src/lxc/lxc-ls.in 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/lxc-ls.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,39 +0,0 @@ -#!/bin/bash - -localstatedir=@LOCALSTATEDIR@ -lxcpath=@LXCPATH@ - -if [ ! -r $lxcpath ]; then - exit 0 -fi - -function get_cgroup() -{ - local mount_string - mount_string=$(mount -t cgroup |grep -E -e '^lxc ') - if test -n "$mount_string"; then - mount_point=$(echo $mount_string |cut -d' ' -f3) - return - fi - mount_string=`grep -m1 -E '^[^ \t]+[ \t]+[^ \t]+[ \t]+cgroup' /proc/self/mounts`; - if test -z "$mount_string"; then - echo "failed to find mounted cgroup" - exit 1 - fi - mount_point=`echo "$mount_string" |cut -d' ' -f2`; -} - -ls "$@" $lxcpath - -active=$(netstat -xl 2>/dev/null | grep $lxcpath | \ - sed -e 's#.*'"$lxcpath/"'\(.*\)/command#\1#'); - -if test -n "$active"; then - get_cgroup - if test -n "$mount_point"; then - # get cgroup for init - init_cgroup=`cat /proc/1/cgroup | awk -F: '{ print $3 }' | head -1` - cd $mount_point/$init_cgroup/lxc - ls "$@" -d $active - fi -fi diff -Nru lxc-0.8.0~rc1/src/lxc/lxc-netstat.in lxc-1.0.0~alpha1/src/lxc/lxc-netstat.in --- lxc-0.8.0~rc1/src/lxc/lxc-netstat.in 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/lxc-netstat.in 2013-09-10 22:22:00.000000000 +0000 @@ -1,95 +1,154 @@ -#!/bin/bash -# set -ex +#!/bin/sh + +# +# lxc: linux Container library + +# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +. @DATADIR@/lxc/lxc.functions usage() { - echo "usage: $(basename $0) --name [netstat options]" + echo "usage: $(basename $0) -n|--name [-P|--lxcpath ] -- [netstat_options]" >&2 } help() { - usage - echo - echo "execute netstat for the specified container" - echo "with the added netstat options" - echo - echo "Options:" - echo "name : name of the container" - echo "help : this current help." - echo - echo "to be executed as root." + usage + echo >&2 + echo "Execute 'netstat' for the specified container." >&2 + echo >&2 + echo " --name NAME specify the container name" >&2 + echo " --lxcpath LXC_PATH use an alternate container path" >&2 + echo " NETSTAT_OPTIONS netstat command options (see \`netstat --help')" >&2 } -exec="" +get_parent_cgroup() +{ + parent_cgroup="" + + # Obtain a list of hierarchies that contain one or more subsystems + hierarchies=$(tail -n +2 /proc/cgroups | cut -f 2) + + # Iterate through the list until a suitable hierarchy is found + for hierarchy in $hierarchies; do + # Obtain information about the init process in the hierarchy + fields=$(grep -E "^$hierarchy:" /proc/1/cgroup | head -n 1) + if [ -z "$fields" ]; then continue; fi + fields=${fields#*:} + + # Get a comma-separated list of the hierarchy's subsystems + subsystems=${fields%:*} + + # Get the cgroup of the init process in the hierarchy + init_cgroup=${fields#*:} + + # Get the filesystem mountpoint of the hierarchy + mountpoint=$(awk -v subsysregex="(^|,)$subsystems(,|\$)" \ + '$3 == "cgroup" && $4 ~ subsysregex {print $2}' /proc/self/mounts) + if [ -z "$mountpoint" ]; then continue; fi + + # Return the absolute path to the containers' parent cgroup + # (do not append '/lxc' if the hierarchy contains the 'ns' subsystem) + case ",$subsystems," in + *,ns,*) parent_cgroup="${mountpoint}${init_cgroup%/}";; + *) parent_cgroup="${mountpoint}${init_cgroup%/}/lxc";; + esac + break + done +} -if [ $# -eq 0 ]; then - usage - exit 1 -fi +exec="" -for i in "$@"; do - case $i in - -h|--help) - help; exit 1;; - -n|--name) - name=$2; shift 2;; - --exec) - exec="exec"; shift;; - esac +while true; do + case $1 in + -h|--help) + help; exit 1;; + -n) + # If we already have a value for $name, treat -n as being an + # argument for netstat + if [ -n "$name" ] + then + break + else + name="$2"; shift 2; + fi + ;; + --name) + name=$2; shift 2;; + -P|--lxcpath) + lxc_path="$2"; shift 2;; + --exec) + exec="exec"; shift;; + --) + shift; break;; + *) + break;; + esac done -if [ -z "$exec" ]; then - exec @BINDIR@/lxc-unshare -s MOUNT -- $0 -n $name --exec "$@" +if [ "$(id -u)" != "0" ]; then + echo "$(basename $0): must be run as root" >&2 + exit 1 fi if [ -z "$name" ]; then - usage - exit 1 + usage + exit 1 fi -lxc-info -n $name 2>&1 | grep -q 'STOPPED' -if [ $? -eq 0 ]; then - echo "Container $name is not running" - exit 1 +if [ -z "$lxc_path" ]; then + echo "$(basename $0): no configuration path defined" >&2 + usage + exit 1 fi -cgroups=$(mount -l -t cgroup) -cgroup_path="" - -for i in "$cgroups"; do +if [ -z "$exec" ]; then + exec @BINDIR@/lxc-unshare -s MOUNT -- $0 -n $name -P "$lxc_path" --exec -- "$@" +fi - cgroup_name=$(echo $i | awk ' { print $1 } ') - cgroup_path=$(echo $i | awk ' { print $3 } ') +if lxc-info -n $name -P "$lxc_path" --state-is 'STOPPED'; then + echo "$(basename $0): container '$name' is not running" >&2 + exit 1 +fi - if [ "$cgroup_name" == "lxc" ]; then - break; - fi +get_parent_cgroup +if [ ! -d "$parent_cgroup" ]; then + echo "$(basename $0): no cgroup mount point found" >&2 + exit 1 +fi -done +pid=$(head -1 $parent_cgroup/$name/tasks) -if [ -z "$cgroup_path" ]; then - cgroups=`grep -m1 -E '^[^ \t]+[ \t]+[^ \t]+[ \t]+cgroup' /proc/self/mounts` - for i in "$cgroups"; do - cgroup_path=$(echo $i | awk ' { print $2 } ') - if [ -n $cgroup_path ]; then - break; - fi - done -fi - -if [ -z "$cgroup_path" ]; then - echo "no cgroup mount point found" +if [ -z "$pid" ]; then + echo "$(basename $0): no process found for '$name'" >&2 exit 1 fi -# the container will be in: -# ${cgroup_path}.${init_cgroup_path}."lxc".$name -init_cgroup=`cat /proc/1/cgroup | awk -F: '{ print $3 }' | head -1` -final_cgroup_path=$cgroup_path/$init_cgroup/lxc -pid=$(head -1 $final_cgroup_path/$name/tasks) +tmpdir=$(mktemp -d) -if [ -z "$pid" ]; then - echo "no process found for '$name'" +if [ -z "$tmpdir" -o ! -d "$tmpdir" ]; then + echo "$(basename $0): unable to create temporary directory" >&2 exit 1 fi -mount -n --bind /proc/$pid/net /proc/$$/net && \ +# Bind mount /proc/$pid/net onto /proc/net before calling 'netstat'. +# However, we can not simply bind mount on top of procfs, so we have +# to move procfs out of the way first. +mount -n --move /proc "$tmpdir" && \ + mount -n -t tmpfs tmpfs /proc && \ + mkdir /proc/root /proc/net && \ + mount -n --move "$tmpdir" /proc/root && \ + rmdir "$tmpdir" && \ + mount -n --bind /proc/root/$pid/net /proc/net && \ exec netstat "$@" diff -Nru lxc-0.8.0~rc1/src/lxc/lxc-ps.in lxc-1.0.0~alpha1/src/lxc/lxc-ps.in --- lxc-0.8.0~rc1/src/lxc/lxc-ps.in 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/lxc-ps.in 2013-09-10 22:22:00.000000000 +0000 @@ -1,9 +1,7 @@ -#!/usr/bin/perl -# -# lxc-ps +#!/bin/sh + # -# Authors: -# Daniel Lezcano +# lxc: linux Container library # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -17,216 +15,163 @@ # 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 - -# -# This script allows to -# display processes information with related container name if available. -# -use strict; +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +. @DATADIR@/lxc/lxc.functions -# Some globals - -our $PS_HEADERS; # String containing headers of the ps output -our $PS_PID_INDEX; # Index of the PID column in the ps headers -our @PS_LINES; # Output lines of the ps command - -our $LXC_DISPLAY = 0; # By default do not display container information -our %LXC_NAMES; # Specified container names (if any) - -sub get_container_names { - my $ref_names = shift; - my $lxcpath = '@LXCPATH@'; - - open(active, "netstat -xa | grep $lxcpath |") or return; - while() { - chomp; - s#.*$lxcpath/(.*)/command.*#$1#; - push @$ref_names, $_; - } - close active; -} - -sub get_cgroup { - my $ref_cgroup = shift; - my $mount_string; - - $mount_string=`mount -t cgroup |grep -E -e '^lxc '`; - if ($mount_string) { - # use the one 'lxc' cgroup mount if it exists - chomp($mount_string); - $$ref_cgroup=`echo "$mount_string" |cut -d' ' -f3`; - chomp($$ref_cgroup); - } - # Otherwise (i.e. cgroup-bin) use the first cgroup mount - $mount_string=`grep -m1 -E '^[^ \t]+[ \t]+[^ \t]+[ \t]+cgroup' /proc/self/mounts`; - unless ($mount_string) { - die "unable to find mounted cgroup" unless $$ref_cgroup; - } - chomp($mount_string); - $$ref_cgroup=`echo "$mount_string" |cut -d' ' -f2`; - chomp($$ref_cgroup); - return; -} - -sub get_pids_in_containers { - my $ref_names = shift; - my $ref_cgroup = shift; - my $ref_pids = shift; - my $init_cgroup = shift; - my @pidlist; - - for (@{$ref_names}) { - my $task_file = "$$ref_cgroup/$init_cgroup/lxc/$_/tasks"; - - $LXC_NAMES{$_} = 1; - open(tasks, "cat $task_file 2>/dev/null |") or next; - while () { - chomp $_; - push @pidlist, $_; - } - close tasks; - } - $$ref_pids = join(',', @pidlist); -} - -sub reclaim_pid_index { - my @headers = split " ", $PS_HEADERS; - for my $i (0 .. $#headers) { - if ($headers[$i] eq "PID") { - $PS_PID_INDEX = $i; - return; - } +usage() +{ + echo "usage: $(basename $0) [-P PATH] [--lxc | --host | --name NAME] [[--] [PS_OPTIONS...]" >&2 +} + +help() { + usage + echo >&2 + echo "List current processes with container names." >&2 + echo >&2 + echo " --lxc show processes in all containers" >&2 + echo " --host show processes not related to any container, i.e. to the host" >&2 + echo " --name NAME show processes in the specified container" >&2 + echo " (multiple containers can be separated by commas)" >&2 + echo " -P PATH show container in lxcpath PATH" >&2 + echo " PS_OPTIONS ps command options (see \`ps --help')" >&2 +} + +get_parent_cgroup() +{ + local hierarchies hierarchy fields init_cgroup mountpoint + + parent_cgroup="" + subsystems="" + + # Obtain a list of hierarchies that contain one or more subsystems + hierarchies=$(tail -n +2 /proc/cgroups | cut -f 2) + + # Iterate through the list until a suitable hierarchy is found + for hierarchy in $hierarchies; do + # Obtain information about the init process in the hierarchy + fields=$(grep -E "^$hierarchy:" /proc/1/cgroup | head -n 1) + if [ -z "$fields" ]; then continue; fi + fields=${fields#*:} + + # Get a comma-separated list of the hierarchy's subsystems + subsystems=${fields%:*} + + # Get the cgroup of the init process in the hierarchy + init_cgroup=${fields#*:} + + # Get the filesystem mountpoint of the hierarchy + mountpoint=$(awk -v subsysregex="(^|,)$subsystems(,|\$)" \ + '$3 == "cgroup" && $4 ~ subsysregex {print $2}' /proc/self/mounts) + if [ -z "$mountpoint" ]; then continue; fi + + # Return the absolute path to the containers' parent cgroup + parent_cgroup="${mountpoint}${init_cgroup%/}"; + break + done +} + +containers="" +list_container_processes=0 +while true; do + case $1 in + -h|--help) + help; exit 1;; + -n|--name) + containers=$2; list_container_processes=1; shift 2;; + --lxc) + list_container_processes=1; shift;; + --host) + list_container_processes=-1; shift;; + -P|--lxcpath) + lxc_path=$2; shift 2;; + --) + shift; break;; + *) + break;; + esac +done + +if [ "$list_container_processes" -eq "1" ]; then + set -- -e $@ +fi + +get_parent_cgroup +if [ ! -d "$parent_cgroup" ]; then + echo "$(basename $0): no cgroup mount point found" >&2 + exit 1 +fi + +if [ -z "$containers" ]; then + case ",$subsystems," in + *,ns,*) containers="$(find $parent_cgroup -mindepth 1 -maxdepth 1 -type d 2>/dev/null | sed 's:.*/::')";; + *) containers="$(find $parent_cgroup/lxc -mindepth 1 -maxdepth 1 -type d 2>/dev/null | sed 's:.*/::')";; + esac +fi + +container_field_width=9 +tasks_files= +for container in ${containers}; do + if [ "${#container}" -gt "$container_field_width" ]; then + container_field_width=${#container} + fi + + if ! lxc-info -P $lxc_path -t STOPPED -n $container; then + initpid=`lxc-info -P $lxc_path -p -n $container | awk -F: '{ print $2 }' | awk '{ print $1 }'` + cgroup=`head -n 1 /proc/$initpid/cgroup | awk -F: '{ print $3}'` + if [ -f "$parent_cgroup/$cgroup/tasks" ]; then + tasks_files="$tasks_files $parent_cgroup$cgroup/tasks" + fi + fi +done + +# first file is stdin, the rest are the container tasks +ps "$@" | awk -v container_field_width="$container_field_width" \ + -v list_container_processes="$list_container_processes" ' +# first line is PS header +NR == 1 { + header = $0 + # find pid field index + for (i = 1; i<=NF; i++) + if ($i == "PID") { + pididx = i + break + } + if (pididx == "") { + print("No PID field found") > "/dev/stderr" + header = "" # to signal error condition to the END rule + exit 1 } - print "Cannot find ps PID column !\n"; - exit 1; + next } -sub execute_ps { - open(ps, "ps @_ |") or die "Cannot execute ps command: $!\n"; - - $PS_HEADERS = ; - reclaim_pid_index; - - while () { - push @PS_LINES, $_; - } - close ps; +# store lines from ps with pid as index +NR == FNR { + ps_line[NR] = $0 + pid_of_line[NR] = $pididx + next } -sub get_init_cgroup { - my $filename = "/proc/1/cgroup"; - open(LXC, "$filename"); - my @cgroup = ; - close LXC; - my $container = ''; - foreach ( @cgroup ) { - chomp; - # find the container name after :/ - s/.*:\///o; - } - return $container; -} - -sub get_container { - my $pid = shift; - my $filename = "/proc/$pid/cgroup"; - open(LXC, "$filename"); - # read all lines at once - my @cgroup = ; - close LXC; - my $container = ''; - foreach ( @cgroup ) { - chomp; - # find the container name after :/ - s/.*:\///o; - # chop off everything up to 'lxc/' - s/lxc\///o; - $container = $_; - } - return $container; +# find container name from filename on first line +FNR == 1 { + container = FILENAME + sub(/\/tasks/, "", container) + sub(/.*\//, "", container) } -sub display_headers { - printf "%-10s %s", "CONTAINER", $PS_HEADERS; +# container tasks +{ + container_of_pid[$0] = container } -sub display_usage { - print < \$arg_help, - 'usage' => \$arg_usage, - 'lxc' => \$arg_lxc, - 'name=s' => \@arg_name); - -@arg_name = split(/,/, join(',', @arg_name)); - -# Some help -if ($arg_help) {display_help; exit 0;} -if ($arg_usage) {display_usage; exit 0;} - -if ($ARGV[0] == '--') { - shift @ARGV; -} - -# Should we filter processes related to containers -if ($arg_lxc) { - $LXC_DISPLAY = 1; - get_container_names \@arg_name; -} -if (@arg_name > 0) { - my $cgroup; - my $pid_list; - $LXC_DISPLAY = 2; - - $init_cgroup = get_init_cgroup(); - get_cgroup \$cgroup; - get_pids_in_containers(\@arg_name, \$cgroup, \$pid_list, $init_cgroup); - if ($pid_list) { - @ARGV = ("-p $pid_list",@ARGV); - } -} - -execute_ps @ARGV; - -display_headers; -for (@PS_LINES) { - my @a = split; - my $container = get_container $a[$PS_PID_INDEX]; - if ($LXC_DISPLAY == 2 and not $LXC_NAMES{$container}) {next;} - if ($LXC_DISPLAY == 1 and $container eq '') {next;} - printf "%-10s %s", $container, $_; +END { + if (!header) exit 1 # quit due to internal error + printf("%-" container_field_width "s %s\n", "CONTAINER", header) + for (i in ps_line) { + container = container_of_pid[pid_of_line[i]] + if (list_container_processes == 0 || (container != "") == (list_container_processes > 0) ) + printf("%-" container_field_width "s %s\n", container, ps_line[i]) + } } -exit 0; +' - $tasks_files diff -Nru lxc-0.8.0~rc1/src/lxc/lxc-setcap.in lxc-1.0.0~alpha1/src/lxc/lxc-setcap.in --- lxc-0.8.0~rc1/src/lxc/lxc-setcap.in 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/lxc-setcap.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,115 +0,0 @@ -#!/bin/bash - -# -# lxc: linux Container library - -# Authors: -# Daniel Lezcano - -# 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 - -# -# This script allows to set or remove the capabilities on the lxc tools. -# When the capabilities are set, a non root user can manage the containers. -# - -LXC_ATTACH_CAPS="cap_sys_admin,cap_dac_override" -LXC_CREATE_CAPS="cap_sys_admin" -LXC_NETSTAT_CAPS="cap_sys_admin" -LXC_INIT_CAPS="cap_sys_admin,cap_dac_override" -LXC_COMMON_CAPS="cap_net_admin,cap_net_raw,cap_sys_admin,cap_dac_override" -LXC_UNSHARE_CAPS=$LXC_COMMON_CAPS -LXC_START_CAPS="$LXC_COMMON_CAPS,cap_fowner,cap_sys_chroot,cap_setpcap" -LXC_EXECUTE_CAPS=$LXC_START_CAPS -LXC_RESTART_CAPS="$LXC_START_CAPS,cap_mknod" -LXC_CHECKPOINT_CAPS="$LXC_COMMON_CAPS,cap_sys_ptrace,cap_mknod" -LXC_DROP_CAPS="" - -usage() -{ - echo "lxc-setcap [-d] : set or remove capabilities on the lxc tools" -} - -lxc_setcaps() -{ - setcap $LXC_ATTACH_CAPS=ep @BINDIR@/lxc-attach - setcap $LXC_CREATE_CAPS=ep @BINDIR@/lxc-create - setcap $LXC_EXECUTE_CAPS=ep @BINDIR@/lxc-execute - setcap $LXC_START_CAPS=ep @BINDIR@/lxc-start - setcap $LXC_RESTART_CAPS=ep @BINDIR@/lxc-restart - setcap $LXC_UNSHARE_CAPS=ep @BINDIR@/lxc-unshare - setcap $LXC_NETSTAT_CAPS=ep @BINDIR@/lxc-netstat - setcap $LXC_CHECKPOINT_CAPS=ep @BINDIR@/lxc-checkpoint - setcap $LXC_INIT_CAPS=ep @LXCINITDIR@/lxc-init - - test -e @LXCPATH@ || mkdir -p @LXCPATH@ - chmod 0777 @LXCPATH@ -} - -lxc_dropcaps() -{ - setcap -r @BINDIR@/lxc-attach - setcap -r @BINDIR@/lxc-create - setcap -r @BINDIR@/lxc-execute - setcap -r @BINDIR@/lxc-start - setcap -r @BINDIR@/lxc-restart - setcap -r @BINDIR@/lxc-unshare - setcap -r @BINDIR@/lxc-netstat - setcap -r @BINDIR@/lxc-checkpoint - setcap -r @LXCINITDIR@/lxc-init - chmod 0755 @LXCPATH@ -} - -libdir=@LIBDIR@ -localstatedir=@LOCALSTATEDIR@ - -if [ "$(id -u)" != "0" ]; then - echo "You have to be root to run this script" - exit 1 -fi - -if [ $? != 0 ]; then - usage - exit 1 -fi - -set -- $(getopt dh "$@") - -for i in "$@"; do - case "$1" in - -d) - LXC_DROP_CAPS="yes" - shift - ;; - -h) - usage - exit 0 - ;; - --) - shift - break - ;; - *) - usage - exit 1 - ;; - esac -done; - -if [ -z "$LXC_DROP_CAPS" ]; then - lxc_setcaps -else - lxc_dropcaps -fi diff -Nru lxc-0.8.0~rc1/src/lxc/lxc-setuid.in lxc-1.0.0~alpha1/src/lxc/lxc-setuid.in --- lxc-0.8.0~rc1/src/lxc/lxc-setuid.in 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/lxc-setuid.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,113 +0,0 @@ -#!/bin/bash - -# -# lxc: linux Container library - -# Authors: -# Daniel Lezcano - -# 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 - -# -# This script allows to set or remove the setuid execution bit on the lxc tools. -# When the capabilities are set, a non root user can manage the containers. -# - -usage() -{ - echo "lxc-setuid [-d] : set or remove setuid on the lxc tools" -} - -setuid() -{ - if [ "$1" = "-r" ]; then - chmod -s $2 - else - chmod +s $1 - fi -} - -lxc_setuid() -{ - setuid @BINDIR@/lxc-attach - setuid @BINDIR@/lxc-create - setuid @BINDIR@/lxc-execute - setuid @BINDIR@/lxc-start - setuid @BINDIR@/lxc-restart - setuid @BINDIR@/lxc-unshare - setuid @BINDIR@/lxc-netstat - setuid @BINDIR@/lxc-checkpoint - setuid @LXCINITDIR@/lxc-init - - test -e @LXCPATH@ || mkdir -p @LXCPATH@ - chmod 0777 @LXCPATH@ -} - -lxc_dropuid() -{ - setuid -r @BINDIR@/lxc-attach - setuid -r @BINDIR@/lxc-create - setuid -r @BINDIR@/lxc-execute - setuid -r @BINDIR@/lxc-start - setuid -r @BINDIR@/lxc-restart - setuid -r @BINDIR@/lxc-unshare - setuid -r @BINDIR@/lxc-netstat - setuid -r @BINDIR@/lxc-checkpoint - setuid -r @LXCINITDIR@/lxc-init - - chmod 0755 @LXCPATH@ -} - -libdir=@LIBDIR@ -localstatedir=@LOCALSTATEDIR@ - -if [ "$(id -u)" != "0" ]; then - echo "You have to be root to run this script" - exit 1 -fi - -if [ $? != 0 ]; then - usage - exit 1 -fi - -set -- $(getopt dh "$@") - -for i in "$@"; do - case "$1" in - -d) - LXC_DROP_CAPS="yes" - shift - ;; - -h) - usage - exit 0 - ;; - --) - shift - break - ;; - *) - usage - exit 1 - ;; - esac -done; - -if [ -z "$LXC_DROP_CAPS" ]; then - lxc_setuid -else - lxc_dropuid -fi diff -Nru lxc-0.8.0~rc1/src/lxc/lxc-start-ephemeral.in lxc-1.0.0~alpha1/src/lxc/lxc-start-ephemeral.in --- lxc-0.8.0~rc1/src/lxc/lxc-start-ephemeral.in 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/lxc-start-ephemeral.in 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,322 @@ +#!/usr/bin/python3 +# +# lxc-start-ephemeral: Start a copy of a container using an overlay +# +# This python implementation is based on the work done in the original +# shell implementation done by Serge Hallyn in Ubuntu (and other contributors) +# +# (C) Copyright Canonical Ltd. 2012 +# +# Authors: +# Stéphane Graber +# +# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# + +# NOTE: To remove once the API is stabilized +import warnings +warnings.filterwarnings("ignore", "The python-lxc API isn't yet stable") + +import argparse +import gettext +import lxc +import os +import sys +import subprocess +import tempfile + +_ = gettext.gettext +gettext.textdomain("lxc-start-ephemeral") + + +# Other functions +def randomMAC(): + import random + + mac = [0x00, 0x16, 0x3e, + random.randint(0x00, 0x7f), + random.randint(0x00, 0xff), + random.randint(0x00, 0xff)] + return ':'.join(map(lambda x: "%02x" % x, mac)) + +# Begin parsing the command line +parser = argparse.ArgumentParser(description=_( + "LXC: Start an ephemeral container"), + formatter_class=argparse.RawTextHelpFormatter, + epilog=_("If a COMMAND is given, then the " + """container will run only as long +as the command runs. +If no COMMAND is given, this command will attach to tty1 and stop the +container when exiting (with ctrl-a-q). + +If no COMMAND is given and -d is used, the name and IP addresses of the +container will be printed to the console.""")) + +parser.add_argument("--lxcpath", "-P", dest="lxcpath", metavar="PATH", + help=_("Use specified container path"), default=None) + +parser.add_argument("--orig", "-o", type=str, required=True, + help=_("name of the original container")) + +parser.add_argument("--name", "-n", type=str, + help=_("name of the target container")) + +parser.add_argument("--bdir", "-b", type=str, + help=_("directory to bind mount into container")) + +parser.add_argument("--user", "-u", type=str, + help=_("the user to connect to the container as")) + +parser.add_argument("--key", "-S", type=str, + help=_("the path to the SSH key to use to connect")) + +parser.add_argument("--daemon", "-d", action="store_true", + help=_("run in the background")) + +parser.add_argument("--storage-type", "-s", type=str, default=None, + choices=("tmpfs", "dir"), + help=("type of storage use by the container")) + +parser.add_argument("--union-type", "-U", type=str, default="overlayfs", + choices=("overlayfs", "aufs"), + help=_("type of union (overlayfs or aufs), " + "defaults to overlayfs.")) + +parser.add_argument("--keep-data", "-k", action="store_true", + help=_("don't wipe everything clean at the end")) + +parser.add_argument("command", metavar='CMD', type=str, nargs="*", + help=_("Run specific command in container " + "(command as argument)")) + +args = parser.parse_args() + +# Basic requirements check +## Check that -d and CMD aren't used at the same time +if args.command and args.daemon: + parser.error(_("You can't use -d and a command at the same time.")) + +## Check that -k isn't used with -s tmpfs +if not args.storage_type: + if args.keep_data: + args.storage_type = "dir" + else: + args.storage_type = "tmpfs" + +if args.keep_data and args.storage_type == "tmpfs": + parser.error(_("You can't use -k with the tmpfs storage type.")) + +## The user needs to be uid 0 +if not os.geteuid() == 0: + parser.error(_("You must be root to run this script. Try running: sudo %s" + % (sys.argv[0]))) + +# Load the orig container +orig = lxc.Container(args.orig, args.lxcpath) +if not orig.defined: + parser.error(_("Source container '%s' doesn't exist." % args.orig)) + +# Create the new container paths +if not args.lxcpath: + lxc_path = lxc.default_config_path +else: + lxc_path = args.lxcpath + +if args.name: + if os.path.exists("%s/%s" % (lxc_path, args.name)): + parser.error(_("A container named '%s' already exists." % args.name)) + dest_path = "%s/%s" % (lxc_path, args.name) + os.mkdir(dest_path) +else: + dest_path = tempfile.mkdtemp(prefix="%s-" % args.orig, dir=lxc_path) +os.mkdir(os.path.join(dest_path, "rootfs")) + +# Setup the new container's configuration +dest = lxc.Container(os.path.basename(dest_path), args.lxcpath) +dest.load_config(orig.config_file_name) +dest.set_config_item("lxc.utsname", dest.name) +dest.set_config_item("lxc.rootfs", os.path.join(dest_path, "rootfs")) +for nic in dest.network: + if hasattr(nic, 'hwaddr'): + nic.hwaddr = randomMAC() + +overlay_dirs = [(orig.get_config_item("lxc.rootfs"), "%s/rootfs/" % dest_path)] + +# Generate a new fstab +if orig.get_config_item("lxc.mount"): + dest.set_config_item("lxc.mount", os.path.join(dest_path, "fstab")) + with open(orig.get_config_item("lxc.mount"), "r") as orig_fd: + with open(dest.get_config_item("lxc.mount"), "w+") as dest_fd: + for line in orig_fd.read().split("\n"): + # Start by replacing any reference to the container rootfs + line.replace(orig.get_config_item("lxc.rootfs"), + dest.get_config_item("lxc.rootfs")) + + # Skip any line that's not a bind mount + fields = line.split() + if len(fields) < 4: + dest_fd.write("%s\n" % line) + continue + + if fields[2] != "bind" and "bind" not in fields[3]: + dest_fd.write("%s\n" % line) + continue + + # Process any remaining line + dest_mount = os.path.abspath(os.path.join("%s/rootfs/" % ( + dest_path), fields[1])) + + if dest_mount == os.path.abspath("%s/rootfs/%s" % ( + dest_path, args.bdir)): + + dest_fd.write("%s\n" % line) + continue + + if "%s/rootfs/" % dest_path not in dest_mount: + print(_("Skipping mount entry '%s' as it's outside " + "of the container rootfs.") % line) + + overlay_dirs += [(fields[0], dest_mount)] + +# Generate pre-mount script +with open(os.path.join(dest_path, "pre-mount"), "w+") as fd: + os.fchmod(fd.fileno(), 0o755) + fd.write("""#!/bin/sh +LXC_DIR="%s" +LXC_BASE="%s" +LXC_NAME="%s" +""" % (dest_path, orig.name, dest.name)) + + count = 0 + for entry in overlay_dirs: + target = "%s/delta%s" % (dest_path, count) + fd.write("mkdir -p %s %s\n" % (target, entry[1])) + + if args.storage_type == "tmpfs": + fd.write("mount -n -t tmpfs none %s\n" % (target)) + + if args.union_type == "overlayfs": + fd.write("mount -n -t overlayfs" + " -oupperdir=%s,lowerdir=%s none %s\n" % ( + target, + entry[0], + entry[1])) + elif args.union_type == "aufs": + fd.write("mount -n -t aufs " + "-o br=${upper}=rw:${lower}=ro,noplink none %s\n" % ( + target, + entry[0], + entry[1])) + count += 1 + + if args.bdir: + if not os.path.exists(args.bdir): + print(_("Path '%s' doesn't exist, won't be bind-mounted.") % + args.bdir) + else: + src_path = os.path.abspath(args.bdir) + dst_path = "%s/rootfs/%s" % (dest_path, os.path.abspath(args.bdir)) + fd.write("mkdir -p %s\nmount -n --bind %s %s\n" % ( + dst_path, src_path, dst_path)) + + fd.write(""" +[ -e $LXC_DIR/configured ] && exit 0 +for file in $LXC_DIR/rootfs/etc/hostname \\ + $LXC_DIR/rootfs/etc/hosts \\ + $LXC_DIR/rootfs/etc/sysconfig/network \\ + $LXC_DIR/rootfs/etc/sysconfig/network-scripts/ifcfg-eth0; do + [ -f "$file" ] && sed -i -e "s/$LXC_BASE/$LXC_NAME/" $file +done +touch $LXC_DIR/configured +""") + +dest.set_config_item("lxc.hook.pre-mount", + os.path.join(dest_path, "pre-mount")) + +# Generate post-stop script +if not args.keep_data: + with open(os.path.join(dest_path, "post-stop"), "w+") as fd: + os.fchmod(fd.fileno(), 0o755) + fd.write("""#!/bin/sh +[ -d "%s" ] && rm -Rf "%s" +""" % (dest_path, dest_path)) + + dest.set_config_item("lxc.hook.post-stop", + os.path.join(dest_path, "post-stop")) + +dest.save_config() + +# Start the container +if not dest.start() or not dest.wait("RUNNING", timeout=5): + print(_("The container '%s' failed to start.") % dest.name) + dest.stop() + if dest.defined: + dest.destroy() + sys.exit(1) + +# Deal with the case where we just attach to the container's console +if not args.command and not args.daemon: + dest.console() + dest.shutdown(timeout=5) + sys.exit(0) + +# Try to get the IP addresses +ips = dest.get_ips(timeout=10) + +# Deal with the case where we just print info about the container +if args.daemon: + print(_("""The ephemeral container is now started. + +You can enter it from the command line with: lxc-console -n %s +The following IP addresses have be found in the container: +%s""") % (dest.name, + "\n".join([" - %s" % entry for entry in ips] + or [" - %s" % _("No address could be found")]))) + sys.exit(0) + +# Now deal with the case where we want to run a command in the container +if not ips: + print(_("Failed to get an IP for container '%s'.") % dest.name) + dest.stop() + if dest.defined: + dest.destroy() + sys.exit(1) + +# NOTE: To replace by .attach() once the kernel supports it +cmd = ["ssh", + "-o", "StrictHostKeyChecking=no", + "-o", "UserKnownHostsFile=/dev/null"] + +if args.user: + cmd += ["-l", args.user] + +if args.key: + cmd += ["-i", args.key] + +for ip in ips: + ssh_cmd = cmd + [ip] + args.command + retval = subprocess.call(ssh_cmd, universal_newlines=True) + if retval == 255: + print(_("SSH failed to connect, trying next IP address.")) + continue + + if retval != 0: + print(_("Command returned with non-zero return code: %s") % retval) + break + +# Shutdown the container +dest.shutdown(timeout=5) + +sys.exit(retval) diff -Nru lxc-0.8.0~rc1/src/lxc/lxc-top lxc-1.0.0~alpha1/src/lxc/lxc-top --- lxc-0.8.0~rc1/src/lxc/lxc-top 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/lxc-top 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,233 @@ +#!/usr/bin/env lua +-- +-- top(1) like monitor for lxc containers +-- +-- Copyright © 2012 Oracle. +-- +-- Authors: +-- Dwight Engen +-- +-- This library is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License version 2, as +-- published by the Free Software Foundation. +-- +-- 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., +-- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +-- + +local lxc = require("lxc") +local core = require("lxc.core") +local getopt = require("alt_getopt") +local lfs = require("lfs") + +local USER_HZ = 100 +local ESC = string.format("%c", 27) +local TERMCLEAR = ESC.."[H"..ESC.."[J" +local TERMNORM = ESC.."[0m" +local TERMBOLD = ESC.."[1m" +local TERMRVRS = ESC.."[7m" + +local containers = {} +local stats = {} +local stats_total = {} +local max_containers + +function printf(...) + local function wrapper(...) io.write(string.format(...)) end + local status, result = pcall(wrapper, ...) + if not status then + error(result, 2) + end +end + +function string:split(delim, max_cols) + local cols = {} + local start = 1 + local nextc + repeat + nextc = string.find(self, delim, start) + if (nextc and #cols ~= max_cols - 1) then + table.insert(cols, string.sub(self, start, nextc-1)) + start = nextc + #delim + else + table.insert(cols, string.sub(self, start, string.len(self))) + nextc = nil + end + until nextc == nil or start > #self + return cols +end + +function strsisize(size, width) + local KiB = 1024 + local MiB = 1048576 + local GiB = 1073741824 + local TiB = 1099511627776 + local PiB = 1125899906842624 + local EiB = 1152921504606846976 + local ZiB = 1180591620717411303424 + + if (size >= ZiB) then + return string.format("%d.%2.2d ZB", size / ZiB, (math.floor(size % ZiB) * 100) / ZiB) + end + if (size >= EiB) then + return string.format("%d.%2.2d EB", size / EiB, (math.floor(size % EiB) * 100) / EiB) + end + if (size >= PiB) then + return string.format("%d.%2.2d PB", size / PiB, (math.floor(size % PiB) * 100) / PiB) + end + if (size >= TiB) then + return string.format("%d.%2.2d TB", size / TiB, (math.floor(size % TiB) * 100) / TiB) + end + if (size >= GiB) then + return string.format("%d.%2.2d GB", size / GiB, (math.floor(size % GiB) * 100) / GiB) + end + if (size >= MiB) then + return string.format("%d.%2.2d MB", size / MiB, (math.floor(size % MiB) * 1000) / (MiB * 10)) + end + if (size >= KiB) then + return string.format("%d.%2.2d KB", size / KiB, (math.floor(size % KiB) * 1000) / (KiB * 10)) + end + return string.format("%3d.00 ", size) +end + +function tty_lines() + local rows = 25 + local f = assert(io.popen("stty -a | head -n 1")) + for line in f:lines() do + local stty_rows + _,_,stty_rows = string.find(line, "rows (%d+)") + if (stty_rows ~= nil) then + rows = stty_rows + break + end + end + f:close() + return rows +end + +function container_sort(a, b) + if (optarg["r"]) then + if (optarg["s"] == "n") then return (a > b) + elseif (optarg["s"] == "c") then return (stats[a].cpu_use_nanos < stats[b].cpu_use_nanos) + elseif (optarg["s"] == "d") then return (stats[a].blkio < stats[b].blkio) + elseif (optarg["s"] == "m") then return (stats[a].mem_used < stats[b].mem_used) + end + else + if (optarg["s"] == "n") then return (a < b) + elseif (optarg["s"] == "c") then return (stats[a].cpu_use_nanos > stats[b].cpu_use_nanos) + elseif (optarg["s"] == "d") then return (stats[a].blkio > stats[b].blkio) + elseif (optarg["s"] == "m") then return (stats[a].mem_used > stats[b].mem_used) + end + end +end + +function container_list_update() + local now_running + + now_running = lxc.containers_running(true) + + -- check for newly started containers + for _,v in ipairs(now_running) do + if (containers[v] == nil) then + local ct = lxc.container:new(v) + -- note, this is a "mixed" table, ie both dictionary and list + containers[v] = ct + table.insert(containers, v) + end + end + + -- check for newly stopped containers + local indx = 1 + while (indx <= #containers) do + local ctname = containers[indx] + if (now_running[ctname] == nil) then + containers[ctname] = nil + stats[ctname] = nil + table.remove(containers, indx) + else + indx = indx + 1 + end + end + + -- get stats for all current containers and resort the list + lxc.stats_clear(stats_total) + for _,ctname in ipairs(containers) do + stats[ctname] = containers[ctname]:stats_get(stats_total) + end + table.sort(containers, container_sort) +end + +function stats_print_header() + printf(TERMRVRS .. TERMBOLD) + printf("%-15s %8s %8s %8s %10s %10s\n", "Container", "CPU", "CPU", "CPU", "BlkIO", "Mem") + printf("%-15s %8s %8s %8s %10s %10s\n", "Name", "Used", "Sys", "User", "Total", "Used") + printf(TERMNORM) +end + +function stats_print(name, stats) + printf("%-15s %8.2f %8.2f %8.2f %10s %10s", + name, + stats.cpu_use_nanos / 1000000000, + stats.cpu_use_sys / USER_HZ, + stats.cpu_use_user / USER_HZ, + strsisize(stats.blkio), + strsisize(stats.mem_used)) +end + +function usage() + printf("Usage: lxc-top [options]\n" .. + " -h|--help print this help message\n" .. + " -m|--max display maximum number of containers\n" .. + " -d|--delay delay in seconds between refreshes (default: 3.0)\n" .. + " -s|--sort sort by [n,c,d,m] (default: n) where\n" .. + " n = Name\n" .. + " c = CPU use\n" .. + " d = Disk I/O use\n" .. + " m = Memory use\n" .. + " -r|--reverse sort in reverse (descending) order\n" + ) + os.exit(1) +end + +local long_opts = { + help = "h", + delay = "d", + max = "m", + reverse = "r", + sort = "s", +} + +optarg,optind = alt_getopt.get_opts (arg, "hd:m:rs:", long_opts) +optarg["d"] = tonumber(optarg["d"]) or 3.0 +optarg["m"] = tonumber(optarg["m"]) or tonumber(tty_lines() - 3) +optarg["r"] = optarg["r"] or false +optarg["s"] = optarg["s"] or "n" +if (optarg["h"] ~= nil) then + usage() +end + +while true +do + container_list_update() + -- if some terminal we care about doesn't support the simple escapes, we + -- may fall back to this, or ncurses. ug. + --os.execute("tput clear") + printf(TERMCLEAR) + stats_print_header() + for index,ctname in ipairs(containers) do + stats_print(ctname, stats[ctname]) + printf("\n") + if (index >= optarg["m"]) then + break + end + end + stats_print(string.format("TOTAL (%-2d)", #containers), stats_total) + io.flush() + core.usleep(optarg["d"] * 1000000) +end diff -Nru lxc-0.8.0~rc1/src/lxc/lxc-version.in lxc-1.0.0~alpha1/src/lxc/lxc-version.in --- lxc-0.8.0~rc1/src/lxc/lxc-version.in 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/lxc-version.in 2013-07-08 15:50:40.000000000 +0000 @@ -1,3 +1,3 @@ -#!/bin/bash +#!/bin/sh echo "lxc version: @PACKAGE_VERSION@" diff -Nru lxc-0.8.0~rc1/src/lxc/lxc.functions.in lxc-1.0.0~alpha1/src/lxc/lxc.functions.in --- lxc-0.8.0~rc1/src/lxc/lxc.functions.in 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/lxc.functions.in 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,30 @@ +# +# lxc: linux Container library + +# Authors: +# Serge Hallyn + +# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +# This file contains helpers for the various lxc shell scripts + +globalconf=@LXC_GLOBAL_CONF@ +bindir=@BINDIR@ +templatedir=@LXCTEMPLATEDIR@ +lxcinitdir=@LXCINITDIR@ + +lxc_path=`lxc-config lxcpath` +lxc_vg=`lxc-config lvm_vg` +lxc_zfsroot=`lxc-config zfsroot` diff -Nru lxc-0.8.0~rc1/src/lxc/lxc.h lxc-1.0.0~alpha1/src/lxc/lxc.h --- lxc-0.8.0~rc1/src/lxc/lxc.h 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/lxc.h 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,7 +18,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __lxc_h #define __lxc_h @@ -28,6 +28,8 @@ #endif #include +#include +#include #include struct lxc_msg; @@ -47,15 +49,8 @@ * @conf : configuration * Returns 0 on sucess, < 0 otherwise */ -extern int lxc_start(const char *name, char *const argv[], struct lxc_conf *conf); - -/* - * Stop the container previously started with lxc_start, all - * the processes running inside this container will be killed. - * @name : the name of the container - * Returns 0 on success, < 0 otherwise - */ -extern int lxc_stop(const char *name); +extern int lxc_start(const char *name, char *const argv[], struct lxc_conf *conf, + const char *lxcpath); /* * Start the specified command inside an application container @@ -66,26 +61,47 @@ * Returns 0 on sucess, < 0 otherwise */ extern int lxc_execute(const char *name, char *const argv[], int quiet, - struct lxc_conf *conf); + struct lxc_conf *conf, const char *lxcpath); /* * Open the monitoring mechanism for a specific container * The function will return an fd corresponding to the events * Returns a file descriptor on success, < 0 otherwise */ -extern int lxc_monitor_open(void); +extern int lxc_monitor_open(const char *lxcpath); /* - * Read the state of the container if this one has changed - * The function will block until there is an event available - * @fd : the file descriptor provided by lxc_monitor_open - * @state : the variable which will be filled with the state + * Blocking read for the next container state change + * @fd : the file descriptor provided by lxc_monitor_open + * @msg : the variable which will be filled with the state * Returns 0 if the monitored container has exited, > 0 if - * data was readen, < 0 otherwise + * data was read, < 0 otherwise */ extern int lxc_monitor_read(int fd, struct lxc_msg *msg); /* + * Blocking read for the next container state change with timeout + * @fd : the file descriptor provided by lxc_monitor_open + * @msg : the variable which will be filled with the state + * @timeout : the timeout in seconds to wait for a state change + * Returns 0 if the monitored container has exited, > 0 if + * data was read, < 0 otherwise + */ +extern int lxc_monitor_read_timeout(int fd, struct lxc_msg *msg, int timeout); + +/* + * Blocking read from multiple monitors for the next container state + * change with timeout + * @rfds : an fd_set of file descriptors provided by lxc_monitor_open + * @nfds : the maximum fd number in rfds + 1 + * @msg : the variable which will be filled with the state + * @timeout : the timeout in seconds to wait for a state change + * Returns 0 if the monitored container has exited, > 0 if + * data was read, < 0 otherwise + */ +extern int lxc_monitor_read_fdset(fd_set *rfds, int nfds, struct lxc_msg *msg, int timeout); + +/* * Close the fd associated with the monitoring * @fd : the file descriptor provided by lxc_monitor_open * Returns 0 on success, < 0 otherwise @@ -93,56 +109,69 @@ extern int lxc_monitor_close(int fd); /* - * Show the console of the container. - * @name : the name of container - * @tty : the tty number - * @fd : a pointer to a tty file descriptor - * Returns 0 on sucess, < 0 otherwise - */ -extern int lxc_console(const char *name, int ttynum, int *fd); - -/* * Freeze all the tasks running inside the container * @name : the container name * Returns 0 on success, < 0 otherwise */ -extern int lxc_freeze(const char *name); +extern int lxc_freeze(const char *name, const char *lxcpath); /* * Unfreeze all previously frozen tasks. * @name : the name of the container * Return 0 on sucess, < 0 otherwise */ -extern int lxc_unfreeze(const char *name); +extern int lxc_unfreeze(const char *name, const char *lxcpath); + +/* + * Unfreeze all previously frozen tasks. + * This is the function to use from inside the monitor + * @name : the name of the container + * Return 0 on sucess, < 0 otherwise + */ +extern int lxc_unfreeze_bypath(const char *cgpath); /* * Retrieve the container state * @name : the name of the container * Returns the state of the container on success, < 0 otherwise */ -extern lxc_state_t lxc_state(const char *name); +extern lxc_state_t lxc_state(const char *name, const char *lxcpath); + +struct lxc_handler; +/* + * Set a specified value for a specified subsystem. The specified + * subsystem must be fully specified, eg. "cpu.shares" + * @d : the cgroup descriptor for the container + * @filename : the cgroup attribute filename + * @value : the value to be set + * Returns 0 on success, < 0 otherwise + */ +extern int lxc_cgroup_set_value(struct lxc_handler *hander, const char *filename, + const char *value); /* * Set a specified value for a specified subsystem. The specified * subsystem must be fully specified, eg. "cpu.shares" * @name : the name of the container - * @filename : the cgroup attribute filename + * @filename : the cgroup attribute filename * @value : the value to be set + * @lxcpath : lxc config path for container * Returns 0 on success, < 0 otherwise */ -extern int lxc_cgroup_set(const char *name, const char *filename, const char *value); +extern int lxc_cgroup_set(const char *name, const char *filename, const char *value, const char *lxcpath); /* * Get a specified value for a specified subsystem. The specified * subsystem must be fully specified, eg. "cpu.shares" * @name : the name of the container - * @filename : the cgroup attribute filename + * @filename : the cgroup attribute filename * @value : the value to be set * @len : the len of the value variable + * @lxcpath : lxc config path for container * Returns the number of bytes read, < 0 on error */ extern int lxc_cgroup_get(const char *name, const char *filename, - char *value, size_t len); + char *value, size_t len, const char *lxcpath); /* * Retrieve the error string associated with the error returned by @@ -169,14 +198,39 @@ * @sfd: fd from which the container is restarted * @conf: lxc_conf structure. * @flags : restart flags (an ORed value) + * @lxcpath: container path * Returns 0 on success, < 0 otherwise */ -extern int lxc_restart(const char *, int, struct lxc_conf *, int); +extern int lxc_restart(const char *, int, struct lxc_conf *, int, const char *); + +/* + * Create and return a new lxccontainer struct. + */ +extern struct lxc_container *lxc_container_new(const char *name, const char *configpath); + +/* + * Returns 1 on success, 0 on failure. + */ +extern int lxc_container_get(struct lxc_container *c); + +/* + * Put a lxccontainer struct reference. + * Return -1 on error. + * Return 0 if this was not the last reference. + * If it is the last reference, free the lxccontainer and return 1. + */ +extern int lxc_container_put(struct lxc_container *c); + +/* + * Get a list of valid wait states. + * If states is NULL, simply return the number of states + */ +extern int lxc_get_wait_states(const char **states); /* - * Returns the version number of the library + * Add a dependency to a container */ -extern const char const *lxc_version(void); +extern int add_rdepend(struct lxc_conf *lxc_conf, char *rdepend); #ifdef __cplusplus } diff -Nru lxc-0.8.0~rc1/src/lxc/lxc_attach.c lxc-1.0.0~alpha1/src/lxc/lxc_attach.c --- lxc-0.8.0~rc1/src/lxc/lxc_attach.c 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/lxc_attach.c 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2010 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,44 +18,77 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #define _GNU_SOURCE -#include -#include -#include -#include -#include -#include #include -#include +#include +#include #include "attach.h" -#include "commands.h" #include "arguments.h" -#include "caps.h" -#include "attach.h" +#include "config.h" #include "confile.h" -#include "start.h" -#include "sync.h" +#include "namespace.h" +#include "caps.h" #include "log.h" +#include "utils.h" lxc_log_define(lxc_attach_ui, lxc); static const struct option my_longopts[] = { {"elevated-privileges", no_argument, 0, 'e'}, {"arch", required_argument, 0, 'a'}, + {"namespaces", required_argument, 0, 's'}, + {"remount-sys-proc", no_argument, 0, 'R'}, + /* TODO: decide upon short option names */ + {"clear-env", no_argument, 0, 500}, + {"keep-env", no_argument, 0, 501}, + {"keep-var", required_argument, 0, 502}, + {"set-var", required_argument, 0, 'v'}, LXC_COMMON_OPTIONS }; static int elevated_privileges = 0; static signed long new_personality = -1; +static int namespace_flags = -1; +static int remount_sys_proc = 0; +static lxc_attach_env_policy_t env_policy = LXC_ATTACH_KEEP_ENV; +static char **extra_env = NULL; +static ssize_t extra_env_size = 0; +static char **extra_keep = NULL; +static ssize_t extra_keep_size = 0; + +static int add_to_simple_array(char ***array, ssize_t *capacity, char *value) +{ + ssize_t count = 0; + + if (*array) + for (; (*array)[count]; count++); + + /* we have to reallocate */ + if (count >= *capacity - 1) { + ssize_t new_capacity = ((count + 1) / 32 + 1) * 32; + char **new_array = realloc((void*)*array, sizeof(char *) * new_capacity); + if (!new_array) + return -1; + memset(&new_array[count], 0, sizeof(char*)*(new_capacity - count)); + *array = new_array; + *capacity = new_capacity; + } + + (*array)[count] = value; + return 0; +} static int my_parser(struct lxc_arguments* args, int c, char* arg) { + int ret; + switch (c) { case 'e': elevated_privileges = 1; break; + case 'R': remount_sys_proc = 1; break; case 'a': new_personality = lxc_config_parse_arch(arg); if (new_personality < 0) { @@ -63,6 +96,34 @@ return -1; } break; + case 's': + namespace_flags = 0; + ret = lxc_fill_namespace_flags(arg, &namespace_flags); + if (ret) + return -1; + /* -s implies -e */ + elevated_privileges = 1; + break; + case 500: /* clear-env */ + env_policy = LXC_ATTACH_CLEAR_ENV; + break; + case 501: /* keep-env */ + env_policy = LXC_ATTACH_KEEP_ENV; + break; + case 502: /* keep-var */ + ret = add_to_simple_array(&extra_keep, &extra_keep_size, arg); + if (ret < 0) { + lxc_error(args, "memory allocation error"); + return -1; + } + break; + case 'v': + ret = add_to_simple_array(&extra_env, &extra_env_size, arg); + if (ret < 0) { + lxc_error(args, "memory allocation error"); + return -1; + } + break; } return 0; @@ -71,9 +132,9 @@ static struct lxc_arguments my_args = { .progname = "lxc-attach", .help = "\ ---name=NAME\n\ +--name=NAME [-- COMMAND]\n\ \n\ -Execute the specified command - enter the container NAME\n\ +Execute the specified COMMAND - enter the container NAME\n\ \n\ Options :\n\ -n, --name=NAME NAME for name of the container\n\ @@ -83,21 +144,41 @@ WARNING: This may leak privleges into the container.\n\ Use with care.\n\ -a, --arch=ARCH Use ARCH for program instead of container's own\n\ - architecture.\n", + architecture.\n\ + -s, --namespaces=FLAGS\n\ + Don't attach to all the namespaces of the container\n\ + but just to the following OR'd list of flags:\n\ + MOUNT, PID, UTSNAME, IPC, USER or NETWORK\n\ + WARNING: Using -s implies -e, it may therefore\n\ + leak privileges into the container. Use with care.\n\ + -R, --remount-sys-proc\n\ + Remount /sys and /proc if not attaching to the\n\ + mount namespace when using -s in order to properly\n\ + reflect the correct namespace context. See the\n\ + lxc-attach(1) manual page for details.\n\ + --clear-env Clear all environment variables before attaching.\n\ + The attached shell/program will start with only\n\ + container=lxc set.\n\ + --keep-env Keep all current enivornment variables. This\n\ + is the current default behaviour, but is likely to\n\ + change in the future.\n\ + -v, --set-var Set an additional variable that is seen by the\n\ + attached program in the container. May be specified\n\ + multiple times.\n\ + --keep-var Keep an additional environment variable. Only\n\ + applicable if --clear-env is specified. May be used\n\ + multiple times.\n", .options = my_longopts, .parser = my_parser, .checker = NULL, }; -int main(int argc, char *argv[], char *envp[]) +int main(int argc, char *argv[]) { int ret; - pid_t pid, init_pid; - struct passwd *passwd; - struct lxc_proc_context_info *init_ctx; - struct lxc_handler *handler; - uid_t uid; - char *curdir; + pid_t pid; + lxc_attach_options_t attach_options = LXC_ATTACH_OPTIONS_DEFAULT; + lxc_attach_command_t command; ret = lxc_caps_init(); if (ret) @@ -107,137 +188,38 @@ if (ret) return ret; - ret = lxc_log_init(my_args.log_file, my_args.log_priority, - my_args.progname, my_args.quiet); + ret = lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority, + my_args.progname, my_args.quiet, my_args.lxcpath[0]); if (ret) return ret; - init_pid = get_init_pid(my_args.name); - if (init_pid < 0) { - ERROR("failed to get the init pid"); - return -1; + if (remount_sys_proc) + attach_options.attach_flags |= LXC_ATTACH_REMOUNT_PROC_SYS; + if (elevated_privileges) + attach_options.attach_flags &= ~(LXC_ATTACH_MOVE_TO_CGROUP | LXC_ATTACH_DROP_CAPABILITIES | LXC_ATTACH_APPARMOR); + attach_options.namespaces = namespace_flags; + attach_options.personality = new_personality; + attach_options.env_policy = env_policy; + attach_options.extra_env_vars = extra_env; + attach_options.extra_keep_env = extra_keep; + + if (my_args.argc) { + command.program = my_args.argv[0]; + command.argv = (char**)my_args.argv; + ret = lxc_attach(my_args.name, my_args.lxcpath[0], lxc_attach_run_command, &command, &attach_options, &pid); + } else { + ret = lxc_attach(my_args.name, my_args.lxcpath[0], lxc_attach_run_shell, NULL, &attach_options, &pid); } - init_ctx = lxc_proc_get_context_info(init_pid); - if (!init_ctx) { - ERROR("failed to get context of the init process, pid = %d", init_pid); + if (ret < 0) return -1; - } - /* hack: we need sync.h infrastructure - and that needs a handler */ - handler = calloc(1, sizeof(*handler)); - - if (lxc_sync_init(handler)) { - ERROR("failed to initialize synchronization socket"); + ret = lxc_wait_for_pid_status(pid); + if (ret < 0) return -1; - } - pid = fork(); + if (WIFEXITED(ret)) + return WEXITSTATUS(ret); - if (pid < 0) { - SYSERROR("failed to fork"); - return -1; - } - - if (pid) { - int status; - - lxc_sync_fini_child(handler); - - /* wait until the child has done configuring itself before - * we put it in a cgroup that potentially limits these - * possibilities */ - if (lxc_sync_wait_child(handler, LXC_SYNC_CONFIGURE)) - return -1; - - if (!elevated_privileges && lxc_attach_proc_to_cgroups(pid, init_ctx)) - return -1; - - /* tell the child we are done initializing */ - if (lxc_sync_wake_child(handler, LXC_SYNC_POST_CONFIGURE)) - return -1; - - lxc_sync_fini(handler); - - again: - if (waitpid(pid, &status, 0) < 0) { - if (errno == EINTR) - goto again; - SYSERROR("failed to wait '%d'", pid); - return -1; - } - - if (WIFEXITED(status)) - return WEXITSTATUS(status); - - return -1; - } - - if (!pid) { - lxc_sync_fini_parent(handler); - - curdir = get_current_dir_name(); - - ret = lxc_attach_to_ns(init_pid); - if (ret < 0) { - ERROR("failed to enter the namespace"); - return -1; - } - - if (curdir && chdir(curdir)) - WARN("could not change directory to '%s'", curdir); - - free(curdir); - - if (new_personality < 0) - new_personality = init_ctx->personality; - - if (personality(new_personality) == -1) { - ERROR("could not ensure correct architecture: %s", - strerror(errno)); - return -1; - } - - if (!elevated_privileges && lxc_attach_drop_privs(init_ctx)) { - ERROR("could not drop privileges"); - return -1; - } - - /* tell parent we are done setting up the container and wait - * until we have been put in the container's cgroup, if - * applicable */ - if (lxc_sync_barrier_parent(handler, LXC_SYNC_CONFIGURE)) - return -1; - - lxc_sync_fini(handler); - - if (my_args.argc) { - execve(my_args.argv[0], my_args.argv, envp); - SYSERROR("failed to exec '%s'", my_args.argv[0]); - return -1; - } - - uid = getuid(); - - passwd = getpwuid(uid); - if (!passwd) { - SYSERROR("failed to get passwd " \ - "entry for uid '%d'", uid); - return -1; - } - - { - char *const args[] = { - passwd->pw_shell, - NULL, - }; - - execve(args[0], args, envp); - SYSERROR("failed to exec '%s'", args[0]); - return -1; - } - - } - - return 0; + return -1; } diff -Nru lxc-0.8.0~rc1/src/lxc/lxc_cgroup.c lxc-1.0.0~alpha1/src/lxc/lxc_cgroup.c --- lxc-0.8.0~rc1/src/lxc/lxc_cgroup.c 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/lxc_cgroup.c 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,7 +18,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include @@ -29,6 +29,7 @@ #include #include +#include #include "arguments.h" lxc_log_define(lxc_cgroup_ui, lxc_cgroup); @@ -36,7 +37,7 @@ static int my_checker(const struct lxc_arguments* args) { if (!args->argc) { - lxc_error(args, "missing cgroup subsystem"); + lxc_error(args, "missing state object"); return -1; } return 0; @@ -49,13 +50,13 @@ static struct lxc_arguments my_args = { .progname = "lxc-cgroup", .help = "\ ---name=NAME subsystem [value]\n\ +--name=NAME state-object [value]\n\ \n\ -lxc-cgroup get or set subsystem value of cgroup\n\ -associated with the NAME container\n\ +Get or set the value of a state object (for example, 'cpuset.cpus')\n\ +in the container's cgroup for the corresponding subsystem.\n\ \n\ Options :\n\ - -n, --name=NAME NAME for name of the container", + -n, --name=NAME container name", .options = my_longopts, .parser = NULL, .checker = my_checker, @@ -63,40 +64,48 @@ int main(int argc, char *argv[]) { - char *subsystem = NULL, *value = NULL; + char *state_object = NULL, *value = NULL; + struct lxc_container *c; if (lxc_arguments_parse(&my_args, argc, argv)) return -1; - if (lxc_log_init(my_args.log_file, my_args.log_priority, - my_args.progname, my_args.quiet)) + if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority, + my_args.progname, my_args.quiet, my_args.lxcpath[0])) return -1; - subsystem = my_args.argv[0]; + state_object = my_args.argv[0]; - if ((argc) > 1) - value = my_args.argv[1]; + c = lxc_container_new(my_args.name, my_args.lxcpath[0]); + if (!c) + return -1; + if (!c->is_running(c)) { + ERROR("'%s:%s' is not running", my_args.lxcpath[0], my_args.name); + lxc_container_put(c); + return -1; + } - if (value) { - if (lxc_cgroup_set(my_args.name, subsystem, value)) { + if ((my_args.argc) > 1) { + value = my_args.argv[1]; + if (!c->set_cgroup_item(c, state_object, value)) { ERROR("failed to assign '%s' value to '%s' for '%s'", - value, subsystem, my_args.name); + value, state_object, my_args.name); + lxc_container_put(c); return -1; } } else { - const unsigned long len = 4096; - int ret; + int len = 4096; char buffer[len]; - - ret = lxc_cgroup_get(my_args.name, subsystem, buffer, len); + int ret = c->get_cgroup_item(c, state_object, buffer, len); if (ret < 0) { - ERROR("failed to retrieve value of '%s' for '%s'", - subsystem, my_args.name); + ERROR("failed to retrieve value of '%s' for '%s:%s'", + state_object, my_args.lxcpath[0], my_args.name); + lxc_container_put(c); return -1; } - printf("%*s", ret, buffer); } + lxc_container_put(c); return 0; } diff -Nru lxc-0.8.0~rc1/src/lxc/lxc_checkpoint.c lxc-1.0.0~alpha1/src/lxc/lxc_checkpoint.c --- lxc-0.8.0~rc1/src/lxc/lxc_checkpoint.c 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/lxc_checkpoint.c 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2010 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,7 +18,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #define _GNU_SOURCE #include @@ -115,8 +115,8 @@ if (ret) return ret; - ret = lxc_log_init(my_args.log_file, my_args.log_priority, - my_args.progname, my_args.quiet); + ret = lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority, + my_args.progname, my_args.quiet, my_args.lxcpath[0]); if (ret) return ret; diff -Nru lxc-0.8.0~rc1/src/lxc/lxc_clone.c lxc-1.0.0~alpha1/src/lxc/lxc_clone.c --- lxc-0.8.0~rc1/src/lxc/lxc_clone.c 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/lxc_clone.c 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,179 @@ +/* + * + * Copyright © 2013 Serge Hallyn . + * Copyright © 2013 Canonical Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "config.h" +#include "lxc.h" +#include "conf.h" +#include "state.h" +#include "lxccontainer.h" + +lxc_log_define(lxc_clone, lxc); + +static unsigned long get_fssize(char *s) +{ + unsigned long ret; + char *end; + + ret = strtoul(s, &end, 0); + if (end == s) + return 0; + while (isblank(*end)) + end++; + if (!(*end)) + return ret; + if (*end == 'g' || *end == 'G') + ret *= 1000000000; + else if (*end == 'm' || *end == 'M') + ret *= 1000000; + else if (*end == 'k' || *end == 'K') + ret *= 1000; + return ret; +} + +void usage(const char *me) +{ + printf("Usage: %s [-s] [-B backingstore] [-L size] [-K] [-M] [-H]\n", me); + printf(" [-p lxcpath] [-P newlxcpath] orig new\n"); + printf("\n"); + printf(" -s: snapshot rather than copy\n"); + printf(" -B: use specified new backingstore. Default is the same as\n"); + printf(" the original. Options include btrfs, lvm, overlayfs, \n"); + printf(" dir and loop\n"); + printf(" -L: for blockdev-backed backingstore, use specified size\n"); + printf(" -K: Keep name - do not change the container name\n"); + printf(" -M: Keep macaddr - do not choose a random new mac address\n"); + printf(" -H: copy Hooks - copy mount hooks into container directory\n"); + printf(" and substitute container names and lxcpaths\n"); + printf(" -p: use container orig from custom lxcpath\n"); + printf(" -P: create container new in custom lxcpath\n"); + exit(1); +} + +static struct option options[] = { + { "snapshot", no_argument, 0, 's'}, + { "backingstore", required_argument, 0, 'B'}, + { "size", required_argument, 0, 'L'}, + { "orig", required_argument, 0, 'o'}, + { "new", required_argument, 0, 'n'}, + { "vgname", required_argument, 0, 'v'}, + { "keepname", no_argument, 0, 'K'}, + { "keepmac", no_argument, 0, 'M'}, + { "copyhooks", no_argument, 0, 'H'}, // should this be default? + { "lxcpath", required_argument, 0, 'p'}, + { "newpath", required_argument, 0, 'P'}, + { "fstype", required_argument, 0, 't'}, + { "help", no_argument, 0, 'h'}, + { 0, 0, 0, 0 }, +}; + +int main(int argc, char *argv[]) +{ + struct lxc_container *c1 = NULL, *c2 = NULL; + int snapshot = 0, keepname = 0, keepmac = 0, copyhooks = 0; + int flags = 0, option_index; + long newsize = 0; + char *bdevtype = NULL, *lxcpath = NULL, *newpath = NULL, *fstype = NULL; + char *orig = NULL, *new = NULL, *vgname = NULL; + char **args = NULL; + char c; + + if (argc < 3) + usage(argv[0]); + + while (1) { + c = getopt_long(argc, argv, "sB:L:o:n:v:KMHp:P:t:h", options, &option_index); + if (c == -1) + break; + switch (c) { + case 's': snapshot = 1; break; + case 'B': bdevtype = optarg; break; + case 'L': newsize = get_fssize(optarg); break; + case 'o': orig = optarg; break; + case 'n': new = optarg; break; + case 'v': vgname = optarg; break; + case 'K': keepname = 1; break; + case 'M': keepmac = 1; break; + case 'H': copyhooks = 1; break; + case 'p': lxcpath = optarg; break; + case 'P': newpath = optarg; break; + case 't': fstype = optarg; break; + case 'h': usage(argv[0]); + default: break; + } + } + if (optind < argc && !orig) + orig = argv[optind++]; + if (optind < argc && !new) + new = argv[optind++]; + if (optind < argc) + /* arguments for the clone hook */ + args = &argv[optind]; + if (!new || !orig) { + printf("Error: you must provide orig and new names\n"); + usage(argv[0]); + } + + if (snapshot) flags |= LXC_CLONE_SNAPSHOT; + if (keepname) flags |= LXC_CLONE_KEEPNAME; + if (keepmac) flags |= LXC_CLONE_KEEPMACADDR; + if (copyhooks) flags |= LXC_CLONE_COPYHOOKS; + + // vgname and fstype could be supported by sending them through the + // bdevdata. However, they currently are not yet. I'm not convinced + // they are worthwhile. + if (vgname) { + printf("Error: vgname not supported\n"); + usage(argv[0]); + } + if (fstype) { + printf("Error: fstype not supported\n"); + usage(argv[0]); + } + + c1 = lxc_container_new(orig, lxcpath); + if (!c1) + exit(1); + if (!c1->is_defined(c1)) { + fprintf(stderr, "Error: container %s is not defined\n", orig); + lxc_container_put(c1); + exit(1); + } + c2 = c1->clone(c1, new, newpath, flags, bdevtype, NULL, newsize, args); + if (c2 == NULL) { + lxc_container_put(c1); + fprintf(stderr, "clone failed\n"); + exit(1); + } + printf("Created container %s as %s of %s\n", new, + snapshot ? "snapshot" : "copy", orig); + lxc_container_put(c1); + lxc_container_put(c2); + return(0); +} diff -Nru lxc-0.8.0~rc1/src/lxc/lxc_config.c lxc-1.0.0~alpha1/src/lxc/lxc_config.c --- lxc-0.8.0~rc1/src/lxc/lxc_config.c 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/lxc_config.c 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,70 @@ +/* lxc_config + * + * Copyright © 2012 Serge Hallyn . + * Copyright © 2012 Canonical Ltd. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include "config.h" +#include "lxccontainer.h" + +struct lxc_config_items { + char *name; + const char *(*fn)(void); +}; + +struct lxc_config_items items[] = +{ + { .name = "lxcpath", .fn = &lxc_get_default_config_path, }, + { .name = "lvm_vg", .fn = &lxc_get_default_lvm_vg, }, + { .name = "zfsroot", .fn = &lxc_get_default_zfs_root, }, + { .name = NULL, }, +}; + +void usage(char *me) +{ + printf("Usage: %s -l: list all available configuration items\n", me); + printf(" %s item: print configuration item\n", me); + exit(1); +} + +void list_config_items(void) +{ + struct lxc_config_items *i; + + for (i = &items[0]; i->name; i++) + printf("%s\n", i->name); + exit(0); +} + +int main(int argc, char *argv[]) +{ + struct lxc_config_items *i; + + if (argc < 2) + usage(argv[0]); + if (strcmp(argv[1], "-l") == 0) + list_config_items(); + for (i = &items[0]; i->name; i++) { + if (strcmp(argv[1], i->name) == 0) { + printf("%s\n", i->fn()); + exit(0); + } + } + printf("Unknown configuration item: %s\n", argv[1]); + exit(-1); +} diff -Nru lxc-0.8.0~rc1/src/lxc/lxc_console.c lxc-1.0.0~alpha1/src/lxc/lxc_console.c --- lxc-0.8.0~rc1/src/lxc/lxc_console.c 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/lxc_console.c 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,7 +18,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #define _GNU_SOURCE @@ -38,11 +38,13 @@ #include #include +#include "../lxc/lxccontainer.h" #include "error.h" #include "lxc.h" #include "log.h" #include "mainloop.h" #include "arguments.h" +#include "commands.h" lxc_log_define(lxc_console_ui, lxc_console); @@ -86,174 +88,34 @@ .escape = 1, }; -static int master = -1; - -static void winsz(void) -{ - struct winsize wsz; - if (ioctl(0, TIOCGWINSZ, &wsz) == 0) - ioctl(master, TIOCSWINSZ, &wsz); -} - -static void sigwinch(int sig) -{ - winsz(); -} - -static int setup_tios(int fd, struct termios *newtios, struct termios *oldtios) -{ - if (!isatty(fd)) { - ERROR("'%d' is not a tty", fd); - return -1; - } - - /* Get current termios */ - if (tcgetattr(0, oldtios)) { - SYSERROR("failed to get current terminal settings"); - return -1; - } - - *newtios = *oldtios; - - /* Remove the echo characters and signal reception, the echo - * will be done below with master proxying */ - newtios->c_iflag &= ~IGNBRK; - newtios->c_iflag &= BRKINT; - newtios->c_lflag &= ~(ECHO|ICANON|ISIG); - newtios->c_cc[VMIN] = 1; - newtios->c_cc[VTIME] = 0; - - /* Set new attributes */ - if (tcsetattr(0, TCSAFLUSH, newtios)) { - ERROR("failed to set new terminal settings"); - return -1; - } - - return 0; -} - -static int stdin_handler(int fd, void *data, struct lxc_epoll_descr *descr) -{ - static int wait4q = 0; - int *peer = (int *)data; - char c; - - if (read(0, &c, 1) < 0) { - SYSERROR("failed to read"); - return 1; - } - - /* we want to exit the console with Ctrl+a q */ - if (c == my_args.escape) { - wait4q = !wait4q; - return 0; - } - - if (c == 'q' && wait4q) - return 1; - - wait4q = 0; - if (write(*peer, &c, 1) < 0) { - SYSERROR("failed to write"); - return 1; - } - - return 0; -} - -static int master_handler(int fd, void *data, struct lxc_epoll_descr *descr) -{ - char buf[1024]; - int *peer = (int *)data; - int r; - - r = read(fd, buf, sizeof(buf)); - if (r < 0) { - SYSERROR("failed to read"); - return 1; - } - r = write(*peer, buf, r); - - return 0; -} - int main(int argc, char *argv[]) { - int err, std_in = 1; - struct lxc_epoll_descr descr; - struct termios newtios, oldtios; - - err = lxc_arguments_parse(&my_args, argc, argv); - if (err) - return -1; - - err = lxc_log_init(my_args.log_file, my_args.log_priority, - my_args.progname, my_args.quiet); - if (err) - return -1; - - err = setup_tios(0, &newtios, &oldtios); - if (err) { - ERROR("failed to setup tios"); - return -1; - } + int ret; + struct lxc_container *c; - err = lxc_console(my_args.name, my_args.ttynum, &master); - if (err) - goto out; - - fprintf(stderr, "\nType to exit the console\n", - 'a' + my_args.escape - 1); - - err = setsid(); - if (err) - INFO("already group leader"); - - if (signal(SIGWINCH, sigwinch) == SIG_ERR) { - SYSERROR("failed to set SIGWINCH handler"); - err = -1; - goto out; - } - - winsz(); + ret = lxc_arguments_parse(&my_args, argc, argv); + if (ret) + return EXIT_FAILURE; - err = lxc_mainloop_open(&descr); - if (err) { - ERROR("failed to create mainloop"); - goto out; - } + ret = lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority, + my_args.progname, my_args.quiet, my_args.lxcpath[0]); + if (ret) + return EXIT_FAILURE; - err = lxc_mainloop_add_handler(&descr, 0, stdin_handler, &master); - if (err) { - ERROR("failed to add handler for the stdin"); - goto out_mainloop_open; + c = lxc_container_new(my_args.name, my_args.lxcpath[0]); + if (!c) { + fprintf(stderr, "System error loading container\n"); + exit(EXIT_FAILURE); } - err = lxc_mainloop_add_handler(&descr, master, master_handler, &std_in); - if (err) { - ERROR("failed to add handler for the master"); - goto out_mainloop_open; + if (!c->is_running(c)) { + fprintf(stderr, "%s is not running\n", my_args.name); + exit(EXIT_FAILURE); } - err = lxc_mainloop(&descr); - if (err) { - ERROR("mainloop returned an error"); - goto out_mainloop_open; + ret = c->console(c, my_args.ttynum, 0, 1, 2, my_args.escape); + if (ret < 0) { + exit(EXIT_FAILURE); } - - err = 0; - -out_mainloop_open: - lxc_mainloop_close(&descr); - -out: - /* Restore previous terminal parameter */ - tcsetattr(0, TCSAFLUSH, &oldtios); - - /* Return to line it is */ - printf("\n"); - - close(master); - - return err; + return EXIT_SUCCESS; } diff -Nru lxc-0.8.0~rc1/src/lxc/lxc_create.c lxc-1.0.0~alpha1/src/lxc/lxc_create.c --- lxc-0.8.0~rc1/src/lxc/lxc_create.c 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/lxc_create.c 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,246 @@ +/* + * + * Copyright © 2013 Serge Hallyn . + * Copyright © 2013 Canonical Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "../lxc/lxccontainer.h" + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "arguments.h" +#include "utils.h" + +lxc_log_define(lxc_create, lxc); + +/* we pass fssize in bytes */ +static unsigned long get_fssize(char *s) +{ + unsigned long ret; + char *end; + + ret = strtoul(s, &end, 0); + if (end == s) + return 0; + while (isblank(*end)) + end++; + if (!(*end)) + return ret; + if (*end == 'g' || *end == 'G') + ret *= 1000000000; + else if (*end == 'm' || *end == 'M') + ret *= 1000000; + else if (*end == 'k' || *end == 'K') + ret *= 1000; + return ret; +} + +static int my_parser(struct lxc_arguments* args, int c, char* arg) +{ + switch (c) { + case 'B': args->bdevtype = arg; break; + case 'f': args->configfile = arg; break; + case 't': args->template = arg; break; + case '0': args->lvname = arg; break; + case '1': args->vgname = arg; break; + case '2': args->fstype = arg; break; + case '3': args->fssize = get_fssize(arg); break; + case '4': args->zfsroot = arg; break; + case '5': args->dir = arg; break; + } + return 0; +} + +static const struct option my_longopts[] = { + {"bdev", required_argument, 0, 'B'}, + {"config", required_argument, 0, 'f'}, + {"template", required_argument, 0, 't'}, + {"lvname", required_argument, 0, '0'}, + {"vgname", required_argument, 0, '1'}, + {"fstype", required_argument, 0, '2'}, + {"fssize", required_argument, 0, '3'}, + {"zfsroot", required_argument, 0, '4'}, + {"dir", required_argument, 0, '5'}, + LXC_COMMON_OPTIONS +}; + +static void create_helpfn(const struct lxc_arguments *args) { + char *argv[3], *path; + size_t len; + int ret; + pid_t pid; + + if (!args->template) + return; + if ((pid = fork()) < 0) + return; + if (pid) + wait_for_pid(pid); + len = strlen(LXCTEMPLATEDIR) + strlen(args->template) + strlen("/lxc-") + 1; + path = alloca(len); + ret = snprintf(path, len, "%s/lxc-%s", LXCTEMPLATEDIR, args->template); + if (ret < 0 || ret >= len) + return; + + argv[0] = path; + argv[1] = "-h"; + argv[2] = NULL; + execv(path, argv); + ERROR("Error executing %s -h", path); + exit(1); +} + +static struct lxc_arguments my_args = { + .progname = "lxc-create", + .helpfn = create_helpfn, + .help = "\ +--name=NAME [-w] [-r] [-t timeout] [-P lxcpath]\n\ +\n\ +lxc-create creates a container\n\ +\n\ +Options :\n\ + -n, --name=NAME NAME for name of the container\n\ + -f, --config=file initial configuration file\n\ + -t, --template=t template to use to setup container\n\ + -B, --bdev=BDEV backing store type to use\n\ + --lxcpath=PATH place container under PATH\n\ + --lvname=LVNAME Use LVM lv name LVNAME\n\ + (Default: container name)\n\ + --vgname=VG Use LVM vg called VG\n\ + (Default: lxc))\n\ + --fstype=TYPE Create fstype TYPE\n\ + (Default: ext3))\n\ + --fssize=SIZE Create filesystem of size SIZE\n\ + (Default: 1G))\n\ + --dir=DIR Place rootfs directory under DIR\n\ + --zfsroot=PATH Create zfs under given zfsroot\n\ + (Default: tank/lxc))\n", + .options = my_longopts, + .parser = my_parser, + .checker = NULL, +}; + +bool validate_bdev_args(struct lxc_arguments *a) +{ + if (a->fstype || a->fssize) { + if (strcmp(a->bdevtype, "lvm") != 0 && + strcmp(a->bdevtype, "loop") != 0) { + fprintf(stderr, "filesystem type and size are only valid with block devices\n"); + return false; + } + } + if (strcmp(a->bdevtype, "lvm") != 0) { + if (a->lvname || a->vgname) { + fprintf(stderr, "--lvname and --vgname are only valid with -B lvm\n"); + return false; + } + } + if (strcmp(a->bdevtype, "zfs") != 0) { + if (a->zfsroot) { + fprintf(stderr, "zfsroot is only valid with -B zfs\n"); + return false; + } + } + return true; +} + +int main(int argc, char *argv[]) +{ + struct lxc_container *c; + struct bdev_specs spec; + int flags = 0; + + if (lxc_arguments_parse(&my_args, argc, argv)) + exit(1); + + if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority, + my_args.progname, my_args.quiet, my_args.lxcpath[0])) + exit(1); + + memset(&spec, 0, sizeof(spec)); + if (!my_args.bdevtype) + my_args.bdevtype = "_unset"; + if (!validate_bdev_args(&my_args)) + exit(1); + + if (geteuid()) { + if (access(my_args.lxcpath[0], O_RDWR) < 0) { + fprintf(stderr, "You lack access to %s\n", my_args.lxcpath[0]); + exit(1); + } + if (strcmp(my_args.bdevtype, "dir") && strcmp(my_args.bdevtype, "_unset")) { + fprintf(stderr, "Unprivileged users can only create directory backed containers\n"); + exit(1); + } + } + + + c = lxc_container_new(my_args.name, my_args.lxcpath[0]); + if (!c) { + fprintf(stderr, "System error loading container\n"); + exit(1); + } + if (c->is_defined(c)) { + fprintf(stderr, "Container already exists\n"); + exit(1); + } + if (my_args.configfile) + c->load_config(c, my_args.configfile); + else + c->load_config(c, LXC_DEFAULT_CONFIG); + + if (strcmp(my_args.bdevtype, "zfs") == 0) { + if (my_args.zfsroot) + spec.u.zfs.zfsroot = my_args.zfsroot; + } else if (strcmp(my_args.bdevtype, "lvm") == 0) { + if (my_args.lvname) + spec.u.lvm.lv = my_args.lvname; + if (my_args.vgname) + spec.u.lvm.vg = my_args.vgname; + if (my_args.fstype) + spec.u.lvm.fstype = my_args.fstype; + if (my_args.fssize) + spec.u.lvm.fssize = my_args.fssize; + } else if (strcmp(my_args.bdevtype, "loop") == 0) { + if (my_args.fstype) + spec.u.lvm.fstype = my_args.fstype; + if (my_args.fssize) + spec.u.lvm.fssize = my_args.fssize; + } else if (my_args.dir) { + ERROR("--dir is not yet supported"); + exit(1); + } + + if (strcmp(my_args.bdevtype, "_unset") == 0) + my_args.bdevtype = NULL; + if (my_args.quiet) + flags = LXC_CREATE_QUIET; + if (!c->create(c, my_args.template, my_args.bdevtype, &spec, flags, &argv[optind])) { + ERROR("Error creating container %s", c->name); + lxc_container_put(c); + exit(1); + } + INFO("container %s created", c->name); + exit(0); +} diff -Nru lxc-0.8.0~rc1/src/lxc/lxc_destroy.c lxc-1.0.0~alpha1/src/lxc/lxc_destroy.c --- lxc-0.8.0~rc1/src/lxc/lxc_destroy.c 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/lxc_destroy.c 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,103 @@ +/* + * + * Copyright © 2013 Serge Hallyn . + * Copyright © 2013 Canonical Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "../lxc/lxccontainer.h" + +#include +#include +#include +#include + +#include +#include + +#include "arguments.h" +#include "utils.h" + +lxc_log_define(lxc_destroy, lxc); + +static int my_parser(struct lxc_arguments* args, int c, char* arg) +{ + switch (c) { + case 'f': args->force = 1; break; + } + return 0; +} + +static const struct option my_longopts[] = { + {"force", no_argument, 0, 'f'}, + LXC_COMMON_OPTIONS +}; + +static struct lxc_arguments my_args = { + .progname = "lxc-destroy", + .help = "\ +--name=NAME [-f] [-P lxcpath]\n\ +\n\ +lxc-destroy destroys a container with the identifier NAME\n\ +\n\ +Options :\n\ + -n, --name=NAME NAME for name of the container\n\ + -f, --force wait for the container to shut down\n", + .options = my_longopts, + .parser = my_parser, + .checker = NULL, +}; + +int main(int argc, char *argv[]) +{ + struct lxc_container *c; + + /* this is a short term test. We'll probably want to check for + * write access to lxcpath instead */ + if (geteuid()) { + fprintf(stderr, "%s must be run as root\n", argv[0]); + exit(1); + } + + if (lxc_arguments_parse(&my_args, argc, argv)) + exit(1); + + if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority, + my_args.progname, my_args.quiet, my_args.lxcpath[0])) + exit(1); + + c = lxc_container_new(my_args.name, my_args.lxcpath[0]); + if (!c) { + fprintf(stderr, "System error loading container\n"); + exit(1); + } + + if (!c->is_defined(c)) { + fprintf(stderr, "Container is not defined\n"); + lxc_container_put(c); + exit(1); + } + + if (c->is_running(c)) { + if (!my_args.force) { + fprintf(stderr, "%s is running\n", my_args.name); + lxc_container_put(c); + exit(1); + } + c->stop(c); + } + + exit(c->destroy(c) ? 0 : 1); +} diff -Nru lxc-0.8.0~rc1/src/lxc/lxc_execute.c lxc-1.0.0~alpha1/src/lxc/lxc_execute.c --- lxc-0.8.0~rc1/src/lxc/lxc_execute.c 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/lxc_execute.c 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,7 +18,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #define _GNU_SOURCE #include @@ -39,6 +39,7 @@ #include "arguments.h" #include "config.h" #include "start.h" +#include "utils.h" lxc_log_define(lxc_execute_ui, lxc_execute); @@ -99,8 +100,8 @@ if (lxc_arguments_parse(&my_args, argc, argv)) return -1; - if (lxc_log_init(my_args.log_file, my_args.log_priority, - my_args.progname, my_args.quiet)) + if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority, + my_args.progname, my_args.quiet, my_args.lxcpath[0])) return -1; /* rcfile is specified in the cli option */ @@ -109,7 +110,7 @@ else { int rc; - rc = asprintf(&rcfile, LXCPATH "/%s/config", my_args.name); + rc = asprintf(&rcfile, "%s/%s/config", my_args.lxcpath[0], my_args.name); if (rc == -1) { SYSERROR("failed to allocate memory"); return -1; @@ -136,5 +137,5 @@ if (lxc_config_define_load(&defines, conf)) return -1; - return lxc_execute(my_args.name, my_args.argv, my_args.quiet, conf); + return lxc_execute(my_args.name, my_args.argv, my_args.quiet, conf, my_args.lxcpath[0]); } diff -Nru lxc-0.8.0~rc1/src/lxc/lxc_freeze.c lxc-1.0.0~alpha1/src/lxc/lxc_freeze.c --- lxc-0.8.0~rc1/src/lxc/lxc_freeze.c 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/lxc_freeze.c 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,7 +18,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include @@ -28,9 +28,12 @@ #include #include +#include #include "arguments.h" +lxc_log_define(lxc_freeze_ui, lxc_cgroup); + static const struct option my_longopts[] = { LXC_COMMON_OPTIONS }; @@ -51,13 +54,28 @@ int main(int argc, char *argv[]) { + struct lxc_container *c; + if (lxc_arguments_parse(&my_args, argc, argv)) - return -1; + exit(1); - if (lxc_log_init(my_args.log_file, my_args.log_priority, - my_args.progname, my_args.quiet)) - return -1; + if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority, + my_args.progname, my_args.quiet, my_args.lxcpath[0])) + exit(1); + + c = lxc_container_new(my_args.name, my_args.lxcpath[0]); + if (!c) { + ERROR("No such container: %s:%s", my_args.lxcpath[0], my_args.name); + exit(1); + } + + if (!c->freeze(c)) { + ERROR("Failed to freeze %s:%s", my_args.lxcpath[0], my_args.name); + lxc_container_put(c); + exit(1); + } - return lxc_freeze(my_args.name); -} + lxc_container_put(c); + return 0; +} diff -Nru lxc-0.8.0~rc1/src/lxc/lxc_info.c lxc-1.0.0~alpha1/src/lxc/lxc_info.c --- lxc-0.8.0~rc1/src/lxc/lxc_info.c 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/lxc_info.c 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,10 +18,11 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include +#include #include #include #include @@ -34,19 +35,30 @@ static bool state; static bool pid; +static char *test_state = NULL; +static char **key = NULL; +static int keys = 0; static int my_parser(struct lxc_arguments* args, int c, char* arg) { switch (c) { + case 'c': + key = realloc(key, keys+1 * sizeof(key[0])); + key[keys] = arg; + keys++; + break; case 's': state = true; break; case 'p': pid = true; break; + case 't': test_state = arg; break; } return 0; } static const struct option my_longopts[] = { + {"config", required_argument, 0, 'c'}, {"state", no_argument, 0, 's'}, {"pid", no_argument, 0, 'p'}, + {"state-is", required_argument, 0, 't'}, LXC_COMMON_OPTIONS, }; @@ -58,9 +70,12 @@ lxc-info display some information about a container with the identifier NAME\n\ \n\ Options :\n\ - -n, --name=NAME NAME for name of the container\n\ - -s, --state shows the state of the container\n\ - -p, --pid shows the process id of the init container\n", + -n, --name=NAME NAME for name of the container\n\ + -c, --config=KEY show configuration variable KEY from running container\n\ + -p, --pid shows the process id of the init container\n\ + -s, --state shows the state of the container\n\ + -t, --state-is=STATE test if current state is STATE\n\ + returns success if it matches, false otherwise\n", .options = my_longopts, .parser = my_parser, .checker = NULL, @@ -68,29 +83,48 @@ int main(int argc, char *argv[]) { - int ret; + int ret,i; ret = lxc_arguments_parse(&my_args, argc, argv); if (ret) return 1; - if (lxc_log_init(my_args.log_file, my_args.log_priority, - my_args.progname, my_args.quiet)) + if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority, + my_args.progname, my_args.quiet, my_args.lxcpath[0])) return 1; - if (!state && !pid) + if (!state && !pid && keys <= 0) state = pid = true; - if (state) { - ret = lxc_getstate(my_args.name); + if (state || test_state) { + ret = lxc_getstate(my_args.name, my_args.lxcpath[0]); if (ret < 0) return 1; + if (test_state) + return strcmp(lxc_state2str(ret), test_state) != 0; printf("state:%10s\n", lxc_state2str(ret)); } - if (pid) - printf("pid:%10d\n", get_init_pid(my_args.name)); + if (pid) { + pid_t initpid; + + initpid = lxc_cmd_get_init_pid(my_args.name, my_args.lxcpath[0]); + if (initpid >= 0) + printf("pid:%10d\n", initpid); + } + + for(i = 0; i < keys; i++) { + char *val; + + val = lxc_cmd_get_config_item(my_args.name, key[i], my_args.lxcpath[0]); + if (val) { + printf("%s = %s\n", key[i], val); + free(val); + } else { + fprintf(stderr, "%s unset or invalid\n", key[i]); + } + } return 0; } diff -Nru lxc-0.8.0~rc1/src/lxc/lxc_init.c lxc-1.0.0~alpha1/src/lxc/lxc_init.c --- lxc-0.8.0~rc1/src/lxc/lxc_init.c 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/lxc_init.c 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,7 +18,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include @@ -43,52 +43,81 @@ static int quiet; static struct option options[] = { - { "quiet", no_argument, &quiet, 1 }, + { "name", required_argument, NULL, 'n' }, + { "logpriority", required_argument, NULL, 'l' }, + { "quiet", no_argument, NULL, 'q' }, + { "lxcpath", required_argument, NULL, 'P' }, { 0, 0, 0, 0 }, }; -static int was_interrupted = 0; +static int was_interrupted = 0; -int main(int argc, char *argv[]) +static void interrupt_handler(int sig) { + if (!was_interrupted) + was_interrupted = sig; +} - void interrupt_handler(int sig) - { - if (!was_interrupted) - was_interrupted = sig; - } +static void usage(void) { + fprintf(stderr, "Usage: lxc-init [OPTION]...\n\n" + "Common options :\n" + " -n, --name=NAME NAME for name of the container\n" + " -l, --logpriority=LEVEL Set log priority to LEVEL\n" + " -q, --quiet Don't produce any output\n" + " -P, --lxcpath=PATH Use specified container path\n" + " -?, --help Give this help list\n" + "\n" + "Mandatory or optional arguments to long options are also mandatory or optional\n" + "for any corresponding short options.\n" + "\n" + "NOTE: lxc-init is intended for use by lxc internally\n" + " and does not need to be run by hand\n\n"); +} +int main(int argc, char *argv[]) +{ pid_t pid; - int nbargs = 0; - int err = -1; + int err; char **aargv; sigset_t mask, omask; - int i, shutdown = 0; - - while (1) { - int ret = getopt_long_only(argc, argv, "", options, NULL); - if (ret == -1) { + int i, have_status = 0, shutdown = 0; + int opt; + char *lxcpath = NULL, *name = NULL, *logpriority = NULL; + + while ((opt = getopt_long(argc, argv, "n:l:qP:", options, NULL)) != -1) { + switch(opt) { + case 'n': + name = optarg; + break; + case 'l': + logpriority = optarg; + break; + case 'q': + quiet = 1; + break; + case 'P': + lxcpath = optarg; break; + default: /* '?' */ + usage(); + exit(EXIT_FAILURE); } - if (ret == '?') - exit(err); - - nbargs++; } if (lxc_caps_init()) - exit(err); + exit(EXIT_FAILURE); - if (lxc_log_init(NULL, 0, basename(argv[0]), quiet)) - exit(err); + err = lxc_log_init(name, name ? NULL : "none", logpriority, + basename(argv[0]), quiet, lxcpath); + if (err < 0) + exit(EXIT_FAILURE); if (!argv[optind]) { ERROR("missing command to launch"); - exit(err); + exit(EXIT_FAILURE); } aargv = &argv[optind]; - argc -= nbargs; /* * mask all the signals so we are safe to install a @@ -126,15 +155,15 @@ } if (lxc_setup_fs()) - exit(err); + exit(EXIT_FAILURE); if (lxc_caps_reset()) - exit(err); + exit(EXIT_FAILURE); pid = fork(); if (pid < 0) - exit(err); + exit(EXIT_FAILURE); if (!pid) { @@ -159,10 +188,9 @@ close(fileno(stdin)); close(fileno(stdout)); - err = 0; + err = EXIT_SUCCESS; for (;;) { int status; - int orphan = 0; pid_t waited_pid; switch (was_interrupted) { @@ -209,10 +237,10 @@ * (not wrapped pid) and continue to wait for * the end of the orphan group. */ - if ((waited_pid != pid) || (orphan ==1)) - continue; - orphan = 1; - err = lxc_error_set_and_log(waited_pid, status); + if (waited_pid == pid && !have_status) { + err = lxc_error_set_and_log(waited_pid, status); + have_status = 1; + } } out: return err; diff -Nru lxc-0.8.0~rc1/src/lxc/lxc_kill.c lxc-1.0.0~alpha1/src/lxc/lxc_kill.c --- lxc-0.8.0~rc1/src/lxc/lxc_kill.c 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/lxc_kill.c 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2010 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,7 +18,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include @@ -61,8 +61,8 @@ if (ret) return ret; - ret = lxc_log_init(my_args.log_file, my_args.log_priority, - my_args.progname, my_args.quiet); + ret = lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority, + my_args.progname, my_args.quiet, my_args.lxcpath[0]); if (ret) return ret; @@ -76,7 +76,7 @@ } else sig=SIGKILL; - pid = get_init_pid(my_args.name); + pid = lxc_cmd_get_init_pid(my_args.name, my_args.lxcpath[0]); if (pid < 0) { ERROR("failed to get the init pid"); return -1; diff -Nru lxc-0.8.0~rc1/src/lxc/lxc_monitor.c lxc-1.0.0~alpha1/src/lxc/lxc_monitor.c --- lxc-0.8.0~rc1/src/lxc/lxc_monitor.c 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/lxc_monitor.c 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,7 +18,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include @@ -52,6 +52,7 @@ .options = my_longopts, .parser = NULL, .checker = NULL, + .lxcpath_additional = -1, }; int main(int argc, char *argv[]) @@ -59,43 +60,70 @@ char *regexp; struct lxc_msg msg; regex_t preg; - int fd; + fd_set rfds, rfds_save; + int len, rc, i, nfds = -1; if (lxc_arguments_parse(&my_args, argc, argv)) return -1; - if (lxc_log_init(my_args.log_file, my_args.log_priority, - my_args.progname, my_args.quiet)) + if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority, + my_args.progname, my_args.quiet, my_args.lxcpath[0])) return -1; - regexp = malloc(strlen(my_args.name) + 3); + len = strlen(my_args.name) + 3; + regexp = malloc(len + 3); if (!regexp) { ERROR("failed to allocate memory"); return -1; } - sprintf(regexp, "^%s$", my_args.name); + rc = snprintf(regexp, len, "^%s$", my_args.name); + if (rc < 0 || rc >= len) { + ERROR("Name too long"); + free(regexp); + return -1; + } if (regcomp(&preg, regexp, REG_NOSUB|REG_EXTENDED)) { ERROR("failed to compile the regex '%s'", my_args.name); return -1; } - fd = lxc_monitor_open(); - if (fd < 0) - return -1; + if (my_args.lxcpath_cnt > FD_SETSIZE) { + ERROR("too many paths requested, only the first %d will be monitored", FD_SETSIZE); + my_args.lxcpath_cnt = FD_SETSIZE; + } + + FD_ZERO(&rfds); + for (i = 0; i < my_args.lxcpath_cnt; i++) { + int fd; + + lxc_monitord_spawn(my_args.lxcpath[i]); + + fd = lxc_monitor_open(my_args.lxcpath[i]); + if (fd < 0) + return -1; + FD_SET(fd, &rfds); + if (fd > nfds) + nfds = fd; + } + memcpy(&rfds_save, &rfds, sizeof(rfds_save)); + nfds++; setlinebuf(stdout); for (;;) { - if (lxc_monitor_read(fd, &msg) < 0) + memcpy(&rfds, &rfds_save, sizeof(rfds)); + + if (lxc_monitor_read_fdset(&rfds, nfds, &msg, -1) < 0) return -1; + msg.name[sizeof(msg.name)-1] = '\0'; if (regexec(&preg, msg.name, 0, NULL, 0)) continue; switch (msg.type) { case lxc_msg_state: - printf("'%s' changed state to [%s]\n", + printf("'%s' changed state to [%s]\n", msg.name, lxc_state2str(msg.value)); break; default: @@ -108,4 +136,3 @@ return 0; } - diff -Nru lxc-0.8.0~rc1/src/lxc/lxc_monitord.c lxc-1.0.0~alpha1/src/lxc/lxc_monitord.c --- lxc-0.8.0~rc1/src/lxc/lxc_monitord.c 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/lxc_monitord.c 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,409 @@ +/* + * lxc: linux Container library + * + * Copyright © 2012 Oracle. + * + * Authors: + * Dwight Engen + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define CLIENTFDS_CHUNK 64 + +lxc_log_define(lxc_monitord, lxc); + +static struct lxc_monitor mon; + +static void lxc_monitord_cleanup(void); + +/* + * Defines the structure to store the monitor information + * @lxcpath : the path being monitored + * @fifofd : the file descriptor for publishers (containers) to write state + * @listenfd : the file descriptor for subscribers (lxc-monitors) to connect + * @clientfds : accepted client file descriptors + * @clientfds_size : number of file descriptors clientfds can hold + * @clientfds_cnt : the count of valid fds in clientfds + * @descr : the lxc_mainloop state + */ +struct lxc_monitor { + const char *lxcpath; + int fifofd; + int listenfd; + int *clientfds; + int clientfds_size; + int clientfds_cnt; + struct lxc_epoll_descr descr; +}; + +static int lxc_monitord_fifo_create(struct lxc_monitor *mon) +{ + char fifo_path[PATH_MAX]; + int ret; + + ret = snprintf(fifo_path, sizeof(fifo_path), "%s/monitor-fifo", mon->lxcpath); + if (ret < 0 || ret >= sizeof(fifo_path)) { + ERROR("lxcpath too long to monitor fifo"); + return -1; + } + + ret = mknod(fifo_path, S_IFIFO|S_IRUSR|S_IWUSR, 0); + if (ret < 0) { + INFO("monitor fifo %s exists, already running?", fifo_path); + return -1; + } + + mon->fifofd = open(fifo_path, O_RDWR); + if (mon->fifofd < 0) { + unlink(fifo_path); + ERROR("failed to open monitor fifo"); + return -1; + } + return 0; +} + +static int lxc_monitord_fifo_delete(struct lxc_monitor *mon) +{ + char fifo_path[PATH_MAX]; + int ret; + + ret = snprintf(fifo_path, sizeof(fifo_path), "%s/monitor-fifo", mon->lxcpath); + if (ret < 0 || ret >= sizeof(fifo_path)) { + ERROR("lxcpath too long to monitor fifo"); + return -1; + } + unlink(fifo_path); + return 0; +} + +static void lxc_monitord_sockfd_remove(struct lxc_monitor *mon, int fd) { + int i; + + if (lxc_mainloop_del_handler(&mon->descr, fd)) + CRIT("fd:%d not found in mainloop", fd); + close(fd); + + for (i = 0; i < mon->clientfds_cnt; i++) { + if (mon->clientfds[i] == fd) + break; + } + if (i >= mon->clientfds_cnt) { + CRIT("fd:%d not found in clients array", fd); + lxc_monitord_cleanup(); + exit(EXIT_FAILURE); + } + + memmove(&mon->clientfds[i], &mon->clientfds[i+1], + (mon->clientfds_cnt - i - 1) * sizeof(mon->clientfds[0])); + mon->clientfds_cnt--; +} + +static int lxc_monitord_sock_handler(int fd, void *data, + struct lxc_epoll_descr *descr) +{ + struct lxc_monitor *mon = data; + + lxc_monitord_sockfd_remove(mon, fd); + return 0; +} + +static int lxc_monitord_sock_accept(int fd, void *data, + struct lxc_epoll_descr *descr) +{ + int ret,clientfd; + struct lxc_monitor *mon = data; + struct ucred cred; + socklen_t credsz = sizeof(cred); + + ret = -1; + clientfd = accept(fd, NULL, 0); + if (clientfd < 0) { + SYSERROR("failed to accept connection"); + goto out; + } + + if (fcntl(clientfd, F_SETFD, FD_CLOEXEC)) { + SYSERROR("failed to set close-on-exec on incoming connection"); + goto err1; + } + + if (getsockopt(clientfd, SOL_SOCKET, SO_PEERCRED, &cred, &credsz)) + { + ERROR("failed to get credentials on socket"); + goto err1; + } + if (cred.uid && cred.uid != geteuid()) { + WARN("monitor denied for uid:%d", cred.uid); + ret = -EACCES; + goto err1; + } + + if (mon->clientfds_cnt + 1 > mon->clientfds_size) { + int *clientfds; + DEBUG("realloc space for %d clientfds", + mon->clientfds_size + CLIENTFDS_CHUNK); + clientfds = realloc(mon->clientfds, + (mon->clientfds_size + CLIENTFDS_CHUNK) * + sizeof(mon->clientfds[0])); + if (clientfds == NULL) { + ERROR("failed to realloc memory for clientfds"); + goto err1; + } + mon->clientfds = clientfds; + mon->clientfds_size += CLIENTFDS_CHUNK; + } + + ret = lxc_mainloop_add_handler(&mon->descr, clientfd, + lxc_monitord_sock_handler, mon); + if (ret) { + ERROR("failed to add socket handler"); + goto err1; + } + + mon->clientfds[mon->clientfds_cnt++] = clientfd; + INFO("accepted client fd:%d clients:%d", clientfd, mon->clientfds_cnt); + goto out; + +err1: + close(clientfd); +out: + return ret; +} + +static int lxc_monitord_sock_create(struct lxc_monitor *mon) +{ + struct sockaddr_un addr; + int fd; + + if (lxc_monitor_sock_name(mon->lxcpath, &addr) < 0) + return -1; + + fd = lxc_af_unix_open(addr.sun_path, SOCK_STREAM, O_TRUNC); + if (fd < 0) { + ERROR("failed to open unix socket : %s", strerror(errno)); + return -1; + } + + mon->listenfd = fd; + return 0; +} + +static int lxc_monitord_sock_delete(struct lxc_monitor *mon) +{ + struct sockaddr_un addr; + + if (lxc_monitor_sock_name(mon->lxcpath, &addr) < 0) + return -1; + if (addr.sun_path[0]) + unlink(addr.sun_path); + return 0; +} + +static int lxc_monitord_create(struct lxc_monitor *mon) +{ + int ret; + + ret = lxc_monitord_fifo_create(mon); + if (ret < 0) + return ret; + + ret = lxc_monitord_sock_create(mon); + return ret; +} + +static void lxc_monitord_delete(struct lxc_monitor *mon) +{ + int i; + + lxc_mainloop_del_handler(&mon->descr, mon->listenfd); + close(mon->listenfd); + lxc_monitord_sock_delete(mon); + + lxc_mainloop_del_handler(&mon->descr, mon->fifofd); + close(mon->fifofd); + lxc_monitord_fifo_delete(mon); + + for (i = 0; i < mon->clientfds_cnt; i++) { + lxc_mainloop_del_handler(&mon->descr, mon->clientfds[i]); + close(mon->clientfds[i]); + } + mon->clientfds_cnt = 0; +} + +static int lxc_monitord_fifo_handler(int fd, void *data, + struct lxc_epoll_descr *descr) +{ + int ret,i; + struct lxc_msg msglxc; + struct lxc_monitor *mon = data; + + ret = read(fd, &msglxc, sizeof(msglxc)); + if (ret != sizeof(msglxc)) { + SYSERROR("read fifo failed : %s", strerror(errno)); + return 1; + } + + for (i = 0; i < mon->clientfds_cnt; i++) { + DEBUG("writing client fd:%d", mon->clientfds[i]); + ret = write(mon->clientfds[i], &msglxc, sizeof(msglxc)); + if (ret < 0) { + ERROR("write failed to client sock:%d %d %s", + mon->clientfds[i], errno, strerror(errno)); + } + } + + return 0; +} + +static int lxc_monitord_mainloop_add(struct lxc_monitor *mon) +{ + int ret; + + ret = lxc_mainloop_add_handler(&mon->descr, mon->fifofd, + lxc_monitord_fifo_handler, mon); + if (ret < 0) { + ERROR("failed to add to mainloop monitor handler for fifo"); + return -1; + } + + ret = lxc_mainloop_add_handler(&mon->descr, mon->listenfd, + lxc_monitord_sock_accept, mon); + if (ret < 0) { + ERROR("failed to add to mainloop monitor handler for listen socket"); + return -1; + } + + return 0; +} + +static void lxc_monitord_cleanup(void) +{ + lxc_monitord_delete(&mon); +} + +static void lxc_monitord_sig_handler(int sig) +{ + INFO("caught signal %d", sig); + lxc_monitord_cleanup(); + exit(EXIT_SUCCESS); +} + +int main(int argc, char *argv[]) +{ + int ret,pipefd; + char *lxcpath = argv[1]; + char logpath[PATH_MAX]; + sigset_t mask; + + if (argc != 3) { + fprintf(stderr, + "Usage: lxc-monitord lxcpath sync-pipe-fd\n\n" + "NOTE: lxc-monitord is intended for use by lxc internally\n" + " and does not need to be run by hand\n\n"); + exit(EXIT_FAILURE); + } + + ret = snprintf(logpath, sizeof(logpath), "%s/lxc-monitord.log", + lxcpath); + if (ret < 0 || ret >= sizeof(logpath)) + return EXIT_FAILURE; + + ret = lxc_log_init(NULL, logpath, "NOTICE", "lxc-monitord", 0, lxcpath); + if (ret) + return ret; + + pipefd = atoi(argv[2]); + + if (sigfillset(&mask) || + sigdelset(&mask, SIGILL) || + sigdelset(&mask, SIGSEGV) || + sigdelset(&mask, SIGBUS) || + sigdelset(&mask, SIGTERM) || + sigprocmask(SIG_BLOCK, &mask, NULL)) { + SYSERROR("failed to set signal mask"); + return -1; + } + + signal(SIGILL, lxc_monitord_sig_handler); + signal(SIGSEGV, lxc_monitord_sig_handler); + signal(SIGBUS, lxc_monitord_sig_handler); + signal(SIGTERM, lxc_monitord_sig_handler); + + ret = EXIT_FAILURE; + memset(&mon, 0, sizeof(mon)); + mon.lxcpath = lxcpath; + if (lxc_mainloop_open(&mon.descr)) { + ERROR("failed to create mainloop"); + goto out; + } + + if (lxc_monitord_create(&mon)) { + goto out; + } + + /* sync with parent, we're ignoring the return from write + * because regardless if it works or not, the following + * close will sync us with the parent process. the + * if-empty-statement construct is to quiet the + * warn-unused-result warning. + */ + if (write(pipefd, "S", 1)) ; + close(pipefd); + + if (lxc_monitord_mainloop_add(&mon)) { + ERROR("failed to add mainloop handlers"); + goto out; + } + + NOTICE("monitoring lxcpath %s", mon.lxcpath); + for(;;) { + ret = lxc_mainloop(&mon.descr, 1000 * 30); + if (mon.clientfds_cnt <= 0) + { + NOTICE("no clients for 30 seconds, exiting"); + break; + } + } + + lxc_mainloop_close(&mon.descr); + lxc_monitord_cleanup(); + ret = EXIT_SUCCESS; + NOTICE("monitor exiting"); +out: + return ret; +} diff -Nru lxc-0.8.0~rc1/src/lxc/lxc_restart.c lxc-1.0.0~alpha1/src/lxc/lxc_restart.c --- lxc-0.8.0~rc1/src/lxc/lxc_restart.c 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/lxc_restart.c 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2010 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,7 +18,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #define _GNU_SOURCE #include @@ -36,6 +36,7 @@ #include "config.h" #include "confile.h" #include "arguments.h" +#include "utils.h" lxc_log_define(lxc_restart_ui, lxc_restart); @@ -122,8 +123,8 @@ if (lxc_arguments_parse(&my_args, argc, argv)) return -1; - if (lxc_log_init(my_args.log_file, my_args.log_priority, - my_args.progname, my_args.quiet)) + if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority, + my_args.progname, my_args.quiet, my_args.lxcpath[0])) return -1; /* rcfile is specified in the cli option */ @@ -132,7 +133,7 @@ else { int rc; - rc = asprintf(&rcfile, LXCPATH "/%s/config", my_args.name); + rc = asprintf(&rcfile, "%s/%s/config", my_args.lxcpath[0], my_args.name); if (rc == -1) { SYSERROR("failed to allocate memory"); return -1; @@ -171,7 +172,7 @@ } } - ret = lxc_restart(my_args.name, sfd, conf, my_args.flags); + ret = lxc_restart(my_args.name, sfd, conf, my_args.flags, my_args.lxcpath[0]); if (my_args.statefile) close(sfd); diff -Nru lxc-0.8.0~rc1/src/lxc/lxc_start.c lxc-1.0.0~alpha1/src/lxc/lxc_start.c --- lxc-0.8.0~rc1/src/lxc/lxc_start.c 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/lxc_start.c 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,7 +18,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #define _GNU_SOURCE #include @@ -43,6 +43,7 @@ #include "log.h" #include "caps.h" #include "lxc.h" +#include "lxccontainer.h" #include "conf.h" #include "cgroup.h" #include "utils.h" @@ -54,14 +55,52 @@ static struct lxc_list defines; +static int ensure_path(char **confpath, const char *path) +{ + int err = -1, fd; + char *fullpath = NULL; + + if (path) { + if (access(path, W_OK)) { + fd = creat(path, 0600); + if (fd < 0 && errno != EEXIST) { + SYSERROR("failed to create '%s'", path); + goto err; + } + if (fd >= 0) + close(fd); + } + + fullpath = realpath(path, NULL); + if (!fullpath) { + SYSERROR("failed to get the real path of '%s'", path); + goto err; + } + + *confpath = strdup(fullpath); + if (!*confpath) { + ERROR("failed to dup string '%s'", fullpath); + goto err; + } + } + err = 0; + +err: + if (fullpath) + free(fullpath); + return err; +} + static int my_parser(struct lxc_arguments* args, int c, char* arg) { switch (c) { case 'c': args->console = arg; break; + case 'L': args->console_log = arg; break; case 'd': args->daemonize = 1; args->close_all_fds = 1; break; case 'f': args->rcfile = arg; break; case 'C': args->close_all_fds = 1; break; case 's': return lxc_config_define_add(&defines, arg); + case 'p': args->pidfile = arg; break; } return 0; } @@ -71,7 +110,9 @@ {"rcfile", required_argument, 0, 'f'}, {"define", required_argument, 0, 's'}, {"console", required_argument, 0, 'c'}, + {"console-log", required_argument, 0, 'L'}, {"close-all-fds", no_argument, 0, 'C'}, + {"pidfile", required_argument, 0, 'p'}, LXC_COMMON_OPTIONS }; @@ -83,18 +124,21 @@ lxc-start start COMMAND in specified container NAME\n\ \n\ Options :\n\ - -n, --name=NAME NAME for name of the container\n\ - -d, --daemon daemonize the container\n\ - -f, --rcfile=FILE Load configuration file FILE\n\ - -c, --console=FILE Set the file output for the container console\n\ - -C, --close-all-fds If any fds are inherited, close them\n\ - If not specified, exit with failure instead\n\ - Note: --daemon implies --close-all-fds\n\ - -s, --define KEY=VAL Assign VAL to configuration variable KEY\n", + -n, --name=NAME NAME for name of the container\n\ + -d, --daemon daemonize the container\n\ + -p, --pidfile=FILE Create a file with the process id\n\ + -f, --rcfile=FILE Load configuration file FILE\n\ + -c, --console=FILE Use specified FILE for the container console\n\ + -L, --console-log=FILE Log container console output to FILE\n\ + -C, --close-all-fds If any fds are inherited, close them\n\ + If not specified, exit with failure instead\n\ + Note: --daemon implies --close-all-fds\n\ + -s, --define KEY=VAL Assign VAL to configuration variable KEY\n", .options = my_longopts, .parser = my_parser, .checker = NULL, .daemonize = 0, + .pidfile = NULL, }; int main(int argc, char *argv[]) @@ -107,6 +151,9 @@ "/sbin/init", '\0', }; + FILE *pid_fp = NULL; + struct lxc_container *c; + char *anonpath; lxc_list_init(&defines); @@ -117,109 +164,116 @@ return err; if (!my_args.argc) - args = default_args; + args = default_args; else args = my_args.argv; - if (lxc_log_init(my_args.log_file, my_args.log_priority, - my_args.progname, my_args.quiet)) + if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority, + my_args.progname, my_args.quiet, my_args.lxcpath[0])) return err; - if (putenv("container=lxc")) { - SYSERROR("failed to set environment variable"); - return err; - } - + anonpath = alloca(strlen(LXCPATH) + 6); + sprintf(anonpath, "%s_anon", LXCPATH); + /* + * rcfile possibilities: + * 1. rcfile from random path specified in cli option + * 2. rcfile not specified, use $lxcpath/$lxcname/config + * 3. rcfile not specified and does not exist. + */ /* rcfile is specified in the cli option */ - if (my_args.rcfile) + if (my_args.rcfile) { rcfile = (char *)my_args.rcfile; - else { + c = lxc_container_new(my_args.name, anonpath); + if (!c) { + ERROR("Failed to create lxc_container"); + return err; + } + if (!c->load_config(c, rcfile)) { + ERROR("Failed to load rcfile"); + lxc_container_put(c); + return err; + } + } else { int rc; + const char *lxcpath = my_args.lxcpath[0]; - rc = asprintf(&rcfile, LXCPATH "/%s/config", my_args.name); + rc = asprintf(&rcfile, "%s/%s/config", lxcpath, my_args.name); if (rc == -1) { SYSERROR("failed to allocate memory"); return err; } + INFO("using rcfile %s", rcfile); /* container configuration does not exist */ if (access(rcfile, F_OK)) { free(rcfile); rcfile = NULL; + lxcpath = anonpath; + } + c = lxc_container_new(my_args.name, lxcpath); + if (!c) { + ERROR("Failed to create lxc_container"); + return err; } } - conf = lxc_conf_init(); - if (!conf) { - ERROR("failed to initialize configuration"); - return err; - } - - if (rcfile && lxc_config_read(rcfile, conf)) { - ERROR("failed to read configuration file"); - return err; - } + /* + * We should use set_config_item() over &defines, which would handle + * unset c->lxc_conf for us and let us not use lxc_config_define_load() + */ + if (!c->lxc_conf) + c->lxc_conf = lxc_conf_init(); + conf = c->lxc_conf; if (lxc_config_define_load(&defines, conf)) - return err; + goto out; if (!rcfile && !strcmp("/sbin/init", args[0])) { - ERROR("no configuration file for '/sbin/init' (may crash the host)"); - return err; + ERROR("Executing '/sbin/init' with no configuration file may crash the host"); + goto out; } - if (my_args.console) { - - char *console, fd; - - if (access(my_args.console, W_OK)) { - - fd = creat(my_args.console, 0600); - if (fd < 0) { - SYSERROR("failed to touch file '%s'", - my_args.console); - return err; - } - close(fd); - } + if (ensure_path(&conf->console.path, my_args.console) < 0) { + ERROR("failed to ensure console path '%s'", my_args.console); + goto out; + } - console = realpath(my_args.console, NULL); - if (!console) { - SYSERROR("failed to get the real path of '%s'", - my_args.console); - return err; - } + if (ensure_path(&conf->console.log_path, my_args.console_log) < 0) { + ERROR("failed to ensure console log '%s'", my_args.console_log); + goto out; + } - conf->console.path = strdup(console); - if (!conf->console.path) { - ERROR("failed to dup string '%s'", console); - return err; + if (my_args.pidfile != NULL) { + pid_fp = fopen(my_args.pidfile, "w"); + if (pid_fp == NULL) { + SYSERROR("failed to create pidfile '%s' for '%s'", + my_args.pidfile, my_args.name); + goto out; } + } - free(console); + if (my_args.daemonize) { + c->want_daemonize(c); } - if (my_args.daemonize && daemon(0, 0)) { - SYSERROR("failed to daemonize '%s'", my_args.name); - return err; + if (pid_fp != NULL) { + if (fprintf(pid_fp, "%d\n", getpid()) < 0) { + SYSERROR("failed to write '%s'", my_args.pidfile); + goto out; + } + fclose(pid_fp); } if (my_args.close_all_fds) conf->close_all_fds = 1; - err = lxc_start(my_args.name, args, conf); + err = c->start(c, 0, args) ? 0 : -1; - /* - * exec ourself, that requires to have all opened fd - * with the close-on-exec flag set - */ - if (conf->reboot) { - INFO("rebooting container"); - execvp(argv[0], argv); - SYSERROR("failed to exec"); - err = -1; - } + if (my_args.pidfile) + unlink(my_args.pidfile); +out: + lxc_container_put(c); return err; } diff -Nru lxc-0.8.0~rc1/src/lxc/lxc_stop.c lxc-1.0.0~alpha1/src/lxc/lxc_stop.c --- lxc-0.8.0~rc1/src/lxc/lxc_stop.c 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/lxc_stop.c 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,7 +18,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include @@ -28,9 +28,29 @@ #include #include +#include #include "arguments.h" +#include "commands.h" +#include "utils.h" + +static int my_parser(struct lxc_arguments* args, int c, char* arg) +{ + switch (c) { + case 'r': args->reboot = 1; break; + case 'W': args->nowait = 1; break; + case 't': args->timeout = atoi(arg); break; + case 'k': args->hardstop = 1; break; + case 's': args->shutdown = 1; break; + } + return 0; +} static const struct option my_longopts[] = { + {"reboot", no_argument, 0, 'r'}, + {"nowait", no_argument, 0, 'W'}, + {"timeout", required_argument, 0, 't'}, + {"kill", no_argument, 0, 'k'}, + {"shutdown", no_argument, 0, 's'}, LXC_COMMON_OPTIONS }; @@ -42,20 +62,114 @@ lxc-stop stops a container with the identifier NAME\n\ \n\ Options :\n\ - -n, --name=NAME NAME for name of the container\n", + -n, --name=NAME NAME for name of the container\n\ + -r, --reboot reboot the container\n\ + -W, --nowait don't wait for shutdown or reboot to complete\n\ + -t, --timeout=T wait T seconds before hard-stopping\n\ + -k, --kill kill container rather than request clean shutdown\n\ + -s, --shutdown Only request clean shutdown, don't later force kill\n", .options = my_longopts, - .parser = NULL, + .parser = my_parser, .checker = NULL, + .timeout = 60, }; -int main(int argc, char *argv[]) +/* returns -1 on failure, 0 on success */ +int do_reboot_and_check(struct lxc_arguments *a, struct lxc_container *c) { - if (lxc_arguments_parse(&my_args, argc, argv)) - return -1; + int ret; + pid_t pid; + pid_t newpid; + int timeout = a->timeout; - if (lxc_log_init(my_args.log_file, my_args.log_priority, - my_args.progname, my_args.quiet)) + pid = c->init_pid(c); + if (pid == -1) + return -1; + if (!c->reboot(c)) return -1; + if (a->nowait) + return 0; + if (timeout <= 0) + goto out; + + for (;;) { + /* can we use c-> wait for this, assuming it will + * re-enter RUNNING? For now just sleep */ + int elapsed_time, curtime = 0; + struct timeval tv; + + newpid = c->init_pid(c); + if (newpid != -1 && newpid != pid) + return 0; + + ret = gettimeofday(&tv, NULL); + if (ret) + break; + curtime = tv.tv_sec; + + sleep(1); + ret = gettimeofday(&tv, NULL); + if (ret) + break; + elapsed_time = tv.tv_sec - curtime; + if (timeout - elapsed_time <= 0) + break; + timeout -= elapsed_time; + } + +out: + newpid = c->init_pid(c); + if (newpid == -1 || newpid == pid) { + printf("Reboot did not complete before timeout\n"); + return -1; + } + return 0; +} + +int main(int argc, char *argv[]) +{ + struct lxc_container *c; + bool s; + int ret = 1; + + if (lxc_arguments_parse(&my_args, argc, argv)) + return 1; - return lxc_stop(my_args.name); + if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority, + my_args.progname, my_args.quiet, my_args.lxcpath[0])) + return 1; + + c = lxc_container_new(my_args.name, my_args.lxcpath[0]); + if (!c) { + fprintf(stderr, "Error opening container\n"); + goto out; + } + + if (!c->is_running(c)) { + fprintf(stderr, "%s is not running\n", c->name); + ret = 2; + goto out; + } + + if (my_args.hardstop) { + ret = c->stop(c) ? 0 : 1; + goto out; + } + if (my_args.reboot) { + ret = do_reboot_and_check(&my_args, c); + goto out; + } + + s = c->shutdown(c, my_args.timeout); + if (!s) { + if (!my_args.shutdown) + ret = c->wait(c, "STOPPED", -1) ? 0 : 1; + else + ret = 1; // fail + } else + ret = 0; + +out: + lxc_container_put(c); + return ret; } diff -Nru lxc-0.8.0~rc1/src/lxc/lxc_unfreeze.c lxc-1.0.0~alpha1/src/lxc/lxc_unfreeze.c --- lxc-0.8.0~rc1/src/lxc/lxc_unfreeze.c 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/lxc_unfreeze.c 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,7 +18,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include @@ -27,9 +27,12 @@ #include #include +#include #include "arguments.h" +lxc_log_define(lxc_unfreeze_ui, lxc_cgroup); + static const struct option my_longopts[] = { LXC_COMMON_OPTIONS }; @@ -50,13 +53,28 @@ int main(int argc, char *argv[]) { + struct lxc_container *c; + if (lxc_arguments_parse(&my_args, argc, argv)) - return -1; + exit(1); - if (lxc_log_init(my_args.log_file, my_args.log_priority, - my_args.progname, my_args.quiet)) - return -1; + if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority, + my_args.progname, my_args.quiet, my_args.lxcpath[0])) + exit(1); + + c = lxc_container_new(my_args.name, my_args.lxcpath[0]); + if (!c) { + ERROR("No such container: %s:%s", my_args.lxcpath[0], my_args.name); + exit(1); + } + + if (!c->unfreeze(c)) { + ERROR("Failed to unfreeze %s:%s", my_args.lxcpath[0], my_args.name); + lxc_container_put(c); + exit(1); + } - return lxc_unfreeze(my_args.name); -} + lxc_container_put(c); + return 0; +} diff -Nru lxc-0.8.0~rc1/src/lxc/lxc_unshare.c lxc-1.0.0~alpha1/src/lxc/lxc_unshare.c --- lxc-0.8.0~rc1/src/lxc/lxc_unshare.c 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/lxc_unshare.c 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,7 +18,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #define _GNU_SOURCE #include @@ -44,23 +44,19 @@ void usage(char *cmd) { - fprintf(stderr, "%s [command]\n", basename(cmd)); + fprintf(stderr, "%s command [command_arguments]\n", basename(cmd)); fprintf(stderr, "Options are:\n"); fprintf(stderr, "\t -s flags: ORed list of flags to unshare:\n" \ "\t MOUNT, PID, UTSNAME, IPC, USER, NETWORK\n"); fprintf(stderr, "\t -u : new id to be set if -s USER is specified\n"); - fprintf(stderr, "\t if -s PID is specified, is mandatory)\n"); _exit(1); } static uid_t lookup_user(const char *optarg) { - int bufflen = sysconf(_SC_GETPW_R_SIZE_MAX); - char buff[bufflen]; char name[sysconf(_SC_LOGIN_NAME_MAX)]; uid_t uid = -1; - struct passwd pwent; - struct passwd *pent; + struct passwd *pwent = NULL; if (!optarg || (optarg[0] == '\0')) return uid; @@ -70,13 +66,15 @@ if (sscanf(optarg, "%s", name) < 1) return uid; - if (getpwnam_r(name, &pwent, buff, bufflen, &pent) || !pent) { + pwent = getpwnam(name); + if (!pwent) { ERROR("invalid username %s", name); return uid; } - uid = pent->pw_uid; + uid = pwent->pw_uid; } else { - if (getpwuid_r(uid, &pwent, buff, bufflen, &pent) || !pent) { + pwent = getpwuid(uid); + if (!pwent) { ERROR("invalid uid %d", uid); uid = -1; return uid; @@ -85,51 +83,6 @@ return uid; } -static char *namespaces_list[] = { - "MOUNT", "PID", "UTSNAME", "IPC", - "USER", "NETWORK" -}; -static int cloneflags_list[] = { - CLONE_NEWNS, CLONE_NEWPID, CLONE_NEWUTS, CLONE_NEWIPC, - CLONE_NEWUSER, CLONE_NEWNET -}; - -static int lxc_namespace_2_cloneflag(char *namespace) -{ - int i, len; - len = sizeof(namespaces_list)/sizeof(namespaces_list[0]); - for (i = 0; i < len; i++) - if (!strcmp(namespaces_list[i], namespace)) - return cloneflags_list[i]; - - ERROR("invalid namespace name %s", namespace); - return -1; -} - -static int lxc_fill_namespace_flags(char *flaglist, int *flags) -{ - char *token, *saveptr = NULL; - int aflag; - - if (!flaglist) { - ERROR("need at least one namespace to unshare"); - return -1; - } - - token = strtok_r(flaglist, "|", &saveptr); - while (token) { - - aflag = lxc_namespace_2_cloneflag(token); - if (aflag < 0) - return -1; - - *flags |= aflag; - - token = strtok_r(NULL, "|", &saveptr); - } - return 0; -} - struct start_arg { char ***args; @@ -159,7 +112,6 @@ { int opt, status; int ret; - char *pid_name; char *namespaces = NULL; char **args; int flags = 0; @@ -172,11 +124,13 @@ .flags = &flags, }; - while ((opt = getopt(argc, argv, "s:u:")) != -1) { + while ((opt = getopt(argc, argv, "s:u:h")) != -1) { switch (opt) { case 's': namespaces = optarg; break; + case 'h': + usage(argv[0]); case 'u': uid = lookup_user(optarg); if (uid == -1) @@ -184,14 +138,19 @@ } } + if (argv[optind] == NULL) { + ERROR("a command to execute in the new namespace is required"); + return 1; + } + args = &argv[optind]; ret = lxc_caps_init(); if (ret) return ret; - ret = lxc_fill_namespace_flags(namespaces, &flags); - if (ret) + ret = lxc_fill_namespace_flags(namespaces, &flags); + if (ret) usage(argv[0]); if (!(flags & CLONE_NEWUSER) && uid != -1) { @@ -210,14 +169,5 @@ return -1; } - if (lxc_ns_is_mounted()) { - if (asprintf(&pid_name, "%d", pid) == -1) { - ERROR("pid_name: failed to allocate memory"); - return -1; - } - lxc_cgroup_destroy(pid_name); - free(pid_name); - } - return lxc_error_set_and_log(pid, status); } diff -Nru lxc-0.8.0~rc1/src/lxc/lxc_user_nic.c lxc-1.0.0~alpha1/src/lxc/lxc_user_nic.c --- lxc-0.8.0~rc1/src/lxc/lxc_user_nic.c 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/lxc_user_nic.c 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,782 @@ +/* + * + * Copyright © 2013 Serge Hallyn . + * Copyright © 2013 Canonical Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "config.h" + +#ifndef HAVE_GETLINE +#ifdef HAVE_FGETLN +#include <../include/getline.h> +#endif +#endif + +#if ISTEST +#define CONF_FILE "/tmp/lxc-usernet" +#define DB_FILE "/tmp/nics" +#else +#define CONF_FILE LXC_USERNIC_CONF +#define DB_FILE LXC_USERNIC_DB +#endif + + +#include "nl.h" + +#ifndef IFLA_LINKMODE +# define IFLA_LINKMODE 17 +#endif + +#ifndef IFLA_LINKINFO +# define IFLA_LINKINFO 18 +#endif + +#ifndef IFLA_NET_NS_PID +# define IFLA_NET_NS_PID 19 +#endif + +#ifndef IFLA_INFO_KIND +# define IFLA_INFO_KIND 1 +#endif + +#ifndef IFLA_VLAN_ID +# define IFLA_VLAN_ID 1 +#endif + +#ifndef IFLA_INFO_DATA +# define IFLA_INFO_DATA 2 +#endif + +#ifndef VETH_INFO_PEER +# define VETH_INFO_PEER 1 +#endif + +#ifndef IFLA_MACVLAN_MODE +# define IFLA_MACVLAN_MODE 1 +#endif + +void usage(char *me, bool fail) +{ + fprintf(stderr, "Usage: %s pid type bridge\n", me); + exit(fail ? 1 : 0); +} + +int open_and_lock(char *path) +{ + int fd; + struct flock lk; + + fd = open(path, O_RDWR|O_CREAT, S_IWUSR | S_IRUSR); + if (fd < 0) { + perror("open"); + return(fd); + } + + lk.l_type = F_WRLCK; + lk.l_whence = SEEK_SET; + lk.l_start = 0; + lk.l_len = 0; + if (fcntl(fd, F_SETLKW, &lk) < 0) { + perror("fcntl lock"); + exit(1); + } + + return fd; +} + + +char *get_username(char **buf) +{ + struct passwd *pwd = getpwuid(getuid()); + + if (pwd == NULL) { + perror("getpwuid"); + return NULL; + } + + return pwd->pw_name; +} + +/* The configuration file consists of lines of the form: + * + * user type bridge nic-name count + * + * We simply count the number of lines in the file, making sure that + * every listed nic is still present. Any nics which have disappeared + * is removed when we count, in case the container died a harsh death + * without being able to clean up after itself. + */ +int get_alloted(char *me, char *intype, char *link) +{ + FILE *fin = fopen(CONF_FILE, "r"); + char *line = NULL; + char user[100], type[100], br[100]; + size_t len = 0; + int n = -1, ret; + + if (!fin) + return -1; + + while ((getline(&line, &len, fin)) != -1) { + ret = sscanf(line, "%99[^ \t] %99[^ \t] %99[^ \t] %d", user, type, br, &n); + + if (ret != 4) + continue; + if (strcmp(user, me) != 0) + continue; + if (strcmp(type, intype) != 0) + continue; + if (strcmp(link, br) != 0) + continue; + free(line); + return n; + } + fclose(fin); + if (line) + free(line); + return -1; +} + +char *get_eol(char *s) +{ + while (*s && *s != '\n') + s++; + return s; +} + +char *get_eow(char *s) +{ + while (*s && !isblank(*s) && *s != '\n') + s++; + return s; +} + +char *find_line(char *p, char *e, char *u, char *t, char *l) +{ + char *p1, *p2, *ret; + + while (p < e && (p1 = get_eol(p)) < e) { + ret = p; + if (*p == '#') + goto next; + while (isblank(*p)) p++; + p2 = get_eow(p); + if (!p2 || p2-p != strlen(u) || strncmp(p, u, strlen(u)) != 0) + goto next; + p = p2+1; + while (isblank(*p)) p++; + p2 = get_eow(p); + if (!p2 || p2-p != strlen(t) || strncmp(p, t, strlen(t)) != 0) + goto next; + p = p2+1; + while (isblank(*p)) p++; + p2 = get_eow(p); + if (!p2 || p2-p != strlen(l) || strncmp(p, l, strlen(l)) != 0) + goto next; + return ret; +next: + p = p1 + 1; + } + + return NULL; +} + +bool nic_exists(char *nic) +{ + char path[200]; + int ret; + struct stat sb; + +#if ISTEST + ret = snprintf(path, 200, "/tmp/lxcnettest/%s", nic); +#else + ret = snprintf(path, 200, "/sys/class/net/%s", nic); +#endif + if (ret < 0 || ret >= 200) + exit(1); + ret = stat(path, &sb); + if (ret != 0) + return false; + return true; +} + +#if ! ISTEST +struct link_req { + struct nlmsg nlmsg; + struct ifinfomsg ifinfomsg; +}; + +int lxc_veth_create(const char *name1, const char *name2) +{ + struct nl_handler nlh; + struct nlmsg *nlmsg = NULL, *answer = NULL; + struct link_req *link_req; + struct rtattr *nest1, *nest2, *nest3; + int len, err; + + err = netlink_open(&nlh, NETLINK_ROUTE); + if (err) + return err; + + err = -EINVAL; + len = strlen(name1); + if (len == 1 || len >= IFNAMSIZ) + goto out; + + len = strlen(name2); + if (len == 1 || len >= IFNAMSIZ) + goto out; + + err = -ENOMEM; + nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE); + if (!nlmsg) + goto out; + + answer = nlmsg_alloc(NLMSG_GOOD_SIZE); + if (!answer) + goto out; + + link_req = (struct link_req *)nlmsg; + link_req->ifinfomsg.ifi_family = AF_UNSPEC; + nlmsg->nlmsghdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); + nlmsg->nlmsghdr.nlmsg_flags = + NLM_F_REQUEST|NLM_F_CREATE|NLM_F_EXCL|NLM_F_ACK; + nlmsg->nlmsghdr.nlmsg_type = RTM_NEWLINK; + + err = -EINVAL; + nest1 = nla_begin_nested(nlmsg, IFLA_LINKINFO); + if (!nest1) + goto out; + + if (nla_put_string(nlmsg, IFLA_INFO_KIND, "veth")) + goto out; + + nest2 = nla_begin_nested(nlmsg, IFLA_INFO_DATA); + if (!nest2) + goto out; + + nest3 = nla_begin_nested(nlmsg, VETH_INFO_PEER); + if (!nest3) + goto out; + + nlmsg->nlmsghdr.nlmsg_len += sizeof(struct ifinfomsg); + + if (nla_put_string(nlmsg, IFLA_IFNAME, name2)) + goto out; + + nla_end_nested(nlmsg, nest3); + + nla_end_nested(nlmsg, nest2); + + nla_end_nested(nlmsg, nest1); + + if (nla_put_string(nlmsg, IFLA_IFNAME, name1)) + goto out; + + err = netlink_transaction(&nlh, nlmsg, answer); +out: + netlink_close(&nlh); + nlmsg_free(answer); + nlmsg_free(nlmsg); + return err; +} + +int lxc_netdev_move(char *ifname, pid_t pid) +{ + struct nl_handler nlh; + struct nlmsg *nlmsg = NULL; + struct link_req *link_req; + int err, index; + + index = if_nametoindex(ifname); + if (!ifname) + return -EINVAL; + + err = netlink_open(&nlh, NETLINK_ROUTE); + if (err) + return err; + + err = -ENOMEM; + nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE); + if (!nlmsg) + goto out; + + link_req = (struct link_req *)nlmsg; + link_req->ifinfomsg.ifi_family = AF_UNSPEC; + link_req->ifinfomsg.ifi_index = index; + nlmsg->nlmsghdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); + nlmsg->nlmsghdr.nlmsg_flags = NLM_F_REQUEST|NLM_F_ACK; + nlmsg->nlmsghdr.nlmsg_type = RTM_NEWLINK; + + if (nla_put_u32(nlmsg, IFLA_NET_NS_PID, pid)) + goto out; + + err = netlink_transaction(&nlh, nlmsg, nlmsg); +out: + netlink_close(&nlh); + nlmsg_free(nlmsg); + return err; +} + +static int setup_private_host_hw_addr(char *veth1) +{ + struct ifreq ifr; + int err; + int sockfd; + + sockfd = socket(AF_INET, SOCK_DGRAM, 0); + if (sockfd < 0) + return -errno; + + snprintf((char *)ifr.ifr_name, IFNAMSIZ, "%s", veth1); + err = ioctl(sockfd, SIOCGIFHWADDR, &ifr); + if (err < 0) { + close(sockfd); + return -errno; + } + + ifr.ifr_hwaddr.sa_data[0] = 0xfe; + err = ioctl(sockfd, SIOCSIFHWADDR, &ifr); + close(sockfd); + if (err < 0) + return -errno; + + return 0; +} + +static int netdev_set_flag(const char *name, int flag) +{ + struct nl_handler nlh; + struct nlmsg *nlmsg = NULL, *answer = NULL; + struct link_req *link_req; + int index, len, err; + + err = netlink_open(&nlh, NETLINK_ROUTE); + if (err) + return err; + + err = -EINVAL; + len = strlen(name); + if (len == 1 || len >= IFNAMSIZ) + goto out; + + err = -ENOMEM; + nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE); + if (!nlmsg) + goto out; + + answer = nlmsg_alloc(NLMSG_GOOD_SIZE); + if (!answer) + goto out; + + err = -EINVAL; + index = if_nametoindex(name); + if (!index) + goto out; + + link_req = (struct link_req *)nlmsg; + link_req->ifinfomsg.ifi_family = AF_UNSPEC; + link_req->ifinfomsg.ifi_index = index; + link_req->ifinfomsg.ifi_change |= IFF_UP; + link_req->ifinfomsg.ifi_flags |= flag; + nlmsg->nlmsghdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); + nlmsg->nlmsghdr.nlmsg_flags = NLM_F_REQUEST|NLM_F_ACK; + nlmsg->nlmsghdr.nlmsg_type = RTM_NEWLINK; + + err = netlink_transaction(&nlh, nlmsg, answer); +out: + netlink_close(&nlh); + nlmsg_free(nlmsg); + nlmsg_free(answer); + return err; +} + +static int instanciate_veth(char *n1, char **n2) +{ + int err; + + err = snprintf(*n2, IFNAMSIZ, "%sp", n1); + if (err < 0 || err >= IFNAMSIZ) { + fprintf(stderr, "nic name too long\n"); + exit(1); + } + + err = lxc_veth_create(n1, *n2); + if (err) { + fprintf(stderr, "failed to create %s-%s : %s\n", n1, *n2, + strerror(-err)); + exit(1); + } + + /* changing the high byte of the mac address to 0xfe, the bridge interface + * will always keep the host's mac address and not take the mac address + * of a container */ + err = setup_private_host_hw_addr(n1); + if (err) { + fprintf(stderr, "failed to change mac address of host interface '%s' : %s", + n1, strerror(-err)); + } + + return netdev_set_flag(n1, IFF_UP); +} + +int lxc_bridge_attach(const char *bridge, const char *ifname) +{ + int fd, index, err; + struct ifreq ifr; + + if (strlen(ifname) >= IFNAMSIZ) + return -EINVAL; + + index = if_nametoindex(ifname); + if (!index) + return -EINVAL; + + fd = socket(AF_INET, SOCK_STREAM, 0); + if (fd < 0) + return -errno; + + strncpy(ifr.ifr_name, bridge, IFNAMSIZ); + ifr.ifr_ifindex = index; + err = ioctl(fd, SIOCBRADDIF, &ifr); + close(fd); + if (err) + err = -errno; + + return err; +} + +int lxc_netdev_delete_by_index(int ifindex) +{ + struct nl_handler nlh; + struct nlmsg *nlmsg = NULL, *answer = NULL; + struct link_req *link_req; + int err; + + err = netlink_open(&nlh, NETLINK_ROUTE); + if (err) + return err; + + err = -ENOMEM; + nlmsg = nlmsg_alloc(NLMSG_GOOD_SIZE); + if (!nlmsg) + goto out; + + answer = nlmsg_alloc(NLMSG_GOOD_SIZE); + if (!answer) + goto out; + + link_req = (struct link_req *)nlmsg; + link_req->ifinfomsg.ifi_family = AF_UNSPEC; + link_req->ifinfomsg.ifi_index = ifindex; + nlmsg->nlmsghdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); + nlmsg->nlmsghdr.nlmsg_flags = NLM_F_ACK|NLM_F_REQUEST; + nlmsg->nlmsghdr.nlmsg_type = RTM_DELLINK; + + err = netlink_transaction(&nlh, nlmsg, answer); +out: + netlink_close(&nlh); + nlmsg_free(answer); + nlmsg_free(nlmsg); + return err; +} + +int lxc_netdev_delete_by_name(const char *name) +{ + int index; + + index = if_nametoindex(name); + if (!index) + return -EINVAL; + + return lxc_netdev_delete_by_index(index); +} +#else +int lxc_netdev_delete_by_name(const char *name) +{ + char path[200]; + sprintf(path, "/tmp/lxcnettest/%s", name); + return unlink(path); +} + +#endif + +bool create_nic(char *nic, char *br, char *pidstr) +{ +#if ISTEST + char path[200]; + sprintf(path, "/tmp/lxcnettest/%s", nic); + int fd = open(path, O_RDWR|O_CREAT, S_IWUSR | S_IRUSR); + if (fd < 0) + return false; + close(fd); + return true; +#else + // not yet implemented + char *veth1buf, *veth2buf; + veth1buf = alloca(IFNAMSIZ); + veth2buf = alloca(IFNAMSIZ); + int ret; + int pid = atoi(pidstr); + + ret = snprintf(veth1buf, IFNAMSIZ, "%s", nic); + if (ret < 0 || ret >= IFNAMSIZ) { + fprintf(stderr, "nic name too long\n"); + exit(1); + } + + /* create the nics */ + if (instanciate_veth(veth1buf, &veth2buf) < 0) { + fprintf(stderr, "Error creating veth tunnel\n"); + return false; + } + + /* attach veth1 to bridge */ + if (lxc_bridge_attach(br, veth1buf) < 0) { + fprintf(stderr, "Error attaching %s to %s\n", veth1buf, br); + goto out_del; + } + + /* pass veth2 to target netns */ + ret = lxc_netdev_move(veth2buf, pid); + if (ret < 0) { + fprintf(stderr, "Error moving %s to netns %d\n", veth2buf, pid); + goto out_del; + } + return true; + +out_del: + lxc_netdev_delete_by_name(veth1buf); + exit(1); +#endif +} + +void get_new_nicname(char **dest, char *br, char *pid) +{ + int i = 0; + // TODO - speed this up. For large installations we won't + // want n stats for every nth container startup. + while (1) { + sprintf(*dest, "lxcuser-%d", i); + if (!nic_exists(*dest) && create_nic(*dest, br, pid)) + return; + i++; + } +} + +bool get_nic_from_line(char *p, char **nic) +{ + char user[100], type[100], br[100]; + int ret; + + ret = sscanf(p, "%99[^ \t\n] %99[^ \t\n] %99[^ \t\n] %99[^ \t\n]", user, type, br, *nic); + if (ret != 4) + return false; + return true; +} + +bool cull_entries(int fd, char *me, char *t, char *br) +{ + struct stat sb; + char *buf, *p, *e, *nic; + off_t len; + + nic = alloca(100); + + fstat(fd, &sb); + len = sb.st_size; + if (len == 0) + return true; + buf = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); + if (buf == MAP_FAILED) { + fprintf(stderr, "Failed to create mapping: error %d\n", errno); + return false; + } + + p = buf; + e = buf + len; + while ((p = find_line(p, e, me, t, br)) != NULL) { + if (!get_nic_from_line(p, &nic)) + continue; + if (nic && !nic_exists(nic)) { + // copy from eol(p)+1..e to p + char *src = get_eol(p) + 1, *dest = p; + int diff = src - p; + while (src < e) + *(dest++) = *(src)++; + e -= diff; + } else + p = get_eol(p) + 1; + if (p >= e) + break; + } + munmap(buf, sb.st_size); + if (ftruncate(fd, e-buf)) + fprintf(stderr, "Failed to set new file size\n"); + return true; +} + +int count_entries(char *buf, off_t len, char *me, char *t, char *br) +{ + char *e = &buf[len]; + int count = 0; + while ((buf = find_line(buf, e, me, t, br)) != NULL) { + count++; + buf = get_eol(buf)+1; + if (buf >= e) + break; + } + + return count; +} + +/* + * The dbfile has lines of the format: + * user type bridge nicname + */ +bool get_nic_if_avail(int fd, char *me, char *pid, char *intype, char *br, int allowed, char **nicname) +{ + off_t len, slen; + struct stat sb; + char *buf = NULL, *newline; + int ret, count = 0; + + cull_entries(fd, me, intype, br); + + fstat(fd, &sb); + len = sb.st_size; + if (len != 0) { + buf = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); + if (buf == MAP_FAILED) { + fprintf(stderr, "Failed to create mapping\n"); + return false; + } + + count = count_entries(buf, len, me, intype, br); + if (count >= allowed) + return false; + } + + + get_new_nicname(nicname, br, pid); + /* me ' ' intype ' ' br ' ' *nicname + '\n' + '\0' */ + slen = strlen(me) + strlen(intype) + strlen(br) + strlen(*nicname) + 5; + newline = alloca(slen); + ret = snprintf(newline, slen, "%s %s %s %s\n", me, intype, br, *nicname); + if (ret < 0 || ret >= slen) { + if (lxc_netdev_delete_by_name(*nicname) != 0) + fprintf(stderr, "Error unlinking %s!\n", *nicname); + return false; + } + if (len) + munmap(buf, len); + if (ftruncate(fd, len + slen)) + fprintf(stderr, "Failed to set new file size\n"); + buf = mmap(NULL, len + slen, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); + if (buf == MAP_FAILED) { + fprintf(stderr, "Failed to create mapping after extending: error %d\n", errno); + if (lxc_netdev_delete_by_name(*nicname) != 0) + fprintf(stderr, "Error unlinking %s!\n", *nicname); + return false; + } + strcpy(buf+len, newline); + munmap(buf, len+slen); + return true; +} + +bool create_db_dir(char *fnam) +{ + char *p = alloca(strlen(fnam)+1); + + strcpy(p, fnam); + fnam = p; + p = p + 1; +again: + while (*p && *p != '/') p++; + if (!*p) + return true; + *p = '\0'; + if (mkdir(fnam, 0755) && errno != EEXIST) { + fprintf(stderr, "failed to create %s\n", fnam); + *p = '/'; + return false; + } + *(p++) = '/'; + goto again; +} + +int main(int argc, char *argv[]) +{ + int n, fd; + bool gotone = false; + char *me, *buf = alloca(400); + char *nicname = alloca(40); + + if ((me = get_username(&buf)) == NULL) { + fprintf(stderr, "Failed to get username\n"); + exit(1); + } + + if (argc != 4) + usage(argv[0], true); + + if (!create_db_dir(DB_FILE)) { + fprintf(stderr, "Failed to create directory for db file\n"); + exit(1); + } + + if ((fd = open_and_lock(DB_FILE)) < 0) { + fprintf(stderr, "Failed to lock %s\n", DB_FILE); + exit(1); + } + + n = get_alloted(me, argv[2], argv[3]); + if (n > 0) + gotone = get_nic_if_avail(fd, me, argv[1], argv[2], argv[3], n, &nicname); + close(fd); + if (!gotone) { + fprintf(stderr, "Quota reached\n"); + exit(1); + } + + // Now create the link + + exit(0); +} diff -Nru lxc-0.8.0~rc1/src/lxc/lxc_usernsexec.c lxc-1.0.0~alpha1/src/lxc/lxc_usernsexec.c --- lxc-0.8.0~rc1/src/lxc/lxc_usernsexec.c 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/lxc_usernsexec.c 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,417 @@ +/* + * (C) Copyright IBM Corp. 2008 + * (C) Copyright Canonical, Inc 2010-2013 + * + * Authors: + * Serge Hallyn + * (Once upon a time, this was based on nsexec from the IBM + * container tools) + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "namespace.h" + +int unshare(int flags); + +static void usage(const char *name) +{ + printf("usage: %s [-h] [-c] [-mnuUip] [-P ]" + "[command [arg ..]]\n", name); + printf("\n"); + printf(" -h this message\n"); + printf("\n"); + printf(" -m uid maps to use\n"); + printf("\n"); + printf(" uid-maps: [u|g|b]:ns_id:host_id:range\n"); + printf(" [u|g|b]: map user id, group id, or both\n"); + printf(" ns_id: the base id in the new namespace\n"); + printf(" host_id: the base id in the parent namespace\n"); + printf(" range: how many ids to map\n"); + printf(" Note: This program uses newuidmap(2) and newgidmap(2).\n"); + printf(" As such, /etc/subuid and /etc/subgid must grant the\n"); + printf(" calling user permission to use the mapped ranges\n"); + exit(1); +} + +static void opentty(const char * tty) { + int i, fd, flags; + + fd = open(tty, O_RDWR | O_NONBLOCK); + if (fd == -1) { + printf("FATAL: can't reopen tty: %s", strerror(errno)); + sleep(1); + exit(1); + } + + flags = fcntl(fd, F_GETFL); + flags &= ~O_NONBLOCK; + fcntl(fd, F_SETFL, flags); + + for (i = 0; i < fd; i++) + close(i); + for (i = 0; i < 3; i++) + if (fd != i) + dup2(fd, i); + if (fd >= 3) + close(fd); +} +// Code copy end + +static int do_child(void *vargv) +{ + char **argv = (char **)vargv; + + // Assume we want to become root + if (setgid(0) < 0) { + perror("setgid"); + return -1; + } + if (setuid(0) < 0) { + perror("setuid"); + return -1; + } + if (setgroups(0, NULL) < 0) { + perror("setgroups"); + return -1; + } + if (unshare(CLONE_NEWNS) < 0) { + perror("unshare CLONE_NEWNS"); + return -1; + } + execvp(argv[0], argv); + perror("execvpe"); + return -1; +} + +struct id_map { + char which; // b or u or g + long host_id, ns_id, range; + struct id_map *next; +}; + +struct id_map default_map = { + .which = 'b', + .host_id = 100000, + .ns_id = 0, + .range = 10000, +}; +static struct id_map *active_map = &default_map; + +/* + * given a string like "b:0:100000:10", map both uids and gids + * 0-10 to 100000 to 100010 + */ +static int parse_map(char *map) +{ + struct id_map *newmap; + int ret; + + if (!map) + return -1; + newmap = malloc(sizeof(*newmap)); + if (!newmap) + return -1; + ret = sscanf(map, "%c:%ld:%ld:%ld", &newmap->which, &newmap->ns_id, &newmap->host_id, &newmap->range); + if (ret != 4) + goto out_free_map; + if (newmap->which != 'b' && newmap->which != 'u' && newmap->which != 'g') + goto out_free_map; + if (active_map != &default_map) + newmap->next = active_map; + else + newmap->next = NULL; + active_map = newmap; + return 0; + +out_free_map: + free(newmap); + return -1; +} + +/* + * go through /etc/subuids and /etc/subgids to find this user's + * allowed map. We only use the first one (bc otherwise we're + * not sure which ns ids he wants to use). + */ +static int read_default_map(char *fnam, char which, char *username) +{ + FILE *fin; + char *line = NULL; + size_t sz = 0; + struct id_map *newmap; + char *p1, *p2; + + fin = fopen(fnam, "r"); + if (!fin) + return -1; + while (getline(&line, &sz, fin) != -1) { + if (sz <= strlen(username) || + strncmp(line, username, strlen(username)) != 0 || + line[strlen(username)] != ':') + continue; + p1 = index(line, ':'); + if (!p1) + continue; + p2 = index(p1+1, ':'); + if (!p2) + continue; + newmap = malloc(sizeof(*newmap)); + if (!newmap) + return -1; + newmap->host_id = atol(p1+1); + newmap->range = atol(p2+1); + newmap->ns_id = 0; + newmap->which = which; + if (active_map != &default_map) + newmap->next = active_map; + else + newmap->next = NULL; + break; + } + + if (line) + free(line); + fclose(fin); + return 0; +} + +#define subuidfile "/etc/subuid" +#define subgidfile "/etc/subgid" +static int find_default_map(void) +{ + struct passwd *p = getpwuid(getuid()); + if (!p) + return -1; + if (read_default_map(subuidfile, 'u', p->pw_name) < 0) + return -1; + if (read_default_map(subgidfile, 'g', p->pw_name) < 0) + return -1; + return 0; +} + +static int run_cmd(char **argv) +{ + int status; + pid_t pid = fork(); + + if (pid < 0) + return pid; + if (pid == 0) { + execvp(argv[0], argv); + perror("exec failed"); + exit(1); + } + if (waitpid(pid, &status, __WALL) < 0) { + perror("waitpid"); + return -1; + } + + return WEXITSTATUS(status); +} + +static int map_child_uids(int pid, struct id_map *map) +{ + char **uidargs = NULL, **gidargs = NULL; + int i, nuargs = 2, ngargs = 2; + struct id_map *m; + + uidargs = malloc(3 * sizeof(*uidargs)); + gidargs = malloc(3 * sizeof(*gidargs)); + if (uidargs == NULL || gidargs == NULL) + return -1; + uidargs[0] = malloc(10); + gidargs[0] = malloc(10); + uidargs[1] = malloc(21); + gidargs[1] = malloc(21); + uidargs[2] = NULL; + gidargs[2] = NULL; + if (!uidargs[0] || !uidargs[1] || !gidargs[0] || !gidargs[1]) + return -1; + sprintf(uidargs[0], "newuidmap"); + sprintf(gidargs[0], "newgidmap"); + sprintf(uidargs[1], "%d", pid); + sprintf(gidargs[1], "%d", pid); + for (m=map; m; m = m->next) { + if (m->which == 'b' || m->which == 'u') { + nuargs += 3; + uidargs = realloc(uidargs, (nuargs+1) * sizeof(*uidargs)); + if (!uidargs) + return -1; + uidargs[nuargs - 3] = malloc(21); + uidargs[nuargs - 2] = malloc(21); + uidargs[nuargs - 1] = malloc(21); + if (!uidargs[nuargs-3] || !uidargs[nuargs-2] || !uidargs[nuargs-1]) + return -1; + sprintf(uidargs[nuargs - 3], "%ld", m->ns_id); + sprintf(uidargs[nuargs - 2], "%ld", m->host_id); + sprintf(uidargs[nuargs - 1], "%ld", m->range); + uidargs[nuargs] = NULL; + } + if (m->which == 'b' || m->which == 'g') { + ngargs += 3; + gidargs = realloc(gidargs, (ngargs+1) * sizeof(*gidargs)); + if (!gidargs) + return -1; + gidargs[ngargs - 3] = malloc(21); + gidargs[ngargs - 2] = malloc(21); + gidargs[ngargs - 1] = malloc(21); + if (!gidargs[ngargs-3] || !gidargs[ngargs-2] || !gidargs[ngargs-1]) + return -1; + sprintf(gidargs[ngargs - 3], "%ld", m->ns_id); + sprintf(gidargs[ngargs - 2], "%ld", m->host_id); + sprintf(gidargs[ngargs - 1], "%ld", m->range); + gidargs[ngargs] = NULL; + } + } + + // exec newuidmap + if (nuargs > 2 && run_cmd(uidargs) != 0) { + fprintf(stderr, "Error mapping uids\n"); + return -2; + } + // exec newgidmap + if (ngargs > 2 && run_cmd(gidargs) != 0) { + fprintf(stderr, "Error mapping gids\n"); + return -2; + } + + for (i=0; i + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,17 +18,19 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include +#include +#include #include #include #include -#include +#include #include "arguments.h" lxc_log_define(lxc_wait_ui, lxc_monitor); @@ -46,12 +48,14 @@ { switch (c) { case 's': args->states = optarg; break; + case 't': args->timeout = atol(optarg); break; } return 0; } static const struct option my_longopts[] = { {"state", required_argument, 0, 's'}, + {"timeout", required_argument, 0, 't'}, LXC_COMMON_OPTIONS }; @@ -66,91 +70,32 @@ -n, --name=NAME NAME for name of the container\n\ -s, --state=STATE ORed states to wait for\n\ STOPPED, STARTING, RUNNING, STOPPING,\n\ - ABORTING, FREEZING, FROZEN\n", + ABORTING, FREEZING, FROZEN, THAWED\n\ + -t, --timeout=TMO Seconds to wait for state changes\n", .options = my_longopts, .parser = my_parser, .checker = my_checker, + .timeout = -1, }; -static int fillwaitedstates(char *strstates, int *states) -{ - char *token, *saveptr = NULL; - int state; - - token = strtok_r(strstates, "|", &saveptr); - while (token) { - - state = lxc_str2state(token); - if (state < 0) - return -1; - - states[state] = 1; - - token = strtok_r(NULL, "|", &saveptr); - } - return 0; -} - int main(int argc, char *argv[]) { - struct lxc_msg msg; - int s[MAX_STATE] = { }, fd; - int state, ret; + struct lxc_container *c; if (lxc_arguments_parse(&my_args, argc, argv)) return -1; - if (lxc_log_init(my_args.log_file, my_args.log_priority, - my_args.progname, my_args.quiet)) + if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority, + my_args.progname, my_args.quiet, my_args.lxcpath[0])) return -1; - if (fillwaitedstates(my_args.states, s)) + c = lxc_container_new(my_args.name, my_args.lxcpath[0]); + if (!c) return -1; - fd = lxc_monitor_open(); - if (fd < 0) + if (!c->wait(c, my_args.states, my_args.timeout)) { + lxc_container_put(c); return -1; - - /* - * if container present, - * then check if already in requested state - */ - ret = -1; - state = lxc_getstate(my_args.name); - if (state < 0) { - goto out_close; - } else if ((state >= 0) && (s[state])) { - ret = 0; - goto out_close; } - - for (;;) { - if (lxc_monitor_read(fd, &msg) < 0) - goto out_close; - - if (strcmp(my_args.name, msg.name)) - continue; - - switch (msg.type) { - case lxc_msg_state: - if (msg.value < 0 || msg.value >= MAX_STATE) { - ERROR("Receive an invalid state number '%d'", - msg.value); - goto out_close; - } - - if (s[msg.value]) { - ret = 0; - goto out_close; - } - break; - default: - /* just ignore garbage */ - break; - } - } - -out_close: - lxc_monitor_close(fd); - return ret; + return 0; } diff -Nru lxc-0.8.0~rc1/src/lxc/lxccontainer.c lxc-1.0.0~alpha1/src/lxc/lxccontainer.c --- lxc-0.8.0~rc1/src/lxc/lxccontainer.c 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/lxccontainer.c 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,2330 @@ +/* liblxcapi + * + * Copyright © 2012 Serge Hallyn . + * Copyright © 2012 Canonical Ltd. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include "config.h" +#include "lxc.h" +#include "state.h" +#include "lxccontainer.h" +#include "conf.h" +#include "confile.h" +#include "console.h" +#include "cgroup.h" +#include "commands.h" +#include "version.h" +#include "log.h" +#include "bdev.h" +#include "utils.h" +#include "attach.h" +#include +#include +#include +#include +#include + +#if HAVE_IFADDRS_H +#include +#else +#include <../include/ifaddrs.h> +#endif + +#ifndef HAVE_GETLINE +#ifdef HAVE_FGETLN +#include <../include/getline.h> +#endif +#endif + +lxc_log_define(lxc_container, lxc); + +static bool file_exists(char *f) +{ + struct stat statbuf; + + return stat(f, &statbuf) == 0; +} + +/* + * A few functions to help detect when a container creation failed. + * If a container creation was killed partway through, then trying + * to actually start that container could harm the host. We detect + * this by creating a 'partial' file under the container directory, + * and keeping an advisory lock. When container creation completes, + * we remove that file. When we load or try to start a container, if + * we find that file, without a flock, we remove the container. + */ +int ongoing_create(struct lxc_container *c) +{ + int len = strlen(c->config_path) + strlen(c->name) + 10; + char *path = alloca(len); + int fd, ret; + struct flock lk; + + ret = snprintf(path, len, "%s/%s/partial", c->config_path, c->name); + if (ret < 0 || ret >= len) { + ERROR("Error writing partial pathname"); + return -1; + } + + if (!file_exists(path)) + return 0; + if (process_lock()) + return -1; + if ((fd = open(path, O_RDWR)) < 0) { + // give benefit of the doubt + SYSERROR("Error opening partial file"); + process_unlock(); + return 0; + } + lk.l_type = F_WRLCK; + lk.l_whence = SEEK_SET; + lk.l_start = 0; + lk.l_len = 0; + lk.l_pid = -1; + if (fcntl(fd, F_GETLK, &lk) == 0 && lk.l_pid != -1) { + // create is still ongoing + close(fd); + process_unlock(); + return 1; + } + // create completed but partial is still there. + close(fd); + process_unlock(); + return 2; +} + +int create_partial(struct lxc_container *c) +{ + // $lxcpath + '/' + $name + '/partial' + \0 + int len = strlen(c->config_path) + strlen(c->name) + 10; + char *path = alloca(len); + int fd, ret; + struct flock lk; + + ret = snprintf(path, len, "%s/%s/partial", c->config_path, c->name); + if (ret < 0 || ret >= len) { + ERROR("Error writing partial pathname"); + return -1; + } + if (process_lock()) + return -1; + if ((fd=open(path, O_RDWR | O_CREAT | O_EXCL, 0755)) < 0) { + SYSERROR("Erorr creating partial file"); + process_unlock(); + return -1; + } + lk.l_type = F_WRLCK; + lk.l_whence = SEEK_SET; + lk.l_start = 0; + lk.l_len = 0; + if (fcntl(fd, F_SETLKW, &lk) < 0) { + SYSERROR("Error locking partial file %s", path); + close(fd); + process_unlock(); + return -1; + } + process_unlock(); + + return fd; +} + +void remove_partial(struct lxc_container *c, int fd) +{ + // $lxcpath + '/' + $name + '/partial' + \0 + int len = strlen(c->config_path) + strlen(c->name) + 10; + char *path = alloca(len); + int ret; + + close(fd); + ret = snprintf(path, len, "%s/%s/partial", c->config_path, c->name); + if (ret < 0 || ret >= len) { + ERROR("Error writing partial pathname"); + return; + } + if (process_lock()) + return; + if (unlink(path) < 0) + SYSERROR("Error unlink partial file %s", path); + process_unlock(); +} + +/* LOCKING + * 1. container_mem_lock(c) protects the struct lxc_container from multiple threads. + * 2. container_disk_lock(c) protects the on-disk container data - in particular the + * container configuration file. + * The container_disk_lock also takes the container_mem_lock. + * 3. thread_mutex protects process data (ex: fd table) from multiple threads. + * NOTHING mutexes two independent programs with their own struct + * lxc_container for the same c->name, between API calls. For instance, + * c->config_read(); c->start(); Between those calls, data on disk + * could change (which shouldn't bother the caller unless for instance + * the rootfs get moved). c->config_read(); update; c->config_write(); + * Two such updaters could race. The callers should therefore check their + * results. Trying to prevent that would necessarily expose us to deadlocks + * due to hung callers. So I prefer to keep the locks only within our own + * functions, not across functions. + * + * If you're going to clone while holding a lxccontainer, increment + * c->numthreads (under privlock) before forking. When deleting, + * decrement numthreads under privlock, then if it hits 0 you can delete. + * Do not ever use a lxccontainer whose numthreads you did not bump. + */ + +static void lxc_container_free(struct lxc_container *c) +{ + if (!c) + return; + + if (c->configfile) { + free(c->configfile); + c->configfile = NULL; + } + if (c->error_string) { + free(c->error_string); + c->error_string = NULL; + } + if (c->slock) { + lxc_putlock(c->slock); + c->slock = NULL; + } + if (c->privlock) { + lxc_putlock(c->privlock); + c->privlock = NULL; + } + if (c->name) { + free(c->name); + c->name = NULL; + } + if (c->lxc_conf) { + lxc_conf_free(c->lxc_conf); + c->lxc_conf = NULL; + } + if (c->config_path) { + free(c->config_path); + c->config_path = NULL; + } + free(c); +} + +/* + * Consider the following case: +freer | racing get()er +================================================================== +lxc_container_put() | lxc_container_get() +\ lxclock(c->privlock) | c->numthreads < 1? (no) +\ c->numthreads = 0 | \ lxclock(c->privlock) -> waits +\ lxcunlock() | \ +\ lxc_container_free() | \ lxclock() returns + | \ c->numthreads < 1 -> return 0 +\ \ (free stuff) | +\ \ sem_destroy(privlock) | + + * When the get()er checks numthreads the first time, one of the following + * is true: + * 1. freer has set numthreads = 0. get() returns 0 + * 2. freer is between lxclock and setting numthreads to 0. get()er will + * sem_wait on privlock, get lxclock after freer() drops it, then see + * numthreads is 0 and exit without touching lxclock again.. + * 3. freer has not yet locked privlock. If get()er runs first, then put()er + * will see --numthreads = 1 and not call lxc_container_free(). +*/ + +int lxc_container_get(struct lxc_container *c) +{ + if (!c) + return 0; + + // if someone else has already started freeing the container, don't + // try to take the lock, which may be invalid + if (c->numthreads < 1) + return 0; + + if (container_mem_lock(c)) + return 0; + if (c->numthreads < 1) { + // bail without trying to unlock, bc the privlock is now probably + // in freed memory + return 0; + } + c->numthreads++; + container_mem_unlock(c); + return 1; +} + +int lxc_container_put(struct lxc_container *c) +{ + if (!c) + return -1; + if (container_mem_lock(c)) + return -1; + if (--c->numthreads < 1) { + container_mem_unlock(c); + lxc_container_free(c); + return 1; + } + container_mem_unlock(c); + return 0; +} + +static bool lxcapi_is_defined(struct lxc_container *c) +{ + struct stat statbuf; + bool ret = false; + int statret; + + if (!c) + return false; + + if (container_mem_lock(c)) + return false; + if (!c->configfile) + goto out; + statret = stat(c->configfile, &statbuf); + if (statret != 0) + goto out; + ret = true; + +out: + container_mem_unlock(c); + return ret; +} + +static const char *lxcapi_state(struct lxc_container *c) +{ + lxc_state_t s; + + if (!c) + return NULL; + s = lxc_getstate(c->name, c->config_path); + return lxc_state2str(s); +} + +static bool is_stopped(struct lxc_container *c) +{ + lxc_state_t s; + s = lxc_getstate(c->name, c->config_path); + return (s == STOPPED); +} + +static bool lxcapi_is_running(struct lxc_container *c) +{ + const char *s; + + if (!c) + return false; + s = lxcapi_state(c); + if (!s || strcmp(s, "STOPPED") == 0) + return false; + return true; +} + +static bool lxcapi_freeze(struct lxc_container *c) +{ + int ret; + if (!c) + return false; + + ret = lxc_freeze(c->name, c->config_path); + if (ret) + return false; + return true; +} + +static bool lxcapi_unfreeze(struct lxc_container *c) +{ + int ret; + if (!c) + return false; + + ret = lxc_unfreeze(c->name, c->config_path); + if (ret) + return false; + return true; +} + +static int lxcapi_console_getfd(struct lxc_container *c, int *ttynum, int *masterfd) +{ + int ttyfd; + if (!c) + return -1; + + ttyfd = lxc_console_getfd(c, ttynum, masterfd); + return ttyfd; +} + +static int lxcapi_console(struct lxc_container *c, int ttynum, int stdinfd, + int stdoutfd, int stderrfd, int escape) +{ + return lxc_console(c, ttynum, stdinfd, stdoutfd, stderrfd, escape); +} + +static pid_t lxcapi_init_pid(struct lxc_container *c) +{ + if (!c) + return -1; + + return lxc_cmd_get_init_pid(c->name, c->config_path); +} + +static bool load_config_locked(struct lxc_container *c, const char *fname) +{ + if (!c->lxc_conf) + c->lxc_conf = lxc_conf_init(); + if (c->lxc_conf && !lxc_config_read(fname, c->lxc_conf)) + return true; + return false; +} + +static bool lxcapi_load_config(struct lxc_container *c, const char *alt_file) +{ + bool ret = false, need_disklock = false; + int lret; + const char *fname; + if (!c) + return false; + + fname = c->configfile; + if (alt_file) + fname = alt_file; + if (!fname) + return false; + /* + * If we're reading something other than the container's config, + * we only need to lock the in-memory container. If loading the + * container's config file, take the disk lock. + */ + if (strcmp(fname, c->configfile) == 0) + need_disklock = true; + + if (need_disklock) + lret = container_disk_lock(c); + else + lret = container_mem_lock(c); + if (lret) + return false; + + ret = load_config_locked(c, fname); + + if (need_disklock) + container_disk_unlock(c); + else + container_mem_unlock(c); + return ret; +} + +static void lxcapi_want_daemonize(struct lxc_container *c) +{ + if (!c) + return; + if (container_mem_lock(c)) { + ERROR("Error getting mem lock"); + return; + } + c->daemonize = 1; + container_mem_unlock(c); +} + +static bool lxcapi_wait(struct lxc_container *c, const char *state, int timeout) +{ + int ret; + + if (!c) + return false; + + ret = lxc_wait(c->name, state, timeout, c->config_path); + return ret == 0; +} + + +static bool wait_on_daemonized_start(struct lxc_container *c) +{ + /* we'll probably want to make this timeout configurable? */ + int timeout = 5, ret, status; + + /* + * our child is going to fork again, then exit. reap the + * child + */ + ret = wait(&status); + if (ret == -1 || !WIFEXITED(status) || WEXITSTATUS(status) != 0) + DEBUG("failed waiting for first dual-fork child"); + return lxcapi_wait(c, "RUNNING", timeout); +} + +/* + * I can't decide if it'd be more convenient for callers if we accept '...', + * or a null-terminated array (i.e. execl vs execv) + */ +static bool lxcapi_start(struct lxc_container *c, int useinit, char * const argv[]) +{ + int ret; + struct lxc_conf *conf; + int daemonize = 0; + char *default_args[] = { + "/sbin/init", + '\0', + }; + + /* container exists */ + if (!c) + return false; + /* container has been setup */ + if (!c->lxc_conf) + return false; + + if ((ret = ongoing_create(c)) < 0) { + ERROR("Error checking for incomplete creation"); + return false; + } + if (ret == 2) { + ERROR("Error: %s creation was not completed", c->name); + c->destroy(c); + return false; + } else if (ret == 1) { + ERROR("Error: creation of %s is ongoing", c->name); + return false; + } + + /* is this app meant to be run through lxcinit, as in lxc-execute? */ + if (useinit && !argv) + return false; + + if (container_mem_lock(c)) + return false; + conf = c->lxc_conf; + daemonize = c->daemonize; + container_mem_unlock(c); + + if (useinit) { + ret = lxc_execute(c->name, argv, 1, conf, c->config_path); + return ret == 0 ? true : false; + } + + if (!argv) + argv = default_args; + + /* + * say, I'm not sure - what locks do we want here? Any? + * Is liblxc's locking enough here to protect the on disk + * container? We don't want to exclude things like lxc_info + * while container is running... + */ + if (daemonize) { + if (!lxc_container_get(c)) + return false; + lxc_monitord_spawn(c->config_path); + + if (process_lock()) + return false; + pid_t pid = fork(); + if (pid < 0) { + lxc_container_put(c); + process_unlock(); + return false; + } + if (pid != 0) { + ret = wait_on_daemonized_start(c); + process_unlock(); + return ret; + } + process_unlock(); + /* second fork to be reparented by init */ + pid = fork(); + if (pid < 0) { + SYSERROR("Error doing dual-fork"); + return false; + } + if (pid != 0) + exit(0); + /* like daemon(), chdir to / and redirect 0,1,2 to /dev/null */ + if (chdir("/")) { + SYSERROR("Error chdir()ing to /."); + return false; + } + close(0); + close(1); + close(2); + open("/dev/zero", O_RDONLY); + open("/dev/null", O_RDWR); + open("/dev/null", O_RDWR); + setsid(); + } + +reboot: + conf->reboot = 0; + ret = lxc_start(c->name, argv, conf, c->config_path); + + if (conf->reboot) { + INFO("container requested reboot"); + conf->reboot = 0; + goto reboot; + } + + if (daemonize) { + lxc_container_put(c); + exit (ret == 0 ? true : false); + } else { + return (ret == 0 ? true : false); + } +} + +/* + * note there MUST be an ending NULL + */ +static bool lxcapi_startl(struct lxc_container *c, int useinit, ...) +{ + va_list ap; + char **inargs = NULL; + bool bret = false; + + /* container exists */ + if (!c) + return false; + + va_start(ap, useinit); + inargs = lxc_va_arg_list_to_argv(ap, 0, 1); + va_end(ap); + + if (!inargs) { + ERROR("Memory allocation error."); + goto out; + } + + /* pass NULL if no arguments were supplied */ + bret = lxcapi_start(c, useinit, *inargs ? inargs : NULL); + +out: + if (inargs) { + char *arg; + for (arg = *inargs; arg; arg++) + free(arg); + free(inargs); + } + + return bret; +} + +static bool lxcapi_stop(struct lxc_container *c) +{ + int ret; + + if (!c) + return false; + + ret = lxc_cmd_stop(c->name, c->config_path); + + return ret == 0; +} + +/* + * create the standard expected container dir + */ +static bool create_container_dir(struct lxc_container *c) +{ + char *s; + int len, ret; + + len = strlen(c->config_path) + strlen(c->name) + 2; + s = malloc(len); + if (!s) + return false; + ret = snprintf(s, len, "%s/%s", c->config_path, c->name); + if (ret < 0 || ret >= len) { + free(s); + return false; + } + ret = mkdir(s, 0755); + if (ret) { + if (errno == EEXIST) + ret = 0; + else + SYSERROR("failed to create container path for %s\n", c->name); + } + free(s); + return ret == 0; +} + +static const char *lxcapi_get_config_path(struct lxc_container *c); +static bool lxcapi_set_config_item(struct lxc_container *c, const char *key, const char *v); + +/* + * do_bdev_create: thin wrapper around bdev_create(). Like bdev_create(), + * it returns a mounted bdev on success, NULL on error. + */ +static struct bdev *do_bdev_create(struct lxc_container *c, const char *type, + struct bdev_specs *specs) +{ + char *dest; + const char *lxcpath = lxcapi_get_config_path(c); + size_t len; + struct bdev *bdev; + int ret; + + /* lxcpath/lxcname/rootfs */ + len = strlen(c->name) + strlen(lxcpath) + 9; + dest = alloca(len); + ret = snprintf(dest, len, "%s/%s/rootfs", lxcpath, c->name); + if (ret < 0 || ret >= len) + return NULL; + + bdev = bdev_create(dest, type, c->name, specs); + if (!bdev) { + ERROR("Failed to create backing store type %s\n", type); + return NULL; + } + + lxcapi_set_config_item(c, "lxc.rootfs", bdev->src); + return bdev; +} + +/* + * Given the '-t' template option to lxc-create, figure out what to + * do. If the template is a full executable path, use that. If it + * is something like 'sshd', then return $templatepath/lxc-sshd. If + * no template was passed in, return NULL (this is ok). + * On error return (char *) -1. + */ +char *get_template_path(const char *t) +{ + int ret, len; + char *tpath; + + if (!t) + return NULL; + + if (t[0] == '/' && access(t, X_OK) == 0) { + tpath = strdup(t); + if (!tpath) + return (char *) -1; + return tpath; + } + + len = strlen(LXCTEMPLATEDIR) + strlen(t) + strlen("/lxc-") + 1; + tpath = malloc(len); + if (!tpath) + return (char *) -1; + ret = snprintf(tpath, len, "%s/lxc-%s", LXCTEMPLATEDIR, t); + if (ret < 0 || ret >= len) { + free(tpath); + return (char *) -1; + } + if (access(tpath, X_OK) < 0) { + SYSERROR("bad template: %s\n", t); + free(tpath); + return (char *) -1; + } + + return tpath; +} + +static char *lxcbasename(char *path) +{ + char *p = path + strlen(path) - 1; + while (*p != '/' && p > path) + p--; + return p; +} + +static bool create_run_template(struct lxc_container *c, char *tpath, bool quiet, + char *const argv[]) +{ + pid_t pid; + + if (!tpath) + return true; + + pid = fork(); + if (pid < 0) { + SYSERROR("failed to fork task for container creation template\n"); + return false; + } + + if (pid == 0) { // child + char *patharg, *namearg, *rootfsarg, *src; + struct bdev *bdev = NULL; + int i; + int ret, len, nargs = 0; + char **newargv; + + if (quiet) { + close(0); + close(1); + close(2); + open("/dev/zero", O_RDONLY); + open("/dev/null", O_RDWR); + open("/dev/null", O_RDWR); + } + if (unshare(CLONE_NEWNS) < 0) { + ERROR("error unsharing mounts"); + exit(1); + } + + src = c->lxc_conf->rootfs.path; + /* + * for an overlayfs create, what the user wants is the template to fill + * in what will become the readonly lower layer. So don't mount for + * the template + */ + if (strncmp(src, "overlayfs:", 10) == 0) { + src = overlayfs_getlower(src+10); + } + bdev = bdev_init(src, c->lxc_conf->rootfs.mount, NULL); + if (!bdev) { + ERROR("Error opening rootfs"); + exit(1); + } + + if (bdev->ops->mount(bdev) < 0) { + ERROR("Error mounting rootfs"); + exit(1); + } + + /* + * create our new array, pre-pend the template name and + * base args + */ + if (argv) + for (nargs = 0; argv[nargs]; nargs++) ; + nargs += 4; // template, path, rootfs and name args + newargv = malloc(nargs * sizeof(*newargv)); + if (!newargv) + exit(1); + newargv[0] = lxcbasename(tpath); + + len = strlen(c->config_path) + strlen(c->name) + strlen("--path=") + 2; + patharg = malloc(len); + if (!patharg) + exit(1); + ret = snprintf(patharg, len, "--path=%s/%s", c->config_path, c->name); + if (ret < 0 || ret >= len) + exit(1); + newargv[1] = patharg; + len = strlen("--name=") + strlen(c->name) + 1; + namearg = malloc(len); + if (!namearg) + exit(1); + ret = snprintf(namearg, len, "--name=%s", c->name); + if (ret < 0 || ret >= len) + exit(1); + newargv[2] = namearg; + + len = strlen("--rootfs=") + 1 + strlen(bdev->dest); + rootfsarg = malloc(len); + if (!rootfsarg) + exit(1); + ret = snprintf(rootfsarg, len, "--rootfs=%s", bdev->dest); + if (ret < 0 || ret >= len) + exit(1); + newargv[3] = rootfsarg; + + /* add passed-in args */ + if (argv) + for (i = 4; i < nargs; i++) + newargv[i] = argv[i-4]; + + /* add trailing NULL */ + nargs++; + newargv = realloc(newargv, nargs * sizeof(*newargv)); + if (!newargv) + exit(1); + newargv[nargs - 1] = NULL; + + /* execute */ + execv(tpath, newargv); + SYSERROR("failed to execute template %s", tpath); + exit(1); + } + + if (wait_for_pid(pid) != 0) { + ERROR("container creation template for %s failed\n", c->name); + return false; + } + + return true; +} + +bool prepend_lxc_header(char *path, const char *t, char *const argv[]) +{ + long flen; + char *contents; + FILE *f; +#if HAVE_LIBGNUTLS + int i, ret; + unsigned char md_value[SHA_DIGEST_LENGTH]; + char *tpath; + bool have_tpath = false; +#endif + + if ((f = fopen(path, "r")) == NULL) { + SYSERROR("Opening old config"); + return false; + } + if (fseek(f, 0, SEEK_END) < 0) { + SYSERROR("Seeking to end of old config file"); + fclose(f); + return false; + } + if ((flen = ftell(f)) < 0) { + SYSERROR("telling size of old config"); + fclose(f); + return false; + } + if (fseek(f, 0, SEEK_SET) < 0) { + SYSERROR("rewinding old config"); + fclose(f); + return false; + } + if ((contents = malloc(flen + 1)) == NULL) { + SYSERROR("out of memory"); + fclose(f); + return false; + } + if (fread(contents, 1, flen, f) != flen) { + SYSERROR("Reading old config"); + free(contents); + fclose(f); + return false; + } + contents[flen] = '\0'; + if (fclose(f) < 0) { + SYSERROR("closing old config"); + free(contents); + return false; + } + +#if HAVE_LIBGNUTLS + tpath = get_template_path(t); + if (tpath == (char *) -1) { + ERROR("bad template: %s\n", t); + free(contents); + return false; + } + + if (tpath) { + have_tpath = true; + ret = sha1sum_file(tpath, md_value); + if (ret < 0) { + ERROR("Error getting sha1sum of %s", tpath); + free(contents); + return false; + } + free(tpath); + } +#endif + + if ((f = fopen(path, "w")) == NULL) { + SYSERROR("reopening config for writing"); + free(contents); + return false; + } + fprintf(f, "# Template used to create this container: %s\n", t); + if (argv) { + fprintf(f, "# Parameters passed to the template:"); + while (*argv) { + fprintf(f, " %s", *argv); + argv++; + } + fprintf(f, "\n"); + } +#if HAVE_LIBGNUTLS + if (have_tpath) { + fprintf(f, "# Template script checksum (SHA-1): "); + for (i=0; isave_config(c, NULL)) { + ERROR("failed to save starting configuration for %s\n", c->name); + goto out; + } + + /* container is already created if we have a config and rootfs.path is accessible */ + if (lxcapi_is_defined(c) && c->lxc_conf && c->lxc_conf->rootfs.path && access(c->lxc_conf->rootfs.path, F_OK) == 0) + goto out; + + /* Mark that this container is being created */ + if ((partial_fd = create_partial(c)) < 0) + goto out; + + /* no need to get disk lock bc we have the partial locked */ + + /* + * Create the backing store + * Note we can't do this in the same task as we use to execute the + * template because of the way zfs works. + * After you 'zfs create', zfs mounts the fs only in the initial + * namespace. + */ + pid = fork(); + if (pid < 0) { + SYSERROR("failed to fork task for container creation template\n"); + goto out_unlock; + } + + if (pid == 0) { // child + struct bdev *bdev = NULL; + + if (!(bdev = do_bdev_create(c, bdevtype, specs))) { + ERROR("Error creating backing store type %s for %s", + bdevtype ? bdevtype : "(none)", c->name); + exit(1); + } + + /* save config file again to store the new rootfs location */ + if (!c->save_config(c, NULL)) { + ERROR("failed to save starting configuration for %s\n", c->name); + // parent task won't see bdev in config so we delete it + bdev->ops->umount(bdev); + bdev->ops->destroy(bdev); + exit(1); + } + exit(0); + } + if (wait_for_pid(pid) != 0) + goto out_unlock; + + /* reload config to get the rootfs */ + if (c->lxc_conf) + lxc_conf_free(c->lxc_conf); + c->lxc_conf = NULL; + if (!load_config_locked(c, c->configfile)) + goto out_unlock; + + if (!create_run_template(c, tpath, !!(flags & LXC_CREATE_QUIET), argv)) + goto out_unlock; + + // now clear out the lxc_conf we have, reload from the created + // container + if (c->lxc_conf) + lxc_conf_free(c->lxc_conf); + c->lxc_conf = NULL; + + if (!prepend_lxc_header(c->configfile, tpath, argv)) { + ERROR("Error prepending header to configuration file"); + goto out_unlock; + } + bret = load_config_locked(c, c->configfile); + +out_unlock: + if (partial_fd >= 0) + remove_partial(c, partial_fd); +out: + if (tpath) + free(tpath); + if (!bret && c) + lxcapi_destroy(c); + return bret; +} + +static bool lxcapi_reboot(struct lxc_container *c) +{ + pid_t pid; + + if (!c) + return false; + if (!c->is_running(c)) + return false; + pid = c->init_pid(c); + if (pid <= 0) + return false; + if (kill(pid, SIGINT) < 0) + return false; + return true; + +} + +static bool lxcapi_shutdown(struct lxc_container *c, int timeout) +{ + bool retv; + pid_t pid; + + if (!c) + return false; + + if (!timeout) + timeout = -1; + if (!c->is_running(c)) + return true; + pid = c->init_pid(c); + if (pid <= 0) + return true; + kill(pid, SIGPWR); + retv = c->wait(c, "STOPPED", timeout); + if (!retv && timeout > 0) { + c->stop(c); + retv = c->wait(c, "STOPPED", 0); // 0 means don't wait + } + return retv; +} + +static bool lxcapi_createl(struct lxc_container *c, const char *t, + const char *bdevtype, struct bdev_specs *specs, int flags, ...) +{ + bool bret = false; + char **args = NULL; + va_list ap; + + if (!c) + return false; + + /* + * since we're going to wait for create to finish, I don't think we + * need to get a copy of the arguments. + */ + va_start(ap, flags); + args = lxc_va_arg_list_to_argv(ap, 0, 0); + va_end(ap); + if (!args) { + ERROR("Memory allocation error."); + goto out; + } + + bret = c->create(c, t, bdevtype, specs, flags, args); + +out: + free(args); + return bret; +} + +static bool lxcapi_clear_config_item(struct lxc_container *c, const char *key) +{ + int ret; + + if (!c || !c->lxc_conf) + return false; + if (container_mem_lock(c)) + return false; + ret = lxc_clear_config_item(c->lxc_conf, key); + container_mem_unlock(c); + return ret == 0; +} + +char** lxcapi_get_ips(struct lxc_container *c, char* interface, char* family, int scope) +{ + int count = 0; + struct ifaddrs *interfaceArray = NULL, *tempIfAddr = NULL; + char addressOutputBuffer[INET6_ADDRSTRLEN]; + void *tempAddrPtr = NULL; + char **addresses = NULL, **temp; + char *address = NULL; + char new_netns_path[MAXPATHLEN]; + int old_netns = -1, new_netns = -1, ret = 0; + + if (!c->is_running(c)) + goto out; + + /* Save reference to old netns */ + old_netns = open("/proc/self/ns/net", O_RDONLY); + if (old_netns < 0) { + SYSERROR("failed to open /proc/self/ns/net"); + goto out; + } + + /* Switch to new netns */ + ret = snprintf(new_netns_path, MAXPATHLEN, "/proc/%d/ns/net", c->init_pid(c)); + if (ret < 0 || ret >= MAXPATHLEN) + goto out; + + new_netns = open(new_netns_path, O_RDONLY); + if (new_netns < 0) { + SYSERROR("failed to open %s", new_netns_path); + goto out; + } + + if (setns(new_netns, CLONE_NEWNET)) { + SYSERROR("failed to setns"); + goto out; + } + + /* Grab the list of interfaces */ + if (getifaddrs(&interfaceArray)) { + SYSERROR("failed to get interfaces list"); + goto out; + } + + /* Iterate through the interfaces */ + for (tempIfAddr = interfaceArray; tempIfAddr != NULL; tempIfAddr = tempIfAddr->ifa_next) { + if(tempIfAddr->ifa_addr->sa_family == AF_INET) { + if (family && strcmp(family, "inet")) + continue; + tempAddrPtr = &((struct sockaddr_in *)tempIfAddr->ifa_addr)->sin_addr; + } + else { + if (family && strcmp(family, "inet6")) + continue; + + if (((struct sockaddr_in6 *)tempIfAddr->ifa_addr)->sin6_scope_id != scope) + continue; + + tempAddrPtr = &((struct sockaddr_in6 *)tempIfAddr->ifa_addr)->sin6_addr; + } + + if (interface && strcmp(interface, tempIfAddr->ifa_name)) + continue; + else if (!interface && strcmp("lo", tempIfAddr->ifa_name) == 0) + continue; + + address = (char *)inet_ntop(tempIfAddr->ifa_addr->sa_family, + tempAddrPtr, + addressOutputBuffer, + sizeof(addressOutputBuffer)); + if (!address) + continue; + + count += 1; + temp = realloc(addresses, count * sizeof(*addresses)); + if (!temp) { + count--; + goto out; + } + addresses = temp; + addresses[count - 1] = strdup(address); + } + +out: + if(interfaceArray) + freeifaddrs(interfaceArray); + + /* Switch back to original netns */ + if (old_netns >= 0 && setns(old_netns, CLONE_NEWNET)) + SYSERROR("failed to setns"); + if (new_netns >= 0) + close(new_netns); + if (old_netns >= 0) + close(old_netns); + + /* Append NULL to the array */ + if (count) { + count++; + temp = realloc(addresses, count * sizeof(*addresses)); + if (!temp) { + int i; + for (i = 0; i < count-1; i++) + free(addresses[i]); + free(addresses); + return NULL; + } + addresses = temp; + addresses[count - 1] = NULL; + } + + return addresses; +} + +static int lxcapi_get_config_item(struct lxc_container *c, const char *key, char *retv, int inlen) +{ + int ret; + + if (!c || !c->lxc_conf) + return -1; + if (container_mem_lock(c)) + return -1; + ret = lxc_get_config_item(c->lxc_conf, key, retv, inlen); + container_mem_unlock(c); + return ret; +} + +static int lxcapi_get_keys(struct lxc_container *c, const char *key, char *retv, int inlen) +{ + if (!key) + return lxc_listconfigs(retv, inlen); + /* + * Support 'lxc.network.', i.e. 'lxc.network.0' + * This is an intelligent result to show which keys are valid given + * the type of nic it is + */ + if (!c || !c->lxc_conf) + return -1; + if (container_mem_lock(c)) + return -1; + int ret = -1; + if (strncmp(key, "lxc.network.", 12) == 0) + ret = lxc_list_nicconfigs(c->lxc_conf, key, retv, inlen); + container_mem_unlock(c); + return ret; +} + +static bool lxcapi_save_config(struct lxc_container *c, const char *alt_file) +{ + FILE *fout; + bool ret = false, need_disklock = false; + int lret; + + if (!alt_file) + alt_file = c->configfile; + if (!alt_file) + return false; // should we write to stdout if no file is specified? + + // If we haven't yet loaded a config, load the stock config + if (!c->lxc_conf) { + if (!c->load_config(c, LXC_DEFAULT_CONFIG)) { + ERROR("Error loading default configuration file %s while saving %s\n", LXC_DEFAULT_CONFIG, c->name); + return false; + } + } + + if (!create_container_dir(c)) + return false; + + /* + * If we're writing to the container's config file, take the + * disk lock. Otherwise just take the memlock to protect the + * struct lxc_container while we're traversing it. + */ + if (strcmp(c->configfile, alt_file) == 0) + need_disklock = true; + + if (need_disklock) + lret = container_disk_lock(c); + else + lret = container_mem_lock(c); + + if (lret) + return false; + + fout = fopen(alt_file, "w"); + if (!fout) + goto out; + write_config(fout, c->lxc_conf); + fclose(fout); + ret = true; + +out: + if (need_disklock) + container_disk_unlock(c); + else + container_mem_unlock(c); + return ret; +} + +static bool mod_rdep(struct lxc_container *c, bool inc) +{ + char path[MAXPATHLEN]; + int ret, v = 0; + FILE *f; + bool bret = false; + + if (container_disk_lock(c)) + return false; + ret = snprintf(path, MAXPATHLEN, "%s/%s/lxc_snapshots", c->config_path, + c->name); + if (ret < 0 || ret > MAXPATHLEN) + goto out; + f = fopen(path, "r"); + if (f) { + ret = fscanf(f, "%d", &v); + fclose(f); + if (ret != 1) { + ERROR("Corrupted file %s", path); + goto out; + } + } + v += inc ? 1 : -1; + f = fopen(path, "w"); + if (!f) + goto out; + if (fprintf(f, "%d\n", v) < 0) { + ERROR("Error writing new snapshots value"); + fclose(f); + goto out; + } + if (fclose(f) != 0) { + SYSERROR("Error writing to or closing snapshots file"); + goto out; + } + + bret = true; + +out: + container_disk_unlock(c); + return bret; +} + +static void strip_newline(char *p) +{ + size_t len = strlen(p); + if (len < 1) + return; + if (p[len-1] == '\n') + p[len-1] = '\0'; +} + +static void mod_all_rdeps(struct lxc_container *c, bool inc) +{ + struct lxc_container *p; + char *lxcpath = NULL, *lxcname = NULL, path[MAXPATHLEN]; + size_t pathlen = 0, namelen = 0; + FILE *f; + int ret; + + ret = snprintf(path, MAXPATHLEN, "%s/%s/lxc_rdepends", + c->config_path, c->name); + if (ret < 0 || ret >= MAXPATHLEN) { + ERROR("Path name too long"); + return; + } + if ((f = fopen(path, "r")) == NULL) + return; + while (getline(&lxcpath, &pathlen, f) != -1) { + if (getline(&lxcname, &namelen, f) == -1) { + ERROR("badly formatted file %s\n", path); + goto out; + } + strip_newline(lxcpath); + strip_newline(lxcname); + if ((p = lxc_container_new(lxcname, lxcpath)) == NULL) { + ERROR("Unable to find dependent container %s:%s", + lxcpath, lxcname); + continue; + } + if (!mod_rdep(p, inc)) + ERROR("Failed to increase numsnapshots for %s:%s", + lxcpath, lxcname); + lxc_container_put(p); + } +out: + if (lxcpath) free(lxcpath); + if (lxcname) free(lxcname); + fclose(f); +} + +static bool has_snapshots(struct lxc_container *c) +{ + char path[MAXPATHLEN]; + int ret, v; + FILE *f; + bool bret = false; + + ret = snprintf(path, MAXPATHLEN, "%s/%s/lxc_snapshots", c->config_path, + c->name); + if (ret < 0 || ret > MAXPATHLEN) + goto out; + f = fopen(path, "r"); + if (!f) + goto out; + ret = fscanf(f, "%d", &v); + fclose(f); + if (ret != 1) + goto out; + bret = v != 0; + +out: + return bret; +} + +// do we want the api to support --force, or leave that to the caller? +static bool lxcapi_destroy(struct lxc_container *c) +{ + struct bdev *r = NULL; + bool ret = false; + + if (!c || !lxcapi_is_defined(c)) + return false; + + if (container_disk_lock(c)) + return false; + + if (!is_stopped(c)) { + // we should queue some sort of error - in c->error_string? + ERROR("container %s is not stopped", c->name); + goto out; + } + + if (c->lxc_conf && has_snapshots(c)) { + ERROR("container %s has dependent snapshots", c->name); + goto out; + } + + if (c->lxc_conf && c->lxc_conf->rootfs.path && c->lxc_conf->rootfs.mount) + r = bdev_init(c->lxc_conf->rootfs.path, c->lxc_conf->rootfs.mount, NULL); + if (r) { + if (r->ops->destroy(r) < 0) { + bdev_put(r); + ERROR("Error destroying rootfs for %s", c->name); + goto out; + } + bdev_put(r); + } + + mod_all_rdeps(c, false); + + const char *p1 = lxcapi_get_config_path(c); + char *path = alloca(strlen(p1) + strlen(c->name) + 2); + sprintf(path, "%s/%s", p1, c->name); + if (lxc_rmdir_onedev(path) < 0) { + ERROR("Error destroying container directory for %s", c->name); + goto out; + } + ret = true; + +out: + container_disk_unlock(c); + return ret; +} + +static bool set_config_item_locked(struct lxc_container *c, const char *key, const char *v) +{ + struct lxc_config_t *config; + + if (!c->lxc_conf) + c->lxc_conf = lxc_conf_init(); + if (!c->lxc_conf) + return false; + config = lxc_getconfig(key); + if (!config) + return false; + return (0 == config->cb(key, v, c->lxc_conf)); +} + +static bool lxcapi_set_config_item(struct lxc_container *c, const char *key, const char *v) +{ + bool b = false; + + if (!c) + return false; + + if (container_mem_lock(c)) + return false; + + b = set_config_item_locked(c, key, v); + + container_mem_unlock(c); + return b; +} + +static char *lxcapi_config_file_name(struct lxc_container *c) +{ + if (!c || !c->configfile) + return NULL; + return strdup(c->configfile); +} + +static const char *lxcapi_get_config_path(struct lxc_container *c) +{ + if (!c || !c->config_path) + return NULL; + return (const char *)(c->config_path); +} + +/* + * not for export + * Just recalculate the c->configfile based on the + * c->config_path, which must be set. + * The lxc_container must be locked or not yet public. + */ +static bool set_config_filename(struct lxc_container *c) +{ + char *newpath; + int len, ret; + + if (!c->config_path) + return false; + + /* $lxc_path + "/" + c->name + "/" + "config" + '\0' */ + len = strlen(c->config_path) + strlen(c->name) + strlen("config") + 3; + newpath = malloc(len); + if (!newpath) + return false; + + ret = snprintf(newpath, len, "%s/%s/config", c->config_path, c->name); + if (ret < 0 || ret >= len) { + fprintf(stderr, "Error printing out config file name\n"); + free(newpath); + return false; + } + + if (c->configfile) + free(c->configfile); + c->configfile = newpath; + + return true; +} + +static bool lxcapi_set_config_path(struct lxc_container *c, const char *path) +{ + char *p; + bool b = false; + char *oldpath = NULL; + + if (!c) + return b; + + if (container_mem_lock(c)) + return b; + + p = strdup(path); + if (!p) { + ERROR("Out of memory setting new lxc path"); + goto err; + } + + b = true; + if (c->config_path) + oldpath = c->config_path; + c->config_path = p; + + /* Since we've changed the config path, we have to change the + * config file name too */ + if (!set_config_filename(c)) { + ERROR("Out of memory setting new config filename"); + b = false; + free(c->config_path); + c->config_path = oldpath; + oldpath = NULL; + } +err: + if (oldpath) + free(oldpath); + container_mem_unlock(c); + return b; +} + + +static bool lxcapi_set_cgroup_item(struct lxc_container *c, const char *subsys, const char *value) +{ + int ret; + + if (!c) + return false; + + if (is_stopped(c)) + return false; + + if (container_disk_lock(c)) + return false; + + ret = lxc_cgroup_set(c->name, subsys, value, c->config_path); + + container_disk_unlock(c); + return ret == 0; +} + +static int lxcapi_get_cgroup_item(struct lxc_container *c, const char *subsys, char *retv, int inlen) +{ + int ret; + + if (!c || !c->lxc_conf) + return -1; + + if (is_stopped(c)) + return -1; + + if (container_disk_lock(c)) + return -1; + + ret = lxc_cgroup_get(c->name, subsys, retv, inlen, c->config_path); + + container_disk_unlock(c); + return ret; +} + +const char *lxc_get_default_config_path(void) +{ + return default_lxc_path(); +} + +const char *lxc_get_default_lvm_vg(void) +{ + return default_lvm_vg(); +} + +const char *lxc_get_default_zfs_root(void) +{ + return default_zfs_root(); +} + +const char *lxc_get_version(void) +{ + return lxc_version(); +} + +static int copy_file(char *old, char *new) +{ + int in, out; + ssize_t len, ret; + char buf[8096]; + struct stat sbuf; + + if (file_exists(new)) { + ERROR("copy destination %s exists", new); + return -1; + } + ret = stat(old, &sbuf); + if (ret < 0) { + INFO("Error stat'ing %s", old); + return -1; + } + + in = open(old, O_RDONLY); + if (in < 0) { + SYSERROR("Error opening original file %s", old); + return -1; + } + out = open(new, O_CREAT | O_EXCL | O_WRONLY, 0644); + if (out < 0) { + SYSERROR("Error opening new file %s", new); + close(in); + return -1; + } + + while (1) { + len = read(in, buf, 8096); + if (len < 0) { + SYSERROR("Error reading old file %s", old); + goto err; + } + if (len == 0) + break; + ret = write(out, buf, len); + if (ret < len) { // should we retry? + SYSERROR("Error: write to new file %s was interrupted", new); + goto err; + } + } + close(in); + close(out); + + // we set mode, but not owner/group + ret = chmod(new, sbuf.st_mode); + if (ret) { + SYSERROR("Error setting mode on %s", new); + return -1; + } + + return 0; + +err: + close(in); + close(out); + return -1; +} + +static int copyhooks(struct lxc_container *oldc, struct lxc_container *c) +{ + int i; + int ret; + struct lxc_list *it; + + for (i=0; ilxc_conf->hooks[i]) { + char *hookname = it->elem; + char *fname = strrchr(hookname, '/'); + char tmppath[MAXPATHLEN]; + if (!fname) // relative path - we don't support, but maybe we should + return 0; + // copy the script, and change the entry in confile + ret = snprintf(tmppath, MAXPATHLEN, "%s/%s/%s", + c->config_path, c->name, fname+1); + if (ret < 0 || ret >= MAXPATHLEN) + return -1; + ret = copy_file(it->elem, tmppath); + if (ret < 0) + return -1; + free(it->elem); + it->elem = strdup(tmppath); + if (!it->elem) { + ERROR("out of memory copying hook path"); + return -1; + } + } + } + + c->save_config(c, NULL); + return 0; +} + +static void new_hwaddr(char *hwaddr) +{ + FILE *f = fopen("/dev/urandom", "r"); + if (f) { + unsigned int seed; + int ret = fread(&seed, sizeof(seed), 1, f); + if (ret != 1) + seed = time(NULL); + fclose(f); + srand(seed); + } else + srand(time(NULL)); + snprintf(hwaddr, 18, "00:16:3e:%02x:%02x:%02x", + rand() % 255, rand() % 255, rand() % 255); +} + +static void network_new_hwaddrs(struct lxc_container *c) +{ + struct lxc_list *it; + + lxc_list_for_each(it, &c->lxc_conf->network) { + struct lxc_netdev *n = it->elem; + if (n->hwaddr) + new_hwaddr(n->hwaddr); + } +} + +static int copy_fstab(struct lxc_container *oldc, struct lxc_container *c) +{ + char newpath[MAXPATHLEN]; + char *oldpath = oldc->lxc_conf->fstab; + int ret; + + if (!oldpath) + return 0; + + char *p = strrchr(oldpath, '/'); + if (!p) + return -1; + ret = snprintf(newpath, MAXPATHLEN, "%s/%s%s", + c->config_path, c->name, p); + if (ret < 0 || ret >= MAXPATHLEN) { + ERROR("error printing new path for %s", oldpath); + return -1; + } + if (file_exists(newpath)) { + ERROR("error: fstab file %s exists", newpath); + return -1; + } + + if (copy_file(oldpath, newpath) < 0) { + ERROR("error: copying %s to %s", oldpath, newpath); + return -1; + } + free(c->lxc_conf->fstab); + c->lxc_conf->fstab = strdup(newpath); + if (!c->lxc_conf->fstab) { + ERROR("error: allocating pathname"); + return -1; + } + + return 0; +} + +static void copy_rdepends(struct lxc_container *c, struct lxc_container *c0) +{ + char path0[MAXPATHLEN], path1[MAXPATHLEN]; + int ret; + + ret = snprintf(path0, MAXPATHLEN, "%s/%s/lxc_rdepends", c0->config_path, + c0->name); + if (ret < 0 || ret >= MAXPATHLEN) { + WARN("Error copying reverse dependencies"); + return; + } + ret = snprintf(path1, MAXPATHLEN, "%s/%s/lxc_rdepends", c->config_path, + c->name); + if (ret < 0 || ret >= MAXPATHLEN) { + WARN("Error copying reverse dependencies"); + return; + } + if (copy_file(path0, path1) < 0) { + INFO("Error copying reverse dependencies"); + return; + } +} + +static bool add_rdepends(struct lxc_container *c, struct lxc_container *c0) +{ + int ret; + char path[MAXPATHLEN]; + FILE *f; + bool bret; + + ret = snprintf(path, MAXPATHLEN, "%s/%s/lxc_rdepends", c->config_path, + c->name); + if (ret < 0 || ret >= MAXPATHLEN) + return false; + f = fopen(path, "a"); + if (!f) + return false; + bret = true; + // if anything goes wrong, just return an error + if (fprintf(f, "%s\n%s\n", c0->config_path, c0->name) < 0) + bret = false; + if (fclose(f) != 0) + bret = false; + return bret; +} + +static int copy_storage(struct lxc_container *c0, struct lxc_container *c, + const char *newtype, int flags, const char *bdevdata, unsigned long newsize) +{ + struct bdev *bdev; + int need_rdep; + + bdev = bdev_copy(c0->lxc_conf->rootfs.path, c0->name, c->name, + c0->config_path, c->config_path, newtype, !!(flags & LXC_CLONE_SNAPSHOT), + bdevdata, newsize, &need_rdep); + if (!bdev) { + ERROR("Error copying storage"); + return -1; + } + free(c->lxc_conf->rootfs.path); + c->lxc_conf->rootfs.path = strdup(bdev->src); + bdev_put(bdev); + if (!c->lxc_conf->rootfs.path) { + ERROR("Out of memory while setting storage path"); + return -1; + } + if (flags & LXC_CLONE_SNAPSHOT) + copy_rdepends(c, c0); + if (need_rdep) { + if (!add_rdepends(c, c0)) + WARN("Error adding reverse dependency from %s to %s", + c->name, c0->name); + } + + mod_all_rdeps(c, true); + + return 0; +} + +static int clone_update_rootfs(struct lxc_container *c0, + struct lxc_container *c, int flags, + char **hookargs) +{ + int ret = -1; + char path[MAXPATHLEN]; + struct bdev *bdev; + FILE *fout; + pid_t pid; + struct lxc_conf *conf = c->lxc_conf; + + /* update hostname in rootfs */ + /* we're going to mount, so run in a clean namespace to simplify cleanup */ + + pid = fork(); + if (pid < 0) + return -1; + if (pid > 0) + return wait_for_pid(pid); + + if (unshare(CLONE_NEWNS) < 0) { + ERROR("error unsharing mounts"); + exit(1); + } + bdev = bdev_init(c->lxc_conf->rootfs.path, c->lxc_conf->rootfs.mount, NULL); + if (!bdev) + exit(1); + if (bdev->ops->mount(bdev) < 0) + exit(1); + + if (!lxc_list_empty(&conf->hooks[LXCHOOK_CLONE])) { + /* Start of environment variable setup for hooks */ + if (setenv("LXC_SRC_NAME", c0->name, 1)) { + SYSERROR("failed to set environment variable for source container name"); + } + if (setenv("LXC_NAME", c->name, 1)) { + SYSERROR("failed to set environment variable for container name"); + } + if (setenv("LXC_CONFIG_FILE", conf->rcfile, 1)) { + SYSERROR("failed to set environment variable for config path"); + } + if (setenv("LXC_ROOTFS_MOUNT", conf->rootfs.mount, 1)) { + SYSERROR("failed to set environment variable for rootfs mount"); + } + if (setenv("LXC_ROOTFS_PATH", conf->rootfs.path, 1)) { + SYSERROR("failed to set environment variable for rootfs mount"); + } + + if (run_lxc_hooks(c->name, "clone", conf, c->get_config_path(c), hookargs)) { + ERROR("Error executing clone hook for %s", c->name); + exit(1); + } + } + + if (!(flags & LXC_CLONE_KEEPNAME)) { + ret = snprintf(path, MAXPATHLEN, "%s/etc/hostname", bdev->dest); + if (ret < 0 || ret >= MAXPATHLEN) + exit(1); + if (!file_exists(path)) + exit(0); + if (!(fout = fopen(path, "w"))) { + SYSERROR("unable to open %s: ignoring\n", path); + exit(0); + } + if (fprintf(fout, "%s", c->name) < 0) + exit(1); + if (fclose(fout) < 0) + exit(1); + } + exit(0); +} + +/* + * We want to support: +sudo lxc-clone -o o1 -n n1 -s -L|-fssize fssize -v|--vgname vgname \ + -p|--lvprefix lvprefix -t|--fstype fstype -B backingstore + +-s [ implies overlayfs] +-s -B overlayfs +-s -B aufs + +only rootfs gets converted (copied/snapshotted) on clone. +*/ + +static int create_file_dirname(char *path) +{ + char *p = strrchr(path, '/'); + int ret; + + if (!p) + return -1; + *p = '\0'; + ret = mkdir(path, 0755); + if (ret && errno != EEXIST) + SYSERROR("creating container path %s\n", path); + *p = '/'; + return ret; +} + +struct lxc_container *lxcapi_clone(struct lxc_container *c, const char *newname, + const char *lxcpath, int flags, + const char *bdevtype, const char *bdevdata, unsigned long newsize, + char **hookargs) +{ + struct lxc_container *c2 = NULL; + char newpath[MAXPATHLEN]; + int ret, storage_copied = 0; + const char *n, *l; + FILE *fout; + + if (!c || !c->is_defined(c)) + return NULL; + + if (container_mem_lock(c)) + return NULL; + + if (!is_stopped(c)) { + ERROR("error: Original container (%s) is running", c->name); + goto out; + } + + // Make sure the container doesn't yet exist. + n = newname ? newname : c->name; + l = lxcpath ? lxcpath : c->get_config_path(c); + ret = snprintf(newpath, MAXPATHLEN, "%s/%s/config", l, n); + if (ret < 0 || ret >= MAXPATHLEN) { + SYSERROR("clone: failed making config pathname"); + goto out; + } + if (file_exists(newpath)) { + ERROR("error: clone: %s exists", newpath); + goto out; + } + + ret = create_file_dirname(newpath); + if (ret < 0 && errno != EEXIST) { + ERROR("Error creating container dir for %s", newpath); + goto out; + } + + // copy the configuration, tweak it as needed, + fout = fopen(newpath, "w"); + if (!fout) { + SYSERROR("open %s", newpath); + goto out; + } + write_config(fout, c->lxc_conf); + fclose(fout); + + sprintf(newpath, "%s/%s/rootfs", l, n); + if (mkdir(newpath, 0755) < 0) { + SYSERROR("error creating %s", newpath); + goto out; + } + + c2 = lxc_container_new(n, l); + if (!c2) { + ERROR("clone: failed to create new container (%s %s)", n, l); + goto out; + } + + // update utsname + if (!set_config_item_locked(c2, "lxc.utsname", newname)) { + ERROR("Error setting new hostname"); + goto out; + } + + + // copy hooks if requested + if (flags & LXC_CLONE_COPYHOOKS) { + ret = copyhooks(c, c2); + if (ret < 0) { + ERROR("error copying hooks"); + goto out; + } + } + + if (copy_fstab(c, c2) < 0) { + ERROR("error copying fstab"); + goto out; + } + + // update macaddrs + if (!(flags & LXC_CLONE_KEEPMACADDR)) + network_new_hwaddrs(c2); + + // copy/snapshot rootfs's + ret = copy_storage(c, c2, bdevtype, flags, bdevdata, newsize); + if (ret < 0) + goto out; + + // We've now successfully created c2's storage, so clear it out if we + // fail after this + storage_copied = 1; + + if (!c2->save_config(c2, NULL)) + goto out; + + if (clone_update_rootfs(c, c2, flags, hookargs) < 0) + goto out; + + // TODO: update c's lxc.snapshot = count + container_mem_unlock(c); + return c2; + +out: + container_mem_unlock(c); + if (c2) { + if (!storage_copied) + c2->lxc_conf->rootfs.path = NULL; + c2->destroy(c2); + lxc_container_put(c2); + } + + return NULL; +} + +static int lxcapi_attach(struct lxc_container *c, lxc_attach_exec_t exec_function, void *exec_payload, lxc_attach_options_t *options, pid_t *attached_process) +{ + if (!c) + return -1; + + return lxc_attach(c->name, c->config_path, exec_function, exec_payload, options, attached_process); +} + +static int lxcapi_attach_run_wait(struct lxc_container *c, lxc_attach_options_t *options, const char *program, const char * const argv[]) +{ + lxc_attach_command_t command; + pid_t pid; + int r; + + if (!c) + return -1; + + command.program = (char*)program; + command.argv = (char**)argv; + r = lxc_attach(c->name, c->config_path, lxc_attach_run_command, &command, options, &pid); + if (r < 0) { + ERROR("ups"); + return r; + } + return lxc_wait_for_pid_status(pid); +} + +static int lxcapi_attach_run_waitl(struct lxc_container *c, lxc_attach_options_t *options, const char *program, const char *arg, ...) +{ + va_list ap; + const char **argv; + int ret; + + if (!c) + return -1; + + va_start(ap, arg); + argv = lxc_va_arg_list_to_argv_const(ap, 1); + va_end(ap); + + if (!argv) { + ERROR("Memory allocation error."); + return -1; + } + argv[0] = arg; + + ret = lxcapi_attach_run_wait(c, options, program, (const char * const *)argv); + free((void*)argv); + return ret; +} + +struct lxc_container *lxc_container_new(const char *name, const char *configpath) +{ + struct lxc_container *c; + + c = malloc(sizeof(*c)); + if (!c) { + fprintf(stderr, "failed to malloc lxc_container\n"); + return NULL; + } + memset(c, 0, sizeof(*c)); + + if (configpath) + c->config_path = strdup(configpath); + else + c->config_path = strdup(default_lxc_path()); + + if (!c->config_path) { + fprintf(stderr, "Out of memory"); + goto err; + } + + c->name = malloc(strlen(name)+1); + if (!c->name) { + fprintf(stderr, "Error allocating lxc_container name\n"); + goto err; + } + strcpy(c->name, name); + + c->numthreads = 1; + if (!(c->slock = lxc_newlock(c->config_path, name))) { + fprintf(stderr, "failed to create lock\n"); + goto err; + } + + if (!(c->privlock = lxc_newlock(NULL, NULL))) { + fprintf(stderr, "failed to alloc privlock\n"); + goto err; + } + + if (!set_config_filename(c)) { + fprintf(stderr, "Error allocating config file pathname\n"); + goto err; + } + + if (file_exists(c->configfile)) + lxcapi_load_config(c, NULL); + + if (ongoing_create(c) == 2) { + ERROR("Error: %s creation was not completed", c->name); + lxcapi_destroy(c); + lxc_conf_free(c->lxc_conf); + c->lxc_conf = NULL; + } + + // assign the member functions + c->is_defined = lxcapi_is_defined; + c->state = lxcapi_state; + c->is_running = lxcapi_is_running; + c->freeze = lxcapi_freeze; + c->unfreeze = lxcapi_unfreeze; + c->console = lxcapi_console; + c->console_getfd = lxcapi_console_getfd; + c->init_pid = lxcapi_init_pid; + c->load_config = lxcapi_load_config; + c->want_daemonize = lxcapi_want_daemonize; + c->start = lxcapi_start; + c->startl = lxcapi_startl; + c->stop = lxcapi_stop; + c->config_file_name = lxcapi_config_file_name; + c->wait = lxcapi_wait; + c->set_config_item = lxcapi_set_config_item; + c->destroy = lxcapi_destroy; + c->save_config = lxcapi_save_config; + c->get_keys = lxcapi_get_keys; + c->create = lxcapi_create; + c->createl = lxcapi_createl; + c->shutdown = lxcapi_shutdown; + c->reboot = lxcapi_reboot; + c->clear_config_item = lxcapi_clear_config_item; + c->get_config_item = lxcapi_get_config_item; + c->get_cgroup_item = lxcapi_get_cgroup_item; + c->set_cgroup_item = lxcapi_set_cgroup_item; + c->get_config_path = lxcapi_get_config_path; + c->set_config_path = lxcapi_set_config_path; + c->clone = lxcapi_clone; + c->get_ips = lxcapi_get_ips; + c->attach = lxcapi_attach; + c->attach_run_wait = lxcapi_attach_run_wait; + c->attach_run_waitl = lxcapi_attach_run_waitl; + + /* we'll allow the caller to update these later */ + if (lxc_log_init(NULL, "none", NULL, "lxc_container", 0, c->config_path)) { + fprintf(stderr, "failed to open log\n"); + goto err; + } + + return c; + +err: + lxc_container_free(c); + return NULL; +} + +int lxc_get_wait_states(const char **states) +{ + int i; + + if (states) + for (i=0; i. + * Copyright © 2012 Canonical Ltd. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __LXC_CONTAINER_H +#define __LXC_CONTAINER_H +#include "lxclock.h" +#include "attach_options.h" +#include +#include + +#include + +#define LXC_CLONE_KEEPNAME (1 << 0) +#define LXC_CLONE_COPYHOOKS (1 << 1) +#define LXC_CLONE_KEEPMACADDR (1 << 2) +#define LXC_CLONE_SNAPSHOT (1 << 3) +#define LXC_CLONE_MAXFLAGS (1 << 4) + +#define LXC_CREATE_QUIET (1 << 0) +#define LXC_CREATE_MAXFLAGS (1 << 1) + +struct bdev_specs; + +struct lxc_container { + // private fields + char *name; + char *configfile; + struct lxc_lock *slock; + struct lxc_lock *privlock; + int numthreads; /* protected by privlock. */ + struct lxc_conf *lxc_conf; // maybe we'll just want the whole lxc_handler? + + // public fields + char *error_string; + int error_num; + int daemonize; + + char *config_path; + + bool (*is_defined)(struct lxc_container *c); // did /var/lib/lxc/$name/config exist + const char *(*state)(struct lxc_container *c); + bool (*is_running)(struct lxc_container *c); // true so long as defined and not stopped + bool (*freeze)(struct lxc_container *c); + bool (*unfreeze)(struct lxc_container *c); + pid_t (*init_pid)(struct lxc_container *c); + bool (*load_config)(struct lxc_container *c, const char *alt_file); + /* The '...' is the command line. If provided, it must be ended with a NULL */ + bool (*start)(struct lxc_container *c, int useinit, char * const argv[]); + bool (*startl)(struct lxc_container *c, int useinit, ...); + bool (*stop)(struct lxc_container *c); + void (*want_daemonize)(struct lxc_container *c); + // Return current config file name. The result is strdup()d, so free the result. + char *(*config_file_name)(struct lxc_container *c); + // for wait, timeout == -1 means wait forever, timeout == 0 means don't wait. + // otherwise timeout is seconds to wait. + bool (*wait)(struct lxc_container *c, const char *state, int timeout); + bool (*set_config_item)(struct lxc_container *c, const char *key, const char *value); + bool (*destroy)(struct lxc_container *c); + bool (*save_config)(struct lxc_container *c, const char *alt_file); + bool (*create)(struct lxc_container *c, const char *t, const char *bdevtype, + struct bdev_specs *specs, int flags, char *const argv[]); + bool (*createl)(struct lxc_container *c, const char *t, const char *bdevtype, + struct bdev_specs *specs, int flags, ...); + /* send SIGINT to ask container to reboot */ + bool (*reboot)(struct lxc_container *c); + /* send SIGPWR. if timeout is not 0 or -1, do a hard stop after timeout seconds */ + bool (*shutdown)(struct lxc_container *c, int timeout); + /* clear all network or capability items in the in-memory configuration */ + bool (*clear_config_item)(struct lxc_container *c, const char *key); + /* print a config item to a in-memory string allocated by the caller. Return + * the length which was our would be printed. */ + int (*get_config_item)(struct lxc_container *c, const char *key, char *retv, int inlen); + int (*get_keys)(struct lxc_container *c, const char *key, char *retv, int inlen); + char** (*get_ips)(struct lxc_container *c, char* interface, char* family, int scope); + /* + * get_cgroup_item returns the number of bytes read, or an error (<0). + * If retv NULL or inlen 0 is passed in, then the length of the cgroup + * file will be returned. * Otherwise it will return the # of bytes read. + * If inlen is less than the number of bytes available, then the returned + * value will be inlen, not the full available size of the file. + */ + int (*get_cgroup_item)(struct lxc_container *c, const char *subsys, char *retv, int inlen); + bool (*set_cgroup_item)(struct lxc_container *c, const char *subsys, const char *value); + + /* + * Each container can have a custom configuration path. However + * by default it will be set to either the LXCPATH configure + * variable, or the lxcpath value in the LXC_GLOBAL_CONF configuration + * file (i.e. /etc/lxc/lxc.conf). + * You can change the value for a specific container with + * set_config_path(). Note there is no other way to specify this in + * general at the moment. + */ + const char *(*get_config_path)(struct lxc_container *c); + bool (*set_config_path)(struct lxc_container *c, const char *path); + + /* + * @c: the original container + * @newname: new name for the container. If NULL, the same name is used, and + * a new lxcpath MUST be specified. + * @lxcpath: lxcpath in which to create the new container. If NULL, then the + * original container's lxcpath will be used. (Shoudl we use the default + * instead?) + * @flags: additional flags to modify cloning behavior. + * LXC_CLONE_KEEPNAME: don't edit the rootfs to change the hostname. + * LXC_CLONE_COPYHOOKS: copy all hooks into the container dir + * LXC_CLONE_KEEPMACADDR: don't change the mac address on network interfaces. + * LXC_CLONE_SNAPSHOT: snapshot the original filesystem(s). If @devtype was not + * specified, then do so with the native bdevtype if possible, else use an + * overlayfs. + * @bdevtype: optionally force the cloned bdevtype to a specified plugin. By + * default the original is used (subject to snapshot requirements). + * @bdevdata: information about how to create the new storage (i.e. fstype and + * fsdata) + * @newsize: in case of a block device backing store, an optional size. If 0, + * then the original backing store's size will be used if possible. Note this + * only applies to the rootfs. For any other filesystems, the original size + * will be duplicated. + * @hookargs: additional arguments to pass to the clone hook script + */ + struct lxc_container *(*clone)(struct lxc_container *c, const char *newname, + const char *lxcpath, int flags, const char *bdevtype, + const char *bdevdata, unsigned long newsize, char **hookargs); + + /* lxcapi_console_getfd: allocate a console tty from container @c + * + * @c : the running container + * @ttynum : in : tty number to attempt to allocate or -1 to + * allocate the first available tty + * out: the tty number that was allocated + * @masterfd : out: fd refering to the master side of pty + * + * Returns "ttyfd" on success, -1 on failure. The returned "ttyfd" is + * used to keep the tty allocated. The caller should close "ttyfd" to + * indicate that it is done with the allocated console so that it can + * be allocated by another caller. + */ + int (*console_getfd)(struct lxc_container *c, int *ttynum, int *masterfd); + + /* lxcapi_console: allocate and run a console tty from container @c + * + * @c : the running container + * @ttynum : tty number to attempt to allocate, -1 to + * allocate the first available tty, or 0 to allocate + * the console + * @stdinfd : fd to read input from + * @stdoutfd : fd to write output to + * @stderrfd : fd to write error output to + * @escape : the escape character (1 == 'a', 2 == 'b', ...) + * + * Returns 0 on success, -1 on failure. This function will not return + * until the console has been exited by the user. + */ + int (*console)(struct lxc_container *c, int ttynum, + int stdinfd, int stdoutfd, int stderrfd, int escape); + + /* create subprocess and attach it to the container, run exec_function inside */ + int (*attach)(struct lxc_container *c, lxc_attach_exec_t exec_function, void *exec_payload, lxc_attach_options_t *options, pid_t *attached_process); + + /* run program in container, wait for it to exit */ + int (*attach_run_wait)(struct lxc_container *c, lxc_attach_options_t *options, const char *program, const char * const argv[]); + int (*attach_run_waitl)(struct lxc_container *c, lxc_attach_options_t *options, const char *program, const char *arg, ...); +}; + +struct lxc_container *lxc_container_new(const char *name, const char *configpath); +int lxc_container_get(struct lxc_container *c); +int lxc_container_put(struct lxc_container *c); +int lxc_get_wait_states(const char **states); +const char *lxc_get_default_config_path(void); +const char *lxc_get_default_lvm_vg(void); +const char *lxc_get_default_zfs_root(void); +const char *lxc_get_version(void); + +#if 0 +char ** lxc_get_valid_keys(); +char ** lxc_get_valid_values(char *key); +#endif +#endif diff -Nru lxc-0.8.0~rc1/src/lxc/lxclock.c lxc-1.0.0~alpha1/src/lxc/lxclock.c --- lxc-0.8.0~rc1/src/lxc/lxclock.c 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/lxclock.c 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,318 @@ +/* liblxcapi + * + * Copyright © 2012 Serge Hallyn . + * Copyright © 2012 Canonical Ltd. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include "lxclock.h" +#include +#include +#include +#include +#include +#define _GNU_SOURCE +#include +#include +#include +#include + +#define OFLAG (O_CREAT | O_RDWR) +#define SEMMODE 0660 +#define SEMVALUE 1 +#define SEMVALUE_LOCKED 0 + +lxc_log_define(lxc_lock, lxc); + +pthread_mutex_t thread_mutex = PTHREAD_MUTEX_INITIALIZER; + +static char *lxclock_name(const char *p, const char *n) +{ + int ret; + int len; + char *dest; + const char *rundir; + struct stat sb; + + /* lockfile will be: + * "/run" + "/lock/lxc/$lxcpath/$lxcname + '\0' if root + * or + * $XDG_RUNTIME_DIR + "/lock/lxc/$lxcpath/$lxcname + '\0' if non-root + */ + + /* length of "/lock/lxc/" + $lxcpath + "/" + $lxcname + '\0' */ + len = strlen("/lock/lxc/") + strlen(n) + strlen(p) + 2; + rundir = getenv("XDG_RUNTIME_DIR"); + if (geteuid() == 0 || rundir == NULL) + rundir = "/run"; + + len += strlen(rundir); + + if ((dest = malloc(len)) == NULL) + return NULL; + + ret = snprintf(dest, len, "%s/lock/lxc/%s", rundir, p); + if (ret < 0 || ret >= len) { + free(dest); + return NULL; + } + process_lock(); + ret = mkdir_p(dest, 0755); + process_unlock(); + if (ret < 0) { + free(dest); + return NULL; + } + + ret = stat(p, &sb); + if (ret == 0) { + // best effort. If this fails, ignore it + if (chown(dest, sb.st_uid, sb.st_gid) < 0) + ERROR("Failed ot set owner for lockdir %s\n", dest); + if (chmod(dest, sb.st_mode) < 0) + ERROR("Failed to set mode for lockdir %s\n", dest); + } + + ret = snprintf(dest, len, "%s/lock/lxc/%s/%s", rundir, p, n); + if (ret < 0 || ret >= len) { + free(dest); + return NULL; + } + return dest; +} + +static sem_t *lxc_new_unnamed_sem(void) +{ + sem_t *s; + int ret; + + s = malloc(sizeof(*s)); + if (!s) + return NULL; + ret = sem_init(s, 0, 1); + if (ret) { + free(s); + return NULL; + } + return s; +} + +struct lxc_lock *lxc_newlock(const char *lxcpath, const char *name) +{ + struct lxc_lock *l; + + l = malloc(sizeof(*l)); + if (!l) + goto out; + + if (!name) { + l->type = LXC_LOCK_ANON_SEM; + l->u.sem = lxc_new_unnamed_sem(); + if (!l->u.sem) { + free(l); + l = NULL; + } + goto out; + } + + l->type = LXC_LOCK_FLOCK; + l->u.f.fname = lxclock_name(lxcpath, name); + if (!l->u.f.fname) { + free(l); + l = NULL; + goto out; + } + l->u.f.fd = -1; + +out: + return l; +} + +int lxclock(struct lxc_lock *l, int timeout) +{ + int ret = -1, saved_errno = errno; + struct flock lk; + + switch(l->type) { + case LXC_LOCK_ANON_SEM: + if (!timeout) { + ret = sem_wait(l->u.sem); + if (ret == -1) + saved_errno = errno; + } else { + struct timespec ts; + if (clock_gettime(CLOCK_REALTIME, &ts) == -1) { + ret = -2; + goto out; + } + ts.tv_sec += timeout; + ret = sem_timedwait(l->u.sem, &ts); + if (ret == -1) + saved_errno = errno; + } + break; + case LXC_LOCK_FLOCK: + ret = -2; + if (timeout) { + ERROR("Error: timeout not supported with flock"); + ret = -2; + goto out; + } + if (!l->u.f.fname) { + ERROR("Error: filename not set for flock"); + ret = -2; + goto out; + } + process_lock(); + if (l->u.f.fd == -1) { + l->u.f.fd = open(l->u.f.fname, O_RDWR|O_CREAT, + S_IWUSR | S_IRUSR); + if (l->u.f.fd == -1) { + process_unlock(); + ERROR("Error opening %s", l->u.f.fname); + goto out; + } + } + lk.l_type = F_WRLCK; + lk.l_whence = SEEK_SET; + lk.l_start = 0; + lk.l_len = 0; + ret = fcntl(l->u.f.fd, F_SETLKW, &lk); + process_unlock(); + if (ret == -1) + saved_errno = errno; + break; + } + +out: + errno = saved_errno; + return ret; +} + +int lxcunlock(struct lxc_lock *l) +{ + int ret = 0, saved_errno = errno; + struct flock lk; + + switch(l->type) { + case LXC_LOCK_ANON_SEM: + if (!l->u.sem) + ret = -2; + else { + ret = sem_post(l->u.sem); + saved_errno = errno; + } + break; + case LXC_LOCK_FLOCK: + process_lock(); + if (l->u.f.fd != -1) { + lk.l_type = F_UNLCK; + lk.l_whence = SEEK_SET; + lk.l_start = 0; + lk.l_len = 0; + ret = fcntl(l->u.f.fd, F_SETLK, &lk); + if (ret < 0) + saved_errno = errno; + close(l->u.f.fd); + l->u.f.fd = -1; + } else + ret = -2; + process_unlock(); + break; + } + + errno = saved_errno; + return ret; +} + +/* + * lxc_putlock() is only called when a container_new() fails, + * or during container_put(), which is already guaranteed to + * only be done by one task. + * So the only exclusion we need to provide here is for regular + * thread safety (i.e. file descriptor table changes). + */ +void lxc_putlock(struct lxc_lock *l) +{ + if (!l) + return; + switch(l->type) { + case LXC_LOCK_ANON_SEM: + if (l->u.sem) { + sem_close(l->u.sem); + free(l->u.sem); + l->u.sem = NULL; + } + break; + case LXC_LOCK_FLOCK: + process_lock(); + if (l->u.f.fd != -1) { + close(l->u.f.fd); + l->u.f.fd = -1; + } + process_unlock(); + if (l->u.f.fname) { + free(l->u.f.fname); + l->u.f.fname = NULL; + } + break; + } + free(l); +} + +int process_lock(void) +{ + int ret; + ret = pthread_mutex_lock(&thread_mutex); + if (ret != 0) + ERROR("pthread_mutex_lock returned:%d %s", ret, strerror(ret)); + return ret; +} + +void process_unlock(void) +{ + pthread_mutex_unlock(&thread_mutex); +} + +int container_mem_lock(struct lxc_container *c) +{ + return lxclock(c->privlock, 0); +} + +void container_mem_unlock(struct lxc_container *c) +{ + lxcunlock(c->privlock); +} + +int container_disk_lock(struct lxc_container *c) +{ + int ret; + + if ((ret = lxclock(c->privlock, 0))) + return ret; + if ((ret = lxclock(c->slock, 0))) { + lxcunlock(c->privlock); + return ret; + } + return 0; +} + +void container_disk_unlock(struct lxc_container *c) +{ + lxcunlock(c->slock); + lxcunlock(c->privlock); +} diff -Nru lxc-0.8.0~rc1/src/lxc/lxclock.h lxc-1.0.0~alpha1/src/lxc/lxclock.h --- lxc-0.8.0~rc1/src/lxc/lxclock.h 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/lxclock.h 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,95 @@ +#ifndef __LXCLOCK_H +#define __LXCLOCK_H +/* liblxcapi + * + * Copyright © 2012 Serge Hallyn . + * Copyright © 2012 Canonical Ltd. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include /* For O_* constants */ +#include /* For mode constants */ +#include +#include +#include +#include + +#define LXC_LOCK_ANON_SEM 1 +#define LXC_LOCK_FLOCK 2 +struct lxc_lock { + short type; + union { + sem_t *sem; // an anonymous semaphore + struct { + int fd; // fd on which a lock is held (if not -1) + char *fname; + } f; + } u; +}; + +/* + * lxc_newlock: Create a new (unlocked) lock. + * + * if name is not given, create an unnamed semaphore. We use these + * to protect against racing threads. + * Note that an unnamed sem was malloced by us and needs to be freed. + * + * sem is initialized to value of 1 + * A sem_t * which can be passed to lxclock() and lxcunlock() + * will be placed in l->u.sem + * + * If lxcpath and name are given (both must be given if either is + * given) then a lockfile is created, $lxcpath/$lxcname/locks/$name. + * We use that to protect the containers as represented on disk. + * lxc_newlock() for the named lock only allocates the pathname in + * memory so we can quickly open+lock it at lxclock. + * l->u.f.fname will contain the malloc'ed name (which must be + * freed when the container is freed), and u.f.fd = -1. + * + * return lxclock on success, NULL on failure. + */ +extern struct lxc_lock *lxc_newlock(const char *lxcpath, const char *name); + +/* + * lxclock: take an existing lock. If timeout is 0, wait + * indefinately. Otherwise use given timeout. + * return 0 if we got the lock, -2 on failure to set timeout, or -1 + * otherwise in which case errno will be set by sem_wait()). + * + * Note that timeout is (currently?) only supported for privlock, not + * for slock. Since currently there is not a single use of the timeout + * (except in the test case) I may remove the support for it in sem as + * well. + */ +extern int lxclock(struct lxc_lock *lock, int timeout); + +/* + * lxcunlock: unlock given sem. Return 0 on success, or -2 if we did not + * have the lock. Otherwise returns -1 with errno saved from flock + * or sem_post function. + */ +extern int lxcunlock(struct lxc_lock *lock); + +extern void lxc_putlock(struct lxc_lock *l); + +extern int process_lock(void); +extern void process_unlock(void); +struct lxc_container; +extern int container_mem_lock(struct lxc_container *c); +extern void container_mem_unlock(struct lxc_container *c); +extern int container_disk_lock(struct lxc_container *c); +extern void container_disk_unlock(struct lxc_container *c); +#endif diff -Nru lxc-0.8.0~rc1/src/lxc/lxcseccomp.h lxc-1.0.0~alpha1/src/lxc/lxcseccomp.h --- lxc-0.8.0~rc1/src/lxc/lxcseccomp.h 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/lxcseccomp.h 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,49 @@ +/* + * lxc: linux Container library + * + * (C) Copyright Canonical, Inc. 2012 + * + * Authors: + * Serge Hallyn + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _lxc_seccomp_h + +#include "conf.h" + +#ifdef HAVE_SECCOMP +int lxc_seccomp_load(struct lxc_conf *conf); +int lxc_read_seccomp_config(struct lxc_conf *conf); +void lxc_seccomp_free(struct lxc_conf *conf); +#else +static inline int lxc_seccomp_load(struct lxc_conf *conf) { + return 0; +} + +static inline int lxc_read_seccomp_config(struct lxc_conf *conf) { + return 0; +} + +static inline void lxc_seccomp_free(struct lxc_conf *conf) { + if (conf->seccomp) { + free(conf->seccomp); + conf->seccomp = NULL; + } +} +#endif + +#endif diff -Nru lxc-0.8.0~rc1/src/lxc/lxcutmp.c lxc-1.0.0~alpha1/src/lxc/lxcutmp.c --- lxc-0.8.0~rc1/src/lxc/lxcutmp.c 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/lxcutmp.c 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,481 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_SYS_TIMERFD_H +#include +#else +#include +#ifndef TFD_NONBLOCK +#define TFD_NONBLOCK O_NONBLOCK +#endif + +#ifndef TFD_CLOEXEC +#define TFD_CLOEXEC O_CLOEXEC +#endif +static int timerfd_create (clockid_t __clock_id, int __flags) { + return syscall(__NR_timerfd_create, __clock_id, __flags); +} + +static int timerfd_settime (int __ufd, int __flags, + const struct itimerspec *__utmr, + struct itimerspec *__otmr) { + + return syscall(__NR_timerfd_settime, __ufd, __flags, + __utmr, __otmr); +} + +#endif + +#include "conf.h" +#include "cgroup.h" +#include "start.h" +#include "mainloop.h" +#include "lxc.h" +#include "log.h" + +#ifndef __USE_GNU +#define __USE_GNU +#endif +#ifdef HAVE_UTMPX_H +#include +#else +#include + +#ifndef RUN_LVL +#define RUN_LVL 1 +#endif + +static int utmpxname(const char *file) { + int result; + result = utmpname(file); + +#ifdef IS_BIONIC + /* Yeah bionic is that weird */ + result = result - 1; +#endif + + return result; +} + +static void setutxent(void) { + return setutent(); +} + +static struct utmp * getutxent (void) { + return (struct utmp *) getutent(); +} + +static void endutxent (void) { +#ifdef IS_BIONIC + /* bionic isn't exporting endutend */ + return; +#else + return endutent(); +#endif +} +#endif +#undef __USE_GNU + +/* This file watches the /var/run/utmp file in the container + * (that should probably be configurable) + * We use inotify to put a watch on the /var/run directory for + * create and modify events. These can trigger a read of the + * utmp file looking for runlevel changes. If a runlevel change + * to reboot or halt states is detected, we set up an itimer to + * regularly check for the container shutdown, and reboot or halt + * as appropriate when we get down to 1 task remaining. + */ + +lxc_log_define(lxc_utmp, lxc); + +struct lxc_utmp { + struct lxc_handler *handler; +#define CONTAINER_STARTING 0 +#define CONTAINER_REBOOTING 1 +#define CONTAINER_HALTING 2 +#define CONTAINER_RUNNING 4 + char container_state; + int timer_fd; + int prev_runlevel, curr_runlevel; +}; + +typedef void (*lxc_mainloop_timer_t) (void *data); + +static int utmp_get_runlevel(struct lxc_utmp *utmp_data); +static int utmp_get_ntasks(struct lxc_handler *handler); +static int utmp_shutdown_handler(int fd, void *data, + struct lxc_epoll_descr *descr); +static int lxc_utmp_add_timer(struct lxc_epoll_descr *descr, + lxc_mainloop_callback_t callback, void *data); +static int lxc_utmp_del_timer(struct lxc_epoll_descr *descr, + struct lxc_utmp *utmp_data); + +static int utmp_handler(int fd, void *data, struct lxc_epoll_descr *descr) +{ + struct inotify_event *ie; + int size, ret, length; + + struct lxc_utmp *utmp_data = (struct lxc_utmp *)data; + + /* + * we're monitoring a directory. ie->name is not included in + * sizeof(struct inotify_event) if we don't read it all at once, + * read gives us EINVAL, so we read and cast to struct ie + */ + char buffer[MAXPATHLEN]; + + if (ioctl(fd, FIONREAD, &size) < 0) { + SYSERROR("cannot determine the size of this notification"); + return -1; + } + + if (read(fd, buffer, size) < 0) { + SYSERROR("failed to read notification"); + return -1; + } + + ie = (struct inotify_event *)buffer; + + if (ie->len <= 0) { + + if (ie->mask & IN_UNMOUNT) { + DEBUG("watched directory removed"); + goto out; + } + + SYSERROR("inotify event with no name (mask %d)", ie->mask); + return -1; + } + + ret = 0; + + DEBUG("got inotify event %d for %s", ie->mask, ie->name); + + length = (4 < ie->len) ? 4 : ie->len; + + /* only care about utmp */ + + if (strncmp(ie->name, "utmp", length)) + return 0; + + if (ie->mask & (IN_MODIFY | IN_CREATE)) + ret = utmp_get_runlevel(utmp_data); + + if (ret < 0) + goto out; + + /* container halting, from running or starting state */ + if (utmp_data->curr_runlevel == '0' + && ((utmp_data->container_state == CONTAINER_RUNNING) + || (utmp_data->container_state == CONTAINER_STARTING))) { + utmp_data->container_state = CONTAINER_HALTING; + if (utmp_data->timer_fd == -1) + lxc_utmp_add_timer(descr, utmp_shutdown_handler, data); + DEBUG("Container halting"); + goto out; + } + + /* container rebooting, from running or starting state */ + if (utmp_data->curr_runlevel == '6' + && ((utmp_data->container_state == CONTAINER_RUNNING) + || (utmp_data->container_state == CONTAINER_STARTING))) { + utmp_data->container_state = CONTAINER_REBOOTING; + if (utmp_data->timer_fd == -1) + lxc_utmp_add_timer(descr, utmp_shutdown_handler, data); + DEBUG("Container rebooting"); + goto out; + } + + /* normal operation, running, from starting state. */ + if (utmp_data->curr_runlevel > '0' && utmp_data->curr_runlevel < '6') { + utmp_data->container_state = CONTAINER_RUNNING; + if (utmp_data->timer_fd > 0) + lxc_utmp_del_timer(descr, utmp_data); + DEBUG("Container running"); + goto out; + } + +out: + return 0; +} + +static int utmp_get_runlevel(struct lxc_utmp *utmp_data) +{ + #if HAVE_UTMPX_H + struct utmpx *utmpx; + #else + struct utmp *utmpx; + #endif + char path[MAXPATHLEN]; + struct lxc_handler *handler = utmp_data->handler; + + if (snprintf(path, MAXPATHLEN, "/proc/%d/root/run/utmp", + handler->pid) > MAXPATHLEN) { + ERROR("path is too long"); + return -1; + } + + if (!access(path, F_OK) && !utmpxname(path)) + goto utmp_ok; + + if (snprintf(path, MAXPATHLEN, "/proc/%d/root/var/run/utmp", + handler->pid) > MAXPATHLEN) { + ERROR("path is too long"); + return -1; + } + + if (utmpxname(path)) { + SYSERROR("failed to 'utmpxname'"); + return -1; + } + +utmp_ok: + + setutxent(); + + while ((utmpx = getutxent())) { + + if (utmpx->ut_type == RUN_LVL) { + utmp_data->prev_runlevel = utmpx->ut_pid / 256; + utmp_data->curr_runlevel = utmpx->ut_pid % 256; + DEBUG("utmp handler - run level is %c/%c", + utmp_data->prev_runlevel, + utmp_data->curr_runlevel); + } + } + + endutxent(); + + return 0; +} + +static int utmp_get_ntasks(struct lxc_handler *handler) +{ + int ntasks; + + ntasks = lxc_cgroup_nrtasks(handler); + + if (ntasks < 0) { + ERROR("failed to get the number of tasks"); + return -1; + } + + DEBUG("there are %d tasks running", ntasks); + + return ntasks; +} + +int lxc_utmp_mainloop_add(struct lxc_epoll_descr *descr, + struct lxc_handler *handler) +{ + char path[MAXPATHLEN]; + char path2[MAXPATHLEN]; + int fd, wd; + struct lxc_utmp *utmp_data; + + /* We set up a watch for the /var/run directory. We're only interested + * in utmp at the moment, but want to watch for delete and create + * events as well. + */ + if (snprintf(path, MAXPATHLEN, "/proc/%d/root/run", + handler->pid) > MAXPATHLEN) { + ERROR("path is too long"); + return -1; + } + if (snprintf(path2, MAXPATHLEN, "/proc/%d/root/run/utmp", + handler->pid) > MAXPATHLEN) { + ERROR("path is too long"); + return -1; + } + if (!access(path2, F_OK)) + goto run_ok; + + if (snprintf(path, MAXPATHLEN, "/proc/%d/root/var/run", + handler->pid) > MAXPATHLEN) { + ERROR("path is too long"); + return -1; + } + + if (access(path, F_OK)) { + WARN("'%s' not found", path); + return 0; + } + +run_ok: + + utmp_data = (struct lxc_utmp *)malloc(sizeof(struct lxc_utmp)); + + if (NULL == utmp_data) { + SYSERROR("failed to malloc handler utmp_data"); + return -1; + } + + memset(utmp_data, 0, sizeof(struct lxc_utmp)); + + fd = inotify_init(); + if (fd < 0) { + SYSERROR("failed to inotify_init"); + goto out; + } + + if (fcntl(fd, F_SETFD, FD_CLOEXEC)) { + SYSERROR("failed to set inotify fd to close-on-exec"); + goto out_close; + + } + + wd = inotify_add_watch(fd, path, IN_MODIFY | IN_CREATE); + if (wd < 0) { + SYSERROR("failed to add watch for '%s'", path); + goto out_close; + } + + utmp_data->handler = handler; + utmp_data->container_state = CONTAINER_STARTING; + utmp_data->timer_fd = -1; + utmp_data->prev_runlevel = 'N'; + utmp_data->curr_runlevel = 'N'; + + if (lxc_mainloop_add_handler + (descr, fd, utmp_handler, (void *)utmp_data)) { + SYSERROR("failed to add mainloop"); + goto out_close; + } + + DEBUG("Added '%s' to inotifywatch", path); + + return 0; +out_close: + close(fd); +out: + free(utmp_data); + return -1; +} + +static int utmp_shutdown_handler(int fd, void *data, + struct lxc_epoll_descr *descr) +{ + int ntasks; + ssize_t nread; + struct lxc_utmp *utmp_data = (struct lxc_utmp *)data; + struct lxc_handler *handler = utmp_data->handler; + struct lxc_conf *conf = handler->conf; + uint64_t expirations; + + /* read and clear notifications */ + nread = read(fd, &expirations, sizeof(expirations)); + if (nread < 0) + SYSERROR("Failed to read timer notification"); + + ntasks = utmp_get_ntasks(handler); + + if (ntasks == 1 && (utmp_data->container_state == CONTAINER_HALTING)) { + INFO("container has shutdown"); + /* shutdown timer */ + lxc_utmp_del_timer(descr, utmp_data); + + kill(handler->pid, SIGKILL); + } + + if (ntasks == 1 && (utmp_data->container_state == CONTAINER_REBOOTING)) { + INFO("container has rebooted"); + conf->reboot = 1; + /* shutdown timer */ + lxc_utmp_del_timer(descr, utmp_data); + /* this seems a bit rough. */ + kill(handler->pid, SIGKILL); + } + return 0; + +} + +int lxc_utmp_add_timer(struct lxc_epoll_descr *descr, + lxc_mainloop_callback_t callback, void *data) +{ + int fd, result; + struct itimerspec timeout; + struct lxc_utmp *utmp_data = (struct lxc_utmp *)data; + + fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC); + if (fd < 0) { + SYSERROR("failed to create timer"); + return -1; + } + + DEBUG("Setting up utmp shutdown timer"); + + /* set a one second timeout. Repeated. */ + timeout.it_value.tv_sec = 1; + timeout.it_value.tv_nsec = 0; + + timeout.it_interval.tv_sec = 1; + timeout.it_interval.tv_nsec = 0; + + result = timerfd_settime(fd, 0, &timeout, NULL); + + if (result < 0) { + SYSERROR("timerfd_settime:"); + return -1; + } + + if (lxc_mainloop_add_handler(descr, fd, callback, utmp_data)) { + SYSERROR("failed to add utmp timer to mainloop"); + close(fd); + return -1; + } + + utmp_data->timer_fd = fd; + + return 0; +} + +int lxc_utmp_del_timer(struct lxc_epoll_descr *descr, + struct lxc_utmp *utmp_data) +{ + int result; + + DEBUG("Clearing utmp shutdown timer"); + + result = lxc_mainloop_del_handler(descr, utmp_data->timer_fd); + if (result < 0) + SYSERROR("failed to del utmp timer from mainloop"); + + /* shutdown timer_fd */ + close(utmp_data->timer_fd); + utmp_data->timer_fd = -1; + + if (result < 0) + return -1; + else + return 0; +} diff -Nru lxc-0.8.0~rc1/src/lxc/lxcutmp.h lxc-1.0.0~alpha1/src/lxc/lxcutmp.h --- lxc-0.8.0~rc1/src/lxc/lxcutmp.h 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/lxcutmp.h 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,30 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +struct lxc_handler; +struct lxc_epoll_descr; + +int lxc_utmp_mainloop_add(struct lxc_epoll_descr *descr, + struct lxc_handler *handler); diff -Nru lxc-0.8.0~rc1/src/lxc/mainloop.c lxc-1.0.0~alpha1/src/lxc/mainloop.c --- lxc-0.8.0~rc1/src/lxc/mainloop.c 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/mainloop.c 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,7 +18,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include @@ -38,7 +38,7 @@ #define MAX_EVENTS 10 -int lxc_mainloop(struct lxc_epoll_descr *descr) +int lxc_mainloop(struct lxc_epoll_descr *descr, int timeout_ms) { int i, nfds; struct mainloop_handler *handler; @@ -46,7 +46,7 @@ for (;;) { - nfds = epoll_wait(descr->epfd, events, MAX_EVENTS, -1); + nfds = epoll_wait(descr->epfd, events, MAX_EVENTS, timeout_ms); if (nfds < 0) { if (errno == EINTR) continue; @@ -59,17 +59,20 @@ /* If the handler returns a positive value, exit the mainloop */ - if (handler->callback(handler->fd, handler->data, + if (handler->callback(handler->fd, handler->data, descr) > 0) return 0; } + if (nfds == 0 && timeout_ms != 0) + return 0; + if (lxc_list_empty(&descr->handlers)) return 0; } } -int lxc_mainloop_add_handler(struct lxc_epoll_descr *descr, int fd, +int lxc_mainloop_add_handler(struct lxc_epoll_descr *descr, int fd, lxc_mainloop_callback_t callback, void *data) { struct epoll_event ev; diff -Nru lxc-0.8.0~rc1/src/lxc/mainloop.h lxc-1.0.0~alpha1/src/lxc/mainloop.h --- lxc-0.8.0~rc1/src/lxc/mainloop.h 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/mainloop.h 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,9 +18,12 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifndef _mainloop_h +#define _mainloop_h + #include "list.h" struct lxc_epoll_descr { @@ -28,13 +31,13 @@ struct lxc_list handlers; }; -typedef int (*lxc_mainloop_callback_t)(int fd, void *data, +typedef int (*lxc_mainloop_callback_t)(int fd, void *data, struct lxc_epoll_descr *descr); -extern int lxc_mainloop(struct lxc_epoll_descr *descr); +extern int lxc_mainloop(struct lxc_epoll_descr *descr, int timeout_ms); extern int lxc_mainloop_add_handler(struct lxc_epoll_descr *descr, int fd, - lxc_mainloop_callback_t callback, + lxc_mainloop_callback_t callback, void *data); extern int lxc_mainloop_del_handler(struct lxc_epoll_descr *descr, int fd); @@ -42,3 +45,5 @@ extern int lxc_mainloop_open(struct lxc_epoll_descr *descr); extern int lxc_mainloop_close(struct lxc_epoll_descr *descr); + +#endif diff -Nru lxc-0.8.0~rc1/src/lxc/monitor.c lxc-1.0.0~alpha1/src/lxc/monitor.c --- lxc-0.8.0~rc1/src/lxc/monitor.c 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/monitor.c 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,8 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano + * Dwight Engen * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,8 +19,9 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ + #include #include #include @@ -30,7 +32,7 @@ #include #include #include -#include +#include #include #include @@ -40,81 +42,230 @@ #include #include #include +#include lxc_log_define(lxc_monitor, lxc); -#ifndef UNIX_PATH_MAX -#define UNIX_PATH_MAX 108 -#endif - -static void lxc_monitor_send(struct lxc_msg *msg) +/* routines used by monitor publishers (containers) */ +static void lxc_monitor_fifo_send(struct lxc_msg *msg, const char *lxcpath) { - int fd; - struct sockaddr_un addr = { .sun_family = AF_UNIX }; - char *offset = &addr.sun_path[1]; + int fd,ret; + char fifo_path[PATH_MAX]; - strcpy(offset, "lxc-monitor"); + BUILD_BUG_ON(sizeof(*msg) > PIPE_BUF); /* write not guaranteed atomic */ + ret = snprintf(fifo_path, sizeof(fifo_path), "%s/monitor-fifo", lxcpath); + if (ret < 0 || ret >= sizeof(fifo_path)) { + ERROR("lxcpath too long to open monitor fifo"); + return; + } - fd = socket(PF_UNIX, SOCK_DGRAM, 0); - if (fd < 0) + fd = open(fifo_path, O_WRONLY); + if (fd < 0) { + /* it is normal for this open to fail when there is no monitor + * running, so we don't log it + */ return; + } - sendto(fd, msg, sizeof(*msg), 0, - (const struct sockaddr *)&addr, sizeof(addr)); + ret = write(fd, msg, sizeof(*msg)); + if (ret != sizeof(*msg)) { + close(fd); + SYSERROR("failed to write monitor fifo %s", fifo_path); + return; + } close(fd); } -void lxc_monitor_send_state(const char *name, lxc_state_t state) +void lxc_monitor_send_state(const char *name, lxc_state_t state, const char *lxcpath) { struct lxc_msg msg = { .type = lxc_msg_state, .value = state }; strncpy(msg.name, name, sizeof(msg.name)); msg.name[sizeof(msg.name) - 1] = 0; - lxc_monitor_send(&msg); + lxc_monitor_fifo_send(&msg, lxcpath); +} + + +/* routines used by monitor subscribers (lxc-monitor) */ +int lxc_monitor_close(int fd) +{ + return close(fd); +} + +int lxc_monitor_sock_name(const char *lxcpath, struct sockaddr_un *addr) { + size_t len; + int ret; + char *sockname = &addr->sun_path[0]; // 1 for abstract + + /* addr.sun_path is only 108 bytes. + * should we take a hash of lxcpath? a subset of it? ftok()? we need + * to make sure it is unique. + */ + memset(addr, 0, sizeof(*addr)); + addr->sun_family = AF_UNIX; + len = sizeof(addr->sun_path) - 1; + ret = snprintf(sockname, len, "%s/monitor-sock", lxcpath); + if (ret < 0 || ret >= len) { + ERROR("lxcpath too long for unix socket"); + return -1; + } + return 0; } -int lxc_monitor_open(void) +int lxc_monitor_open(const char *lxcpath) { - struct sockaddr_un addr = { .sun_family = AF_UNIX }; - char *offset = &addr.sun_path[1]; - int fd; + struct sockaddr_un addr; + int fd,ret; + int retry,backoff_ms[] = {10, 50, 100}; - strcpy(offset, "lxc-monitor"); + if (lxc_monitor_sock_name(lxcpath, &addr) < 0) + return -1; - fd = socket(PF_UNIX, SOCK_DGRAM, 0); + fd = socket(PF_UNIX, SOCK_STREAM, 0); if (fd < 0) { ERROR("socket : %s", strerror(errno)); return -1; } - if (bind(fd, (struct sockaddr *)&addr, sizeof(addr))) { - ERROR("bind : %s", strerror(errno)); - close(fd); - return -1; + for (retry = 0; retry < sizeof(backoff_ms)/sizeof(backoff_ms[0]); retry++) { + ret = connect(fd, (struct sockaddr *)&addr, sizeof(addr)); + if (ret == 0 || errno != ECONNREFUSED) + break; + ERROR("connect : backing off %d", backoff_ms[retry]); + usleep(backoff_ms[retry] * 1000); } + if (ret < 0) { + ERROR("connect : %s", strerror(errno)); + goto err1; + } return fd; +err1: + close(fd); + return ret; } -int lxc_monitor_read(int fd, struct lxc_msg *msg) +int lxc_monitor_read_fdset(fd_set *rfds, int nfds, struct lxc_msg *msg, + int timeout) { - struct sockaddr_un from; - socklen_t len = sizeof(from); - int ret; + struct timeval tval,*tv = NULL; + int ret,i; - ret = recvfrom(fd, msg, sizeof(*msg), 0, - (struct sockaddr *)&from, &len); - if (ret < 0) { - SYSERROR("failed to receive state"); + if (timeout != -1) { + tv = &tval; + tv->tv_sec = timeout; + tv->tv_usec = 0; + } + + ret = select(nfds, rfds, NULL, NULL, tv); + if (ret == -1) return -1; + else if (ret == 0) + return -2; // timed out + + /* only read from the first ready fd, the others will remain ready + * for when this routine is called again + */ + for (i = 0; i < nfds; i++) { + if (FD_ISSET(i, rfds)) { + ret = recv(i, msg, sizeof(*msg), 0); + if (ret <= 0) { + SYSERROR("client failed to recv (monitord died?) %s", + strerror(errno)); + return -1; + } + return ret; + } } + SYSERROR("no ready fd found?"); + return -1; +} - return ret; +int lxc_monitor_read_timeout(int fd, struct lxc_msg *msg, int timeout) +{ + fd_set rfds; + + FD_ZERO(&rfds); + FD_SET(fd, &rfds); + + return lxc_monitor_read_fdset(&rfds, fd+1, msg, timeout); } -int lxc_monitor_close(int fd) +int lxc_monitor_read(int fd, struct lxc_msg *msg) { - return close(fd); + return lxc_monitor_read_timeout(fd, msg, -1); +} + + + +/* used to spawn a monitord either on startup of a daemon container, or when + * lxc-monitor starts + */ +int lxc_monitord_spawn(const char *lxcpath) +{ + pid_t pid1,pid2; + int pipefd[2]; + char pipefd_str[11]; + + char * const args[] = { + "lxc-monitord", + (char *)lxcpath, + pipefd_str, + NULL, + }; + + /* double fork to avoid zombies when monitord exits */ + pid1 = fork(); + if (pid1 < 0) { + SYSERROR("failed to fork"); + return -1; + } + + if (pid1) { + if (waitpid(pid1, NULL, 0) != pid1) + return -1; + return 0; + } + + if (pipe(pipefd) < 0) { + SYSERROR("failed to create pipe"); + exit(EXIT_FAILURE); + } + + pid2 = fork(); + if (pid2 < 0) { + SYSERROR("failed to fork"); + exit(EXIT_FAILURE); + } + if (pid2) { + char c; + /* wait for daemon to create socket */ + close(pipefd[1]); + /* sync with child, we're ignoring the return from read + * because regardless if it works or not, either way we've + * synced with the child process. the if-empty-statement + * construct is to quiet the warn-unused-result warning. + */ + if (read(pipefd[0], &c, 1)) ; + close(pipefd[0]); + exit(EXIT_SUCCESS); + } + + umask(0); + if (setsid() < 0) { + SYSERROR("failed to setsid"); + exit(EXIT_FAILURE); + } + close(0); + close(1); + close(2); + open("/dev/null", O_RDONLY); + open("/dev/null", O_RDWR); + open("/dev/null", O_RDWR); + close(pipefd[0]); + sprintf(pipefd_str, "%d", pipefd[1]); + execvp(args[0], args); + exit(EXIT_FAILURE); } diff -Nru lxc-0.8.0~rc1/src/lxc/monitor.h lxc-1.0.0~alpha1/src/lxc/monitor.h --- lxc-0.8.0~rc1/src/lxc/monitor.h 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/monitor.h 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,12 +18,15 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __monitor_h #define __monitor_h #include +#include + +#include typedef enum { lxc_msg_state, @@ -32,12 +35,14 @@ struct lxc_msg { lxc_msg_type_t type; - char name[MAXPATHLEN]; + char name[NAME_MAX+1]; int value; }; -void lxc_monitor_send_state(const char *name, lxc_state_t state); -void lxc_monitor_send_priority(const char *name, int priority); -void lxc_monitor_cleanup(const char *name); +extern int lxc_monitor_open(const char *lxcpath); +extern int lxc_monitor_sock_name(const char *lxcpath, struct sockaddr_un *addr); +extern void lxc_monitor_send_state(const char *name, lxc_state_t state, + const char *lxcpath); +extern int lxc_monitord_spawn(const char *lxcpath); #endif diff -Nru lxc-0.8.0~rc1/src/lxc/namespace.c lxc-1.0.0~alpha1/src/lxc/namespace.c --- lxc-0.8.0~rc1/src/lxc/namespace.c 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/namespace.c 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2009 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,14 +18,13 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include -#include #include #include #include @@ -54,7 +53,7 @@ .arg = arg, }; - long stack_size = sysconf(_SC_PAGESIZE); + size_t stack_size = sysconf(_SC_PAGESIZE); void *stack = alloca(stack_size); pid_t ret; @@ -69,3 +68,48 @@ return ret; } + +static char *namespaces_list[] = { + "MOUNT", "PID", "UTSNAME", "IPC", + "USER", "NETWORK" +}; +static int cloneflags_list[] = { + CLONE_NEWNS, CLONE_NEWPID, CLONE_NEWUTS, CLONE_NEWIPC, + CLONE_NEWUSER, CLONE_NEWNET +}; + +int lxc_namespace_2_cloneflag(char *namespace) +{ + int i, len; + len = sizeof(namespaces_list)/sizeof(namespaces_list[0]); + for (i = 0; i < len; i++) + if (!strcmp(namespaces_list[i], namespace)) + return cloneflags_list[i]; + + ERROR("invalid namespace name %s", namespace); + return -1; +} + +int lxc_fill_namespace_flags(char *flaglist, int *flags) +{ + char *token, *saveptr = NULL; + int aflag; + + if (!flaglist) { + ERROR("need at least one namespace to unshare"); + return -1; + } + + token = strtok_r(flaglist, "|", &saveptr); + while (token) { + + aflag = lxc_namespace_2_cloneflag(token); + if (aflag < 0) + return -1; + + *flags |= aflag; + + token = strtok_r(NULL, "|", &saveptr); + } + return 0; +} diff -Nru lxc-0.8.0~rc1/src/lxc/namespace.h lxc-1.0.0~alpha1/src/lxc/namespace.h --- lxc-0.8.0~rc1/src/lxc/namespace.h 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/namespace.h 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2009 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,14 +18,16 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __namespace_h #define __namespace_h -#include +#include #include +#include "config.h" + #ifndef CLONE_FS # define CLONE_FS 0x00000200 #endif @@ -48,6 +50,19 @@ # define CLONE_NEWNET 0x40000000 #endif +#if defined(__ia64__) +int __clone2(int (*__fn) (void *__arg), void *__child_stack_base, + size_t __child_stack_size, int __flags, void *__arg, ...); +#else +int clone(int (*fn)(void *), void *child_stack, + int flags, void *arg, ... + /* pid_t *ptid, struct user_desc *tls, pid_t *ctid */ ); +#endif + + extern pid_t lxc_clone(int (*fn)(void *), void *arg, int flags); +extern int lxc_namespace_2_cloneflag(char *namespace); +extern int lxc_fill_namespace_flags(char *flaglist, int *flags); + #endif diff -Nru lxc-0.8.0~rc1/src/lxc/network.c lxc-1.0.0~alpha1/src/lxc/network.c --- lxc-0.8.0~rc1/src/lxc/network.c 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/network.c 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,7 +18,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #define _GNU_SOURCE #include @@ -47,6 +47,7 @@ #include "nl.h" #include "network.h" +#include "conf.h" #ifndef IFLA_LINKMODE # define IFLA_LINKMODE 17 @@ -412,7 +413,7 @@ } /* XXX: merge with lxc_macvlan_create */ -int lxc_vlan_create(const char *master, const char *name, ushort vlanid) +int lxc_vlan_create(const char *master, const char *name, unsigned short vlanid) { struct nl_handler nlh; struct nlmsg *nlmsg = NULL, *answer = NULL; @@ -582,12 +583,15 @@ static int ip_forward_set(const char *ifname, int family, int flag) { char path[MAXPATHLEN]; + int rc; if (family != AF_INET && family != AF_INET6) return -EINVAL; - snprintf(path, MAXPATHLEN, "/proc/sys/net/%s/conf/%s/forwarding", + rc = snprintf(path, MAXPATHLEN, "/proc/sys/net/%s/conf/%s/forwarding", family == AF_INET?"ipv4":"ipv6" , ifname); + if (rc >= MAXPATHLEN) + return -E2BIG; return proc_sys_net_write(path, flag?"1":"0"); } @@ -605,13 +609,16 @@ static int neigh_proxy_set(const char *ifname, int family, int flag) { char path[MAXPATHLEN]; + int ret; if (family != AF_INET && family != AF_INET6) return -EINVAL; - sprintf(path, "/proc/sys/net/%s/conf/%s/%s", + ret = snprintf(path, MAXPATHLEN, "/proc/sys/net/%s/conf/%s/%s", family == AF_INET?"ipv4":"ipv6" , ifname, family == AF_INET?"proxy_arp":"proxy_ndp"); + if (ret < 0 || ret >= MAXPATHLEN) + return -E2BIG; return proc_sys_net_write(path, flag?"1":"0"); } @@ -776,8 +783,11 @@ /* We might have found an IFA_ADDRESS before, * which we now overwrite with an IFA_LOCAL. */ - if (!*res) + if (!*res) { *res = malloc(addrlen); + if (!*res) + return -1; + } memcpy(*res, RTA_DATA(rta), addrlen); @@ -829,7 +839,6 @@ err = netlink_send(&nlh, nlmsg); if (err < 0) goto out; - err = 0; do { /* Restore the answer buffer length, it might have been @@ -998,3 +1007,18 @@ return err; } + +static char* lxc_network_types[LXC_NET_MAXCONFTYPE + 1] = { + [LXC_NET_VETH] = "veth", + [LXC_NET_MACVLAN] = "macvlan", + [LXC_NET_VLAN] = "vlan", + [LXC_NET_PHYS] = "phys", + [LXC_NET_EMPTY] = "empty", +}; + +const char *lxc_net_type_to_str(int type) +{ + if (type < 0 || type > LXC_NET_MAXCONFTYPE) + return NULL; + return lxc_network_types[type]; +} diff -Nru lxc-0.8.0~rc1/src/lxc/network.h lxc-1.0.0~alpha1/src/lxc/network.h --- lxc-0.8.0~rc1/src/lxc/network.h 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/network.h 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,7 +18,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _network_h #define _network_h @@ -61,7 +61,7 @@ */ extern int lxc_veth_create(const char *name1, const char *name2); extern int lxc_macvlan_create(const char *master, const char *name, int mode); -extern int lxc_vlan_create(const char *master, const char *name, ushort vid); +extern int lxc_vlan_create(const char *master, const char *name, unsigned short vid); /* * Activate forwarding @@ -100,7 +100,7 @@ */ extern int lxc_bridge_attach(const char *bridge, const char *ifname); -/* +/* * Create default gateway */ extern int lxc_route_create_default(const char *addr, const char *ifname, @@ -122,4 +122,5 @@ */ extern int lxc_neigh_proxy_off(const char *name, int family); +extern const char *lxc_net_type_to_str(int type); #endif diff -Nru lxc-0.8.0~rc1/src/lxc/nl.c lxc-1.0.0~alpha1/src/lxc/nl.c --- lxc-0.8.0~rc1/src/lxc/nl.c 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/nl.c 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,7 +18,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include @@ -48,7 +48,7 @@ return data; } -static int nla_put(struct nlmsg *nlmsg, int attr, +static int nla_put(struct nlmsg *nlmsg, int attr, const void *data, size_t len) { struct rtattr *rta; @@ -63,7 +63,7 @@ return 0; } -extern int nla_put_buffer(struct nlmsg *nlmsg, int attr, +extern int nla_put_buffer(struct nlmsg *nlmsg, int attr, const void *data, size_t size) { return nla_put(nlmsg, attr, data, size); @@ -79,7 +79,7 @@ return nla_put(nlmsg, attr, &value, sizeof(value)); } -extern int nla_put_u16(struct nlmsg *nlmsg, int attr, ushort value) +extern int nla_put_u16(struct nlmsg *nlmsg, int attr, unsigned short value) { return nla_put(nlmsg, attr, &value, 2); } @@ -193,7 +193,7 @@ #ifndef NLMSG_ERROR #define NLMSG_ERROR 0x2 #endif -extern int netlink_transaction(struct nl_handler *handler, +extern int netlink_transaction(struct nl_handler *handler, struct nlmsg *request, struct nlmsg *answer) { int ret; @@ -226,11 +226,11 @@ if (handler->fd < 0) return -errno; - if (setsockopt(handler->fd, SOL_SOCKET, SO_SNDBUF, + if (setsockopt(handler->fd, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf)) < 0) return -errno; - if (setsockopt(handler->fd, SOL_SOCKET, SO_RCVBUF, + if (setsockopt(handler->fd, SOL_SOCKET, SO_RCVBUF, &rcvbuf,sizeof(rcvbuf)) < 0) return -errno; @@ -238,12 +238,12 @@ handler->local.nl_family = AF_NETLINK; handler->local.nl_groups = 0; - if (bind(handler->fd, (struct sockaddr*)&handler->local, + if (bind(handler->fd, (struct sockaddr*)&handler->local, sizeof(handler->local)) < 0) return -errno; socklen = sizeof(handler->local); - if (getsockname(handler->fd, (struct sockaddr*)&handler->local, + if (getsockname(handler->fd, (struct sockaddr*)&handler->local, &socklen) < 0) return -errno; diff -Nru lxc-0.8.0~rc1/src/lxc/nl.h lxc-1.0.0~alpha1/src/lxc/nl.h --- lxc-0.8.0~rc1/src/lxc/nl.h 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/nl.h 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,7 +18,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __nl_h #define __nl_h @@ -39,7 +39,7 @@ * struct nl_handler : the handler for netlink sockets, this structure * is used all along the netlink socket life cycle to specify the * netlink socket to be used. - * + * * @fd: the file descriptor of the netlink socket * @seq: the sequence number of the netlink messages * @local: the bind address @@ -77,7 +77,7 @@ int netlink_open(struct nl_handler *handler, int protocol); /* - * netlink_close : close a netlink socket, after this call, + * netlink_close : close a netlink socket, after this call, * the handler is no longer valid * * @handler: a handler to the netlink socket @@ -87,8 +87,8 @@ int netlink_close(struct nl_handler *handler); /* - * netlink_rcv : receive a netlink message from the kernel. - * It is up to the caller to manage the allocation of the + * netlink_rcv : receive a netlink message from the kernel. + * It is up to the caller to manage the allocation of the * netlink message * * @handler: a handler to the netlink socket @@ -110,8 +110,8 @@ int netlink_send(struct nl_handler *handler, struct nlmsg *nlmsg); /* - * netlink_transaction: send a request to the kernel and read the response. - * This is useful for transactional protocol. It is up to the caller + * netlink_transaction: send a request to the kernel and read the response. + * This is useful for transactional protocol. It is up to the caller * to manage the allocation of the netlink message. * * @handler: a handler to a opened netlink socket @@ -120,11 +120,11 @@ * * Returns 0 on success, < 0 otherwise */ -int netlink_transaction(struct nl_handler *handler, +int netlink_transaction(struct nl_handler *handler, struct nlmsg *request, struct nlmsg *anwser); /* - * nla_put_string: copy a null terminated string to a netlink message + * nla_put_string: copy a null terminated string to a netlink message * attribute * * @nlmsg: the netlink message to be filled @@ -146,7 +146,7 @@ * * Returns 0 on success, < 0 otherwise */ -int nla_put_buffer(struct nlmsg *nlmsg, int attr, +int nla_put_buffer(struct nlmsg *nlmsg, int attr, const void *data, size_t size); /* @@ -169,10 +169,10 @@ * * Returns 0 on success, < 0 otherwise */ -int nla_put_u16(struct nlmsg *nlmsg, int attr, ushort value); +int nla_put_u16(struct nlmsg *nlmsg, int attr, unsigned short value); /* - * nla_put_attr: add an attribute name to a netlink + * nla_put_attr: add an attribute name to a netlink * * @nlmsg: the netlink message to be filled * @attr: the attribute name of the integer @@ -185,7 +185,7 @@ * nla_begin_nested: begin the nesting attribute * * @nlmsg: the netlink message to be filled - * @attr: the netsted attribute name + * @attr: the netsted attribute name * * Returns current nested pointer to be reused * to nla_end_nested. @@ -198,17 +198,17 @@ * @nlmsg: the netlink message * @nested: the nested pointer * - * Returns the current + * Returns the current */ void nla_end_nested(struct nlmsg *nlmsg, struct rtattr *attr); /* - * nlmsg_allocate : allocate a netlink message. The netlink format message + * nlmsg_allocate : allocate a netlink message. The netlink format message * is a header, a padding, a payload and a padding again. - * When a netlink message is allocated, the size specify the + * When a netlink message is allocated, the size specify the * payload we want. So the real size of the allocated message * is sizeof(header) + sizeof(padding) + payloadsize + sizeof(padding), - * in other words, the function will allocate more than specified. When + * in other words, the function will allocate more than specified. When * the buffer is allocated, the content is zeroed. * The function will also fill the field nlmsg_len with computed size. * If the allocation must be for the specified size, just use malloc. @@ -228,7 +228,7 @@ /* * nlmsg_data : returns a pointer to the data contained in the netlink message - * + * * @nlmsg : the netlink message to get the data * * Returns a pointer to the netlink data or NULL if there is no data diff -Nru lxc-0.8.0~rc1/src/lxc/parse.c lxc-1.0.0~alpha1/src/lxc/parse.c --- lxc-0.8.0~rc1/src/lxc/parse.c 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/parse.c 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,7 +18,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #define _GNU_SOURCE #include @@ -29,8 +29,21 @@ #include #include "parse.h" +#include "config.h" +#include "utils.h" #include +/* Workaround for the broken signature of alphasort() in bionic. + This was fixed upstream in 40e467ec668b59be25491bd44bf348a884d6a68d so the + workaround can probably be dropped with the next version of the Android NDK. + */ +#ifdef IS_BIONIC +int bionic_alphasort(const struct dirent** a, const struct dirent** b) { + return strcoll((*a)->d_name, (*b)->d_name); +} +#endif + + lxc_log_define(lxc_parse, lxc); static int dir_filter(const struct dirent *dirent) @@ -47,7 +60,11 @@ struct dirent **namelist; int n, ret = 0; +#ifdef IS_BIONIC + n = scandir(directory, &namelist, dir_filter, bionic_alphasort); +#else n = scandir(directory, &namelist, dir_filter, alphasort); +#endif if (n < 0) { SYSERROR("failed to scan %s directory", directory); return -1; diff -Nru lxc-0.8.0~rc1/src/lxc/parse.h lxc-1.0.0~alpha1/src/lxc/parse.h --- lxc-0.8.0~rc1/src/lxc/parse.h 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/parse.h 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,7 +18,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __parse_h #define __parse_h diff -Nru lxc-0.8.0~rc1/src/lxc/restart.c lxc-1.0.0~alpha1/src/lxc/restart.c --- lxc-0.8.0~rc1/src/lxc/restart.c 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/restart.c 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2010 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,7 +18,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" @@ -64,7 +64,8 @@ .post_start = post_restart }; -int lxc_restart(const char *name, int sfd, struct lxc_conf *conf, int flags) +int lxc_restart(const char *name, int sfd, struct lxc_conf *conf, int flags, + const char *lxcpath) { struct restart_args restart_arg = { .sfd = sfd, @@ -74,5 +75,5 @@ if (lxc_check_inherited(conf, sfd)) return -1; - return __lxc_start(name, conf, &restart_ops, &restart_arg); + return __lxc_start(name, conf, &restart_ops, &restart_arg, lxcpath); } diff -Nru lxc-0.8.0~rc1/src/lxc/rtnl.c lxc-1.0.0~alpha1/src/lxc/rtnl.c --- lxc-0.8.0~rc1/src/lxc/rtnl.c 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/rtnl.c 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,7 +18,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include @@ -53,7 +53,7 @@ return netlink_send(&handler->nlh, (struct nlmsg *)&rtnlmsg->nlmsghdr); } -extern int rtnetlink_transaction(struct rtnl_handler *handler, +extern int rtnetlink_transaction(struct rtnl_handler *handler, struct rtnlmsg *request, struct rtnlmsg *answer) { return netlink_transaction(&handler->nlh, (struct nlmsg *)&request->nlmsghdr, diff -Nru lxc-0.8.0~rc1/src/lxc/rtnl.h lxc-1.0.0~alpha1/src/lxc/rtnl.h --- lxc-0.8.0~rc1/src/lxc/rtnl.h 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/rtnl.h 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,7 +18,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __genl_h #define __genl_h @@ -30,7 +30,7 @@ #define RTNLMSG_DATA(glh) ((void *)(NLMSG_DATA(glh) + RTNL_HDRLEN)) /* - * struct genl_handler : the structure which store the netlink handler + * struct genl_handler : the structure which store the netlink handler * and the family number * * @nlh: the netlink socket handler @@ -105,6 +105,6 @@ * * Returns 0 on success, < 0 otherwise */ -int rtnetlink_transaction(struct rtnl_handler *handler, +int rtnetlink_transaction(struct rtnl_handler *handler, struct rtnlmsg *request, struct rtnlmsg *answer); #endif diff -Nru lxc-0.8.0~rc1/src/lxc/seccomp.c lxc-1.0.0~alpha1/src/lxc/seccomp.c --- lxc-0.8.0~rc1/src/lxc/seccomp.c 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/seccomp.c 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,155 @@ +/* + * lxc: linux Container library + * + * (C) Copyright Canonical, Inc. 2012 + * + * Authors: + * Serge Hallyn + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include "config.h" +#include "lxcseccomp.h" + +#include "log.h" + +lxc_log_define(lxc_seccomp, lxc); + +/* + * The first line of the config file has a policy language version + * the second line has some directives + * then comes policy subject to the directives + * right now version must be '1' + * the directives must include 'whitelist' (only type of policy currently + * supported) and can include 'debug' (though debug is not yet supported). + */ +static int parse_config(FILE *f, struct lxc_conf *conf) +{ + char line[1024]; + int ret, version; + + ret = fscanf(f, "%d\n", &version); + if (ret != 1 || version != 1) { + ERROR("invalid version"); + return -1; + } + if (!fgets(line, 1024, f)) { + ERROR("invalid config file"); + return -1; + } + if (!strstr(line, "whitelist")) { + ERROR("only whitelist policy is supported"); + return -1; + } + if (strstr(line, "debug")) { + ERROR("debug not yet implemented"); + return -1; + } + /* now read in the whitelist entries one per line */ + while (fgets(line, 1024, f)) { + int nr; + ret = sscanf(line, "%d", &nr); + if (ret != 1) + return -1; + ret = seccomp_rule_add( +#if HAVE_SCMP_FILTER_CTX + conf->seccomp_ctx, +#endif + SCMP_ACT_ALLOW, nr, 0); + if (ret < 0) { + ERROR("failed loading allow rule for %d\n", nr); + return ret; + } + } + return 0; +} + +int lxc_read_seccomp_config(struct lxc_conf *conf) +{ + FILE *f; + int ret; + + if (!conf->seccomp) + return 0; + +#if HAVE_SCMP_FILTER_CTX + /* XXX for debug, pass in SCMP_ACT_TRAP */ + conf->seccomp_ctx = seccomp_init(SCMP_ACT_ERRNO(31)); + ret = !conf->seccomp_ctx; +#else + ret = seccomp_init(SCMP_ACT_ERRNO(31)) < 0; +#endif + if (ret) { + ERROR("failed initializing seccomp"); + return -1; + } + + /* turn of no-new-privs. We don't want it in lxc, and it breaks + * with apparmor */ + if (seccomp_attr_set( +#if HAVE_SCMP_FILTER_CTX + conf->seccomp_ctx, +#endif + SCMP_FLTATR_CTL_NNP, 0)) { + ERROR("failed to turn off n-new-privs\n"); + return -1; + } + + f = fopen(conf->seccomp, "r"); + if (!f) { + SYSERROR("failed to open seccomp policy file %s\n", conf->seccomp); + return -1; + } + ret = parse_config(f, conf); + fclose(f); + return ret; +} + +int lxc_seccomp_load(struct lxc_conf *conf) +{ + int ret; + if (!conf->seccomp) + return 0; + ret = seccomp_load( +#if HAVE_SCMP_FILTER_CTX + conf->seccomp_ctx +#endif + ); + if (ret < 0) { + ERROR("Error loading the seccomp policy"); + return -1; + } + return 0; +} + +void lxc_seccomp_free(struct lxc_conf *conf) { + if (conf->seccomp) { + free(conf->seccomp); + conf->seccomp = NULL; + } +#if HAVE_SCMP_FILTER_CTX + if (conf->seccomp_ctx) { + seccomp_release(conf->seccomp_ctx); + conf->seccomp_ctx = NULL; + } +#endif +} diff -Nru lxc-0.8.0~rc1/src/lxc/start.c lxc-1.0.0~alpha1/src/lxc/start.c --- lxc-0.8.0~rc1/src/lxc/start.c 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/start.c 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,7 +18,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" @@ -38,74 +38,16 @@ #include #include #include +#include #include #include -#include #include #include #include +#include -#ifdef HAVE_SYS_SIGNALFD_H -# include -#else -/* assume kernel headers are too old */ -#include -struct signalfd_siginfo -{ - uint32_t ssi_signo; - int32_t ssi_errno; - int32_t ssi_code; - uint32_t ssi_pid; - uint32_t ssi_uid; - int32_t ssi_fd; - uint32_t ssi_tid; - uint32_t ssi_band; - uint32_t ssi_overrun; - uint32_t ssi_trapno; - int32_t ssi_status; - int32_t ssi_int; - uint64_t ssi_ptr; - uint64_t ssi_utime; - uint64_t ssi_stime; - uint64_t ssi_addr; - uint8_t __pad[48]; -}; - -# ifndef __NR_signalfd4 -/* assume kernel headers are too old */ -# if __i386__ -# define __NR_signalfd4 327 -# elif __x86_64__ -# define __NR_signalfd4 289 -# elif __powerpc__ -# define __NR_signalfd4 313 -# elif __s390x__ -# define __NR_signalfd4 322 -# endif -#endif - -# ifndef __NR_signalfd -/* assume kernel headers are too old */ -# if __i386__ -# define __NR_signalfd 321 -# elif __x86_64__ -# define __NR_signalfd 282 -# elif __powerpc__ -# define __NR_signalfd 305 -# elif __s390x__ -# define __NR_signalfd 316 -# endif -#endif - -int signalfd(int fd, const sigset_t *mask, int flags) -{ - int retval; - - retval = syscall (__NR_signalfd4, fd, mask, _NSIG / 8, flags); - if (errno == ENOSYS && flags == 0) - retval = syscall (__NR_signalfd, fd, mask, _NSIG / 8); - return retval; -} +#if HAVE_SYS_CAPABILITY_H +#include #endif #if !HAVE_DECL_PR_CAPBSET_DROP @@ -120,12 +62,15 @@ #include "af_unix.h" #include "mainloop.h" #include "utils.h" -#include "utmp.h" +#include "lxcutmp.h" #include "monitor.h" #include "commands.h" #include "console.h" #include "sync.h" #include "namespace.h" +#include "apparmor.h" +#include "lxcseccomp.h" +#include "caps.h" lxc_log_define(lxc_start, lxc); @@ -190,6 +135,7 @@ sigdelset(&mask, SIGILL) || sigdelset(&mask, SIGSEGV) || sigdelset(&mask, SIGBUS) || + sigdelset(&mask, SIGWINCH) || sigprocmask(SIG_BLOCK, &mask, oldmask)) { SYSERROR("failed to set signal mask"); return -1; @@ -216,8 +162,10 @@ struct lxc_epoll_descr *descr) { struct signalfd_siginfo siginfo; + siginfo_t info; int ret; pid_t *pid = data; + bool init_died = false; ret = read(fd, &siginfo, sizeof(siginfo)); if (ret < 0) { @@ -230,16 +178,23 @@ return -1; } + // check whether init is running + info.si_pid = 0; + ret = waitid(P_PID, *pid, &info, WEXITED | WNOWAIT | WNOHANG); + if (ret == 0 && info.si_pid == *pid) { + init_died = true; + } + if (siginfo.ssi_signo != SIGCHLD) { kill(*pid, siginfo.ssi_signo); INFO("forwarded signal %d to pid %d", siginfo.ssi_signo, *pid); - return 0; + return init_died ? 1 : 0; } if (siginfo.ssi_code == CLD_STOPPED || siginfo.ssi_code == CLD_CONTINUED) { INFO("container init process was stopped/continued"); - return 0; + return init_died ? 1 : 0; } /* more robustness, protect ourself from a SIGCHLD sent @@ -247,40 +202,17 @@ */ if (siginfo.ssi_pid != *pid) { WARN("invalid pid for SIGCHLD"); - return 0; + return init_died ? 1 : 0; } DEBUG("container init process exited"); return 1; } -int lxc_pid_callback(int fd, struct lxc_request *request, - struct lxc_handler *handler) -{ - struct lxc_answer answer; - int ret; - - answer.pid = handler->pid; - answer.ret = 0; - - ret = send(fd, &answer, sizeof(answer), 0); - if (ret < 0) { - WARN("failed to send answer to the peer"); - return -1; - } - - if (ret != sizeof(answer)) { - ERROR("partial answer sent"); - return -1; - } - - return 0; -} - int lxc_set_state(const char *name, struct lxc_handler *handler, lxc_state_t state) { handler->state = state; - lxc_monitor_send_state(name, state); + lxc_monitor_send_state(name, state, handler->lxcpath); return 0; } @@ -305,19 +237,23 @@ goto out_mainloop_open; } - if (lxc_command_mainloop_add(name, &descr, handler)) { + if (lxc_cmd_mainloop_add(name, &descr, handler)) { ERROR("failed to add command handler to mainloop"); goto out_mainloop_open; } if (handler->conf->need_utmp_watch) { + #if HAVE_SYS_CAPABILITY_H if (lxc_utmp_mainloop_add(&descr, handler)) { ERROR("failed to add utmp handler to mainloop"); goto out_mainloop_open; } + #else + DEBUG("not starting utmp handler as cap_sys_boot cannot be dropped without capabilities support\n"); + #endif } - return lxc_mainloop(&descr); + return lxc_mainloop(&descr, -1); out_mainloop_open: lxc_mainloop_close(&descr); @@ -326,17 +262,10 @@ return -1; } -extern int lxc_caps_check(void); - -struct lxc_handler *lxc_init(const char *name, struct lxc_conf *conf) +struct lxc_handler *lxc_init(const char *name, struct lxc_conf *conf, const char *lxcpath) { struct lxc_handler *handler; - if (!lxc_caps_check()) { - ERROR("Not running with sufficient privilege"); - return NULL; - } - handler = malloc(sizeof(*handler)); if (!handler) return NULL; @@ -344,27 +273,59 @@ memset(handler, 0, sizeof(*handler)); handler->conf = conf; + handler->lxcpath = lxcpath; + handler->pinfd = -1; + apparmor_handler_init(handler); handler->name = strdup(name); if (!handler->name) { ERROR("failed to allocate memory"); goto out_free; } - /* Begin the set the state to STARTING*/ + if (lxc_cmd_init(name, handler, lxcpath)) + goto out_free_name; + + if (lxc_read_seccomp_config(conf) != 0) { + ERROR("failed loading seccomp policy"); + goto out_close_maincmd_fd; + } + + /* Begin by setting the state to STARTING */ if (lxc_set_state(name, handler, STARTING)) { ERROR("failed to set state '%s'", lxc_state2str(STARTING)); - goto out_free_name; + goto out_close_maincmd_fd; } - if (lxc_create_tty(name, conf)) { - ERROR("failed to create the ttys"); + /* Start of environment variable setup for hooks */ + if (setenv("LXC_NAME", name, 1)) { + SYSERROR("failed to set environment variable for container name"); + } + if (setenv("LXC_CONFIG_FILE", conf->rcfile, 1)) { + SYSERROR("failed to set environment variable for config path"); + } + if (setenv("LXC_ROOTFS_MOUNT", conf->rootfs.mount, 1)) { + SYSERROR("failed to set environment variable for rootfs mount"); + } + if (setenv("LXC_ROOTFS_PATH", conf->rootfs.path, 1)) { + SYSERROR("failed to set environment variable for rootfs mount"); + } + if (conf->console.path && setenv("LXC_CONSOLE", conf->console.path, 1)) { + SYSERROR("failed to set environment variable for console path"); + } + if (conf->console.log_path && setenv("LXC_CONSOLE_LOGPATH", conf->console.log_path, 1)) { + SYSERROR("failed to set environment variable for console log"); + } + /* End of environment variable setup for hooks */ + + if (run_lxc_hooks(name, "pre-start", conf, handler->lxcpath, NULL)) { + ERROR("failed to run pre-start hooks for container '%s'.", name); goto out_aborting; } - if (lxc_create_console(conf)) { - ERROR("failed to create console"); - goto out_delete_tty; + if (lxc_create_tty(name, conf)) { + ERROR("failed to create the ttys"); + goto out_aborting; } /* the signal fd has to be created before forking otherwise @@ -373,18 +334,27 @@ handler->sigfd = setup_signal_fd(&handler->oldmask); if (handler->sigfd < 0) { ERROR("failed to set sigchild fd handler"); - goto out_delete_console; + goto out_delete_tty; + } + + /* do this after setting up signals since it might unblock SIGWINCH */ + if (lxc_console_create(conf)) { + ERROR("failed to create console"); + goto out_restore_sigmask; } INFO("'%s' is initialized", name); return handler; -out_delete_console: - lxc_delete_console(&conf->console); +out_restore_sigmask: + sigprocmask(SIG_SETMASK, &handler->oldmask, NULL); out_delete_tty: lxc_delete_tty(&conf->tty_info); out_aborting: lxc_set_state(name, handler, ABORTING); +out_close_maincmd_fd: + close(conf->maincmd_fd); + conf->maincmd_fd = -1; out_free_name: free(handler->name); handler->name = NULL; @@ -393,7 +363,7 @@ return NULL; } -void lxc_fini(const char *name, struct lxc_handler *handler) +static void lxc_fini(const char *name, struct lxc_handler *handler) { /* The STOPPING state is there for future cleanup code * which can take awhile @@ -401,21 +371,33 @@ lxc_set_state(name, handler, STOPPING); lxc_set_state(name, handler, STOPPED); + if (run_lxc_hooks(name, "post-stop", handler->conf, handler->lxcpath, NULL)) + ERROR("failed to run post-stop hooks for container '%s'.", name); + /* reset mask set by setup_signal_fd */ if (sigprocmask(SIG_SETMASK, &handler->oldmask, NULL)) WARN("failed to restore sigprocmask"); - lxc_delete_console(&handler->conf->console); + lxc_console_delete(&handler->conf->console); lxc_delete_tty(&handler->conf->tty_info); + close(handler->conf->maincmd_fd); + handler->conf->maincmd_fd = -1; free(handler->name); + if (handler->cgroup) { + lxc_cgroup_destroy_desc(handler->cgroup); + handler->cgroup = NULL; + } free(handler); } void lxc_abort(const char *name, struct lxc_handler *handler) { + int ret, status; + lxc_set_state(name, handler, ABORTING); if (handler->pid > 0) kill(handler->pid, SIGKILL); + while ((ret = waitpid(-1, &status, 0)) > 0) ; } #include @@ -437,12 +419,12 @@ return 0; } -static int must_drop_cap_sys_boot(void) +static int must_drop_cap_sys_boot(struct lxc_conf *conf) { FILE *f = fopen("/proc/sys/kernel/ctrl-alt-del", "r"); - int ret, cmd, v; + int ret, cmd, v, flags; long stack_size = 4096; - void *stack = alloca(stack_size) + stack_size; + void *stack = alloca(stack_size); int status; pid_t pid; @@ -459,7 +441,16 @@ } cmd = v ? LINUX_REBOOT_CMD_CAD_ON : LINUX_REBOOT_CMD_CAD_OFF; - pid = clone(container_reboot_supported, stack, CLONE_NEWPID | SIGCHLD, &cmd); + flags = CLONE_NEWPID | SIGCHLD; + if (!lxc_list_empty(&conf->id_map)) + flags |= CLONE_NEWUSER; + +#ifdef __ia64__ + pid = __clone2(container_reboot_supported, stack, stack_size, flags, &cmd); +#else + stack += stack_size; + pid = clone(container_reboot_supported, stack, flags, &cmd); +#endif if (pid < 0) { SYSERROR("failed to clone\n"); return -1; @@ -497,55 +488,138 @@ lxc_sync_fini_parent(handler); + /* don't leak the pinfd to the container */ + if (handler->pinfd >= 0) + close(handler->pinfd); + /* Tell the parent task it can begin to configure the * container and wait for it to finish */ if (lxc_sync_barrier_parent(handler, LXC_SYNC_CONFIGURE)) return -1; - if (must_drop_cap_sys_boot()) { + /* + * if we are in a new user namespace, become root there to have + * privilege over our namespace + */ + if (!lxc_list_empty(&handler->conf->id_map)) { + NOTICE("switching to gid/uid 0 in new user namespace"); + if (setgid(0)) { + SYSERROR("setgid"); + goto out_warn_father; + } + if (setuid(0)) { + SYSERROR("setuid"); + goto out_warn_father; + } + } + + #if HAVE_SYS_CAPABILITY_H + if (handler->conf->need_utmp_watch) { if (prctl(PR_CAPBSET_DROP, CAP_SYS_BOOT, 0, 0, 0)) { SYSERROR("failed to remove CAP_SYS_BOOT capability"); - return -1; + goto out_warn_father; } - handler->conf->need_utmp_watch = 1; DEBUG("Dropped cap_sys_boot\n"); - } else { - DEBUG("Not dropping cap_sys_boot or watching utmp\n"); - handler->conf->need_utmp_watch = 0; } + #endif /* Setup the container, ip, names, utsname, ... */ - if (lxc_setup(handler->name, handler->conf)) { + if (lxc_setup(handler->name, handler->conf, handler->lxcpath)) { ERROR("failed to setup the container"); goto out_warn_father; } + /* ask father to setup cgroups and wait for him to finish */ + if (lxc_sync_barrier_parent(handler, LXC_SYNC_CGROUP)) + return -1; + + if (apparmor_load(handler) < 0) + goto out_warn_father; + + if (lxc_seccomp_load(handler->conf) != 0) + goto out_warn_father; + + if (run_lxc_hooks(handler->name, "start", handler->conf, handler->lxcpath, NULL)) { + ERROR("failed to run start hooks for container '%s'.", handler->name); + goto out_warn_father; + } + + /* The clearenv() and putenv() calls have been moved here + * to allow us to use enviroment variables passed to the various + * hooks, such as the start hook above. Not all of the + * variables like CONFIG_PATH or ROOTFS are valid in this + * context but others are. */ + if (clearenv()) { + SYSERROR("failed to clear environment"); + /* don't error out though */ + } + + if (putenv("container=lxc")) { + SYSERROR("failed to set environment variable"); + goto out_warn_father; + } + close(handler->sigfd); /* after this call, we are in error because this * ops should not return as it execs */ - if (handler->ops->start(handler, handler->data)) - return -1; + handler->ops->start(handler, handler->data); out_warn_father: + /* we want the parent to know something went wrong, so any + * value other than what it expects is ok. */ lxc_sync_wake_parent(handler, LXC_SYNC_POST_CONFIGURE); return -1; } +int save_phys_nics(struct lxc_conf *conf) +{ + struct lxc_list *iterator; + + lxc_list_for_each(iterator, &conf->network) { + struct lxc_netdev *netdev = iterator->elem; + + if (netdev->type != LXC_NET_PHYS) + continue; + conf->saved_nics = realloc(conf->saved_nics, + (conf->num_savednics+1)*sizeof(struct saved_nic)); + if (!conf->saved_nics) { + SYSERROR("failed to allocate memory"); + return -1; + } + conf->saved_nics[conf->num_savednics].ifindex = netdev->ifindex; + conf->saved_nics[conf->num_savednics].orig_name = strdup(netdev->link); + if (!conf->saved_nics[conf->num_savednics].orig_name) { + SYSERROR("failed to allocate memory"); + return -1; + } + INFO("stored saved_nic #%d idx %d name %s\n", conf->num_savednics, + conf->saved_nics[conf->num_savednics].ifindex, + conf->saved_nics[conf->num_savednics].orig_name); + conf->num_savednics++; + } + + return 0; +} + +extern bool is_in_subcgroup(int pid, const char *subsystem, struct cgroup_desc *d); int lxc_spawn(struct lxc_handler *handler) { - int clone_flags; int failed_before_rename = 0; const char *name = handler->name; if (lxc_sync_init(handler)) return -1; - clone_flags = CLONE_NEWUTS|CLONE_NEWPID|CLONE_NEWIPC|CLONE_NEWNS; + handler->clone_flags = CLONE_NEWUTS|CLONE_NEWPID|CLONE_NEWIPC|CLONE_NEWNS; + if (!lxc_list_empty(&handler->conf->id_map)) { + INFO("Cloning a new user namespace"); + handler->clone_flags |= CLONE_NEWUSER; + } if (!lxc_list_empty(&handler->conf->network)) { - clone_flags |= CLONE_NEWNET; + handler->clone_flags |= CLONE_NEWNET; /* Find gateway addresses from the link device, which is * no longer accessible inside the container. Do this @@ -567,8 +641,24 @@ } } + if (save_phys_nics(handler->conf)) { + ERROR("failed to save physical nic info"); + goto out_abort; + } + + /* + * if the rootfs is not a blockdev, prevent the container from + * marking it readonly. + */ + + handler->pinfd = pin_rootfs(handler->conf->rootfs.path); + if (handler->pinfd == -1) { + ERROR("failed to pin the container's rootfs"); + goto out_delete_net; + } + /* Create a process in a new set of namespaces */ - handler->pid = lxc_clone(do_start, handler, clone_flags); + handler->pid = lxc_clone(do_start, handler, handler->clone_flags); if (handler->pid < 0) { SYSERROR("failed to fork into a new namespace"); goto out_delete_net; @@ -579,26 +669,67 @@ if (lxc_sync_wait_child(handler, LXC_SYNC_CONFIGURE)) failed_before_rename = 1; - if (lxc_cgroup_create(name, handler->pid)) + if ((handler->cgroup = lxc_cgroup_path_create(name)) == NULL) + goto out_delete_net; + + if (setup_cgroup(handler, &handler->conf->cgroup)) { + ERROR("failed to setup the cgroups for '%s'", name); + goto out_delete_net; + } + + if (lxc_cgroup_enter(handler->cgroup, handler->pid) < 0) goto out_delete_net; if (failed_before_rename) goto out_delete_net; /* Create the network configuration */ - if (clone_flags & CLONE_NEWNET) { + if (handler->clone_flags & CLONE_NEWNET) { if (lxc_assign_network(&handler->conf->network, handler->pid)) { ERROR("failed to create the configured network"); goto out_delete_net; } } - /* Tell the child to continue its initialization and wait for - * it to exec or return an error + /* map the container uids - the container became an invalid + * userid the moment it was cloned with CLONE_NEWUSER - this + * call doesn't change anything immediately, but allows the + * container to setuid(0) (0 being mapped to something else on + * the host) later to become a valid uid again */ + if (lxc_map_ids(&handler->conf->id_map, handler->pid)) { + ERROR("failed to set up id mapping"); + goto out_delete_net; + } + + /* Tell the child to continue its initialization. we'll get + * LXC_SYNC_CGROUP when it is ready for us to setup cgroups */ if (lxc_sync_barrier_child(handler, LXC_SYNC_POST_CONFIGURE)) + goto out_delete_net; + + if (setup_cgroup_devices(handler, &handler->conf->cgroup)) { + ERROR("failed to setup the devices cgroup for '%s'", name); + goto out_delete_net; + } + + /* Tell the child to complete its initialization and wait for + * it to exec or return an error. (the child will never + * return LXC_SYNC_POST_CGROUP+1. It will either close the + * sync pipe, causing lxc_sync_barrier_child to return + * success, or return a different value, causing us to error + * out). + */ + if (lxc_sync_barrier_child(handler, LXC_SYNC_POST_CGROUP)) return -1; + if (detect_shared_rootfs()) + umount2(handler->conf->rootfs.mount, MNT_DETACH); + + /* If child is in a fresh user namespace, chown his ptys for + * it */ + if (uid_shift_ttys(handler->pid, handler->conf)) + DEBUG("Failed to chown ptys.\n"); + if (handler->ops->post_start(handler, handler->data)) goto out_abort; @@ -609,25 +740,31 @@ } lxc_sync_fini(handler); + return 0; out_delete_net: - if (clone_flags & CLONE_NEWNET) - lxc_delete_network(&handler->conf->network); + if (handler->clone_flags & CLONE_NEWNET) + lxc_delete_network(handler); out_abort: lxc_abort(name, handler); lxc_sync_fini(handler); + if (handler->pinfd >= 0) { + close(handler->pinfd); + handler->pinfd = -1; + } + return -1; } int __lxc_start(const char *name, struct lxc_conf *conf, - struct lxc_operations* ops, void *data) + struct lxc_operations* ops, void *data, const char *lxcpath) { struct lxc_handler *handler; int err = -1; int status; - handler = lxc_init(name, conf); + handler = lxc_init(name, conf, lxcpath); if (!handler) { ERROR("failed to initialize the container"); return -1; @@ -635,10 +772,21 @@ handler->ops = ops; handler->data = data; + if (must_drop_cap_sys_boot(handler->conf)) { + #if HAVE_SYS_CAPABILITY_H + DEBUG("Dropping cap_sys_boot\n"); + #else + DEBUG("Can't drop cap_sys_boot as capabilities aren't supported\n"); + #endif + } else { + DEBUG("Not dropping cap_sys_boot or watching utmp\n"); + handler->conf->need_utmp_watch = 0; + } + err = lxc_spawn(handler); if (err) { ERROR("failed to spawn '%s'", name); - goto out_fini; + goto out_fini_nonet; } err = lxc_poll(name, handler); @@ -671,9 +819,18 @@ } } + lxc_rename_phys_nics_on_shutdown(handler->conf); + + if (handler->pinfd >= 0) { + close(handler->pinfd); + handler->pinfd = -1; + } + err = lxc_error_set_and_log(handler->pid, status); out_fini: - lxc_cgroup_destroy(name); + lxc_delete_network(handler); + +out_fini_nonet: lxc_fini(name, handler); return err; @@ -710,7 +867,8 @@ .post_start = post_start }; -int lxc_start(const char *name, char *const argv[], struct lxc_conf *conf) +int lxc_start(const char *name, char *const argv[], struct lxc_conf *conf, + const char *lxcpath) { struct start_args start_arg = { .argv = argv, @@ -720,5 +878,5 @@ return -1; conf->need_utmp_watch = 1; - return __lxc_start(name, conf, &start_ops, &start_arg); + return __lxc_start(name, conf, &start_ops, &start_arg, lxcpath); } diff -Nru lxc-0.8.0~rc1/src/lxc/start.h lxc-1.0.0~alpha1/src/lxc/start.h --- lxc-0.8.0~rc1/src/lxc/start.h 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/start.h 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,11 +18,13 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __lxc_state_h #define __lxc_state_h +#include "config.h" + #include #include @@ -35,28 +37,36 @@ int (*post_start)(struct lxc_handler *, void *); }; +struct cgroup_desc; + struct lxc_handler { pid_t pid; char *name; lxc_state_t state; + int clone_flags; int sigfd; sigset_t oldmask; struct lxc_conf *conf; struct lxc_operations *ops; void *data; int sv[2]; +#if HAVE_APPARMOR + int aa_enabled; +#endif + int pinfd; + const char *lxcpath; + struct cgroup_desc *cgroup; }; -extern struct lxc_handler *lxc_init(const char *name, struct lxc_conf *); +extern struct lxc_handler *lxc_init(const char *name, struct lxc_conf *, const char *); extern int lxc_spawn(struct lxc_handler *); extern int lxc_poll(const char *name, struct lxc_handler *handler); extern void lxc_abort(const char *name, struct lxc_handler *handler); -extern void lxc_fini(const char *name, struct lxc_handler *handler); extern int lxc_set_state(const char *, struct lxc_handler *, lxc_state_t); extern int lxc_check_inherited(struct lxc_conf *conf, int fd_to_ignore); int __lxc_start(const char *, struct lxc_conf *, struct lxc_operations *, - void *); + void *, const char *); #endif diff -Nru lxc-0.8.0~rc1/src/lxc/state.c lxc-1.0.0~alpha1/src/lxc/state.c --- lxc-0.8.0~rc1/src/lxc/state.c 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/state.c 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,9 +18,10 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include +#include #include #include #include @@ -31,9 +32,11 @@ #include #include +#include #include #include #include +#include #include "commands.h" #include "config.h" @@ -53,7 +56,8 @@ lxc_state_t lxc_str2state(const char *state) { - int i, len; + size_t len; + lxc_state_t i; len = sizeof(strstate)/sizeof(strstate[0]); for (i = 0; i < len; i++) if (!strcmp(strstate[i], state)) @@ -63,100 +67,167 @@ return -1; } -static int freezer_state(const char *name) +static lxc_state_t freezer_state(const char *name, const char *lxcpath) { - char *nsgroup; + char *cgabspath = NULL; char freezer[MAXPATHLEN]; char status[MAXPATHLEN]; FILE *file; - int err; + int ret; - err = lxc_cgroup_path_get(&nsgroup, "freezer", name); - if (err) + cgabspath = lxc_cgroup_path_get("freezer", name, lxcpath); + if (!cgabspath) return -1; - snprintf(freezer, MAXPATHLEN, "%s/freezer.state", nsgroup); + ret = snprintf(freezer, MAXPATHLEN, "%s/freezer.state", cgabspath); + if (ret < 0 || ret >= MAXPATHLEN) + goto out; file = fopen(freezer, "r"); - if (!file) - return -1; + if (!file) { + ret = -1; + goto out; + } - err = fscanf(file, "%s", status); + ret = fscanf(file, "%s", status); fclose(file); - if (err == EOF) { + if (ret == EOF) { SYSERROR("failed to read %s", freezer); - return -1; - } - - return lxc_str2state(status); -} - -static lxc_state_t __lxc_getstate(const char *name) -{ - struct lxc_command command = { - .request = { .type = LXC_COMMAND_STATE }, - }; - - int ret, stopped = 0; - - ret = lxc_command(name, &command, &stopped); - if (ret < 0 && stopped) - return STOPPED; - - if (ret < 0) { - ERROR("failed to send command"); - return -1; - } - - if (!ret) { - WARN("'%s' has stopped before sending its state", name); - return -1; - } - - if (command.answer.ret < 0) { - ERROR("failed to get state for '%s': %s", - name, strerror(-command.answer.ret)); - return -1; + ret = -1; + goto out; } - DEBUG("'%s' is in '%s' state", name, lxc_state2str(command.answer.ret)); + ret = lxc_str2state(status); - return command.answer.ret; +out: + free(cgabspath); + return ret; } -lxc_state_t lxc_getstate(const char *name) +lxc_state_t lxc_getstate(const char *name, const char *lxcpath) { - int state = freezer_state(name); + lxc_state_t state = freezer_state(name, lxcpath); if (state != FROZEN && state != FREEZING) - state = __lxc_getstate(name); + state = lxc_cmd_get_state(name, lxcpath); return state; } -/*---------------------------------------------------------------------------- - * functions used by lxc-start mainloop - * to handle above command request. - *--------------------------------------------------------------------------*/ -extern int lxc_state_callback(int fd, struct lxc_request *request, - struct lxc_handler *handler) +static int fillwaitedstates(const char *strstates, int *states) { - struct lxc_answer answer; - int ret; - - answer.ret = handler->state; - - ret = send(fd, &answer, sizeof(answer), 0); - if (ret < 0) { - WARN("failed to send answer to the peer"); - goto out; - } - - if (ret != sizeof(answer)) { - ERROR("partial answer sent"); - goto out; + char *token, *saveptr = NULL; + char *strstates_dup = strdup(strstates); + int state; + + if (!strstates_dup) + return -1; + + token = strtok_r(strstates_dup, "|", &saveptr); + while (token) { + + state = lxc_str2state(token); + if (state < 0) { + free(strstates_dup); + return -1; + } + + states[state] = 1; + + token = strtok_r(NULL, "|", &saveptr); + } + free(strstates_dup); + return 0; +} + +extern int lxc_wait(const char *lxcname, const char *states, int timeout, const char *lxcpath) +{ + struct lxc_msg msg; + int state, ret; + int s[MAX_STATE] = { }, fd; + + if (fillwaitedstates(states, s)) + return -1; + + if (lxc_monitord_spawn(lxcpath)) + return -1; + + fd = lxc_monitor_open(lxcpath); + if (fd < 0) + return -1; + + /* + * if container present, + * then check if already in requested state + */ + ret = -1; + state = lxc_getstate(lxcname, lxcpath); + if (state < 0) { + goto out_close; + } else if ((state >= 0) && (s[state])) { + ret = 0; + goto out_close; + } + + for (;;) { + int elapsed_time, curtime = 0; + struct timeval tv; + int stop = 0; + int retval; + + if (timeout != -1) { + retval = gettimeofday(&tv, NULL); + if (retval) + goto out_close; + curtime = tv.tv_sec; + } + if (lxc_monitor_read_timeout(fd, &msg, timeout) < 0) { + /* try again if select interrupted by signal */ + if (errno != EINTR) + goto out_close; + } + + if (timeout != -1) { + retval = gettimeofday(&tv, NULL); + if (retval) + goto out_close; + elapsed_time = tv.tv_sec - curtime; + if (timeout - elapsed_time <= 0) + stop = 1; + timeout -= elapsed_time; + } + + if (strcmp(lxcname, msg.name)) { + if (stop) { + ret = -2; + goto out_close; + } + continue; + } + + switch (msg.type) { + case lxc_msg_state: + if (msg.value < 0 || msg.value >= MAX_STATE) { + ERROR("Receive an invalid state number '%d'", + msg.value); + goto out_close; + } + + if (s[msg.value]) { + ret = 0; + goto out_close; + } + break; + default: + if (stop) { + ret = -2; + goto out_close; + } + /* just ignore garbage */ + break; + } } -out: +out_close: + lxc_monitor_close(fd); return ret; } - diff -Nru lxc-0.8.0~rc1/src/lxc/state.h lxc-1.0.0~alpha1/src/lxc/state.h --- lxc-0.8.0~rc1/src/lxc/state.h 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/state.h 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,7 +18,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _state_h #define _state_h @@ -29,9 +29,10 @@ } lxc_state_t; extern int lxc_rmstate(const char *name); -extern lxc_state_t lxc_getstate(const char *name); +extern lxc_state_t lxc_getstate(const char *name, const char *lxcpath); extern lxc_state_t lxc_str2state(const char *state); extern const char *lxc_state2str(lxc_state_t state); +extern int lxc_wait(const char *lxcname, const char *states, int timeout, const char *lxcpath); #endif diff -Nru lxc-0.8.0~rc1/src/lxc/stop.c lxc-1.0.0~alpha1/src/lxc/stop.c --- lxc-0.8.0~rc1/src/lxc/stop.c 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/stop.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,110 +0,0 @@ -/* - * lxc: linux Container library - * - * (C) Copyright IBM Corp. 2007, 2008 - * - * Authors: - * Daniel Lezcano - * - * 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 - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "lxc.h" -#include "commands.h" - -lxc_log_define(lxc_stop, lxc); - -int lxc_stop(const char *name) -{ - struct lxc_command command = { - .request = { .type = LXC_COMMAND_STOP }, - }; - - int ret, stopped = 0; - - ret = lxc_command(name, &command,&stopped); - if (ret < 0 && stopped) { - INFO("'%s' is already stopped", name); - return 0; - } - - if (ret < 0) { - ERROR("failed to send command"); - return -1; - } - - /* we do not expect any answer, because we wait for the connection to be - * closed - */ - if (ret > 0) { - ERROR("failed to stop '%s': %s", - name, strerror(-command.answer.ret)); - return -1; - } - - INFO("'%s' has stopped", name); - - return 0; -} - -/*---------------------------------------------------------------------------- - * functions used by lxc-start mainloop - * to handle above command request. - *--------------------------------------------------------------------------*/ -extern int lxc_stop_callback(int fd, struct lxc_request *request, - struct lxc_handler *handler) -{ - struct lxc_answer answer; - int ret; - - answer.ret = kill(handler->pid, SIGKILL); - if (!answer.ret) { - ret = lxc_unfreeze(handler->name); - if (!ret) - return 0; - - ERROR("failed to unfreeze container"); - answer.ret = ret; - } - - ret = send(fd, &answer, sizeof(answer), 0); - if (ret < 0) { - WARN("failed to send answer to the peer"); - goto out; - } - - if (ret != sizeof(answer)) { - ERROR("partial answer sent"); - goto out; - } - -out: - return -1; -} - diff -Nru lxc-0.8.0~rc1/src/lxc/sync.c lxc-1.0.0~alpha1/src/lxc/sync.c --- lxc-0.8.0~rc1/src/lxc/sync.c 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/sync.c 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,7 +18,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include diff -Nru lxc-0.8.0~rc1/src/lxc/sync.h lxc-1.0.0~alpha1/src/lxc/sync.h --- lxc-0.8.0~rc1/src/lxc/sync.h 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/sync.h 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,7 +18,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __lxc_sync_h #define __lxc_sync_h @@ -28,6 +28,8 @@ enum { LXC_SYNC_CONFIGURE, LXC_SYNC_POST_CONFIGURE, + LXC_SYNC_CGROUP, + LXC_SYNC_POST_CGROUP, LXC_SYNC_RESTART, LXC_SYNC_POST_RESTART, }; diff -Nru lxc-0.8.0~rc1/src/lxc/utils.c lxc-1.0.0~alpha1/src/lxc/utils.c --- lxc-0.8.0~rc1/src/lxc/utils.c 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/utils.c 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,7 +18,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #define _GNU_SOURCE @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -34,80 +35,87 @@ #include #include #include +#include +#include +#include "utils.h" #include "log.h" lxc_log_define(lxc_utils, lxc); -int lxc_copy_file(const char *srcfile, const char *dstfile) +static int _recursive_rmdir_onedev(char *dirname, dev_t pdev) { - void *srcaddr = NULL, *dstaddr; - struct stat stat; - int srcfd, dstfd, ret = -1; - char c = '\0'; - - dstfd = open(dstfile, O_CREAT | O_EXCL | O_RDWR, 0600); - if (dstfd < 0) { - SYSERROR("failed to creat '%s'", dstfile); - goto out; - } - - srcfd = open(srcfile, O_RDONLY); - if (srcfd < 0) { - SYSERROR("failed to open '%s'", srcfile); - goto err; + struct dirent dirent, *direntp; + DIR *dir; + int ret, failed=0; + char pathname[MAXPATHLEN]; + + dir = opendir(dirname); + if (!dir) { + ERROR("%s: failed to open %s", __func__, dirname); + return 0; } - if (fstat(srcfd, &stat)) { - SYSERROR("failed to stat '%s'", srcfile); - goto err; + while (!readdir_r(dir, &dirent, &direntp)) { + struct stat mystat; + int rc; + + if (!direntp) + break; + + if (!strcmp(direntp->d_name, ".") || + !strcmp(direntp->d_name, "..")) + continue; + + rc = snprintf(pathname, MAXPATHLEN, "%s/%s", dirname, direntp->d_name); + if (rc < 0 || rc >= MAXPATHLEN) { + ERROR("pathname too long"); + failed=1; + continue; + } + ret = lstat(pathname, &mystat); + if (ret) { + ERROR("%s: failed to stat %s", __func__, pathname); + failed=1; + continue; + } + if (mystat.st_dev != pdev) + continue; + if (S_ISDIR(mystat.st_mode)) { + if (!_recursive_rmdir_onedev(pathname, pdev)) + failed=1; + } else { + if (unlink(pathname) < 0) { + ERROR("%s: failed to delete %s", __func__, pathname); + failed=1; + } + } } - if (!stat.st_size) { - INFO("copy '%s' which is an empty file", srcfile); - ret = 0; - goto out_close; + if (rmdir(dirname) < 0) { + ERROR("%s: failed to delete %s", __func__, dirname); + failed=1; } - if (lseek(dstfd, stat.st_size - 1, SEEK_SET) < 0) { - SYSERROR("failed to seek dest file '%s'", dstfile); - goto err; + if (closedir(dir)) { + ERROR("%s: failed to close directory %s", __func__, dirname); + failed=1; } - /* fixup length */ - if (write(dstfd, &c, 1) < 0) { - SYSERROR("failed to write to '%s'", dstfile); - goto err; - } + return !failed; +} - srcaddr = mmap(NULL, stat.st_size, PROT_READ, MAP_SHARED, srcfd, 0L); - if (srcaddr == MAP_FAILED) { - SYSERROR("failed to mmap '%s'", srcfile); - goto err; - } +/* returns 1 on success, 0 if there were any failures */ +extern int lxc_rmdir_onedev(char *path) +{ + struct stat mystat; - dstaddr = mmap(NULL, stat.st_size, PROT_WRITE, MAP_SHARED, dstfd, 0L); - if (dstaddr == MAP_FAILED) { - SYSERROR("failed to mmap '%s'", dstfile); - goto err; + if (lstat(path, &mystat) < 0) { + ERROR("%s: failed to stat %s", __func__, path); + return 0; } - ret = 0; - - memcpy(dstaddr, srcaddr, stat.st_size); - - munmap(dstaddr, stat.st_size); -out_mmap: - if (srcaddr) - munmap(srcaddr, stat.st_size); -out_close: - close(dstfd); - close(srcfd); -out: - return ret; -err: - unlink(dstfile); - goto out_mmap; + return _recursive_rmdir_onedev(path, mystat.st_dev); } static int mount_fs(const char *source, const char *target, const char *type) @@ -142,14 +150,15 @@ return 0; } + /* continue even without posix message queue support */ if (mount_fs("mqueue", "/dev/mqueue", "mqueue")) - return -1; + INFO("failed to mount /dev/mqueue"); return 0; } /* borrowed from iproute2 */ -extern int get_u16(ushort *val, const char *arg, int base) +extern int get_u16(unsigned short *val, const char *arg, int base) { unsigned long res; char *ptr; @@ -166,30 +175,323 @@ return 0; } -extern int mkdir_p(char *dir, mode_t mode) +extern int mkdir_p(const char *dir, mode_t mode) +{ + const char *tmp = dir; + const char *orig = dir; + char *makeme; + + do { + dir = tmp + strspn(tmp, "/"); + tmp = dir + strcspn(dir, "/"); + makeme = strndup(orig, dir - orig); + if (*makeme) { + if (mkdir(makeme, mode) && errno != EEXIST) { + SYSERROR("failed to create directory '%s'\n", makeme); + free(makeme); + return -1; + } + } + free(makeme); + } while(tmp != dir); + + return 0; +} + +static char *copypath(char *p) +{ + int len = strlen(p); + char *retbuf; + + if (len < 1) + return NULL; + if (p[len-1] == '\n') { + p[len-1] = '\0'; + len--; + } + retbuf = malloc(len+1); + if (!retbuf) + return NULL; + strcpy(retbuf, p); + return retbuf; +} + +char *default_lxcpath; +#define DEFAULT_VG "lxc" +char *default_lvmvg; +#define DEFAULT_ZFSROOT "lxc" +char *default_zfsroot; + +const char *default_lvm_vg(void) +{ + char buf[1024], *p; + FILE *fin; + + if (default_lvmvg) + return default_lvmvg; + + fin = fopen(LXC_GLOBAL_CONF, "r"); + if (fin) { + while (fgets(buf, 1024, fin)) { + if (buf[0] == '#') + continue; + p = strstr(buf, "lvm_vg"); + if (!p) + continue; + p = strchr(p, '='); + if (!p) + continue; + p++; + while (*p && (*p == ' ' || *p == '\t')) p++; + if (!*p) + continue; + default_lvmvg = copypath(p); + goto out; + } + } + default_lvmvg = DEFAULT_VG; + +out: + if (fin) + fclose(fin); + return default_lvmvg; +} + +const char *default_zfs_root(void) +{ + char buf[1024], *p; + FILE *fin; + + if (default_zfsroot) + return default_zfsroot; + + fin = fopen(LXC_GLOBAL_CONF, "r"); + if (fin) { + while (fgets(buf, 1024, fin)) { + if (buf[0] == '#') + continue; + p = strstr(buf, "zfsroot"); + if (!p) + continue; + p = strchr(p, '='); + if (!p) + continue; + p++; + while (*p && (*p == ' ' || *p == '\t')) p++; + if (!*p) + continue; + default_zfsroot = copypath(p); + goto out; + } + } + default_zfsroot = DEFAULT_ZFSROOT; + +out: + if (fin) + fclose(fin); + return default_zfsroot; +} +const char *default_lxc_path(void) +{ + char buf[1024], *p; + FILE *fin; + + if (default_lxcpath) + return default_lxcpath; + + fin = fopen(LXC_GLOBAL_CONF, "r"); + if (fin) { + while (fgets(buf, 1024, fin)) { + if (buf[0] == '#') + continue; + p = strstr(buf, "lxcpath"); + if (!p) + continue; + p = strchr(p, '='); + if (!p) + continue; + p++; + while (*p && (*p == ' ' || *p == '\t')) p++; + if (!*p) + continue; + default_lxcpath = copypath(p); + goto out; + } + } + /* we couldn't open the file, or didn't find a lxcpath + * entry there. Return @LXCPATH@ */ + default_lxcpath = LXCPATH; + +out: + if (fin) + fclose(fin); + return default_lxcpath; +} + +int wait_for_pid(pid_t pid) +{ + int status, ret; + +again: + ret = waitpid(pid, &status, 0); + if (ret == -1) { + if (errno == EINTR) + goto again; + return -1; + } + if (ret != pid) + goto again; + if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) + return -1; + return 0; +} + +int lxc_wait_for_pid_status(pid_t pid) +{ + int status, ret; + +again: + ret = waitpid(pid, &status, 0); + if (ret == -1) { + if (errno == EINTR) + goto again; + return -1; + } + if (ret != pid) + goto again; + return status; +} + +ssize_t lxc_write_nointr(int fd, const void* buf, size_t count) +{ + ssize_t ret; +again: + ret = write(fd, buf, count); + if (ret < 0 && errno == EINTR) + goto again; + return ret; +} + +ssize_t lxc_read_nointr(int fd, void* buf, size_t count) +{ + ssize_t ret; +again: + ret = read(fd, buf, count); + if (ret < 0 && errno == EINTR) + goto again; + return ret; +} + +ssize_t lxc_read_nointr_expect(int fd, void* buf, size_t count, const void* expected_buf) +{ + ssize_t ret; + ret = lxc_read_nointr(fd, buf, count); + if (ret <= 0) + return ret; + if ((size_t)ret != count) + return -1; + if (expected_buf && memcmp(buf, expected_buf, count) != 0) { + errno = EINVAL; + return -1; + } + return ret; +} + +#if HAVE_LIBGNUTLS +#include +#include +int sha1sum_file(char *fnam, unsigned char *digest) { - int ret; - char *d; + char *buf; + int ret; + FILE *f; + long flen; - if (!strcmp(dir, "/")) - return 0; + if (!fnam) + return -1; + if ((f = fopen(fnam, "r")) < 0) { + SYSERROR("Error opening template"); + return -1; + } + if (fseek(f, 0, SEEK_END) < 0) { + SYSERROR("Error seeking to end of template"); + fclose(f); + return -1; + } + if ((flen = ftell(f)) < 0) { + SYSERROR("Error telling size of template"); + fclose(f); + return -1; + } + if (fseek(f, 0, SEEK_SET) < 0) { + SYSERROR("Error seeking to start of template"); + fclose(f); + return -1; + } + if ((buf = malloc(flen+1)) == NULL) { + SYSERROR("Out of memory"); + fclose(f); + return -1; + } + if (fread(buf, 1, flen, f) != flen) { + SYSERROR("Failure reading template"); + free(buf); + fclose(f); + return -1; + } + if (fclose(f) < 0) { + SYSERROR("Failre closing template"); + free(buf); + return -1; + } + buf[flen] = '\0'; + ret = gnutls_hash_fast(GNUTLS_DIG_SHA1, buf, flen, (void *)digest); + free(buf); + return ret; +} +#endif - d = strdup(dir); - if (!d) - return -1; +char** lxc_va_arg_list_to_argv(va_list ap, size_t skip, int do_strdup) +{ + va_list ap2; + size_t count = 1 + skip; + char **result; + + /* first determine size of argument list, we don't want to reallocate + * constantly... + */ + va_copy(ap2, ap); + while (1) { + char* arg = va_arg(ap2, char*); + if (!arg) + break; + count++; + } + va_end(ap2); - ret = mkdir_p(dirname(d), mode); - free(d); - if (ret) - return -1; + result = calloc(count, sizeof(char*)); + if (!result) + return NULL; + count = skip; + while (1) { + char* arg = va_arg(ap, char*); + if (!arg) + break; + arg = do_strdup ? strdup(arg) : arg; + if (!arg) + goto oom; + result[count++] = arg; + } - if (!access(dir, F_OK)) - return 0; + /* calloc has already set last element to NULL*/ + return result; - if (mkdir(dir, mode)) { - SYSERROR("failed to create directory '%s'\n", dir); - return -1; - } +oom: + free(result); + return NULL; +} - return 0; +const char** lxc_va_arg_list_to_argv_const(va_list ap, size_t skip) +{ + return (const char**)lxc_va_arg_list_to_argv(ap, skip, 0); } diff -Nru lxc-0.8.0~rc1/src/lxc/utils.h lxc-1.0.0~alpha1/src/lxc/utils.h --- lxc-0.8.0~rc1/src/lxc/utils.h 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/utils.h 2013-09-10 22:22:00.000000000 +0000 @@ -4,7 +4,7 @@ * (C) Copyright IBM Corp. 2007, 2008 * * Authors: - * Daniel Lezcano + * Daniel Lezcano * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,14 +18,178 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _utils_h #define _utils_h -extern int lxc_copy_file(const char *src, const char *dst); +#include +#include +#include +#include +#include +#include "config.h" + +/* returns 1 on success, 0 if there were any failures */ +extern int lxc_rmdir_onedev(char *path); extern int lxc_setup_fs(void); -extern int get_u16(ushort *val, const char *arg, int base); +extern int get_u16(unsigned short *val, const char *arg, int base); extern int mkdir_p(const char *dir, mode_t mode); +/* + * Return a newly allocated buffer containing the default container + * path. Caller must free this buffer. + */ +extern const char *default_lxc_path(void); +extern const char *default_zfs_root(void); +extern const char *default_lvm_vg(void); + +/* Define getline() if missing from the C library */ +#ifndef HAVE_GETLINE +#ifdef HAVE_FGETLN +#include <../include/getline.h> +#endif +#endif + +/* Define setns() if missing from the C library */ +#ifndef HAVE_SETNS +static inline int setns(int fd, int nstype) +{ +#ifdef __NR_setns + return syscall(__NR_setns, fd, nstype); +#else + errno = ENOSYS; + return -1; +#endif +} +#endif + +/* Define unshare() if missing from the C library */ +#ifndef HAVE_UNSHARE +static inline int unshare(int flags) +{ +#ifdef __NR_unshare + return syscall(__NR_unshare, flags); +#else + errno = ENOSYS; + return -1; +#endif +} +#else +int unshare(int); +#endif + +/* Define signalfd() if missing from the C library */ +#ifdef HAVE_SYS_SIGNALFD_H +# include +#else +/* assume kernel headers are too old */ +#include +struct signalfd_siginfo +{ + uint32_t ssi_signo; + int32_t ssi_errno; + int32_t ssi_code; + uint32_t ssi_pid; + uint32_t ssi_uid; + int32_t ssi_fd; + uint32_t ssi_tid; + uint32_t ssi_band; + uint32_t ssi_overrun; + uint32_t ssi_trapno; + int32_t ssi_status; + int32_t ssi_int; + uint64_t ssi_ptr; + uint64_t ssi_utime; + uint64_t ssi_stime; + uint64_t ssi_addr; + uint8_t __pad[48]; +}; + +# ifndef __NR_signalfd4 +/* assume kernel headers are too old */ +# if __i386__ +# define __NR_signalfd4 327 +# elif __x86_64__ +# define __NR_signalfd4 289 +# elif __powerpc__ +# define __NR_signalfd4 313 +# elif __s390x__ +# define __NR_signalfd4 322 +# elif __arm__ +# define __NR_signalfd4 355 +# endif +#endif + +# ifndef __NR_signalfd +/* assume kernel headers are too old */ +# if __i386__ +# define __NR_signalfd 321 +# elif __x86_64__ +# define __NR_signalfd 282 +# elif __powerpc__ +# define __NR_signalfd 305 +# elif __s390x__ +# define __NR_signalfd 316 +# elif __arm__ +# define __NR_signalfd 349 +# endif +#endif + +static inline int signalfd(int fd, const sigset_t *mask, int flags) +{ + int retval; + + retval = syscall (__NR_signalfd4, fd, mask, _NSIG / 8, flags); + if (errno == ENOSYS && flags == 0) + retval = syscall (__NR_signalfd, fd, mask, _NSIG / 8); + return retval; +} +#endif + + +/** + * BUILD_BUG_ON - break compile if a condition is true. + * @condition: the condition which the compiler should know is false. + * + * If you have some code which relies on certain constants being equal, or + * other compile-time-evaluated condition, you should use BUILD_BUG_ON to + * detect if someone changes it. + * + * The implementation uses gcc's reluctance to create a negative array, but + * gcc (as of 4.4) only emits that error for obvious cases (eg. not arguments + * to inline functions). So as a fallback we use the optimizer; if it can't + * prove the condition is false, it will cause a link error on the undefined + * "__build_bug_on_failed". This error message can be harder to track down + * though, hence the two different methods. + */ +#ifndef __OPTIMIZE__ +#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)])) +#else +extern int __build_bug_on_failed; +#define BUILD_BUG_ON(condition) \ + do { \ + ((void)sizeof(char[1 - 2*!!(condition)])); \ + if (condition) __build_bug_on_failed = 1; \ + } while(0) +#endif + +/* + * wait on a child we forked + */ +extern int wait_for_pid(pid_t pid); +extern int lxc_wait_for_pid_status(pid_t pid); + +/* send and receive buffers completely */ +extern ssize_t lxc_write_nointr(int fd, const void* buf, size_t count); +extern ssize_t lxc_read_nointr(int fd, void* buf, size_t count); +extern ssize_t lxc_read_nointr_expect(int fd, void* buf, size_t count, const void* expected_buf); +#if HAVE_LIBGNUTLS +#define SHA_DIGEST_LENGTH 20 +extern int sha1sum_file(char *fnam, unsigned char *md_value); +#endif + +/* convert variadic argument lists to arrays (for execl type argument lists) */ +extern char** lxc_va_arg_list_to_argv(va_list ap, size_t skip, int do_strdup); +extern const char** lxc_va_arg_list_to_argv_const(va_list ap, size_t skip); #endif diff -Nru lxc-0.8.0~rc1/src/lxc/utmp.c lxc-1.0.0~alpha1/src/lxc/utmp.c --- lxc-0.8.0~rc1/src/lxc/utmp.c 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/utmp.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,416 +0,0 @@ -/* - * lxc: linux Container library - * - * (C) Copyright IBM Corp. 2007, 2008 - * - * Authors: - * Daniel Lezcano - * - * 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 - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "conf.h" -#include "cgroup.h" -#include "start.h" -#include "mainloop.h" -#include "lxc.h" -#include "log.h" -#define __USE_GNU -#include -#undef __USE_GNU - -/* This file watches the /var/run/utmp file in the container - * (that should probably be configurable) - * We use inotify to put a watch on the /var/run directory for - * create and modify events. These can trigger a read of the - * utmp file looking for runlevel changes. If a runlevel change - * to reboot or halt states is detected, we set up an itimer to - * regularly check for the container shutdown, and reboot or halt - * as appropriate when we get down to 1 task remaining. - */ - -lxc_log_define(lxc_utmp, lxc); - -struct lxc_utmp { - struct lxc_handler *handler; -#define CONTAINER_STARTING 0 -#define CONTAINER_REBOOTING 1 -#define CONTAINER_HALTING 2 -#define CONTAINER_RUNNING 4 - char container_state; - int timer_fd; - int prev_runlevel, curr_runlevel; -}; - -typedef void (*lxc_mainloop_timer_t) (void *data); - -static int utmp_get_runlevel(struct lxc_utmp *utmp_data); -static int utmp_get_ntasks(struct lxc_handler *handler); -static int utmp_shutdown_handler(int fd, void *data, - struct lxc_epoll_descr *descr); -static int lxc_utmp_add_timer(struct lxc_epoll_descr *descr, - lxc_mainloop_callback_t callback, void *data); -static int lxc_utmp_del_timer(struct lxc_epoll_descr *descr, - struct lxc_utmp *utmp_data); - -static int utmp_handler(int fd, void *data, struct lxc_epoll_descr *descr) -{ - struct inotify_event *ie; - int size, ret, length; - - struct lxc_utmp *utmp_data = (struct lxc_utmp *)data; - - /* - * we're monitoring a directory. ie->name is not included in - * sizeof(struct inotify_event) if we don't read it all at once, - * read gives us EINVAL, so we read and cast to struct ie - */ - char buffer[MAXPATHLEN]; - - if (ioctl(fd, FIONREAD, &size) < 0) { - SYSERROR("cannot determine the size of this notification"); - return -1; - } - - if (read(fd, buffer, size) < 0) { - SYSERROR("failed to read notification"); - return -1; - } - - ie = (struct inotify_event *)buffer; - - if (ie->len <= 0) { - - if (ie->mask & IN_UNMOUNT) { - DEBUG("watched directory removed"); - goto out; - } - - SYSERROR("inotify event with no name (mask %d)", ie->mask); - return -1; - } - - ret = 0; - - DEBUG("got inotify event %d for %s", ie->mask, ie->name); - - length = (4 < ie->len) ? 4 : ie->len; - - /* only care about utmp */ - - if (strncmp(ie->name, "utmp", length)) - return 0; - - if (ie->mask & (IN_MODIFY | IN_CREATE)) - ret = utmp_get_runlevel(utmp_data); - - if (ret < 0) - goto out; - - /* container halting, from running or starting state */ - if (utmp_data->curr_runlevel == '0' - && ((utmp_data->container_state == CONTAINER_RUNNING) - || (utmp_data->container_state == CONTAINER_STARTING))) { - utmp_data->container_state = CONTAINER_HALTING; - if (utmp_data->timer_fd == -1) - lxc_utmp_add_timer(descr, utmp_shutdown_handler, data); - DEBUG("Container halting"); - goto out; - } - - /* container rebooting, from running or starting state */ - if (utmp_data->curr_runlevel == '6' - && ((utmp_data->container_state == CONTAINER_RUNNING) - || (utmp_data->container_state == CONTAINER_STARTING))) { - utmp_data->container_state = CONTAINER_REBOOTING; - if (utmp_data->timer_fd == -1) - lxc_utmp_add_timer(descr, utmp_shutdown_handler, data); - DEBUG("Container rebooting"); - goto out; - } - - /* normal operation, running, from starting state. */ - if (utmp_data->curr_runlevel > '0' && utmp_data->curr_runlevel < '6') { - utmp_data->container_state = CONTAINER_RUNNING; - if (utmp_data->timer_fd > 0) - lxc_utmp_del_timer(descr, utmp_data); - DEBUG("Container running"); - goto out; - } - -out: - return 0; -} - -static int utmp_get_runlevel(struct lxc_utmp *utmp_data) -{ - struct utmpx *utmpx; - char path[MAXPATHLEN]; - struct lxc_handler *handler = utmp_data->handler; - - if (snprintf(path, MAXPATHLEN, "/proc/%d/root/run/utmp", - handler->pid) > MAXPATHLEN) { - ERROR("path is too long"); - return -1; - } - - if (!access(path, F_OK) && !utmpxname(path)) - goto utmp_ok; - - if (snprintf(path, MAXPATHLEN, "/proc/%d/root/var/run/utmp", - handler->pid) > MAXPATHLEN) { - ERROR("path is too long"); - return -1; - } - - if (utmpxname(path)) { - SYSERROR("failed to 'utmpxname'"); - return -1; - } - -utmp_ok: - - setutxent(); - - while ((utmpx = getutxent())) { - - if (utmpx->ut_type == RUN_LVL) { - utmp_data->prev_runlevel = utmpx->ut_pid / 256; - utmp_data->curr_runlevel = utmpx->ut_pid % 256; - DEBUG("utmp handler - run level is %c/%c", - utmp_data->prev_runlevel, - utmp_data->curr_runlevel); - } - } - - endutxent(); - - return 0; -} - -static int utmp_get_ntasks(struct lxc_handler *handler) -{ - int ntasks; - - ntasks = lxc_cgroup_nrtasks(handler->name); - - if (ntasks < 0) { - ERROR("failed to get the number of tasks"); - return -1; - } - - DEBUG("there are %d tasks running", ntasks); - - return ntasks; -} - -int lxc_utmp_mainloop_add(struct lxc_epoll_descr *descr, - struct lxc_handler *handler) -{ - char path[MAXPATHLEN]; - char path2[MAXPATHLEN]; - int fd, wd; - struct lxc_utmp *utmp_data; - struct lxc_conf *conf = handler->conf; - - if (!conf->rootfs.path) - return 0; - - /* We set up a watch for the /var/run directory. We're only interested - * in utmp at the moment, but want to watch for delete and create - * events as well. - */ - if (snprintf(path, MAXPATHLEN, "/proc/%d/root/run", - handler->pid) > MAXPATHLEN) { - ERROR("path is too long"); - return -1; - } - if (snprintf(path2, MAXPATHLEN, "/proc/%d/root/run/utmp", - handler->pid) > MAXPATHLEN) { - ERROR("path is too long"); - return -1; - } - if (!access(path2, F_OK)) - goto run_ok; - - if (snprintf(path, MAXPATHLEN, "/proc/%d/root/var/run", - handler->pid) > MAXPATHLEN) { - ERROR("path is too long"); - return -1; - } - - if (access(path, F_OK)) { - WARN("'%s' not found", path); - return 0; - } - -run_ok: - - utmp_data = (struct lxc_utmp *)malloc(sizeof(struct lxc_utmp)); - - if (NULL == utmp_data) { - SYSERROR("failed to malloc handler utmp_data"); - return -1; - } - - memset(utmp_data, 0, sizeof(struct lxc_utmp)); - - fd = inotify_init(); - if (fd < 0) { - SYSERROR("failed to inotify_init"); - goto out; - } - - if (fcntl(fd, F_SETFD, FD_CLOEXEC)) { - SYSERROR("failed to set inotify fd to close-on-exec"); - goto out_close; - - } - - wd = inotify_add_watch(fd, path, IN_MODIFY | IN_CREATE); - if (wd < 0) { - SYSERROR("failed to add watch for '%s'", path); - goto out_close; - } - - utmp_data->handler = handler; - utmp_data->container_state = CONTAINER_STARTING; - utmp_data->timer_fd = -1; - utmp_data->prev_runlevel = 'N'; - utmp_data->curr_runlevel = 'N'; - - if (lxc_mainloop_add_handler - (descr, fd, utmp_handler, (void *)utmp_data)) { - SYSERROR("failed to add mainloop"); - goto out_close; - } - - DEBUG("Added '%s' to inotifywatch", path); - - return 0; -out_close: - close(fd); -out: - free(utmp_data); - return -1; -} - -static int utmp_shutdown_handler(int fd, void *data, - struct lxc_epoll_descr *descr) -{ - int ntasks; - ssize_t nread; - struct lxc_utmp *utmp_data = (struct lxc_utmp *)data; - struct lxc_handler *handler = utmp_data->handler; - struct lxc_conf *conf = handler->conf; - uint64_t expirations; - - /* read and clear notifications */ - nread = read(fd, &expirations, sizeof(expirations)); - if (nread < 0) - SYSERROR("Failed to read timer notification"); - - ntasks = utmp_get_ntasks(handler); - - if (ntasks == 1 && (utmp_data->container_state == CONTAINER_HALTING)) { - INFO("container has shutdown"); - /* shutdown timer */ - lxc_utmp_del_timer(descr, utmp_data); - - kill(handler->pid, SIGKILL); - } - - if (ntasks == 1 && (utmp_data->container_state == CONTAINER_REBOOTING)) { - INFO("container has rebooted"); - conf->reboot = 1; - /* shutdown timer */ - lxc_utmp_del_timer(descr, utmp_data); - /* this seems a bit rough. */ - kill(handler->pid, SIGKILL); - } - return 0; - -} - -int lxc_utmp_add_timer(struct lxc_epoll_descr *descr, - lxc_mainloop_callback_t callback, void *data) -{ - int fd, result; - struct itimerspec timeout; - struct lxc_utmp *utmp_data = (struct lxc_utmp *)data; - - fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC); - if (fd < 0) { - SYSERROR("failed to create timer"); - return -1; - } - - DEBUG("Setting up utmp shutdown timer"); - - /* set a one second timeout. Repeated. */ - timeout.it_value.tv_sec = 1; - timeout.it_value.tv_nsec = 0; - - timeout.it_interval.tv_sec = 1; - timeout.it_interval.tv_nsec = 0; - - result = timerfd_settime(fd, 0, &timeout, NULL); - - if (result < 0) { - SYSERROR("timerfd_settime:"); - return -1; - } - - if (lxc_mainloop_add_handler(descr, fd, callback, utmp_data)) { - SYSERROR("failed to add utmp timer to mainloop"); - close(fd); - return -1; - } - - utmp_data->timer_fd = fd; - - return 0; -} - -int lxc_utmp_del_timer(struct lxc_epoll_descr *descr, - struct lxc_utmp *utmp_data) -{ - int result; - - DEBUG("Clearing utmp shutdown timer"); - - result = lxc_mainloop_del_handler(descr, utmp_data->timer_fd); - if (result < 0) - SYSERROR("failed to del utmp timer from mainloop"); - - /* shutdown timer_fd */ - close(utmp_data->timer_fd); - utmp_data->timer_fd = -1; - - if (result < 0) - return -1; - else - return 0; -} diff -Nru lxc-0.8.0~rc1/src/lxc/utmp.h lxc-1.0.0~alpha1/src/lxc/utmp.h --- lxc-0.8.0~rc1/src/lxc/utmp.h 2011-12-11 22:36:28.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/utmp.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,28 +0,0 @@ -/* - * lxc: linux Container library - * - * (C) Copyright IBM Corp. 2007, 2008 - * - * Authors: - * Daniel Lezcano - * - * 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 - */ - -struct lxc_handler; -struct lxc_epoll_descr; - -int lxc_utmp_mainloop_add(struct lxc_epoll_descr *descr, - struct lxc_handler *handler); diff -Nru lxc-0.8.0~rc1/src/lxc/version.c lxc-1.0.0~alpha1/src/lxc/version.c --- lxc-0.8.0~rc1/src/lxc/version.c 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/version.c 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,29 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "../config.h" + +const char const* lxc_version(void) +{ + return PACKAGE_VERSION; +} diff -Nru lxc-0.8.0~rc1/src/lxc/version.h lxc-1.0.0~alpha1/src/lxc/version.h --- lxc-0.8.0~rc1/src/lxc/version.h 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/lxc/version.h 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,31 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef _version_h +#define _version_h + +/* + * Returns the version number of the library + */ +extern const char const *lxc_version(void); + +#endif diff -Nru lxc-0.8.0~rc1/src/python-lxc/Makefile.am lxc-1.0.0~alpha1/src/python-lxc/Makefile.am --- lxc-0.8.0~rc1/src/python-lxc/Makefile.am 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/python-lxc/Makefile.am 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,27 @@ +if ENABLE_PYTHON + +if HAVE_DEBIAN + DISTSETUPOPTS=--install-layout=deb +else + DISTSETUPOPTS= +endif + +all: + CFLAGS="$(CFLAGS) -I ../../src -L../../src/lxc/" $(PYTHON) setup.py build + +install: + if [ "$(DESTDIR)" = "" ]; then \ + $(PYTHON) setup.py install --prefix=$(prefix) --no-compile $(DISTSETUPOPTS); \ + else \ + $(PYTHON) setup.py install --root=$(DESTDIR) --prefix=$(prefix) --no-compile $(DISTSETUPOPTS); \ + fi + +clean-local: + rm -rf build + +endif +EXTRA_DIST = \ + setup.py \ + lxc.c \ + lxc/__init__.py \ + examples/api_test.py diff -Nru lxc-0.8.0~rc1/src/python-lxc/Makefile.in lxc-1.0.0~alpha1/src/python-lxc/Makefile.in --- lxc-0.8.0~rc1/src/python-lxc/Makefile.in 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/python-lxc/Makefile.in 2013-09-10 22:30:09.000000000 +0000 @@ -0,0 +1,462 @@ +# Makefile.in generated by automake 1.13.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = src/python-lxc +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/src/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +APPARMOR_LIBS = @APPARMOR_LIBS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BINDIR = @BINDIR@ +CAP_LIBS = @CAP_LIBS@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIR = @DATADIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DOCDIR = @DOCDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GREP = @GREP@ +INCLUDEDIR = @INCLUDEDIR@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBDIR = @LIBDIR@ +LIBEXECDIR = @LIBEXECDIR@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LOCALSTATEDIR = @LOCALSTATEDIR@ +LOGPATH = @LOGPATH@ +LTLIBOBJS = @LTLIBOBJS@ +LUA_CFLAGS = @LUA_CFLAGS@ +LUA_INSTALL_CMOD = @LUA_INSTALL_CMOD@ +LUA_INSTALL_LMOD = @LUA_INSTALL_LMOD@ +LUA_LIBS = @LUA_LIBS@ +LUA_VERSION = @LUA_VERSION@ +LXCHOOKDIR = @LXCHOOKDIR@ +LXCINITDIR = @LXCINITDIR@ +LXCPATH = @LXCPATH@ +LXCROOTFSMOUNT = @LXCROOTFSMOUNT@ +LXCTEMPLATEDIR = @LXCTEMPLATEDIR@ +LXC_DEFAULT_CONFIG = @LXC_DEFAULT_CONFIG@ +LXC_DISTRO_CONF = @LXC_DISTRO_CONF@ +LXC_GENERATE_DATE = @LXC_GENERATE_DATE@ +LXC_GLOBAL_CONF = @LXC_GLOBAL_CONF@ +LXC_USERNIC_CONF = @LXC_USERNIC_CONF@ +LXC_USERNIC_DB = @LXC_USERNIC_DB@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +NEWUIDMAP = @NEWUIDMAP@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PREFIX = @PREFIX@ +PYTHON = @PYTHON@ +PYTHONDEV_CFLAGS = @PYTHONDEV_CFLAGS@ +PYTHONDEV_LIBS = @PYTHONDEV_LIBS@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +SECCOMP_LIBS = @SECCOMP_LIBS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SYSCONFDIR = @SYSCONFDIR@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +db2xman = @db2xman@ +docdir = @docdir@ +docdtd = @docdtd@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +@ENABLE_PYTHON_TRUE@@HAVE_DEBIAN_FALSE@DISTSETUPOPTS = +@ENABLE_PYTHON_TRUE@@HAVE_DEBIAN_TRUE@DISTSETUPOPTS = --install-layout=deb +EXTRA_DIST = \ + setup.py \ + lxc.c \ + lxc/__init__.py \ + examples/api_test.py + +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/python-lxc/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/python-lxc/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +tags TAGS: + +ctags CTAGS: + +cscope cscopelist: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile +installdirs: +@ENABLE_PYTHON_FALSE@install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +@ENABLE_PYTHON_FALSE@clean-local: +clean: clean-am + +clean-am: clean-generic clean-local mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic clean-local \ + cscopelist-am ctags-am distclean distclean-generic distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ + pdf-am ps ps-am tags-am uninstall uninstall-am + + +@ENABLE_PYTHON_TRUE@all: +@ENABLE_PYTHON_TRUE@ CFLAGS="$(CFLAGS) -I ../../src -L../../src/lxc/" $(PYTHON) setup.py build + +@ENABLE_PYTHON_TRUE@install: +@ENABLE_PYTHON_TRUE@ if [ "$(DESTDIR)" = "" ]; then \ +@ENABLE_PYTHON_TRUE@ $(PYTHON) setup.py install --prefix=$(prefix) --no-compile $(DISTSETUPOPTS); \ +@ENABLE_PYTHON_TRUE@ else \ +@ENABLE_PYTHON_TRUE@ $(PYTHON) setup.py install --root=$(DESTDIR) --prefix=$(prefix) --no-compile $(DISTSETUPOPTS); \ +@ENABLE_PYTHON_TRUE@ fi + +@ENABLE_PYTHON_TRUE@clean-local: +@ENABLE_PYTHON_TRUE@ rm -rf build + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff -Nru lxc-0.8.0~rc1/src/python-lxc/examples/api_test.py lxc-1.0.0~alpha1/src/python-lxc/examples/api_test.py --- lxc-0.8.0~rc1/src/python-lxc/examples/api_test.py 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/python-lxc/examples/api_test.py 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,165 @@ +#!/usr/bin/python3 +# +# api_test.py: Test/demo of the python3-lxc API +# +# (C) Copyright Canonical Ltd. 2012 +# +# Authors: +# Stéphane Graber +# +# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# + +import warnings +warnings.filterwarnings("ignore", "The python-lxc API isn't yet stable") + +import lxc +import uuid +import sys +import time + +# Some constants +LXC_TEMPLATE = "ubuntu" + +# Let's pick a random name, avoiding clashes +CONTAINER_NAME = str(uuid.uuid1()) +CLONE_NAME = str(uuid.uuid1()) + +## Instantiate the container instance +print("Getting instance for '%s'" % CONTAINER_NAME) +container = lxc.Container(CONTAINER_NAME) + +# A few basic checks of the current state +assert(container.config_file_name == "%s/%s/config" % + (lxc.default_config_path, CONTAINER_NAME)) +assert(not container.defined) +assert(container.init_pid == -1) +assert(container.name == CONTAINER_NAME) +assert(not container.running) +assert(container.state == "STOPPED") + +## Create a rootfs +print("Creating rootfs using '%s'" % LXC_TEMPLATE) +container.create(LXC_TEMPLATE) + +assert(container.defined) +assert(container.name == CONTAINER_NAME + == container.get_config_item("lxc.utsname")) +assert(container.name in lxc.list_containers()) + +## Test the config +print("Testing the configuration") +capdrop = container.get_config_item("lxc.cap.drop") +container.clear_config_item("lxc.cap.drop") +container.set_config_item("lxc.cap.drop", capdrop[:-1]) +container.append_config_item("lxc.cap.drop", capdrop[-1]) +container.save_config() + +# A few basic checks of the current state +assert(isinstance(capdrop, list)) +assert(capdrop == container.get_config_item("lxc.cap.drop")) + +## Test the networking +print("Testing the networking") + +# A few basic checks of the current state +assert("name" in container.get_keys("lxc.network.0")) +assert(len(container.network) == 1) +assert(container.network[0].hwaddr.startswith("00:16:3e")) + +## Starting the container +print("Starting the container") +container.start() +container.wait("RUNNING", 3) + +# A few basic checks of the current state +assert(container.init_pid > 1) +assert(container.running) +assert(container.state == "RUNNING") + +## Checking IP address +print("Getting the IP addresses") + +count = 0 +ips = [] +while not ips or count == 10: + ips = container.get_ips() + time.sleep(1) + count += 1 +container.attach_wait(lxc.attach_run_command, ["ifconfig", "eth0"], + namespaces=(lxc.CLONE_NEWNET + lxc.CLONE_NEWUTS)) + +# A few basic checks of the current state +assert(len(ips) > 0) + +## Testing cgroups a bit +print("Testing cgroup API") +max_mem = container.get_cgroup_item("memory.max_usage_in_bytes") +current_limit = container.get_cgroup_item("memory.limit_in_bytes") +assert(container.set_cgroup_item("memory.limit_in_bytes", max_mem)) +assert(container.get_cgroup_item("memory.limit_in_bytes") != current_limit) + +## Freezing the container +print("Freezing the container") +container.freeze() +container.wait("FROZEN", 3) + +# A few basic checks of the current state +assert(container.init_pid > 1) +assert(container.running) +assert(container.state == "FROZEN") + +## Unfreezing the container +print("Unfreezing the container") +container.unfreeze() +container.wait("RUNNING", 3) + +# A few basic checks of the current state +assert(container.init_pid > 1) +assert(container.running) +assert(container.state == "RUNNING") + +if len(sys.argv) > 1 and sys.argv[1] == "--with-console": + ## Attaching to tty1 + print("Attaching to tty1") + container.console(tty=1) + +## Shutting down the container +print("Shutting down the container") +container.shutdown(3) + +if container.running: + print("Stopping the container") + container.stop() + container.wait("STOPPED", 3) + +# A few basic checks of the current state +assert(container.init_pid == -1) +assert(not container.running) +assert(container.state == "STOPPED") + +## Cloning the container +print("Cloning the container") +clone = lxc.Container(CLONE_NAME) +clone.clone(container) +clone.start() +clone.stop() +clone.destroy() + +## Destroy the container +print("Destroying the container") +container.destroy() + +assert(not container.defined) diff -Nru lxc-0.8.0~rc1/src/python-lxc/lxc/__init__.py lxc-1.0.0~alpha1/src/python-lxc/lxc/__init__.py --- lxc-0.8.0~rc1/src/python-lxc/lxc/__init__.py 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/python-lxc/lxc/__init__.py 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,475 @@ +# +# python-lxc: Python bindings for LXC +# +# (C) Copyright Canonical Ltd. 2012 +# +# Authors: +# Stéphane Graber +# +# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# + +import _lxc +import glob +import os +import subprocess +import stat +import time +import warnings + +warnings.warn("The python-lxc API isn't yet stable " + "and may change at any point in the future.", Warning, 2) + +default_config_path = _lxc.get_default_config_path() +version = _lxc.get_version() + + +class ContainerNetwork(): + props = {} + + def __init__(self, container, index): + self.container = container + self.index = index + + for key in self.container.get_keys("lxc.network.%s" % self.index): + if "." in key: + self.props[key.replace(".", "_")] = key + else: + self.props[key] = key + + if not self.props: + return False + + def __delattr__(self, key): + if key in ["container", "index", "props"]: + return object.__delattr__(self, key) + + if key not in self.props: + raise AttributeError("'%s' network has no attribute '%s'" % ( + self.__get_network_item("type"), key)) + + return self.__clear_network_item(self.props[key]) + + def __dir__(self): + return sorted(self.props.keys()) + + def __getattr__(self, key): + if key in ["container", "index", "props"]: + return object.__getattribute__(self, key) + + if key not in self.props: + raise AttributeError("'%s' network has no attribute '%s'" % ( + self.__get_network_item("type"), key)) + + return self.__get_network_item(self.props[key]) + + def __hasattr__(self, key): + if key in ["container", "index", "props"]: + return object.__hasattr__(self, key) + + if key not in self.props: + raise AttributeError("'%s' network has no attribute '%s'" % ( + self.__get_network_item("type"), key)) + + return True + + def __repr__(self): + return "'%s' network at index '%s'" % ( + self.__get_network_item("type"), self.index) + + def __setattr__(self, key, value): + if key in ["container", "index", "props"]: + return object.__setattr__(self, key, value) + + if key not in self.props: + raise AttributeError("'%s' network has no attribute '%s'" % ( + self.__get_network_item("type"), key)) + + return self.__set_network_item(self.props[key], value) + + def __clear_network_item(self, key): + return self.container.clear_config_item("lxc.network.%s.%s" % ( + self.index, key)) + + def __get_network_item(self, key): + return self.container.get_config_item("lxc.network.%s.%s" % ( + self.index, key)) + + def __set_network_item(self, key, value): + return self.container.set_config_item("lxc.network.%s.%s" % ( + self.index, key), value) + + +class ContainerNetworkList(): + def __init__(self, container): + self.container = container + + def __getitem__(self, index): + if index >= len(self): + raise IndexError("list index out of range") + + return ContainerNetwork(self.container, index) + + def __len__(self): + values = self.container.get_config_item("lxc.network") + + if values: + return len(values) + else: + return 0 + + def add(self, network_type): + index = len(self) + + return self.container.set_config_item("lxc.network.%s.type" % index, + network_type) + + def remove(self, index): + count = len(self) + if index >= count: + raise IndexError("list index out of range") + + return self.container.clear_config_item("lxc.network.%s" % index) + + +class Container(_lxc.Container): + def __init__(self, name, config_path=None): + """ + Creates a new Container instance. + """ + + if os.geteuid() != 0: + raise Exception("Running as non-root.") + + if config_path: + _lxc.Container.__init__(self, name, config_path) + else: + _lxc.Container.__init__(self, name) + + self.network = ContainerNetworkList(self) + + def add_device_node(self, path, destpath=None): + """ + Add block/char device to running container. + """ + + if not self.running: + return False + + if not destpath: + destpath = path + + if not os.path.exists(path): + return False + + # Lookup the source + path_stat = os.stat(path) + mode = stat.S_IMODE(path_stat.st_mode) + + # Allow the target + if stat.S_ISBLK(path_stat.st_mode): + self.set_cgroup_item("devices.allow", + "b %s:%s rwm" % + (int(path_stat.st_rdev / 256), + int(path_stat.st_rdev % 256))) + elif stat.S_ISCHR(path_stat.st_mode): + self.set_cgroup_item("devices.allow", + "c %s:%s rwm" % + (int(path_stat.st_rdev / 256), + int(path_stat.st_rdev % 256))) + + # Create the target + rootfs = "/proc/%s/root/" % self.init_pid + container_path = "%s/%s" % (rootfs, destpath) + + if os.path.exists(container_path): + os.remove(container_path) + + os.mknod(container_path, path_stat.st_mode, path_stat.st_rdev) + os.chmod(container_path, mode) + os.chown(container_path, 0, 0) + + return True + + def add_device_net(self, name, destname=None): + """ + Add network device to running container. + """ + + if not self.running: + return False + + if not destname: + destname = name + + if not os.path.exists("/sys/class/net/%s/" % name): + return False + + return subprocess.call(['ip', 'link', 'set', + 'dev', name, + 'netns', str(self.init_pid), + 'name', destname]) == 0 + + def append_config_item(self, key, value): + """ + Append 'value' to 'key', assuming 'key' is a list. + If 'key' isn't a list, 'value' will be set as the value of 'key'. + """ + + return _lxc.Container.set_config_item(self, key, value) + + def create(self, template, args={}): + """ + Create a new rootfs for the container. + + "template" must be a valid template name. + + "args" (optional) is a dictionary of parameters and values to pass + to the template. + """ + + template_args = [] + for item in args.items(): + template_args.append("--%s" % item[0]) + template_args.append("%s" % item[1]) + + return _lxc.Container.create(self, template, tuple(template_args)) + + def clone(self, container): + """ + Clone an existing container into a new one. + """ + + if self.defined: + return False + + if isinstance(container, Container): + source = container + else: + source = Container(container) + + if not source.defined: + return False + + if subprocess.call(["lxc-clone", "-o", source.name, "-n", self.name], + universal_newlines=True) != 0: + return False + + self.load_config() + return True + + def console(self, ttynum=-1, stdinfd=0, stdoutfd=1, stderrfd=2, escape=1): + """ + Attach to console of running container. + """ + + if not self.running: + return False + + return _lxc.Container.console(self, ttynum, stdinfd, stdoutfd, + stderrfd, escape) + + def console_getfd(self, ttynum=-1): + """ + Attach to console of running container. + """ + + if not self.running: + return False + + return _lxc.Container.console_getfd(self, ttynum) + + def get_cgroup_item(self, key): + """ + Returns the value for a given cgroup entry. + A list is returned when multiple values are set. + """ + value = _lxc.Container.get_cgroup_item(self, key) + + if value is False: + return False + else: + return value.rstrip("\n") + + def get_config_item(self, key): + """ + Returns the value for a given config key. + A list is returned when multiple values are set. + """ + value = _lxc.Container.get_config_item(self, key) + + if value is False: + return False + elif value.endswith("\n"): + return value.rstrip("\n").split("\n") + else: + return value + + def get_keys(self, key=None): + """ + Returns a list of valid sub-keys. + """ + if key: + value = _lxc.Container.get_keys(self, key) + else: + value = _lxc.Container.get_keys(self) + + if value is False: + return False + elif value.endswith("\n"): + return value.rstrip("\n").split("\n") + else: + return value + + def get_ips(self, interface=None, family=None, scope=None, timeout=0): + """ + Get a tuple of IPs for the container. + """ + + kwargs = {} + if interface: + kwargs['interface'] = interface + if family: + kwargs['family'] = family + if scope: + kwargs['scope'] = scope + + ips = None + timeout = int(os.environ.get('LXC_GETIP_TIMEOUT', timeout)) + + while not ips: + ips = _lxc.Container.get_ips(self, **kwargs) + if timeout == 0: + break + + timeout -= 1 + time.sleep(1) + + return ips + + def set_config_item(self, key, value): + """ + Set a config key to a provided value. + The value can be a list for the keys supporting multiple values. + """ + try: + old_value = self.get_config_item(key) + except KeyError: + old_value = None + + # Check if it's a list + def set_key(key, value): + self.clear_config_item(key) + if isinstance(value, list): + for entry in value: + if not _lxc.Container.set_config_item(self, key, entry): + return False + else: + _lxc.Container.set_config_item(self, key, value) + + set_key(key, value) + new_value = self.get_config_item(key) + + if (isinstance(value, str) and isinstance(new_value, str) and + value == new_value): + return True + elif (isinstance(value, list) and isinstance(new_value, list) and + set(value) == set(new_value)): + return True + elif (isinstance(value, str) and isinstance(new_value, list) and + set([value]) == set(new_value)): + return True + elif old_value: + set_key(key, old_value) + return False + else: + self.clear_config_item(key) + return False + + def wait(self, state, timeout=-1): + """ + Wait for the container to reach a given state or timeout. + """ + + if isinstance(state, str): + state = state.upper() + + return _lxc.Container.wait(self, state, timeout) + + +def list_containers(as_object=False, config_path=None): + """ + List the containers on the system. + """ + + if not config_path: + config_path = default_config_path + + containers = [] + for entry in glob.glob("%s/*/config" % config_path): + if as_object: + containers.append(Container(entry.split("/")[-2], config_path)) + else: + containers.append(entry.split("/")[-2]) + return containers + +def attach_run_command(cmd): + """ + Run a command when attaching + + Please do not call directly, this will execvp the command. + This is to be used in conjunction with the attach method + of a container. + """ + if isinstance(cmd, tuple): + return _lxc.attach_run_command(cmd) + elif isinstance(cmd, list): + return _lxc.attach_run_command((cmd[0], cmd)) + else: + return _lxc.attach_run_command((cmd, [cmd])) + +def attach_run_shell(): + """ + Run a shell when attaching + + Please do not call directly, this will execvp the shell. + This is to be used in conjunction with the attach method + of a container. + """ + return _lxc.attach_run_shell(None) + +def arch_to_personality(arch): + """ + Determine the process personality corresponding to the architecture + """ + if isinstance(arch, bytes): + arch = str(arch, 'utf-8') + return _lxc.arch_to_personality(arch) + +# Some constants for attach +LXC_ATTACH_KEEP_ENV = _lxc.LXC_ATTACH_KEEP_ENV +LXC_ATTACH_CLEAR_ENV = _lxc.LXC_ATTACH_CLEAR_ENV +LXC_ATTACH_MOVE_TO_CGROUP = _lxc.LXC_ATTACH_MOVE_TO_CGROUP +LXC_ATTACH_DROP_CAPABILITIES = _lxc.LXC_ATTACH_DROP_CAPABILITIES +LXC_ATTACH_SET_PERSONALITY = _lxc.LXC_ATTACH_SET_PERSONALITY +LXC_ATTACH_APPARMOR = _lxc.LXC_ATTACH_APPARMOR +LXC_ATTACH_REMOUNT_PROC_SYS = _lxc.LXC_ATTACH_REMOUNT_PROC_SYS +LXC_ATTACH_DEFAULT = _lxc.LXC_ATTACH_DEFAULT +CLONE_NEWUTS = _lxc.CLONE_NEWUTS +CLONE_NEWIPC = _lxc.CLONE_NEWIPC +CLONE_NEWUSER = _lxc.CLONE_NEWUSER +CLONE_NEWPID = _lxc.CLONE_NEWPID +CLONE_NEWNET = _lxc.CLONE_NEWNET +CLONE_NEWNS = _lxc.CLONE_NEWNS diff -Nru lxc-0.8.0~rc1/src/python-lxc/lxc.c lxc-1.0.0~alpha1/src/python-lxc/lxc.c --- lxc-0.8.0~rc1/src/python-lxc/lxc.c 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/python-lxc/lxc.c 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,1238 @@ +/* + * python-lxc: Python bindings for LXC + * + * (C) Copyright Canonical Ltd. 2012-2013 + * + * Authors: + * Stéphane Graber + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include "structmember.h" +#include +#include +#include +#include +#include +#include + +typedef struct { + PyObject_HEAD + struct lxc_container *container; +} Container; + +char** +convert_tuple_to_char_pointer_array(PyObject *argv) { + int argc; + int i, j; + + /* not a list or tuple */ + if (!PyList_Check(argv) && !PyTuple_Check(argv)) { + PyErr_SetString(PyExc_TypeError, "Expected list or tuple."); + return NULL; + } + + argc = PySequence_Fast_GET_SIZE(argv); + + char **result = (char**) calloc(argc + 1, sizeof(char*)); + + if (result == NULL) { + PyErr_SetNone(PyExc_MemoryError); + return NULL; + } + + for (i = 0; i < argc; i++) { + PyObject *pyobj = PySequence_Fast_GET_ITEM(argv, i); + assert(pyobj != NULL); + + char *str = NULL; + PyObject *pystr = NULL; + + if (!PyUnicode_Check(pyobj)) { + PyErr_SetString(PyExc_ValueError, "Expected a string"); + goto error; + } + + pystr = PyUnicode_AsUTF8String(pyobj); + if (!pystr) { + /* Maybe it wasn't UTF-8 encoded. An exception is already set. */ + goto error; + } + + str = PyBytes_AsString(pystr); + if (!str) { + /* Maybe pystr wasn't a valid object. An exception is already set. + */ + Py_DECREF(pystr); + goto error; + } + + /* We must make a copy of str, because it points into internal memory + * which we do not own. Assume it's NULL terminated, otherwise we'd + * have to use PyUnicode_AsUTF8AndSize() and be explicit about copying + * the memory. + */ + result[i] = strdup(str); + + /* Do not decref pyobj since we stole a reference by using + * PyTuple_GET_ITEM(). + */ + Py_DECREF(pystr); + if (result[i] == NULL) { + PyErr_SetNone(PyExc_MemoryError); + goto error; + } + } + + result[argc] = NULL; + return result; + +error: + /* We can only iterate up to but not including i because malloc() does not + * initialize its memory. Thus if we got here, i points to the index + * after the last strdup'd entry in result. + */ + for (j = 0; j < i; j++) + free(result[j]); + free(result); + return NULL; +} + +static void +Container_dealloc(Container* self) +{ + lxc_container_put(self->container); + Py_TYPE(self)->tp_free((PyObject*)self); +} + +static PyObject * +Container_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + Container *self; + + self = (Container *)type->tp_alloc(type, 0); + + return (PyObject *)self; +} + +static int +Container_init(Container *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"name", "config_path", NULL}; + char *name = NULL; + PyObject *fs_config_path = NULL; + char *config_path = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|O&", kwlist, + &name, + PyUnicode_FSConverter, &fs_config_path)) + return -1; + + if (fs_config_path != NULL) { + config_path = PyBytes_AS_STRING(fs_config_path); + assert(config_path != NULL); + } + + self->container = lxc_container_new(name, config_path); + if (!self->container) { + Py_XDECREF(fs_config_path); + fprintf(stderr, "%d: error creating container %s\n", __LINE__, name); + return -1; + } + + Py_XDECREF(fs_config_path); + return 0; +} + +static PyObject * +LXC_get_default_config_path(PyObject *self, PyObject *args) +{ + return PyUnicode_FromString(lxc_get_default_config_path()); +} + +static PyObject * +LXC_get_version(PyObject *self, PyObject *args) +{ + return PyUnicode_FromString(lxc_get_version()); +} + +// Container properties +static PyObject * +Container_config_file_name(Container *self, void *closure) +{ + return PyUnicode_FromString( + self->container->config_file_name(self->container)); +} + +static PyObject * +Container_defined(Container *self, void *closure) +{ + if (self->container->is_defined(self->container)) { + Py_RETURN_TRUE; + } + + Py_RETURN_FALSE; +} + +static PyObject * +Container_init_pid(Container *self, void *closure) +{ + return PyLong_FromLong(self->container->init_pid(self->container)); +} + +static PyObject * +Container_name(Container *self, void *closure) +{ + return PyUnicode_FromString(self->container->name); +} + +static PyObject * +Container_running(Container *self, void *closure) +{ + if (self->container->is_running(self->container)) { + Py_RETURN_TRUE; + } + + Py_RETURN_FALSE; +} + +static PyObject * +Container_state(Container *self, void *closure) +{ + return PyUnicode_FromString(self->container->state(self->container)); +} + +// Container Functions +static PyObject * +Container_clear_config_item(Container *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"key", NULL}; + char *key = NULL; + + if (! PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist, + &key)) + return NULL; + + if (self->container->clear_config_item(self->container, key)) { + Py_RETURN_TRUE; + } + + Py_RETURN_FALSE; +} + +static PyObject * +Container_create(Container *self, PyObject *args, PyObject *kwds) +{ + char* template_name = NULL; + char** create_args = {NULL}; + PyObject *retval = NULL, *vargs = NULL; + int i = 0; + static char *kwlist[] = {"template", "args", NULL}; + + if (! PyArg_ParseTupleAndKeywords(args, kwds, "s|O", kwlist, + &template_name, &vargs)) + return NULL; + + if (vargs) { + if (PyTuple_Check(vargs)) { + create_args = convert_tuple_to_char_pointer_array(vargs); + if (!create_args) { + return NULL; + } + } + else { + PyErr_SetString(PyExc_ValueError, "args needs to be a tuple"); + return NULL; + } + } + + if (self->container->create(self->container, template_name, NULL, NULL, 0, create_args)) + retval = Py_True; + else + retval = Py_False; + + if (vargs) { + /* We cannot have gotten here unless vargs was given and create_args + * was successfully allocated. + */ + for (i = 0; i < PyTuple_GET_SIZE(vargs); i++) + free(create_args[i]); + free(create_args); + } + + Py_INCREF(retval); + return retval; +} + +static PyObject * +Container_destroy(Container *self, PyObject *args, PyObject *kwds) +{ + if (self->container->destroy(self->container)) { + Py_RETURN_TRUE; + } + + Py_RETURN_FALSE; +} + +static PyObject * +Container_freeze(Container *self, PyObject *args, PyObject *kwds) +{ + if (self->container->freeze(self->container)) { + Py_RETURN_TRUE; + } + + Py_RETURN_FALSE; +} + +static PyObject * +Container_get_cgroup_item(Container *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"key", NULL}; + char* key = NULL; + int len = 0; + PyObject *ret = NULL; + + if (! PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist, + &key)) + return NULL; + + len = self->container->get_cgroup_item(self->container, key, NULL, 0); + + if (len < 0) { + PyErr_SetString(PyExc_KeyError, "Invalid cgroup entry"); + return NULL; + } + + char* value = (char*) malloc(sizeof(char)*len + 1); + if (value == NULL) + return PyErr_NoMemory(); + + if (self->container->get_cgroup_item(self->container, + key, value, len + 1) != len) { + PyErr_SetString(PyExc_ValueError, "Unable to read config value"); + free(value); + return NULL; + } + + ret = PyUnicode_FromString(value); + free(value); + return ret; +} + +static PyObject * +Container_get_config_item(Container *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"key", NULL}; + char* key = NULL; + int len = 0; + PyObject *ret = NULL; + + if (! PyArg_ParseTupleAndKeywords(args, kwds, "s|", kwlist, + &key)) + return NULL; + + len = self->container->get_config_item(self->container, key, NULL, 0); + + if (len < 0) { + PyErr_SetString(PyExc_KeyError, "Invalid configuration key"); + return NULL; + } + + char* value = (char*) malloc(sizeof(char)*len + 1); + if (value == NULL) + return PyErr_NoMemory(); + + if (self->container->get_config_item(self->container, + key, value, len + 1) != len) { + PyErr_SetString(PyExc_ValueError, "Unable to read config value"); + free(value); + return NULL; + } + + ret = PyUnicode_FromString(value); + free(value); + return ret; +} + +static PyObject * +Container_get_config_path(Container *self, PyObject *args, PyObject *kwds) +{ + return PyUnicode_FromString( + self->container->get_config_path(self->container)); +} + +static PyObject * +Container_get_keys(Container *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"key", NULL}; + char* key = NULL; + int len = 0; + PyObject *ret = NULL; + + if (! PyArg_ParseTupleAndKeywords(args, kwds, "|s", kwlist, + &key)) + return NULL; + + len = self->container->get_keys(self->container, key, NULL, 0); + + if (len < 0) { + PyErr_SetString(PyExc_KeyError, "Invalid configuration key"); + return NULL; + } + + char* value = (char*) malloc(sizeof(char)*len + 1); + if (value == NULL) + return PyErr_NoMemory(); + + if (self->container->get_keys(self->container, + key, value, len + 1) != len) { + PyErr_SetString(PyExc_ValueError, "Unable to read config keys"); + free(value); + return NULL; + } + + ret = PyUnicode_FromString(value); + free(value); + return ret; +} + +static PyObject * +Container_get_ips(Container *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"interface", "family", "scope", NULL}; + char* interface = NULL; + char* family = NULL; + int scope = 0; + + int i = 0; + char** ips = NULL; + + PyObject* ret; + + if (! PyArg_ParseTupleAndKeywords(args, kwds, "|ssi", kwlist, + &interface, &family, &scope)) + return NULL; + + /* Get the IPs */ + ips = self->container->get_ips(self->container, interface, family, scope); + if (!ips) + return PyTuple_New(0); + + /* Count the entries */ + while (ips[i]) + i++; + + /* Create the new tuple */ + ret = PyTuple_New(i); + if (!ret) + return NULL; + + /* Add the entries to the tuple and free the memory */ + i = 0; + while (ips[i]) { + PyObject *unicode = PyUnicode_FromString(ips[i]); + if (!unicode) { + Py_DECREF(ret); + ret = NULL; + break; + } + PyTuple_SET_ITEM(ret, i, unicode); + i++; + } + + /* Free the list of IPs */ + i = 0; + while (ips[i]) { + free(ips[i]); + i++; + } + free(ips); + + return ret; +} + +static PyObject * +Container_load_config(Container *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"path", NULL}; + PyObject *fs_path = NULL; + char* path = NULL; + + if (! PyArg_ParseTupleAndKeywords(args, kwds, "|O&", kwlist, + PyUnicode_FSConverter, &fs_path)) + return NULL; + + if (fs_path != NULL) { + path = PyBytes_AS_STRING(fs_path); + assert(path != NULL); + } + + if (self->container->load_config(self->container, path)) { + Py_XDECREF(fs_path); + Py_RETURN_TRUE; + } + + Py_XDECREF(fs_path); + Py_RETURN_FALSE; +} + +static PyObject * +Container_save_config(Container *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"path", NULL}; + PyObject *fs_path = NULL; + char* path = NULL; + + if (! PyArg_ParseTupleAndKeywords(args, kwds, "|O&", kwlist, + PyUnicode_FSConverter, &fs_path)) + return NULL; + + if (fs_path != NULL) { + path = PyBytes_AS_STRING(fs_path); + assert(path != NULL); + } + + if (self->container->save_config(self->container, path)) { + Py_XDECREF(fs_path); + Py_RETURN_TRUE; + } + + Py_XDECREF(fs_path); + Py_RETURN_FALSE; +} + +static PyObject * +Container_set_cgroup_item(Container *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"key", "value", NULL}; + char *key = NULL; + char *value = NULL; + + if (! PyArg_ParseTupleAndKeywords(args, kwds, "ss", kwlist, + &key, &value)) + return NULL; + + if (self->container->set_cgroup_item(self->container, key, value)) { + Py_RETURN_TRUE; + } + + Py_RETURN_FALSE; +} + +static PyObject * +Container_set_config_item(Container *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"key", "value", NULL}; + char *key = NULL; + char *value = NULL; + + if (! PyArg_ParseTupleAndKeywords(args, kwds, "ss", kwlist, + &key, &value)) + return NULL; + + if (self->container->set_config_item(self->container, key, value)) { + Py_RETURN_TRUE; + } + + Py_RETURN_FALSE; +} + +static PyObject * +Container_set_config_path(Container *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"path", NULL}; + char *path = NULL; + + if (! PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist, + &path)) + return NULL; + + if (self->container->set_config_path(self->container, path)) { + Py_RETURN_TRUE; + } + + Py_RETURN_FALSE; +} + +static PyObject * +Container_shutdown(Container *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"timeout", NULL}; + int timeout = -1; + + if (! PyArg_ParseTupleAndKeywords(args, kwds, "|i", kwlist, + &timeout)) + return NULL; + + if (self->container->shutdown(self->container, timeout)) { + Py_RETURN_TRUE; + } + + Py_RETURN_FALSE; +} + +static PyObject * +Container_start(Container *self, PyObject *args, PyObject *kwds) +{ + char** init_args = {NULL}; + PyObject *useinit = NULL, *retval = NULL, *vargs = NULL; + int init_useinit = 0, i = 0; + static char *kwlist[] = {"useinit", "cmd", NULL}; + + if (! PyArg_ParseTupleAndKeywords(args, kwds, "|OO", kwlist, + &useinit, &vargs)) + return NULL; + + if (useinit && useinit == Py_True) { + init_useinit = 1; + } + + if (vargs && PyTuple_Check(vargs)) { + init_args = convert_tuple_to_char_pointer_array(vargs); + if (!init_args) { + return NULL; + } + } + + self->container->want_daemonize(self->container); + + if (self->container->start(self->container, init_useinit, init_args)) + retval = Py_True; + else + retval = Py_False; + + if (vargs) { + /* We cannot have gotten here unless vargs was given and create_args + * was successfully allocated. + */ + for (i = 0; i < PyTuple_GET_SIZE(vargs); i++) + free(init_args[i]); + free(init_args); + } + + Py_INCREF(retval); + return retval; +} + +static PyObject * +Container_stop(Container *self, PyObject *args, PyObject *kwds) +{ + if (self->container->stop(self->container)) { + Py_RETURN_TRUE; + } + + Py_RETURN_FALSE; +} + +static PyObject * +Container_unfreeze(Container *self, PyObject *args, PyObject *kwds) +{ + if (self->container->unfreeze(self->container)) { + Py_RETURN_TRUE; + } + + Py_RETURN_FALSE; +} + +static PyObject * +Container_console(Container *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"ttynum", "stdinfd", "stdoutfd", "stderrfd", "escape", NULL}; + int ttynum = -1, stdinfd = 0, stdoutfd = 1, stderrfd = 2, escape = 1; + + if (! PyArg_ParseTupleAndKeywords(args, kwds, "|iiiii", kwlist, + &ttynum, &stdinfd, &stdoutfd, &stderrfd, + &escape)) + return NULL; + + if (self->container->console(self->container, ttynum, + stdinfd, stdoutfd, stderrfd, escape) == 0) { + Py_RETURN_TRUE; + } + Py_RETURN_FALSE; +} + +static PyObject * +Container_console_getfd(Container *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"ttynum", NULL}; + int ttynum = -1, masterfd; + + if (! PyArg_ParseTupleAndKeywords(args, kwds, "|i", kwlist, &ttynum)) + return NULL; + + if (self->container->console_getfd(self->container, &ttynum, &masterfd) < 0) { + PyErr_SetString(PyExc_ValueError, "Unable to allocate tty"); + return NULL; + } + return PyLong_FromLong(masterfd); +} + +static PyObject * +Container_wait(Container *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"state", "timeout", NULL}; + char *state = NULL; + int timeout = -1; + + if (! PyArg_ParseTupleAndKeywords(args, kwds, "s|i", kwlist, + &state, &timeout)) + return NULL; + + if (self->container->wait(self->container, state, timeout)) { + Py_RETURN_TRUE; + } + + Py_RETURN_FALSE; +} + +struct lxc_attach_python_payload { + PyObject *fn; + PyObject *arg; +}; + +static int lxc_attach_python_exec(void* _payload) +{ + struct lxc_attach_python_payload *payload = (struct lxc_attach_python_payload *)_payload; + PyObject *result = PyObject_CallFunctionObjArgs(payload->fn, payload->arg, NULL); + + if (!result) { + PyErr_Print(); + return -1; + } + if (PyLong_Check(result)) + return (int)PyLong_AsLong(result); + else + return -1; +} + +static void lxc_attach_free_options(lxc_attach_options_t *options); + +static lxc_attach_options_t *lxc_attach_parse_options(PyObject *kwds) +{ + static char *kwlist[] = {"attach_flags", "namespaces", "personality", "initial_cwd", "uid", "gid", "env_policy", "extra_env_vars", "extra_keep_env", "stdin", "stdout", "stderr", NULL}; + long temp_uid, temp_gid; + int temp_env_policy; + PyObject *extra_env_vars_obj = NULL; + PyObject *extra_keep_env_obj = NULL; + PyObject *stdin_obj = NULL; + PyObject *stdout_obj = NULL; + PyObject *stderr_obj = NULL; + PyObject *initial_cwd_obj = NULL; + PyObject *dummy; + bool parse_result; + + lxc_attach_options_t default_options = LXC_ATTACH_OPTIONS_DEFAULT; + lxc_attach_options_t *options = malloc(sizeof(*options)); + + if (!options) { + PyErr_SetNone(PyExc_MemoryError); + return NULL; + } + memcpy(options, &default_options, sizeof(*options)); + + /* we need some dummy variables because we can't be sure + * the data types match completely */ + temp_uid = -1; + temp_gid = -1; + temp_env_policy = options->env_policy; + + /* we need a dummy tuple */ + dummy = PyTuple_New(0); + + parse_result = PyArg_ParseTupleAndKeywords(dummy, kwds, "|iilO&lliOOOOO", kwlist, + &options->attach_flags, &options->namespaces, &options->personality, + PyUnicode_FSConverter, &initial_cwd_obj, &temp_uid, &temp_gid, + &temp_env_policy, &extra_env_vars_obj, &extra_keep_env_obj, + &stdin_obj, &stdout_obj, &stderr_obj); + + /* immediately get rid of the dummy tuple */ + Py_DECREF(dummy); + + if (!parse_result) { + lxc_attach_free_options(options); + return NULL; + } + + /* duplicate the string, so we don't depend on some random Python object */ + if (initial_cwd_obj != NULL) { + options->initial_cwd = strndup(PyBytes_AsString(initial_cwd_obj), PyBytes_Size(initial_cwd_obj)); + Py_DECREF(initial_cwd_obj); + } + + /* do the type conversion from the types that match the parse string */ + if (temp_uid != -1) options->uid = (uid_t)temp_uid; + if (temp_gid != -1) options->gid = (gid_t)temp_gid; + options->env_policy = (lxc_attach_env_policy_t)temp_env_policy; + + if (extra_env_vars_obj) + options->extra_env_vars = convert_tuple_to_char_pointer_array(extra_env_vars_obj); + if (extra_keep_env_obj) + options->extra_keep_env = convert_tuple_to_char_pointer_array(extra_keep_env_obj); + if (stdin_obj) { + options->stdin_fd = PyObject_AsFileDescriptor(stdin_obj); + if (options->stdin_fd < 0) { + lxc_attach_free_options(options); + return NULL; + } + } + if (stdout_obj) { + options->stdout_fd = PyObject_AsFileDescriptor(stdout_obj); + if (options->stdout_fd < 0) { + lxc_attach_free_options(options); + return NULL; + } + } + if (stderr_obj) { + options->stderr_fd = PyObject_AsFileDescriptor(stderr_obj); + if (options->stderr_fd < 0) { + lxc_attach_free_options(options); + return NULL; + } + } + + return options; +} + +void lxc_attach_free_options(lxc_attach_options_t *options) +{ + int i; + if (!options) + return; + if (options->initial_cwd) + free(options->initial_cwd); + if (options->extra_env_vars) { + for (i = 0; options->extra_env_vars[i]; i++) + free(options->extra_env_vars[i]); + free(options->extra_env_vars); + } + if (options->extra_keep_env) { + for (i = 0; options->extra_keep_env[i]; i++) + free(options->extra_keep_env[i]); + free(options->extra_keep_env); + } + free(options); +} + +static PyObject * +Container_attach_and_possibly_wait(Container *self, PyObject *args, PyObject *kwds, int wait) +{ + struct lxc_attach_python_payload payload = { NULL, NULL }; + lxc_attach_options_t *options = NULL; + long ret; + pid_t pid; + + if (!PyArg_ParseTuple(args, "O|O", &payload.fn, &payload.arg)) + return NULL; + if (!PyCallable_Check(payload.fn)) { + PyErr_Format(PyExc_TypeError, "attach: object not callable"); + return NULL; + } + + options = lxc_attach_parse_options(kwds); + if (!options) + return NULL; + + ret = self->container->attach(self->container, lxc_attach_python_exec, &payload, options, &pid); + if (ret < 0) + goto out; + + if (wait) { + ret = lxc_wait_for_pid_status(pid); + /* handle case where attach fails */ + if (WIFEXITED(ret) && WEXITSTATUS(ret) == 255) + ret = -1; + } else { + ret = (long)pid; + } + +out: + lxc_attach_free_options(options); + return PyLong_FromLong(ret); +} + +static PyObject * +Container_attach(Container *self, PyObject *args, PyObject *kwds) +{ + return Container_attach_and_possibly_wait(self, args, kwds, 0); +} + +static PyObject * +Container_attach_wait(Container *self, PyObject *args, PyObject *kwds) +{ + return Container_attach_and_possibly_wait(self, args, kwds, 1); +} + +static PyObject * +LXC_attach_run_shell(PyObject *self, PyObject *arg) +{ + int rv; + + rv = lxc_attach_run_shell(NULL); + + return PyLong_FromLong(rv); +} + +static PyObject * +LXC_arch_to_personality(PyObject *self, PyObject *arg) +{ + long rv = -1; + PyObject *pystr; + char *str; + + if (!PyUnicode_Check(arg)) { + PyErr_SetString(PyExc_ValueError, "Expected a string"); + return NULL; + } + + pystr = PyUnicode_AsUTF8String(arg); + if (!pystr) + return NULL; + + str = PyBytes_AsString(pystr); + if (!str) + goto out; + + rv = lxc_config_parse_arch(str); + if (rv == -1) + PyErr_SetString(PyExc_KeyError, "Failed to lookup architecture."); + +out: + Py_DECREF(pystr); + return rv == -1 ? NULL : PyLong_FromLong(rv); +} + +static PyObject * +LXC_attach_run_command(PyObject *self, PyObject *arg) +{ + PyObject *args_obj = NULL; + int i, rv; + lxc_attach_command_t cmd = { + NULL, /* program */ + NULL /* argv[] */ + }; + + if (!PyArg_ParseTuple(arg, "sO", (const char**)&cmd.program, &args_obj)) + return NULL; + if (args_obj && PyList_Check(args_obj)) { + cmd.argv = convert_tuple_to_char_pointer_array(args_obj); + } else { + PyErr_Format(PyExc_TypeError, "Second part of tuple passed to attach_run_command must be a list."); + return NULL; + } + + if (!cmd.argv) + return NULL; + + rv = lxc_attach_run_command(&cmd); + + for (i = 0; cmd.argv[i]; i++) + free(cmd.argv[i]); + free(cmd.argv); + + return PyLong_FromLong(rv); +} + +static PyGetSetDef Container_getseters[] = { + {"config_file_name", + (getter)Container_config_file_name, NULL, + "Path to the container configuration", + NULL}, + {"defined", + (getter)Container_defined, NULL, + "Boolean indicating whether the container configuration exists", + NULL}, + {"init_pid", + (getter)Container_init_pid, NULL, + "PID of the container's init process in the host's PID namespace", + NULL}, + {"name", + (getter)Container_name, NULL, + "Container name", + NULL}, + {"running", + (getter)Container_running, NULL, + "Boolean indicating whether the container is running or not", + NULL}, + {"state", + (getter)Container_state, NULL, + "Container state", + NULL}, + {NULL, NULL, NULL, NULL, NULL} +}; + +static PyMethodDef Container_methods[] = { + {"clear_config_item", (PyCFunction)Container_clear_config_item, + METH_VARARGS|METH_KEYWORDS, + "clear_config_item(key) -> boolean\n" + "\n" + "Clear the current value of a config key." + }, + {"create", (PyCFunction)Container_create, + METH_VARARGS|METH_KEYWORDS, + "create(template, args = (,)) -> boolean\n" + "\n" + "Create a new rootfs for the container, using the given template " + "and passing some optional arguments to it." + }, + {"destroy", (PyCFunction)Container_destroy, + METH_NOARGS, + "destroy() -> boolean\n" + "\n" + "Destroys the container." + }, + {"freeze", (PyCFunction)Container_freeze, + METH_NOARGS, + "freeze() -> boolean\n" + "\n" + "Freezes the container and returns its return code." + }, + {"get_cgroup_item", (PyCFunction)Container_get_cgroup_item, + METH_VARARGS|METH_KEYWORDS, + "get_cgroup_item(key) -> string\n" + "\n" + "Get the current value of a cgroup entry." + }, + {"get_config_item", (PyCFunction)Container_get_config_item, + METH_VARARGS|METH_KEYWORDS, + "get_config_item(key) -> string\n" + "\n" + "Get the current value of a config key." + }, + {"get_config_path", (PyCFunction)Container_get_config_path, + METH_NOARGS, + "get_config_path() -> string\n" + "\n" + "Return the LXC config path (where the containers are stored)." + }, + {"get_keys", (PyCFunction)Container_get_keys, + METH_VARARGS|METH_KEYWORDS, + "get_keys(key) -> string\n" + "\n" + "Get a list of valid sub-keys for a key." + }, + {"get_ips", (PyCFunction)Container_get_ips, + METH_VARARGS|METH_KEYWORDS, + "get_ips(interface, family, scope) -> tuple\n" + "\n" + "Get a tuple of IPs for the container." + }, + {"load_config", (PyCFunction)Container_load_config, + METH_VARARGS|METH_KEYWORDS, + "load_config(path = DEFAULT) -> boolean\n" + "\n" + "Read the container configuration from its default " + "location or from an alternative location if provided." + }, + {"save_config", (PyCFunction)Container_save_config, + METH_VARARGS|METH_KEYWORDS, + "save_config(path = DEFAULT) -> boolean\n" + "\n" + "Save the container configuration to its default " + "location or to an alternative location if provided." + }, + {"set_cgroup_item", (PyCFunction)Container_set_cgroup_item, + METH_VARARGS|METH_KEYWORDS, + "set_cgroup_item(key, value) -> boolean\n" + "\n" + "Set a cgroup entry to the provided value." + }, + {"set_config_item", (PyCFunction)Container_set_config_item, + METH_VARARGS|METH_KEYWORDS, + "set_config_item(key, value) -> boolean\n" + "\n" + "Set a config key to the provided value." + }, + {"set_config_path", (PyCFunction)Container_set_config_path, + METH_VARARGS|METH_KEYWORDS, + "set_config_path(path) -> boolean\n" + "\n" + "Set the LXC config path (where the containers are stored)." + }, + {"shutdown", (PyCFunction)Container_shutdown, + METH_VARARGS|METH_KEYWORDS, + "shutdown(timeout = -1) -> boolean\n" + "\n" + "Sends SIGPWR to the container and wait for it to shutdown " + "unless timeout is set to a positive value, in which case " + "the container will be killed when the timeout is reached." + }, + {"start", (PyCFunction)Container_start, + METH_VARARGS|METH_KEYWORDS, + "start(useinit = False, cmd = (,)) -> boolean\n" + "\n" + "Start the container, optionally using lxc-init and " + "an alternate init command, then returns its return code." + }, + {"stop", (PyCFunction)Container_stop, + METH_NOARGS, + "stop() -> boolean\n" + "\n" + "Stop the container and returns its return code." + }, + {"unfreeze", (PyCFunction)Container_unfreeze, + METH_NOARGS, + "unfreeze() -> boolean\n" + "\n" + "Unfreezes the container and returns its return code." + }, + {"wait", (PyCFunction)Container_wait, + METH_VARARGS|METH_KEYWORDS, + "wait(state, timeout = -1) -> boolean\n" + "\n" + "Wait for the container to reach a given state or timeout." + }, + {"console", (PyCFunction)Container_console, + METH_VARARGS|METH_KEYWORDS, + "console(ttynum = -1, stdinfd = 0, stdoutfd = 1, stderrfd = 2, escape = 0) -> boolean\n" + "\n" + "Attach to container's console." + }, + {"console_getfd", (PyCFunction)Container_console_getfd, + METH_VARARGS|METH_KEYWORDS, + "console(ttynum = -1) -> boolean\n" + "\n" + "Attach to container's console." + }, + {"attach", (PyCFunction)Container_attach, + METH_VARARGS|METH_KEYWORDS, + "attach(run, payload) -> int\n" + "\n" + "Attach to the container. Returns the pid of the attached process." + }, + {"attach_wait", (PyCFunction)Container_attach_wait, + METH_VARARGS|METH_KEYWORDS, + "attach(run, payload) -> int\n" + "\n" + "Attach to the container. Returns the exit code of the process." + }, + {NULL, NULL, 0, NULL} +}; + +static PyTypeObject _lxc_ContainerType = { +PyVarObject_HEAD_INIT(NULL, 0) + "lxc.Container", /* tp_name */ + sizeof(Container), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)Container_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | + Py_TPFLAGS_BASETYPE, /* tp_flags */ + "Container objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + Container_methods, /* tp_methods */ + 0, /* tp_members */ + Container_getseters, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)Container_init, /* tp_init */ + 0, /* tp_alloc */ + Container_new, /* tp_new */ +}; + +static PyMethodDef LXC_methods[] = { + {"attach_run_shell", (PyCFunction)LXC_attach_run_shell, METH_O, + "Starts up a shell when attaching, to use as the run parameter for attach or attach_wait"}, + {"attach_run_command", (PyCFunction)LXC_attach_run_command, METH_O, + "Runs a command when attaching, to use as the run parameter for attach or attach_wait"}, + {"arch_to_personality", (PyCFunction)LXC_arch_to_personality, METH_O, + "Returns the process personality of the corresponding architecture"}, + {"get_default_config_path", (PyCFunction)LXC_get_default_config_path, METH_NOARGS, + "Returns the current LXC config path"}, + {"get_version", (PyCFunction)LXC_get_version, METH_NOARGS, + "Returns the current LXC library version"}, + {NULL, NULL, 0, NULL} +}; + +static PyModuleDef _lxcmodule = { + PyModuleDef_HEAD_INIT, + "_lxc", + "Binding for liblxc in python", + -1, + LXC_methods +}; + +PyMODINIT_FUNC +PyInit__lxc(void) +{ + PyObject* m; + PyObject* d; + + if (PyType_Ready(&_lxc_ContainerType) < 0) + return NULL; + + m = PyModule_Create(&_lxcmodule); + if (m == NULL) + return NULL; + + Py_INCREF(&_lxc_ContainerType); + PyModule_AddObject(m, "Container", (PyObject *)&_lxc_ContainerType); + + /* add constants */ + d = PyModule_GetDict(m); + + #define PYLXC_EXPORT_CONST(c) PyDict_SetItemString(d, #c, PyLong_FromLong(c)) + + /* environment variable handling */ + PYLXC_EXPORT_CONST(LXC_ATTACH_KEEP_ENV); + PYLXC_EXPORT_CONST(LXC_ATTACH_CLEAR_ENV); + + /* attach options */ + PYLXC_EXPORT_CONST(LXC_ATTACH_MOVE_TO_CGROUP); + PYLXC_EXPORT_CONST(LXC_ATTACH_DROP_CAPABILITIES); + PYLXC_EXPORT_CONST(LXC_ATTACH_SET_PERSONALITY); + PYLXC_EXPORT_CONST(LXC_ATTACH_APPARMOR); + PYLXC_EXPORT_CONST(LXC_ATTACH_REMOUNT_PROC_SYS); + PYLXC_EXPORT_CONST(LXC_ATTACH_DEFAULT); + + /* namespace flags (no other python lib exports this) */ + PYLXC_EXPORT_CONST(CLONE_NEWUTS); + PYLXC_EXPORT_CONST(CLONE_NEWIPC); + PYLXC_EXPORT_CONST(CLONE_NEWUSER); + PYLXC_EXPORT_CONST(CLONE_NEWPID); + PYLXC_EXPORT_CONST(CLONE_NEWNET); + PYLXC_EXPORT_CONST(CLONE_NEWNS); + + #undef PYLXC_EXPORT_CONST + + return m; +} + +/* + * kate: space-indent on; indent-width 4; mixedindent off; indent-mode cstyle; + */ diff -Nru lxc-0.8.0~rc1/src/python-lxc/setup.py lxc-1.0.0~alpha1/src/python-lxc/setup.py --- lxc-0.8.0~rc1/src/python-lxc/setup.py 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/python-lxc/setup.py 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,33 @@ +#!/usr/bin/python3 +# +# python-lxc: Python bindings for LXC +# +# (C) Copyright Canonical Ltd. 2012 +# +# Authors: +# Stéphane Graber +# +# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +from distutils.core import setup, Extension + +module = Extension('_lxc', sources=['lxc.c'], libraries=['lxc']) + +setup(name='_lxc', + version='0.1', + description='LXC', + packages=['lxc'], + package_dir={'lxc': 'lxc'}, + ext_modules=[module]) diff -Nru lxc-0.8.0~rc1/src/tests/Makefile.am lxc-1.0.0~alpha1/src/tests/Makefile.am --- lxc-0.8.0~rc1/src/tests/Makefile.am 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/tests/Makefile.am 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,51 @@ +if ENABLE_TESTS + +LDADD = ../lxc/liblxc.so + +lxc_test_containertests_SOURCES = containertests.c +lxc_test_locktests_SOURCES = locktests.c +lxc_test_startone_SOURCES = startone.c +lxc_test_destroytest_SOURCES = destroytest.c +lxc_test_saveconfig_SOURCES = saveconfig.c +lxc_test_createtest_SOURCES = createtest.c +lxc_test_shutdowntest_SOURCES = shutdowntest.c +lxc_test_get_item_SOURCES = get_item.c +lxc_test_getkeys_SOURCES = getkeys.c +lxc_test_lxcpath_SOURCES = lxcpath.c +lxc_test_cgpath_SOURCES = cgpath.c +lxc_test_clonetest_SOURCES = clonetest.c +lxc_test_console_SOURCES = console.c +lxc_usernic_test_SOURCES = ../lxc/lxc_user_nic.c ../lxc/nl.c +lxc_usernic_test_CFLAGS = -DISTEST + +AM_CFLAGS=-I$(top_srcdir)/src \ + -DLXCROOTFSMOUNT=\"$(LXCROOTFSMOUNT)\" \ + -DLXCPATH=\"$(LXCPATH)\" \ + -DLXC_GLOBAL_CONF=\"$(LXC_GLOBAL_CONF)\" \ + -DLXCINITDIR=\"$(LXCINITDIR)\" \ + -DLXC_DEFAULT_CONFIG=\"$(LXC_DEFAULT_CONFIG)\" + +bin_PROGRAMS = lxc-test-containertests lxc-test-locktests lxc-test-startone \ + lxc-test-destroytest lxc-test-saveconfig lxc-test-createtest \ + lxc-test-shutdowntest lxc-test-get_item lxc-test-getkeys lxc-test-lxcpath \ + lxc-test-cgpath lxc-test-clonetest lxc-test-console lxc-usernic-test + +bin_SCRIPTS = lxc-test-usernic + +endif + +EXTRA_DIST = \ + cgpath.c \ + containertests.c \ + createtest.c \ + destroytest.c \ + get_item.c \ + getkeys.c \ + locktests.c \ + lxcpath.c \ + saveconfig.c \ + shutdowntest.c \ + clonetest.c \ + startone.c \ + console.c \ + lxc-test-usernic diff -Nru lxc-0.8.0~rc1/src/tests/Makefile.in lxc-1.0.0~alpha1/src/tests/Makefile.in --- lxc-0.8.0~rc1/src/tests/Makefile.in 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/tests/Makefile.in 2013-09-10 22:30:10.000000000 +0000 @@ -0,0 +1,940 @@ +# Makefile.in generated by automake 1.13.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + +VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@ENABLE_TESTS_TRUE@bin_PROGRAMS = lxc-test-containertests$(EXEEXT) \ +@ENABLE_TESTS_TRUE@ lxc-test-locktests$(EXEEXT) \ +@ENABLE_TESTS_TRUE@ lxc-test-startone$(EXEEXT) \ +@ENABLE_TESTS_TRUE@ lxc-test-destroytest$(EXEEXT) \ +@ENABLE_TESTS_TRUE@ lxc-test-saveconfig$(EXEEXT) \ +@ENABLE_TESTS_TRUE@ lxc-test-createtest$(EXEEXT) \ +@ENABLE_TESTS_TRUE@ lxc-test-shutdowntest$(EXEEXT) \ +@ENABLE_TESTS_TRUE@ lxc-test-get_item$(EXEEXT) \ +@ENABLE_TESTS_TRUE@ lxc-test-getkeys$(EXEEXT) \ +@ENABLE_TESTS_TRUE@ lxc-test-lxcpath$(EXEEXT) \ +@ENABLE_TESTS_TRUE@ lxc-test-cgpath$(EXEEXT) \ +@ENABLE_TESTS_TRUE@ lxc-test-clonetest$(EXEEXT) \ +@ENABLE_TESTS_TRUE@ lxc-test-console$(EXEEXT) \ +@ENABLE_TESTS_TRUE@ lxc-usernic-test$(EXEEXT) +subdir = src/tests +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(top_srcdir)/config/depcomp +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/src/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)" +PROGRAMS = $(bin_PROGRAMS) +am__lxc_test_cgpath_SOURCES_DIST = cgpath.c +@ENABLE_TESTS_TRUE@am_lxc_test_cgpath_OBJECTS = cgpath.$(OBJEXT) +lxc_test_cgpath_OBJECTS = $(am_lxc_test_cgpath_OBJECTS) +lxc_test_cgpath_LDADD = $(LDADD) +@ENABLE_TESTS_TRUE@lxc_test_cgpath_DEPENDENCIES = ../lxc/liblxc.so +am__lxc_test_clonetest_SOURCES_DIST = clonetest.c +@ENABLE_TESTS_TRUE@am_lxc_test_clonetest_OBJECTS = \ +@ENABLE_TESTS_TRUE@ clonetest.$(OBJEXT) +lxc_test_clonetest_OBJECTS = $(am_lxc_test_clonetest_OBJECTS) +lxc_test_clonetest_LDADD = $(LDADD) +@ENABLE_TESTS_TRUE@lxc_test_clonetest_DEPENDENCIES = ../lxc/liblxc.so +am__lxc_test_console_SOURCES_DIST = console.c +@ENABLE_TESTS_TRUE@am_lxc_test_console_OBJECTS = console.$(OBJEXT) +lxc_test_console_OBJECTS = $(am_lxc_test_console_OBJECTS) +lxc_test_console_LDADD = $(LDADD) +@ENABLE_TESTS_TRUE@lxc_test_console_DEPENDENCIES = ../lxc/liblxc.so +am__lxc_test_containertests_SOURCES_DIST = containertests.c +@ENABLE_TESTS_TRUE@am_lxc_test_containertests_OBJECTS = \ +@ENABLE_TESTS_TRUE@ containertests.$(OBJEXT) +lxc_test_containertests_OBJECTS = \ + $(am_lxc_test_containertests_OBJECTS) +lxc_test_containertests_LDADD = $(LDADD) +@ENABLE_TESTS_TRUE@lxc_test_containertests_DEPENDENCIES = \ +@ENABLE_TESTS_TRUE@ ../lxc/liblxc.so +am__lxc_test_createtest_SOURCES_DIST = createtest.c +@ENABLE_TESTS_TRUE@am_lxc_test_createtest_OBJECTS = \ +@ENABLE_TESTS_TRUE@ createtest.$(OBJEXT) +lxc_test_createtest_OBJECTS = $(am_lxc_test_createtest_OBJECTS) +lxc_test_createtest_LDADD = $(LDADD) +@ENABLE_TESTS_TRUE@lxc_test_createtest_DEPENDENCIES = \ +@ENABLE_TESTS_TRUE@ ../lxc/liblxc.so +am__lxc_test_destroytest_SOURCES_DIST = destroytest.c +@ENABLE_TESTS_TRUE@am_lxc_test_destroytest_OBJECTS = \ +@ENABLE_TESTS_TRUE@ destroytest.$(OBJEXT) +lxc_test_destroytest_OBJECTS = $(am_lxc_test_destroytest_OBJECTS) +lxc_test_destroytest_LDADD = $(LDADD) +@ENABLE_TESTS_TRUE@lxc_test_destroytest_DEPENDENCIES = \ +@ENABLE_TESTS_TRUE@ ../lxc/liblxc.so +am__lxc_test_get_item_SOURCES_DIST = get_item.c +@ENABLE_TESTS_TRUE@am_lxc_test_get_item_OBJECTS = get_item.$(OBJEXT) +lxc_test_get_item_OBJECTS = $(am_lxc_test_get_item_OBJECTS) +lxc_test_get_item_LDADD = $(LDADD) +@ENABLE_TESTS_TRUE@lxc_test_get_item_DEPENDENCIES = ../lxc/liblxc.so +am__lxc_test_getkeys_SOURCES_DIST = getkeys.c +@ENABLE_TESTS_TRUE@am_lxc_test_getkeys_OBJECTS = getkeys.$(OBJEXT) +lxc_test_getkeys_OBJECTS = $(am_lxc_test_getkeys_OBJECTS) +lxc_test_getkeys_LDADD = $(LDADD) +@ENABLE_TESTS_TRUE@lxc_test_getkeys_DEPENDENCIES = ../lxc/liblxc.so +am__lxc_test_locktests_SOURCES_DIST = locktests.c +@ENABLE_TESTS_TRUE@am_lxc_test_locktests_OBJECTS = \ +@ENABLE_TESTS_TRUE@ locktests.$(OBJEXT) +lxc_test_locktests_OBJECTS = $(am_lxc_test_locktests_OBJECTS) +lxc_test_locktests_LDADD = $(LDADD) +@ENABLE_TESTS_TRUE@lxc_test_locktests_DEPENDENCIES = ../lxc/liblxc.so +am__lxc_test_lxcpath_SOURCES_DIST = lxcpath.c +@ENABLE_TESTS_TRUE@am_lxc_test_lxcpath_OBJECTS = lxcpath.$(OBJEXT) +lxc_test_lxcpath_OBJECTS = $(am_lxc_test_lxcpath_OBJECTS) +lxc_test_lxcpath_LDADD = $(LDADD) +@ENABLE_TESTS_TRUE@lxc_test_lxcpath_DEPENDENCIES = ../lxc/liblxc.so +am__lxc_test_saveconfig_SOURCES_DIST = saveconfig.c +@ENABLE_TESTS_TRUE@am_lxc_test_saveconfig_OBJECTS = \ +@ENABLE_TESTS_TRUE@ saveconfig.$(OBJEXT) +lxc_test_saveconfig_OBJECTS = $(am_lxc_test_saveconfig_OBJECTS) +lxc_test_saveconfig_LDADD = $(LDADD) +@ENABLE_TESTS_TRUE@lxc_test_saveconfig_DEPENDENCIES = \ +@ENABLE_TESTS_TRUE@ ../lxc/liblxc.so +am__lxc_test_shutdowntest_SOURCES_DIST = shutdowntest.c +@ENABLE_TESTS_TRUE@am_lxc_test_shutdowntest_OBJECTS = \ +@ENABLE_TESTS_TRUE@ shutdowntest.$(OBJEXT) +lxc_test_shutdowntest_OBJECTS = $(am_lxc_test_shutdowntest_OBJECTS) +lxc_test_shutdowntest_LDADD = $(LDADD) +@ENABLE_TESTS_TRUE@lxc_test_shutdowntest_DEPENDENCIES = \ +@ENABLE_TESTS_TRUE@ ../lxc/liblxc.so +am__lxc_test_startone_SOURCES_DIST = startone.c +@ENABLE_TESTS_TRUE@am_lxc_test_startone_OBJECTS = startone.$(OBJEXT) +lxc_test_startone_OBJECTS = $(am_lxc_test_startone_OBJECTS) +lxc_test_startone_LDADD = $(LDADD) +@ENABLE_TESTS_TRUE@lxc_test_startone_DEPENDENCIES = ../lxc/liblxc.so +am__lxc_usernic_test_SOURCES_DIST = ../lxc/lxc_user_nic.c ../lxc/nl.c +am__dirstamp = $(am__leading_dot)dirstamp +@ENABLE_TESTS_TRUE@am_lxc_usernic_test_OBJECTS = ../lxc/lxc_usernic_test-lxc_user_nic.$(OBJEXT) \ +@ENABLE_TESTS_TRUE@ ../lxc/lxc_usernic_test-nl.$(OBJEXT) +lxc_usernic_test_OBJECTS = $(am_lxc_usernic_test_OBJECTS) +lxc_usernic_test_LDADD = $(LDADD) +@ENABLE_TESTS_TRUE@lxc_usernic_test_DEPENDENCIES = ../lxc/liblxc.so +lxc_usernic_test_LINK = $(CCLD) $(lxc_usernic_test_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +SCRIPTS = $(bin_SCRIPTS) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src +depcomp = $(SHELL) $(top_srcdir)/config/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(lxc_test_cgpath_SOURCES) $(lxc_test_clonetest_SOURCES) \ + $(lxc_test_console_SOURCES) $(lxc_test_containertests_SOURCES) \ + $(lxc_test_createtest_SOURCES) $(lxc_test_destroytest_SOURCES) \ + $(lxc_test_get_item_SOURCES) $(lxc_test_getkeys_SOURCES) \ + $(lxc_test_locktests_SOURCES) $(lxc_test_lxcpath_SOURCES) \ + $(lxc_test_saveconfig_SOURCES) \ + $(lxc_test_shutdowntest_SOURCES) $(lxc_test_startone_SOURCES) \ + $(lxc_usernic_test_SOURCES) +DIST_SOURCES = $(am__lxc_test_cgpath_SOURCES_DIST) \ + $(am__lxc_test_clonetest_SOURCES_DIST) \ + $(am__lxc_test_console_SOURCES_DIST) \ + $(am__lxc_test_containertests_SOURCES_DIST) \ + $(am__lxc_test_createtest_SOURCES_DIST) \ + $(am__lxc_test_destroytest_SOURCES_DIST) \ + $(am__lxc_test_get_item_SOURCES_DIST) \ + $(am__lxc_test_getkeys_SOURCES_DIST) \ + $(am__lxc_test_locktests_SOURCES_DIST) \ + $(am__lxc_test_lxcpath_SOURCES_DIST) \ + $(am__lxc_test_saveconfig_SOURCES_DIST) \ + $(am__lxc_test_shutdowntest_SOURCES_DIST) \ + $(am__lxc_test_startone_SOURCES_DIST) \ + $(am__lxc_usernic_test_SOURCES_DIST) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +APPARMOR_LIBS = @APPARMOR_LIBS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BINDIR = @BINDIR@ +CAP_LIBS = @CAP_LIBS@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIR = @DATADIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DOCDIR = @DOCDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GREP = @GREP@ +INCLUDEDIR = @INCLUDEDIR@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBDIR = @LIBDIR@ +LIBEXECDIR = @LIBEXECDIR@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LOCALSTATEDIR = @LOCALSTATEDIR@ +LOGPATH = @LOGPATH@ +LTLIBOBJS = @LTLIBOBJS@ +LUA_CFLAGS = @LUA_CFLAGS@ +LUA_INSTALL_CMOD = @LUA_INSTALL_CMOD@ +LUA_INSTALL_LMOD = @LUA_INSTALL_LMOD@ +LUA_LIBS = @LUA_LIBS@ +LUA_VERSION = @LUA_VERSION@ +LXCHOOKDIR = @LXCHOOKDIR@ +LXCINITDIR = @LXCINITDIR@ +LXCPATH = @LXCPATH@ +LXCROOTFSMOUNT = @LXCROOTFSMOUNT@ +LXCTEMPLATEDIR = @LXCTEMPLATEDIR@ +LXC_DEFAULT_CONFIG = @LXC_DEFAULT_CONFIG@ +LXC_DISTRO_CONF = @LXC_DISTRO_CONF@ +LXC_GENERATE_DATE = @LXC_GENERATE_DATE@ +LXC_GLOBAL_CONF = @LXC_GLOBAL_CONF@ +LXC_USERNIC_CONF = @LXC_USERNIC_CONF@ +LXC_USERNIC_DB = @LXC_USERNIC_DB@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +NEWUIDMAP = @NEWUIDMAP@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PREFIX = @PREFIX@ +PYTHON = @PYTHON@ +PYTHONDEV_CFLAGS = @PYTHONDEV_CFLAGS@ +PYTHONDEV_LIBS = @PYTHONDEV_LIBS@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +SECCOMP_LIBS = @SECCOMP_LIBS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SYSCONFDIR = @SYSCONFDIR@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +db2xman = @db2xman@ +docdir = @docdir@ +docdtd = @docdtd@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +@ENABLE_TESTS_TRUE@LDADD = ../lxc/liblxc.so +@ENABLE_TESTS_TRUE@lxc_test_containertests_SOURCES = containertests.c +@ENABLE_TESTS_TRUE@lxc_test_locktests_SOURCES = locktests.c +@ENABLE_TESTS_TRUE@lxc_test_startone_SOURCES = startone.c +@ENABLE_TESTS_TRUE@lxc_test_destroytest_SOURCES = destroytest.c +@ENABLE_TESTS_TRUE@lxc_test_saveconfig_SOURCES = saveconfig.c +@ENABLE_TESTS_TRUE@lxc_test_createtest_SOURCES = createtest.c +@ENABLE_TESTS_TRUE@lxc_test_shutdowntest_SOURCES = shutdowntest.c +@ENABLE_TESTS_TRUE@lxc_test_get_item_SOURCES = get_item.c +@ENABLE_TESTS_TRUE@lxc_test_getkeys_SOURCES = getkeys.c +@ENABLE_TESTS_TRUE@lxc_test_lxcpath_SOURCES = lxcpath.c +@ENABLE_TESTS_TRUE@lxc_test_cgpath_SOURCES = cgpath.c +@ENABLE_TESTS_TRUE@lxc_test_clonetest_SOURCES = clonetest.c +@ENABLE_TESTS_TRUE@lxc_test_console_SOURCES = console.c +@ENABLE_TESTS_TRUE@lxc_usernic_test_SOURCES = ../lxc/lxc_user_nic.c ../lxc/nl.c +@ENABLE_TESTS_TRUE@lxc_usernic_test_CFLAGS = -DISTEST +@ENABLE_TESTS_TRUE@AM_CFLAGS = -I$(top_srcdir)/src \ +@ENABLE_TESTS_TRUE@ -DLXCROOTFSMOUNT=\"$(LXCROOTFSMOUNT)\" \ +@ENABLE_TESTS_TRUE@ -DLXCPATH=\"$(LXCPATH)\" \ +@ENABLE_TESTS_TRUE@ -DLXC_GLOBAL_CONF=\"$(LXC_GLOBAL_CONF)\" \ +@ENABLE_TESTS_TRUE@ -DLXCINITDIR=\"$(LXCINITDIR)\" \ +@ENABLE_TESTS_TRUE@ -DLXC_DEFAULT_CONFIG=\"$(LXC_DEFAULT_CONFIG)\" + +@ENABLE_TESTS_TRUE@bin_SCRIPTS = lxc-test-usernic +EXTRA_DIST = \ + cgpath.c \ + containertests.c \ + createtest.c \ + destroytest.c \ + get_item.c \ + getkeys.c \ + locktests.c \ + lxcpath.c \ + saveconfig.c \ + shutdowntest.c \ + clonetest.c \ + startone.c \ + console.c \ + lxc-test-usernic + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/tests/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/tests/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' \ + `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) + +lxc-test-cgpath$(EXEEXT): $(lxc_test_cgpath_OBJECTS) $(lxc_test_cgpath_DEPENDENCIES) $(EXTRA_lxc_test_cgpath_DEPENDENCIES) + @rm -f lxc-test-cgpath$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(lxc_test_cgpath_OBJECTS) $(lxc_test_cgpath_LDADD) $(LIBS) + +lxc-test-clonetest$(EXEEXT): $(lxc_test_clonetest_OBJECTS) $(lxc_test_clonetest_DEPENDENCIES) $(EXTRA_lxc_test_clonetest_DEPENDENCIES) + @rm -f lxc-test-clonetest$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(lxc_test_clonetest_OBJECTS) $(lxc_test_clonetest_LDADD) $(LIBS) + +lxc-test-console$(EXEEXT): $(lxc_test_console_OBJECTS) $(lxc_test_console_DEPENDENCIES) $(EXTRA_lxc_test_console_DEPENDENCIES) + @rm -f lxc-test-console$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(lxc_test_console_OBJECTS) $(lxc_test_console_LDADD) $(LIBS) + +lxc-test-containertests$(EXEEXT): $(lxc_test_containertests_OBJECTS) $(lxc_test_containertests_DEPENDENCIES) $(EXTRA_lxc_test_containertests_DEPENDENCIES) + @rm -f lxc-test-containertests$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(lxc_test_containertests_OBJECTS) $(lxc_test_containertests_LDADD) $(LIBS) + +lxc-test-createtest$(EXEEXT): $(lxc_test_createtest_OBJECTS) $(lxc_test_createtest_DEPENDENCIES) $(EXTRA_lxc_test_createtest_DEPENDENCIES) + @rm -f lxc-test-createtest$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(lxc_test_createtest_OBJECTS) $(lxc_test_createtest_LDADD) $(LIBS) + +lxc-test-destroytest$(EXEEXT): $(lxc_test_destroytest_OBJECTS) $(lxc_test_destroytest_DEPENDENCIES) $(EXTRA_lxc_test_destroytest_DEPENDENCIES) + @rm -f lxc-test-destroytest$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(lxc_test_destroytest_OBJECTS) $(lxc_test_destroytest_LDADD) $(LIBS) + +lxc-test-get_item$(EXEEXT): $(lxc_test_get_item_OBJECTS) $(lxc_test_get_item_DEPENDENCIES) $(EXTRA_lxc_test_get_item_DEPENDENCIES) + @rm -f lxc-test-get_item$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(lxc_test_get_item_OBJECTS) $(lxc_test_get_item_LDADD) $(LIBS) + +lxc-test-getkeys$(EXEEXT): $(lxc_test_getkeys_OBJECTS) $(lxc_test_getkeys_DEPENDENCIES) $(EXTRA_lxc_test_getkeys_DEPENDENCIES) + @rm -f lxc-test-getkeys$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(lxc_test_getkeys_OBJECTS) $(lxc_test_getkeys_LDADD) $(LIBS) + +lxc-test-locktests$(EXEEXT): $(lxc_test_locktests_OBJECTS) $(lxc_test_locktests_DEPENDENCIES) $(EXTRA_lxc_test_locktests_DEPENDENCIES) + @rm -f lxc-test-locktests$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(lxc_test_locktests_OBJECTS) $(lxc_test_locktests_LDADD) $(LIBS) + +lxc-test-lxcpath$(EXEEXT): $(lxc_test_lxcpath_OBJECTS) $(lxc_test_lxcpath_DEPENDENCIES) $(EXTRA_lxc_test_lxcpath_DEPENDENCIES) + @rm -f lxc-test-lxcpath$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(lxc_test_lxcpath_OBJECTS) $(lxc_test_lxcpath_LDADD) $(LIBS) + +lxc-test-saveconfig$(EXEEXT): $(lxc_test_saveconfig_OBJECTS) $(lxc_test_saveconfig_DEPENDENCIES) $(EXTRA_lxc_test_saveconfig_DEPENDENCIES) + @rm -f lxc-test-saveconfig$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(lxc_test_saveconfig_OBJECTS) $(lxc_test_saveconfig_LDADD) $(LIBS) + +lxc-test-shutdowntest$(EXEEXT): $(lxc_test_shutdowntest_OBJECTS) $(lxc_test_shutdowntest_DEPENDENCIES) $(EXTRA_lxc_test_shutdowntest_DEPENDENCIES) + @rm -f lxc-test-shutdowntest$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(lxc_test_shutdowntest_OBJECTS) $(lxc_test_shutdowntest_LDADD) $(LIBS) + +lxc-test-startone$(EXEEXT): $(lxc_test_startone_OBJECTS) $(lxc_test_startone_DEPENDENCIES) $(EXTRA_lxc_test_startone_DEPENDENCIES) + @rm -f lxc-test-startone$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(lxc_test_startone_OBJECTS) $(lxc_test_startone_LDADD) $(LIBS) +../lxc/$(am__dirstamp): + @$(MKDIR_P) ../lxc + @: > ../lxc/$(am__dirstamp) +../lxc/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) ../lxc/$(DEPDIR) + @: > ../lxc/$(DEPDIR)/$(am__dirstamp) +../lxc/lxc_usernic_test-lxc_user_nic.$(OBJEXT): \ + ../lxc/$(am__dirstamp) ../lxc/$(DEPDIR)/$(am__dirstamp) +../lxc/lxc_usernic_test-nl.$(OBJEXT): ../lxc/$(am__dirstamp) \ + ../lxc/$(DEPDIR)/$(am__dirstamp) + +lxc-usernic-test$(EXEEXT): $(lxc_usernic_test_OBJECTS) $(lxc_usernic_test_DEPENDENCIES) $(EXTRA_lxc_usernic_test_DEPENDENCIES) + @rm -f lxc-usernic-test$(EXEEXT) + $(AM_V_CCLD)$(lxc_usernic_test_LINK) $(lxc_usernic_test_OBJECTS) $(lxc_usernic_test_LDADD) $(LIBS) +install-binSCRIPTS: $(bin_SCRIPTS) + @$(NORMAL_INSTALL) + @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n' \ + -e 'h;s|.*|.|' \ + -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) { files[d] = files[d] " " $$1; \ + if (++n[d] == $(am__install_max)) { \ + print "f", d, files[d]; n[d] = 0; files[d] = "" } } \ + else { print "f", d "/" $$4, $$1 } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binSCRIPTS: + @$(NORMAL_UNINSTALL) + @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 's,.*/,,;$(transform)'`; \ + dir='$(DESTDIR)$(bindir)'; $(am__uninstall_files_from_dir) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + -rm -f ../lxc/*.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@../lxc/$(DEPDIR)/lxc_usernic_test-lxc_user_nic.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@../lxc/$(DEPDIR)/lxc_usernic_test-nl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cgpath.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clonetest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/console.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/containertests.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/createtest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/destroytest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/get_item.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getkeys.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/locktests.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxcpath.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/saveconfig.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/shutdowntest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/startone.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +../lxc/lxc_usernic_test-lxc_user_nic.o: ../lxc/lxc_user_nic.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lxc_usernic_test_CFLAGS) $(CFLAGS) -MT ../lxc/lxc_usernic_test-lxc_user_nic.o -MD -MP -MF ../lxc/$(DEPDIR)/lxc_usernic_test-lxc_user_nic.Tpo -c -o ../lxc/lxc_usernic_test-lxc_user_nic.o `test -f '../lxc/lxc_user_nic.c' || echo '$(srcdir)/'`../lxc/lxc_user_nic.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../lxc/$(DEPDIR)/lxc_usernic_test-lxc_user_nic.Tpo ../lxc/$(DEPDIR)/lxc_usernic_test-lxc_user_nic.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../lxc/lxc_user_nic.c' object='../lxc/lxc_usernic_test-lxc_user_nic.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lxc_usernic_test_CFLAGS) $(CFLAGS) -c -o ../lxc/lxc_usernic_test-lxc_user_nic.o `test -f '../lxc/lxc_user_nic.c' || echo '$(srcdir)/'`../lxc/lxc_user_nic.c + +../lxc/lxc_usernic_test-lxc_user_nic.obj: ../lxc/lxc_user_nic.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lxc_usernic_test_CFLAGS) $(CFLAGS) -MT ../lxc/lxc_usernic_test-lxc_user_nic.obj -MD -MP -MF ../lxc/$(DEPDIR)/lxc_usernic_test-lxc_user_nic.Tpo -c -o ../lxc/lxc_usernic_test-lxc_user_nic.obj `if test -f '../lxc/lxc_user_nic.c'; then $(CYGPATH_W) '../lxc/lxc_user_nic.c'; else $(CYGPATH_W) '$(srcdir)/../lxc/lxc_user_nic.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../lxc/$(DEPDIR)/lxc_usernic_test-lxc_user_nic.Tpo ../lxc/$(DEPDIR)/lxc_usernic_test-lxc_user_nic.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../lxc/lxc_user_nic.c' object='../lxc/lxc_usernic_test-lxc_user_nic.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lxc_usernic_test_CFLAGS) $(CFLAGS) -c -o ../lxc/lxc_usernic_test-lxc_user_nic.obj `if test -f '../lxc/lxc_user_nic.c'; then $(CYGPATH_W) '../lxc/lxc_user_nic.c'; else $(CYGPATH_W) '$(srcdir)/../lxc/lxc_user_nic.c'; fi` + +../lxc/lxc_usernic_test-nl.o: ../lxc/nl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lxc_usernic_test_CFLAGS) $(CFLAGS) -MT ../lxc/lxc_usernic_test-nl.o -MD -MP -MF ../lxc/$(DEPDIR)/lxc_usernic_test-nl.Tpo -c -o ../lxc/lxc_usernic_test-nl.o `test -f '../lxc/nl.c' || echo '$(srcdir)/'`../lxc/nl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../lxc/$(DEPDIR)/lxc_usernic_test-nl.Tpo ../lxc/$(DEPDIR)/lxc_usernic_test-nl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../lxc/nl.c' object='../lxc/lxc_usernic_test-nl.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lxc_usernic_test_CFLAGS) $(CFLAGS) -c -o ../lxc/lxc_usernic_test-nl.o `test -f '../lxc/nl.c' || echo '$(srcdir)/'`../lxc/nl.c + +../lxc/lxc_usernic_test-nl.obj: ../lxc/nl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lxc_usernic_test_CFLAGS) $(CFLAGS) -MT ../lxc/lxc_usernic_test-nl.obj -MD -MP -MF ../lxc/$(DEPDIR)/lxc_usernic_test-nl.Tpo -c -o ../lxc/lxc_usernic_test-nl.obj `if test -f '../lxc/nl.c'; then $(CYGPATH_W) '../lxc/nl.c'; else $(CYGPATH_W) '$(srcdir)/../lxc/nl.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../lxc/$(DEPDIR)/lxc_usernic_test-nl.Tpo ../lxc/$(DEPDIR)/lxc_usernic_test-nl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../lxc/nl.c' object='../lxc/lxc_usernic_test-nl.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lxc_usernic_test_CFLAGS) $(CFLAGS) -c -o ../lxc/lxc_usernic_test-nl.obj `if test -f '../lxc/nl.c'; then $(CYGPATH_W) '../lxc/nl.c'; else $(CYGPATH_W) '$(srcdir)/../lxc/nl.c'; fi` + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) $(SCRIPTS) +installdirs: + for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -rm -f ../lxc/$(DEPDIR)/$(am__dirstamp) + -rm -f ../lxc/$(am__dirstamp) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-binPROGRAMS clean-generic mostlyclean-am + +distclean: distclean-am + -rm -rf ../lxc/$(DEPDIR) ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-binPROGRAMS install-binSCRIPTS + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ../lxc/$(DEPDIR) ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ + clean-binPROGRAMS clean-generic cscopelist-am ctags ctags-am \ + distclean distclean-compile distclean-generic distclean-tags \ + distdir dvi dvi-am html html-am info info-am install \ + install-am install-binPROGRAMS install-binSCRIPTS install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-binPROGRAMS uninstall-binSCRIPTS + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff -Nru lxc-0.8.0~rc1/src/tests/cgpath.c lxc-1.0.0~alpha1/src/tests/cgpath.c --- lxc-0.8.0~rc1/src/tests/cgpath.c 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/tests/cgpath.c 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,240 @@ +/* liblxcapi + * + * Copyright 2012 Serge Hallyn . + * Copyright 2012 Canonical Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#include "../lxc/lxccontainer.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "../lxc/cgroup.h" +#include "../lxc/lxc.h" +#include "../lxc/commands.h" + +#define MYNAME "lxctest1" + +#define TSTERR(fmt, ...) do { \ + fprintf(stderr, "%s:%d " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__); \ +} while (0) + +/* + * test_running_container: test cgroup functions against a running container + * + * @group : name of the container group or NULL for default "lxc" + * @name : name of the container + */ +static int test_running_container(const char *lxcpath, + const char *group, const char *name) +{ + int ret = -1; + struct lxc_container *c = NULL; + char *cgrelpath; + char *cgabspath; + char relpath[PATH_MAX+1]; + char abspath[PATH_MAX+1]; + char value[NAME_MAX], value_save[NAME_MAX]; + + sprintf(relpath, "%s/%s", group ? group : "lxc", name); + + if ((c = lxc_container_new(name, lxcpath)) == NULL) { + TSTERR("container %s couldn't instantiate", name); + goto err1; + } + if (!c->is_defined(c)) { + TSTERR("container %s does not exist", name); + goto err2; + } + + cgrelpath = lxc_cmd_get_cgroup_path(c->name, c->config_path, "freezer"); + if (!cgrelpath) { + TSTERR("lxc_cmd_get_cgroup_path returned NULL"); + goto err2; + } + if (!strstr(cgrelpath, relpath)) { + TSTERR("lxc_cmd_get_cgroup_path %s not in %s", relpath, cgrelpath); + goto err3; + } + + /* test get/set value using memory.swappiness file */ + ret = lxc_cgroup_get(c->name, "memory.swappiness", value, + sizeof(value), c->config_path); + if (ret < 0) { + TSTERR("lxc_cgroup_get failed"); + goto err3; + } + strcpy(value_save, value); + + ret = lxc_cgroup_set(c->name, "memory.swappiness", "100", c->config_path); + if (ret < 0) { + TSTERR("lxc_cgroup_set_bypath failed"); + goto err3; + } + ret = lxc_cgroup_get(c->name, "memory.swappiness", value, + sizeof(value), c->config_path); + if (ret < 0) { + TSTERR("lxc_cgroup_get failed"); + goto err3; + } + if (strcmp(value, "100\n")) { + TSTERR("lxc_cgroup_set_bypath failed to set value >%s<", value); + goto err3; + } + + /* restore original value */ + ret = lxc_cgroup_set(c->name, "memory.swappiness", value_save, + c->config_path); + if (ret < 0) { + TSTERR("lxc_cgroup_set failed"); + goto err3; + } + ret = lxc_cgroup_get(c->name, "memory.swappiness", value, + sizeof(value), c->config_path); + if (ret < 0) { + TSTERR("lxc_cgroup_get failed"); + goto err3; + } + if (strcmp(value, value_save)) { + TSTERR("lxc_cgroup_set failed to set value >%s<", value); + goto err3; + } + + cgabspath = lxc_cgroup_path_get("freezer", c->name, c->config_path); + if (!cgabspath) { + TSTERR("lxc_cgroup_path_get returned NULL"); + goto err3; + } + sprintf(abspath, "%s/%s/%s", "freezer", group ? group : "lxc", c->name); + if (!strstr(cgabspath, abspath)) { + TSTERR("lxc_cgroup_path_get %s not in %s", abspath, cgabspath); + goto err4; + } + + free(cgabspath); + cgabspath = lxc_cgroup_path_get("freezer.state", c->name, c->config_path); + if (!cgabspath) { + TSTERR("lxc_cgroup_path_get returned NULL"); + goto err3; + } + sprintf(abspath, "%s/%s/%s", "freezer", group ? group : "lxc", c->name); + if (!strstr(cgabspath, abspath)) { + TSTERR("lxc_cgroup_path_get %s not in %s", abspath, cgabspath); + goto err4; + } + + ret = 0; +err4: + free(cgabspath); +err3: + free(cgrelpath); +err2: + lxc_container_put(c); +err1: + return ret; +} + +static int test_container(const char *lxcpath, + const char *group, const char *name, + const char *template) +{ + int ret; + struct lxc_container *c = NULL; + + if (lxcpath) { + ret = mkdir(lxcpath, 0755); + if (ret < 0 && errno != EEXIST) { + TSTERR("failed to mkdir %s %s", lxcpath, strerror(errno)); + goto out1; + } + } + ret = -1; + + if ((c = lxc_container_new(name, lxcpath)) == NULL) { + TSTERR("instantiating container %s", name); + goto out1; + } + if (c->is_defined(c)) { + c->stop(c); + c->destroy(c); + c = lxc_container_new(name, lxcpath); + } + c->set_config_item(c, "lxc.network.type", "empty"); + if (!c->createl(c, template, NULL, NULL, 0, NULL)) { + TSTERR("creating container %s", name); + goto out2; + } + c->load_config(c, NULL); + c->want_daemonize(c); + if (!c->startl(c, 0, NULL)) { + TSTERR("starting container %s", name); + goto out3; + } + + ret = test_running_container(lxcpath, group, name); + + c->stop(c); +out3: + c->destroy(c); +out2: + lxc_container_put(c); +out1: + return ret; +} + +int main() +{ + int ret = EXIT_FAILURE; + + /* won't require privilege necessarily once users are classified by + * pam_cgroup */ + if (geteuid() != 0) { + TSTERR("requires privilege"); + exit(0); + } + + #if TEST_ALREADY_RUNNING_CT + + /* + * This is useful for running with valgrind to test for memory + * leaks. The container should already be running, we can't start + * the container ourselves because valgrind gets confused by lxc's + * internal calls to clone. + */ + if (test_running_container(NULL, NULL, "bb01") < 0) + goto out; + printf("Running container cgroup tests...Passed\n"); + + #else + + if (test_container(NULL, NULL, MYNAME, "busybox") < 0) + goto out; + printf("Container creation tests...Passed\n"); + + if (test_container("/var/lib/lxctest2", NULL, MYNAME, "busybox") < 0) + goto out; + printf("Container creation with LXCPATH tests...Passed\n"); + + #endif + + ret = EXIT_SUCCESS; +out: + return ret; +} diff -Nru lxc-0.8.0~rc1/src/tests/clonetest.c lxc-1.0.0~alpha1/src/tests/clonetest.c --- lxc-0.8.0~rc1/src/tests/clonetest.c 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/tests/clonetest.c 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,178 @@ +/* liblxcapi + * + * Copyright © 2012 Serge Hallyn . + * Copyright © 2012 Canonical Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#include "../lxc/lxccontainer.h" + +#include +#include +#include +#include +#include +#include +#include + +#define MYNAME "clonetest1" +#define MYNAME2 "clonetest2" + +int main(int argc, char *argv[]) +{ + struct lxc_container *c = NULL, *c2 = NULL, *c3 = NULL; + int ret = 1; + + c = lxc_container_new(MYNAME, NULL); + c2 = lxc_container_new(MYNAME2, NULL); + if (c) { + c->destroy(c); + lxc_container_put(c); + c = NULL; + } + if (c2) { + c2->destroy(c2); + lxc_container_put(c2); + c2 = NULL; + } + + if ((c = lxc_container_new(MYNAME, NULL)) == NULL) { + fprintf(stderr, "%d: error opening lxc_container %s\n", __LINE__, MYNAME); + ret = 1; + goto out; + } + c->save_config(c, NULL); + if (!c->createl(c, "ubuntu", NULL, NULL, 0, NULL)) { + fprintf(stderr, "%d: failed to create a container\n", __LINE__); + goto out; + } + c->load_config(c, NULL); + + if (!c->is_defined(c)) { + fprintf(stderr, "%d: %s thought it was not defined\n", __LINE__, MYNAME); + goto out; + } + + c2 = c->clone(c, MYNAME2, NULL, 0, NULL, NULL, 0, NULL); + if (!c2) { + fprintf(stderr, "%d: %s clone returned NULL\n", __LINE__, MYNAME2); + goto out; + } + + if (!c2->is_defined(c2)) { + fprintf(stderr, "%d: %s not defined after clone\n", __LINE__, MYNAME2); + goto out; + } + + fprintf(stderr, "directory backing store tests passed\n"); + + // now test with lvm + // Only do this if clonetestlvm1 exists - user has to set this up + // in advance + //c2->destroy(c2); + lxc_container_put(c2); + //c->destroy(c); + lxc_container_put(c); + c = NULL; + + c2 = lxc_container_new("clonetestlvm2", NULL); + if (c2) { + if (c2->is_defined(c2)) + c2->destroy(c2); + lxc_container_put(c2); + } + c2 = lxc_container_new("clonetest-o1", NULL); + if (c2) { + if (c2->is_defined(c2)) + c2->destroy(c2); + lxc_container_put(c2); + } + c2 = lxc_container_new("clonetest-o2", NULL); + if (c2) { + if (c2->is_defined(c2)) + c2->destroy(c2); + lxc_container_put(c2); + } + c2 = NULL; + + // lvm-copied + c = lxc_container_new("clonetestlvm1", NULL); + if (!c) { + fprintf(stderr, "failed loading clonetestlvm1\n"); + goto out; + } + if (!c->is_defined(c)) { + fprintf(stderr, "clonetestlvm1 does not exist, skipping lvm tests\n"); + ret = 0; + goto out; + } + + if ((c2 = c->clone(c, "clonetestlvm2", NULL, 0, NULL, NULL, 0, NULL)) == NULL) { + fprintf(stderr, "lvm clone failed\n"); + goto out; + } + + lxc_container_put(c2); + + // lvm-snapshot + c2 = lxc_container_new("clonetestlvm3", NULL); + if (c2) { + if (c2->is_defined(c2)) + c2->destroy(c2); + lxc_container_put(c2); + c2 = NULL; + } + + if ((c2 = c->clone(c, "clonetestlvm3", NULL, LXC_CLONE_SNAPSHOT, NULL, NULL, 0, NULL)) == NULL) { + fprintf(stderr, "lvm clone failed\n"); + goto out; + } + lxc_container_put(c2); + lxc_container_put(c); + c = c2 = NULL; + + if ((c = lxc_container_new(MYNAME, NULL)) == NULL) { + fprintf(stderr, "error opening original container for overlay test\n"); + goto out; + } + + // Now create an overlayfs clone of a dir-backed container + if ((c2 = c->clone(c, "clonetest-o1", NULL, LXC_CLONE_SNAPSHOT, "overlayfs", NULL, 0, NULL)) == NULL) { + fprintf(stderr, "overlayfs clone of dir failed\n"); + goto out; + } + + // Now create an overlayfs clone of the overlayfs clone + if ((c3 = c2->clone(c2, "clonetest-o2", NULL, LXC_CLONE_SNAPSHOT, "overlayfs", NULL, 0, NULL)) == NULL) { + fprintf(stderr, "overlayfs clone of overlayfs failed\n"); + goto out; + } + + fprintf(stderr, "all clone tests passed for %s\n", c->name); + ret = 0; + +out: + if (c3) { + lxc_container_put(c3); + } + if (c2) { + //c2->destroy(c2); // keep around to verify manuall + lxc_container_put(c2); + } + if (c) { + //c->destroy(c); + lxc_container_put(c); + } + exit(ret); +} diff -Nru lxc-0.8.0~rc1/src/tests/console.c lxc-1.0.0~alpha1/src/tests/console.c --- lxc-0.8.0~rc1/src/tests/console.c 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/tests/console.c 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,177 @@ +/* liblxcapi + * + * Copyright © 2013 Oracle. + * + * Authors: + * Dwight Engen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "../lxc/lxccontainer.h" + +#include +#include + +#define TTYCNT 4 +#define TTYCNT_STR "4" +#define TSTNAME "lxcconsoletest" +#define MAXCONSOLES 512 + +#define TSTERR(fmt, ...) do { \ + fprintf(stderr, "%s:%d " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__); \ +} while (0) + +static void test_console_close_all(int ttyfd[MAXCONSOLES], + int masterfd[MAXCONSOLES]) +{ + int i; + + for (i = 0; i < MAXCONSOLES; i++) { + if (masterfd[i] != -1) { + close(masterfd[i]); + masterfd[i] = -1; + } + if (ttyfd[i] != -1) { + close(ttyfd[i]); + ttyfd[i] = -1; + } + } +} + +static int test_console_running_container(struct lxc_container *c) +{ + int nrconsoles, i, ret = -1; + int ttynum [MAXCONSOLES]; + int ttyfd [MAXCONSOLES]; + int masterfd[MAXCONSOLES]; + + for (i = 0; i < MAXCONSOLES; i++) + ttynum[i] = ttyfd[i] = masterfd[i] = -1; + + ttynum[0] = 1; + ret = c->console_getfd(c, &ttynum[0], &masterfd[0]); + if (ret < 0) { + TSTERR("console allocate failed"); + goto err1; + } + ttyfd[0] = ret; + if (ttynum[0] != 1) { + TSTERR("console allocate got bad ttynum %d", ttynum[0]); + goto err2; + } + + /* attempt to alloc same ttynum */ + ret = c->console_getfd(c, &ttynum[0], &masterfd[1]); + if (ret != -1) { + TSTERR("console allocate should fail for allocated ttynum %d", ttynum[0]); + goto err2; + } + close(masterfd[0]); masterfd[0] = -1; + close(ttyfd[0]); ttyfd[0] = -1; + + /* ensure we can allocate all consoles, we do this a few times to + * show that the closes are freeing up the allocated slots + */ + for (i = 0; i < 10; i++) { + for (nrconsoles = 0; nrconsoles < MAXCONSOLES; nrconsoles++) { + ret = c->console_getfd(c, &ttynum[nrconsoles], &masterfd[nrconsoles]); + if (ret < 0) + break; + ttyfd[nrconsoles] = ret; + } + if (nrconsoles != TTYCNT) { + TSTERR("didn't allocate all consoles %d != %d", nrconsoles, TTYCNT); + goto err2; + } + test_console_close_all(ttyfd, masterfd); + } + ret = 0; + +err2: + test_console_close_all(ttyfd, masterfd); +err1: + return ret; +} + +/* test_container: test console function + * + * @lxcpath : the lxcpath in which to create the container + * @group : name of the container group or NULL for default "lxc" + * @name : name of the container + * @template : template to use when creating the container + */ +static int test_console(const char *lxcpath, + const char *group, const char *name, + const char *template) +{ + int ret; + struct lxc_container *c = NULL; + + if (lxcpath) { + ret = mkdir(lxcpath, 0755); + if (ret < 0 && errno != EEXIST) { + TSTERR("failed to mkdir %s %s", lxcpath, strerror(errno)); + goto out1; + } + } + ret = -1; + + if ((c = lxc_container_new(name, lxcpath)) == NULL) { + TSTERR("instantiating container %s", name); + goto out1; + } + if (c->is_defined(c)) { + c->stop(c); + c->destroy(c); + c = lxc_container_new(name, lxcpath); + } + if (!c->createl(c, template, NULL, NULL, 0, NULL)) { + TSTERR("creating container %s", name); + goto out2; + } + c->load_config(c, NULL); + c->set_config_item(c, "lxc.tty", TTYCNT_STR); + c->save_config(c, NULL); + c->want_daemonize(c); + if (!c->startl(c, 0, NULL)) { + TSTERR("starting container %s", name); + goto out3; + } + + ret = test_console_running_container(c); + + c->stop(c); +out3: + c->destroy(c); +out2: + lxc_container_put(c); +out1: + return ret; +} + +int main(int argc, char *argv[]) +{ + int ret; + ret = test_console(NULL, NULL, TSTNAME, "busybox"); + if (ret < 0) + goto err1; + + ret = test_console("/var/lib/lxctest2", NULL, TSTNAME, "busybox"); + if (ret < 0) + goto err1; + printf("All tests passed\n"); +err1: + return ret; +} diff -Nru lxc-0.8.0~rc1/src/tests/containertests.c lxc-1.0.0~alpha1/src/tests/containertests.c --- lxc-0.8.0~rc1/src/tests/containertests.c 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/tests/containertests.c 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,262 @@ +/* liblxcapi + * + * Copyright © 2012 Serge Hallyn . + * Copyright © 2012 Canonical Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#include "../lxc/lxccontainer.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#define MYNAME "lxctest1" + +static int destroy_busybox(void) +{ + int status, ret; + pid_t pid = fork(); + + if (pid < 0) { + perror("fork"); + return -1; + } + if (pid == 0) { + ret = execlp("lxc-destroy", "lxc-destroy", "-f", "-n", MYNAME, NULL); + // Should not return + perror("execl"); + exit(1); + } +again: + ret = waitpid(pid, &status, 0); + if (ret == -1) { + if (errno == -EINTR) + goto again; + perror("waitpid"); + return -1; + } + if (ret != pid) + goto again; + if (!WIFEXITED(status)) { // did not exit normally + fprintf(stderr, "%d: lxc-create exited abnormally\n", __LINE__); + return -1; + } + return WEXITSTATUS(status); +} + +static int create_busybox(void) +{ + int status, ret; + pid_t pid = fork(); + + if (pid < 0) { + perror("fork"); + return -1; + } + if (pid == 0) { + ret = execlp("lxc-create", "lxc-create", "-t", "busybox", "-f", LXC_DEFAULT_CONFIG, "-n", MYNAME, NULL); + // Should not return + perror("execl"); + exit(1); + } +again: + ret = waitpid(pid, &status, 0); + if (ret == -1) { + if (errno == -EINTR) + goto again; + perror("waitpid"); + return -1; + } + if (ret != pid) + goto again; + if (!WIFEXITED(status)) { // did not exit normally + fprintf(stderr, "%d: lxc-create exited abnormally\n", __LINE__); + return -1; + } + return WEXITSTATUS(status); +} + +int main(int argc, char *argv[]) +{ + struct lxc_container *c; + int ret = 0; + const char *s; + bool b; + char *str; + + ret = 1; + /* test refcounting */ + c = lxc_container_new(MYNAME, NULL); + if (!c) { + fprintf(stderr, "%d: error creating lxc_container %s\n", __LINE__, MYNAME); + goto out; + } + if (!lxc_container_get(c)) { + fprintf(stderr, "%d: error getting refcount\n", __LINE__); + goto out; + } + /* peek in, inappropriately, make sure refcount is a we'd like */ + if (c->numthreads != 2) { + fprintf(stderr, "%d: refcount is %d, not %d\n", __LINE__, c->numthreads, 2); + goto out; + } + if (strcmp(c->name, MYNAME) != 0) { + fprintf(stderr, "%d: container has wrong name (%s not %s)\n", __LINE__, c->name, MYNAME); + goto out; + } + str = c->config_file_name(c); +#define CONFIGFNAM LXCPATH "/" MYNAME "/config" + if (!str || strcmp(str, CONFIGFNAM)) { + fprintf(stderr, "%d: got wrong config file name (%s, not %s)\n", __LINE__, str, CONFIGFNAM); + goto out; + } + free(str); + free(c->configfile); + c->configfile = NULL; + str = c->config_file_name(c); + if (str) { + fprintf(stderr, "%d: config file name was not NULL as it should have been\n", __LINE__); + goto out; + } + if (lxc_container_put(c) != 0) { + fprintf(stderr, "%d: c was freed on non-final put\n", __LINE__); + goto out; + } + if (c->numthreads != 1) { + fprintf(stderr, "%d: refcount is %d, not %d\n", __LINE__, c->numthreads, 1); + goto out; + } + if (lxc_container_put(c) != 1) { + fprintf(stderr, "%d: c was not freed on final put\n", __LINE__); + goto out; + } + + /* test a real container */ + c = lxc_container_new(MYNAME, NULL); + if (!c) { + fprintf(stderr, "%d: error creating lxc_container %s\n", __LINE__, MYNAME); + ret = 1; + goto out; + } + + if (c->lxc_conf != NULL) { + fprintf(stderr, "%d: lxc_conf is not NULL as it should be\n", __LINE__); + ret = 1; + goto out; + } + b = c->is_defined(c); + if (b) { + fprintf(stderr, "%d: %s thought it was defined\n", __LINE__, MYNAME); + goto out; + } + + s = c->state(c); + if (s && strcmp(s, "STOPPED") != 0) { + // liblxc says a container is STOPPED if it doesn't exist. That's because + // the container may be an application container - it's not wrong, just + // sometimes unintuitive. + fprintf(stderr, "%d: %s thinks it is in state %s\n", __LINE__, c->name, s); + goto out; + } + + // create a container + // the liblxc api does not support creation - it probably will eventually, + // but not yet. + // So we just call out to lxc-create. We'll create a busybox container. + ret = create_busybox(); + if (ret) { + fprintf(stderr, "%d: failed to create a busybox container\n", __LINE__); + goto out; + } + + b = c->is_defined(c); + if (!b) { + fprintf(stderr, "%d: %s thought it was not defined\n", __LINE__, MYNAME); + goto out; + } + + s = c->state(c); + if (!s || strcmp(s, "STOPPED")) { + fprintf(stderr, "%d: %s is in state %s, not in STOPPED.\n", __LINE__, c->name, s ? s : "undefined"); + goto out; + } + + b = c->load_config(c, NULL); + if (!b) { + fprintf(stderr, "%d: %s failed to read its config\n", __LINE__, c->name); + goto out; + } + + // test wait states + int numstates = lxc_get_wait_states(NULL); + if (numstates != MAX_STATE) { + fprintf(stderr, "%d: lxc_get_wait_states gave %d not %d\n", __LINE__, numstates, MAX_STATE); + goto out; + } + const char **sstr = malloc(numstates * sizeof(const char *)); + numstates = lxc_get_wait_states(sstr); + int i; + for (i=0; iwant_daemonize(c); + if (!c->startl(c, 0, NULL, NULL)) { + fprintf(stderr, "%d: %s failed to start daemonized\n", __LINE__, c->name); + goto out; + } + + if (!c->wait(c, "RUNNING", -1)) { + fprintf(stderr, "%d: failed waiting for state RUNNING\n", __LINE__); + goto out; + } + + sleep(3); + s = c->state(c); + if (!s || strcmp(s, "RUNNING")) { + fprintf(stderr, "%d: %s is in state %s, not in RUNNING.\n", __LINE__, c->name, s ? s : "undefined"); + goto out; + } + + printf("hit return to finish"); + ret = scanf("%c", &mychar); + if (ret < 0) + goto out; + + + fprintf(stderr, "all lxc_container tests passed for %s\n", c->name); + ret = 0; + +out: + if (c) { + c->stop(c); + destroy_busybox(); + } + lxc_container_put(c); + exit(ret); +} diff -Nru lxc-0.8.0~rc1/src/tests/createtest.c lxc-1.0.0~alpha1/src/tests/createtest.c --- lxc-0.8.0~rc1/src/tests/createtest.c 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/tests/createtest.c 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,92 @@ +/* liblxcapi + * + * Copyright © 2012 Serge Hallyn . + * Copyright © 2012 Canonical Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#include "../lxc/lxccontainer.h" + +#include +#include +#include +#include +#include +#include +#include + +#define MYNAME "lxctest1" + +int main(int argc, char *argv[]) +{ + struct lxc_container *c; + int ret = 1; + + if ((c = lxc_container_new(MYNAME, NULL)) == NULL) { + fprintf(stderr, "%d: error opening lxc_container %s\n", __LINE__, MYNAME); + ret = 1; + goto out; + } + + if (c->is_defined(c)) { + fprintf(stderr, "%d: %s thought it was defined\n", __LINE__, MYNAME); + goto out; + } + + if (!c->set_config_item(c, "lxc.network.type", "veth")) { + fprintf(stderr, "%d: failed to set network type\n", __LINE__); + goto out; + } + c->set_config_item(c, "lxc.network.link", "lxcbr0"); + c->set_config_item(c, "lxc.network.flags", "up"); + if (!c->createl(c, "ubuntu", NULL, NULL, 0, "-r", "lucid", NULL)) { + fprintf(stderr, "%d: failed to create a lucid container\n", __LINE__); + goto out; + } + + if (!c->is_defined(c)) { + fprintf(stderr, "%d: %s thought it was not defined\n", __LINE__, MYNAME); + goto out; + } + + c->load_config(c, NULL); + c->want_daemonize(c); + if (!c->startl(c, 0, NULL)) { + fprintf(stderr, "%d: failed to start %s\n", __LINE__, MYNAME); + goto out; + } + fprintf(stderr, "%d: %s started, you have 60 seconds to test a console\n", __LINE__, MYNAME); + sleep(60); // wait a minute to let user connect to console + + if (!c->stop(c)) { + fprintf(stderr, "%d: failed to stop %s\n", __LINE__, MYNAME); + goto out; + } + + if (!c->destroy(c)) { + fprintf(stderr, "%d: error deleting %s\n", __LINE__, MYNAME); + goto out; + } + + if (c->is_defined(c)) { + fprintf(stderr, "%d: %s thought it was defined\n", __LINE__, MYNAME); + goto out; + } + + fprintf(stderr, "all lxc_container tests passed for %s\n", c->name); + ret = 0; +out: + lxc_container_put(c); + exit(ret); +} diff -Nru lxc-0.8.0~rc1/src/tests/destroytest.c lxc-1.0.0~alpha1/src/tests/destroytest.c --- lxc-0.8.0~rc1/src/tests/destroytest.c 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/tests/destroytest.c 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,104 @@ +/* liblxcapi + * + * Copyright © 2012 Serge Hallyn . + * Copyright © 2012 Canonical Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#include "../lxc/lxccontainer.h" + +#include +#include +#include +#include +#include +#include +#include + +#define MYNAME "lxctest1" + +static int create_ubuntu(void) +{ + int status, ret; + pid_t pid = fork(); + + if (pid < 0) { + perror("fork"); + return -1; + } + if (pid == 0) { + ret = execlp("lxc-create", "lxc-create", "-t", "ubuntu", "-f", LXC_DEFAULT_CONFIG, "-n", MYNAME, NULL); + // Should not return + perror("execl"); + exit(1); + } +again: + ret = waitpid(pid, &status, 0); + if (ret == -1) { + if (errno == -EINTR) + goto again; + perror("waitpid"); + return -1; + } + if (ret != pid) + goto again; + if (!WIFEXITED(status)) { // did not exit normally + fprintf(stderr, "%d: lxc-create exited abnormally\n", __LINE__); + return -1; + } + return WEXITSTATUS(status); +} + +int main(int argc, char *argv[]) +{ + struct lxc_container *c; + int ret = 1; + + if ((c = lxc_container_new(MYNAME, NULL)) == NULL) { + fprintf(stderr, "%d: error opening lxc_container %s\n", __LINE__, MYNAME); + ret = 1; + goto out; + } + + if (c->is_defined(c)) { + fprintf(stderr, "%d: %s thought it was defined\n", __LINE__, MYNAME); + goto out; + } + + if (create_ubuntu()) { + fprintf(stderr, "%d: failed to create a ubuntu container\n", __LINE__); + goto out; + } + + if (!c->is_defined(c)) { + fprintf(stderr, "%d: %s thought it was not defined\n", __LINE__, MYNAME); + goto out; + } + + if (!c->destroy(c)) { + fprintf(stderr, "%d: error deleting %s\n", __LINE__, MYNAME); + goto out; + } + + if (c->is_defined(c)) { + fprintf(stderr, "%d: %s thought it was defined\n", __LINE__, MYNAME); + goto out; + } + + fprintf(stderr, "all lxc_container tests passed for %s\n", c->name); + ret = 0; +out: + lxc_container_put(c); + exit(ret); +} diff -Nru lxc-0.8.0~rc1/src/tests/get_item.c lxc-1.0.0~alpha1/src/tests/get_item.c --- lxc-0.8.0~rc1/src/tests/get_item.c 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/tests/get_item.c 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,308 @@ +/* liblxcapi + * + * Copyright © 2012 Serge Hallyn . + * Copyright © 2012 Canonical Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#include "../lxc/lxccontainer.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#define MYNAME "lxctest1" + +int main(int argc, char *argv[]) +{ + struct lxc_container *c; + int ret; + char v1[2], v2[256], v3[2048]; + + if ((c = lxc_container_new("testxyz", NULL)) == NULL) { + fprintf(stderr, "%d: error opening lxc_container %s\n", __LINE__, MYNAME); + ret = 1; + goto out; + } + + if (!c->set_config_item(c, "lxc.hook.pre-start", "hi there")) { + fprintf(stderr, "%d: failed to set hook.pre-start\n", __LINE__); + ret = 1; + goto out; + } + ret = c->get_config_item(c, "lxc.hook.pre-start", v2, 255); + if (ret < 0) { + fprintf(stderr, "%d: get_config_item(lxc.hook.pre-start) returned %d\n", __LINE__, ret); + ret = 1; + goto out; + } + fprintf(stderr, "lxc.hook.pre-start returned %d %s\n", ret, v2); + + ret = c->get_config_item(c, "lxc.network", v2, 255); + if (ret < 0) { + fprintf(stderr, "%d: get_config_item returned %d\n", __LINE__, ret); + ret = 1; + goto out; + } + fprintf(stderr, "%d: get_config_item(lxc.network) returned %d %s\n", __LINE__, ret, v2); + if (!c->set_config_item(c, "lxc.tty", "4")) { + fprintf(stderr, "%d: failed to set tty\n", __LINE__); + ret = 1; + goto out; + } + ret = c->get_config_item(c, "lxc.tty", v2, 255); + if (ret < 0) { + fprintf(stderr, "%d: get_config_item(lxc.tty) returned %d\n", __LINE__, ret); + ret = 1; + goto out; + } + fprintf(stderr, "lxc.tty returned %d %s\n", ret, v2); + + if (!c->set_config_item(c, "lxc.arch", "x86")) { + fprintf(stderr, "%d: failed to set arch\n", __LINE__); + ret = 1; + goto out; + } + ret = c->get_config_item(c, "lxc.arch", v2, 255); + if (ret < 0) { + fprintf(stderr, "%d: get_config_item(lxc.arch) returned %d\n", __LINE__, ret); + ret = 1; + goto out; + } + printf("lxc.arch returned %d %s\n", ret, v2); + +#define HNAME "hostname1" + // demonstrate proper usage: + char *alloced; + if (!c->set_config_item(c, "lxc.utsname", HNAME)) { + fprintf(stderr, "%d: failed to set utsname\n", __LINE__); + ret = 1; + goto out; + } + + int len; + len = c->get_config_item(c, "lxc.utsname", NULL, 0); // query the size of the string + if (len < 0) { + fprintf(stderr, "%d: get_config_item(lxc.utsname) returned %d\n", __LINE__, len); + ret = 1; + goto out; + } + printf("lxc.utsname returned %d\n", len); + + // allocate the length of string + 1 for trailing \0 + alloced = malloc(len+1); + if (!alloced) { + fprintf(stderr, "%d: failed to allocate %d bytes for utsname\n", __LINE__, len); + ret = 1; + goto out; + } + // now pass in the malloc'd array, and pass in length of string + 1: again + // because we need room for the trailing \0 + ret = c->get_config_item(c, "lxc.utsname", alloced, len+1); + if (ret < 0) { + fprintf(stderr, "%d: get_config_item(lxc.utsname) returned %d\n", __LINE__, ret); + ret = 1; + goto out; + } + if (strcmp(alloced, HNAME) != 0 || ret != len) { + fprintf(stderr, "lxc.utsname returned wrong value: %d %s not %d %s\n", ret, alloced, len, HNAME); + ret = 1; + goto out; + } + printf("lxc.utsname returned %d %s\n", len, alloced); + free(alloced); + + if (!c->set_config_item(c, "lxc.mount.entry", "hi there")) { + fprintf(stderr, "%d: failed to set mount.entry\n", __LINE__); + ret = 1; + goto out; + } + ret = c->get_config_item(c, "lxc.mount.entry", v2, 255); + if (ret < 0) { + fprintf(stderr, "%d: get_config_item(lxc.mount.entry) returned %d\n", __LINE__, ret); + ret = 1; + goto out; + } + printf("lxc.mount.entry returned %d %s\n", ret, v2); + + if (!c->set_config_item(c, "lxc.aa_profile", "unconfined")) { + fprintf(stderr, "%d: failed to set aa_profile\n", __LINE__); + ret = 1; + goto out; + } + ret = c->get_config_item(c, "lxc.aa_profile", v2, 255); + if (ret < 0) { + fprintf(stderr, "%d: get_config_item(lxc.aa_profile) returned %d\n", __LINE__, ret); + ret = 1; + goto out; + } + printf("lxc.aa_profile returned %d %s\n", ret, v2); + + lxc_container_put(c); + + // new test with real container + if ((c = lxc_container_new(MYNAME, NULL)) == NULL) { + fprintf(stderr, "%d: error opening lxc_container %s\n", __LINE__, MYNAME); + ret = 1; + goto out; + } + c->destroy(c); + lxc_container_put(c); + + if ((c = lxc_container_new(MYNAME, NULL)) == NULL) { + fprintf(stderr, "%d: error opening lxc_container %s\n", __LINE__, MYNAME); + ret = 1; + goto out; + } + if (!c->createl(c, "ubuntu", NULL, NULL, 0, "-r", "lucid", NULL)) { + fprintf(stderr, "%d: failed to create a lucid container\n", __LINE__); + ret = 1; + goto out; + } + + lxc_container_put(c); + + /* XXX TODO load_config needs to clear out any old config first */ + if ((c = lxc_container_new(MYNAME, NULL)) == NULL) { + fprintf(stderr, "%d: error opening lxc_container %s\n", __LINE__, MYNAME); + ret = 1; + goto out; + } + + ret = c->get_config_item(c, "lxc.cap.drop", NULL, 300); + if (ret < 5 || ret > 255) { + fprintf(stderr, "%d: get_config_item(lxc.cap.drop) with NULL returned %d\n", __LINE__, ret); + ret = 1; + goto out; + } + ret = c->get_config_item(c, "lxc.cap.drop", v1, 1); + if (ret < 5 || ret > 255) { + fprintf(stderr, "%d: get_config_item(lxc.cap.drop) returned %d\n", __LINE__, ret); + ret = 1; + goto out; + } + ret = c->get_config_item(c, "lxc.cap.drop", v2, 255); + if (ret < 0) { + fprintf(stderr, "%d: get_config_item(lxc.cap.drop) returned %d %s\n", __LINE__, ret, v2); + ret = 1; + goto out; + } + printf("%d: get_config_item(lxc.cap.drop) returned %d %s\n", __LINE__, ret, v2); + ret = c->get_config_item(c, "lxc.network", v2, 255); + if (ret < 0) { + fprintf(stderr, "%d: get_config_item returned %d\n", __LINE__, ret); + ret = 1; + goto out; + } + printf("%d: get_config_item(lxc.network) returned %d %s\n", __LINE__, ret, v2); + + if (!c->set_config_item(c, "lxc.network.ipv4", "10.2.3.4")) { + fprintf(stderr, "%d: failed to set ipv4\n", __LINE__); + ret = 1; + goto out; + } + + ret = c->get_config_item(c, "lxc.network.0.ipv4", v2, 255); + if (ret <= 0) { + fprintf(stderr, "%d: lxc.network.0.ipv4 returned %d\n", __LINE__, ret); + ret = 1; + goto out; + } + if (!c->clear_config_item(c, "lxc.network.0.ipv4")) { + fprintf(stderr, "%d: failed clearing all ipv4 entries\n", __LINE__); + ret = 1; + goto out; + } + ret = c->get_config_item(c, "lxc.network.0.ipv4", v2, 255); + if (ret != 0) { + fprintf(stderr, "%d: after clearing ipv4 entries get_item(lxc.network.0.ipv4 returned %d\n", __LINE__, ret); + ret = 1; + goto out; + } + + ret = c->get_config_item(c, "lxc.network.0.link", v2, 255); + if (ret < 0) { + fprintf(stderr, "%d: get_config_item returned %d\n", __LINE__, ret); + ret = 1; + goto out; + } + printf("%d: get_config_item (link) returned %d %s\n", __LINE__, ret, v2); + ret = c->get_config_item(c, "lxc.network.0.name", v2, 255); + if (ret < 0) { + fprintf(stderr, "%d: get_config_item returned %d\n", __LINE__, ret); + ret = 1; + goto out; + } + printf("%d: get_config_item (name) returned %d %s\n", __LINE__, ret, v2); + + if (!c->clear_config_item(c, "lxc.network")) { + fprintf(stderr, "%d: clear_config_item failed\n", __LINE__); + ret = 1; + goto out; + } + ret = c->get_config_item(c, "lxc.network", v2, 255); + if (ret != 0) { + fprintf(stderr, "%d: network was not actually cleared (get_network returned %d)\n", __LINE__, ret); + ret = 1; + goto out; + } + + ret = c->get_config_item(c, "lxc.cgroup", v3, 2047); + if (ret < 0) { + fprintf(stderr, "%d: get_config_item(cgroup.devices) returned %d\n", __LINE__, ret); + ret = 1; + goto out; + } + printf("%d: get_config_item (cgroup.devices) returned %d %s\n", __LINE__, ret, v3); + + ret = c->get_config_item(c, "lxc.cgroup.devices.allow", v3, 2047); + if (ret < 0) { + fprintf(stderr, "%d: get_config_item(cgroup.devices.devices.allow) returned %d\n", __LINE__, ret); + ret = 1; + goto out; + } + printf("%d: get_config_item (cgroup.devices.devices.allow) returned %d %s\n", __LINE__, ret, v3); + + if (!c->clear_config_item(c, "lxc.cgroup")) { + fprintf(stderr, "%d: failed clearing lxc.cgroup", __LINE__); + ret = 1; + goto out; + } + if (!c->clear_config_item(c, "lxc.cap.drop")) { + fprintf(stderr, "%d: failed clearing lxc.cap.drop", __LINE__); + ret = 1; + goto out; + } + if (!c->clear_config_item(c, "lxc.mount.entries")) { + fprintf(stderr, "%d: failed clearing lxc.mount.entries", __LINE__); + ret = 1; + goto out; + } + if (!c->clear_config_item(c, "lxc.hook")) { + fprintf(stderr, "%d: failed clearing lxc.hook", __LINE__); + ret = 1; + goto out; + } + c->destroy(c); + printf("All get_item tests passed\n"); + ret = 0; +out: + lxc_container_put(c); + exit(ret); +}; diff -Nru lxc-0.8.0~rc1/src/tests/getkeys.c lxc-1.0.0~alpha1/src/tests/getkeys.c --- lxc-0.8.0~rc1/src/tests/getkeys.c 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/tests/getkeys.c 2013-09-03 18:26:12.000000000 +0000 @@ -0,0 +1,71 @@ +/* liblxcapi + * + * Copyright © 2012 Serge Hallyn . + * Copyright © 2012 Canonical Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#include "../lxc/lxccontainer.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#define MYNAME "lxctest1" + +int main(int argc, char *argv[]) +{ + struct lxc_container *c; + int len, ret; + char v3[2048]; + + if ((c = lxc_container_new(MYNAME, NULL)) == NULL) { + fprintf(stderr, "%d: error opening lxc_container %s\n", __LINE__, MYNAME); + ret = 1; + goto out; + } + + c->set_config_item(c, "lxc.network.type", "veth"); + + len = c->get_keys(c, NULL, NULL, 0); + if (len < 0) { + fprintf(stderr, "%d: failed to get length of all keys (%d)\n", __LINE__, len); + ret = 1; + goto out; + } + ret = c->get_keys(c, NULL, v3, len+1); + if (ret != len) { + fprintf(stderr, "%d: failed to get keys (%d)\n", __LINE__, ret); + ret = 1; + goto out; + } + printf("get_keys returned %d\n%s", ret, v3); + + ret = c->get_keys(c, "lxc.network.0", v3, 2000); + if (ret < 0) { + fprintf(stderr, "%d: failed to get nic 0 keys(%d)\n", __LINE__, ret); + ret = 1; + goto out; + } + printf("get_keys for nic 1 returned %d\n%s", ret, v3); + +out: + lxc_container_put(c); + exit(ret); +} diff -Nru lxc-0.8.0~rc1/src/tests/locktests.c lxc-1.0.0~alpha1/src/tests/locktests.c --- lxc-0.8.0~rc1/src/tests/locktests.c 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/tests/locktests.c 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,141 @@ +/* liblxcapi + * + * Copyright © 2012 Serge Hallyn . + * Copyright © 2012 Canonical Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#include "../lxc/lxclock.h" +#include +#include +#include +#include +#include +#include + +#define mycontainername "lxctest.sem" +#define TIMEOUT_SECS 3 + +void test_two_locks(void) +{ + struct lxc_lock *l; + pid_t pid; + int ret, status; + int p[2]; + char c; + + if (pipe(p) < 0) + exit(1); + if ((pid = fork()) < 0) + exit(1); + if (pid == 0) { + if (read(p[0], &c, 1) < 0) { + perror("read"); + exit(1); + } + l = lxc_newlock("/tmp", "lxctest-sem"); + if (!l) { + fprintf(stderr, "%d: child: failed to create lock\n", __LINE__); + exit(1); + } + if (lxclock(l, 0) < 0) { + fprintf(stderr, "%d: child: failed to grab lock\n", __LINE__); + exit(1); + } + fprintf(stderr, "%d: child: grabbed lock\n", __LINE__); + exit(0); + } + l = lxc_newlock("/tmp", "lxctest-sem"); + if (!l) { + fprintf(stderr, "%d: failed to create lock\n", __LINE__); + exit(1); + } + if (lxclock(l, 0) < 0) { + fprintf(stderr, "%d; failed to get lock\n", __LINE__); + exit(1); + } + if (write(p[1], &c, 1) < 0) { + perror("write"); + exit(1); + } + sleep(3); + ret = waitpid(pid, &status, WNOHANG); + if (ret == pid) { // task exited + if (WIFEXITED(status)) { + printf("%d exited normally with exit code %d\n", pid, + WEXITSTATUS(status)); + if (WEXITSTATUS(status) == 0) + exit(1); + } else + printf("%d did not exit normally\n", pid); + return; + } else if (ret < 0) { + perror("waitpid"); + exit(1); + } + kill(pid, SIGKILL); + wait(&status); + close(p[1]); + close(p[0]); + lxcunlock(l); + lxc_putlock(l); +} + +int main(int argc, char *argv[]) +{ + int ret; + struct lxc_lock *lock; + + lock = lxc_newlock(NULL, NULL); + if (!lock) { + fprintf(stderr, "%d: failed to get unnamed lock\n", __LINE__); + exit(1); + } + ret = lxclock(lock, 0); + if (ret) { + fprintf(stderr, "%d: failed to take unnamed lock (%d)\n", __LINE__, ret); + exit(1); + } + + ret = lxcunlock(lock); + if (ret) { + fprintf(stderr, "%d: failed to put unnamed lock (%d)\n", __LINE__, ret); + exit(1); + } + lxc_putlock(lock); + + lock = lxc_newlock("/var/lib/lxc", mycontainername); + if (!lock) { + fprintf(stderr, "%d: failed to get lock\n", __LINE__); + exit(1); + } + struct stat sb; + // we don't create the file until the container is running, so this + // bit of the test needs to be changed + //char *pathname = "/run/lock/lxc/var/lib/lxc/" mycontainername; + char *pathname = "/run/lock/lxc/var/lib/lxc/"; + ret = stat(pathname, &sb); + if (ret != 0) { + fprintf(stderr, "%d: filename %s not created\n", __LINE__, + pathname); + exit(1); + } + lxc_putlock(lock); + + test_two_locks(); + + fprintf(stderr, "all tests passed\n"); + + exit(ret); +} diff -Nru lxc-0.8.0~rc1/src/tests/lxc-test-usernic lxc-1.0.0~alpha1/src/tests/lxc-test-usernic --- lxc-0.8.0~rc1/src/tests/lxc-test-usernic 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/tests/lxc-test-usernic 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,67 @@ +#!/bin/bash + +# lxc: linux Container library + +# Authors: +# Serge Hallyn +# +# This is a test script for the lxc-user-nic program + +# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +conffile="/tmp/lxc-usernet" +dbfile="/tmp/nics" +sysfsdir=/tmp/lxcnettest + +rm -f $conffile $dbfile + +rm -rf $sysfsdir +mkdir -p $sysfsdir + +# there is no conffile, so we have no permissions +lxc-usernic-test 1111 veth lxcbr0 > /dev/null 2>&1 +if [ $? -eq 0 ]; then + echo "Fail: empty conffile should not allow me a nic" + exit 1 +fi + +cat > $conffile << EOF +$(id -un) veth lxcbr0 1 +EOF + +# Should be allowed one but not two +lxc-usernic-test 1111 veth lxcbr0 > /dev/null 2>&1 +if [ $? -ne 0 ]; then + echo "Failed to get one allowed nic" + exit 1 +fi + +lxc-usernic-test 1111 veth lxcbr0 > /dev/null 2>&1 +if [ $? -eq 0 ]; then + echo "Fail: was able to get a second nic" + exit 1 +fi + +# now remove the 'existing nic' and make sure we're allowed to create +# a new one +lxc-usernic-test 1111 veth lxcbr0 > /dev/null 2>&1 +rm -rf $sysfsdir +mkdir -p $sysfsdir +if [ $? -ne 0 ]; then + echo "Fail: was unable to get a replacement nic" + exit 1 +fi + +echo "All tests passed" diff -Nru lxc-0.8.0~rc1/src/tests/lxcpath.c lxc-1.0.0~alpha1/src/tests/lxcpath.c --- lxc-0.8.0~rc1/src/tests/lxcpath.c 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/tests/lxcpath.c 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,85 @@ +/* liblxcapi + * + * Copyright 2012 Serge Hallyn . + * Copyright 2012 Canonical Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#include "../lxc/lxccontainer.h" + +#include +#include +#include +#include +#include +#include +#include + +#define MYNAME "lxctest1" + +#define TSTERR(x) do { \ + fprintf(stderr, "%d: %s\n", __LINE__, x); \ +} while (0) + +int main() +{ + struct lxc_container *c; + const char *p1, *p2; + int retval = -1; + + c = lxc_container_new(MYNAME, NULL); + if (!c) { + TSTERR("create using default path"); + goto err; + } + p1 = c->get_config_path(c); + p2 = c->config_file_name(c); + if (!p1 || !p2 || strncmp(p1, p2, strlen(p1))) { + TSTERR("Bad result for path names"); + goto err; + } + +#define CPATH "/boo" +#define FPATH "/boo/lxctest1/config" + if (!c->set_config_path(c, "/boo")) { + TSTERR("Error setting custom path"); + goto err; + } + p1 = c->get_config_path(c); + p2 = c->config_file_name(c); + if (strcmp(p1, CPATH) || strcmp(p2, FPATH)) { + TSTERR("Bad result for path names after set_config_path()"); + goto err; + } + lxc_container_put(c); + + c = lxc_container_new(MYNAME, CPATH); + if (!c) { + TSTERR("create using custom path"); + goto err; + } + + p1 = c->get_config_path(c); + p2 = c->config_file_name(c); + if (strcmp(p1, CPATH) || strcmp(p2, FPATH)) { + TSTERR("Bad result for path names after create with custom path"); + goto err; + } + + retval = 0; + +err: + lxc_container_put(c); + return retval; +} diff -Nru lxc-0.8.0~rc1/src/tests/saveconfig.c lxc-1.0.0~alpha1/src/tests/saveconfig.c --- lxc-0.8.0~rc1/src/tests/saveconfig.c 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/tests/saveconfig.c 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,106 @@ +/* liblxcapi + * + * Copyright © 2012 Serge Hallyn . + * Copyright © 2012 Canonical Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#include "../lxc/lxccontainer.h" + +#include +#include +#include +#include +#include +#include +#include + +#define MYNAME "lxctest1" + +static int create_ubuntu(void) +{ + int status, ret; + pid_t pid = fork(); + + if (pid < 0) { + perror("fork"); + return -1; + } + if (pid == 0) { + ret = execlp("lxc-create", "lxc-create", "-t", "ubuntu", "-f", LXC_DEFAULT_CONFIG, "-n", MYNAME, NULL); + // Should not return + perror("execl"); + exit(1); + } +again: + ret = waitpid(pid, &status, 0); + if (ret == -1) { + if (errno == -EINTR) + goto again; + perror("waitpid"); + return -1; + } + if (ret != pid) + goto again; + if (!WIFEXITED(status)) { // did not exit normally + fprintf(stderr, "%d: lxc-create exited abnormally\n", __LINE__); + return -1; + } + return WEXITSTATUS(status); +} + +int main(int argc, char *argv[]) +{ + struct lxc_container *c; + int ret = 1; + + if ((c = lxc_container_new(MYNAME, NULL)) == NULL) { + fprintf(stderr, "%d: error opening lxc_container %s\n", __LINE__, MYNAME); + ret = 1; + goto out; + } + + if (c->is_defined(c)) { + fprintf(stderr, "%d: %s thought it was defined\n", __LINE__, MYNAME); + goto out; + } + + if (create_ubuntu()) { + fprintf(stderr, "%d: failed to create a ubuntu container\n", __LINE__); + goto out; + } + + if (!c->is_defined(c)) { + fprintf(stderr, "%d: %s thought it was not defined\n", __LINE__, MYNAME); + goto out; + } + + c->load_config(c, NULL); + unlink("/tmp/lxctest1"); + if (!c->save_config(c, "/tmp/lxctest1")) { + fprintf(stderr, "%d: failed writing config file /tmp/lxctest1\n", __LINE__); + goto out; + } + rename(LXCPATH "/" MYNAME "/config", LXCPATH "/" MYNAME "/config.bak"); + if (!c->save_config(c, NULL)) { + fprintf(stderr, "%d: failed writing config file\n", __LINE__); + goto out; + } + + fprintf(stderr, "all lxc_container tests passed for %s\n", c->name); + ret = 0; +out: + lxc_container_put(c); + exit(ret); +} diff -Nru lxc-0.8.0~rc1/src/tests/shutdowntest.c lxc-1.0.0~alpha1/src/tests/shutdowntest.c --- lxc-0.8.0~rc1/src/tests/shutdowntest.c 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/tests/shutdowntest.c 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,93 @@ + +/* liblxcapi + * + * Copyright © 2012 Serge Hallyn . + * Copyright © 2012 Canonical Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#include "../lxc/lxccontainer.h" + +#include +#include +#include +#include +#include +#include +#include + +#define MYNAME "lxctest1" + +int main(int argc, char *argv[]) +{ + struct lxc_container *c; + int ret = 1; + + if ((c = lxc_container_new(MYNAME, NULL)) == NULL) { + fprintf(stderr, "%d: error opening lxc_container %s\n", __LINE__, MYNAME); + ret = 1; + goto out; + } + + if (c->is_defined(c)) { + fprintf(stderr, "%d: %s thought it was defined\n", __LINE__, MYNAME); + goto out; + } + + if (!c->set_config_item(c, "lxc.network.type", "veth")) { + fprintf(stderr, "%d: failed to set network type\n", __LINE__); + goto out; + } + c->set_config_item(c, "lxc.network.link", "lxcbr0"); + c->set_config_item(c, "lxc.network.flags", "up"); + if (!c->createl(c, "ubuntu", NULL, NULL, 0, "-r", "lucid", NULL)) { + fprintf(stderr, "%d: failed to create a lucid container\n", __LINE__); + goto out; + } + + if (!c->is_defined(c)) { + fprintf(stderr, "%d: %s thought it was not defined\n", __LINE__, MYNAME); + goto out; + } + + c->load_config(c, NULL); + c->want_daemonize(c); + if (!c->startl(c, 0, NULL)) { + fprintf(stderr, "%d: failed to start %s\n", __LINE__, MYNAME); + goto out; + } + fprintf(stderr, "%d: %s started, you have 60 seconds to test a console\n", __LINE__, MYNAME); + sleep(60); // wait a minute to let user connect to console + + if (!c->shutdown(c, 60)) { + fprintf(stderr, "%d: failed to shut down %s\n", __LINE__, MYNAME); + goto out; + } + + if (!c->destroy(c)) { + fprintf(stderr, "%d: error deleting %s\n", __LINE__, MYNAME); + goto out; + } + + if (c->is_defined(c)) { + fprintf(stderr, "%d: %s thought it was defined\n", __LINE__, MYNAME); + goto out; + } + + fprintf(stderr, "all lxc_container tests passed for %s\n", c->name); + ret = 0; +out: + lxc_container_put(c); + exit(ret); +} diff -Nru lxc-0.8.0~rc1/src/tests/startone.c lxc-1.0.0~alpha1/src/tests/startone.c --- lxc-0.8.0~rc1/src/tests/startone.c 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/src/tests/startone.c 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,266 @@ +/* liblxcapi + * + * Copyright © 2012 Serge Hallyn . + * Copyright © 2012 Canonical Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#include "../lxc/lxccontainer.h" + +#include +#include +#include +#include +#include +#include +#include + +#define MYNAME "lxctest1" + +static int destroy_ubuntu(void) +{ + int status, ret; + pid_t pid = fork(); + + if (pid < 0) { + perror("fork"); + return -1; + } + if (pid == 0) { + ret = execlp("lxc-destroy", "lxc-destroy", "-f", "-n", MYNAME, NULL); + // Should not return + perror("execl"); + exit(1); + } +again: + ret = waitpid(pid, &status, 0); + if (ret == -1) { + if (errno == -EINTR) + goto again; + perror("waitpid"); + return -1; + } + if (ret != pid) + goto again; + if (!WIFEXITED(status)) { // did not exit normally + fprintf(stderr, "%d: lxc-create exited abnormally\n", __LINE__); + return -1; + } + return WEXITSTATUS(status); +} + +static int create_ubuntu(void) +{ + int status, ret; + pid_t pid = fork(); + + if (pid < 0) { + perror("fork"); + return -1; + } + if (pid == 0) { + ret = execlp("lxc-create", "lxc-create", "-t", "ubuntu", "-f", LXC_DEFAULT_CONFIG, "-n", MYNAME, NULL); + // Should not return + perror("execl"); + exit(1); + } +again: + ret = waitpid(pid, &status, 0); + if (ret == -1) { + if (errno == -EINTR) + goto again; + perror("waitpid"); + return -1; + } + if (ret != pid) + goto again; + if (!WIFEXITED(status)) { // did not exit normally + fprintf(stderr, "%d: lxc-create exited abnormally\n", __LINE__); + return -1; + } + return WEXITSTATUS(status); +} + +int main(int argc, char *argv[]) +{ + struct lxc_container *c; + int ret = 0; + const char *s; + bool b; + char buf[201]; + int len; + + ret = 1; + /* test a real container */ + c = lxc_container_new(MYNAME, NULL); + if (!c) { + fprintf(stderr, "%d: error creating lxc_container %s\n", __LINE__, MYNAME); + ret = 1; + goto out; + } + + if (c->is_defined(c)) { + fprintf(stderr, "%d: %s thought it was defined\n", __LINE__, MYNAME); + goto out; + } + + ret = create_ubuntu(); + if (ret) { + fprintf(stderr, "%d: failed to create a ubuntu container\n", __LINE__); + goto out; + } + + b = c->is_defined(c); + if (!b) { + fprintf(stderr, "%d: %s thought it was not defined\n", __LINE__, MYNAME); + goto out; + } + + len = c->get_cgroup_item(c, "cpuset.cpus", buf, 200); + if (len >= 0) { + fprintf(stderr, "%d: %s not running but had cgroup settings\n", __LINE__, MYNAME); + goto out; + } + + sprintf(buf, "0"); + b = c->set_cgroup_item(c, "cpuset.cpus", buf); + if (b) { + fprintf(stderr, "%d: %s not running but coudl set cgroup settings\n", __LINE__, MYNAME); + goto out; + } + + s = c->state(c); + if (!s || strcmp(s, "STOPPED")) { + fprintf(stderr, "%d: %s is in state %s, not in STOPPED.\n", __LINE__, c->name, s ? s : "undefined"); + goto out; + } + + b = c->load_config(c, NULL); + if (!b) { + fprintf(stderr, "%d: %s failed to read its config\n", __LINE__, c->name); + goto out; + } + + if (!c->set_config_item(c, "lxc.utsname", "bobo")) { + fprintf(stderr, "%d: failed setting lxc.utsname\n", __LINE__); + goto out; + } + + printf("hit return to start container"); + char mychar; + ret = scanf("%c", &mychar); + if (ret < 0) + goto out; + + if (!lxc_container_get(c)) { + fprintf(stderr, "%d: failed to get extra ref to container\n", __LINE__); + exit(1); + } + pid_t pid = fork(); + if (pid < 0) { + fprintf(stderr, "%d: fork failed\n", __LINE__); + goto out; + } + if (pid == 0) { + b = c->startl(c, 0, NULL); + if (!b) + fprintf(stderr, "%d: %s failed to start\n", __LINE__, c->name); + lxc_container_put(c); + exit(!b); + } + + sleep(3); + s = c->state(c); + if (!s || strcmp(s, "RUNNING")) { + fprintf(stderr, "%d: %s is in state %s, not in RUNNING.\n", __LINE__, c->name, s ? s : "undefined"); + goto out; + } + + len = c->get_cgroup_item(c, "cpuset.cpus", buf, 0); + if (len <= 0) { + fprintf(stderr, "%d: not able to get length of cpuset.cpus (ret %d)\n", __LINE__, len); + goto out; + } + + len = c->get_cgroup_item(c, "cpuset.cpus", buf, 200); + if (len <= 0 || strcmp(buf, "0\n")) { + fprintf(stderr, "%d: not able to get cpuset.cpus (len %d buf %s)\n", __LINE__, len, buf); + goto out; + } + + sprintf(buf, "FROZEN"); + b = c->set_cgroup_item(c, "freezer.state", buf); + if (!b) { + fprintf(stderr, "%d: not able to set freezer.state.\n", __LINE__); + goto out; + } + + sprintf(buf, "XXX"); + len = c->get_cgroup_item(c, "freezer.state", buf, 200); + if (len <= 0 || (strcmp(buf, "FREEZING\n") && strcmp(buf, "FROZEN\n"))) { + fprintf(stderr, "%d: not able to get freezer.state (len %d buf %s)\n", __LINE__, len, buf); + goto out; + } + + c->set_cgroup_item(c, "freezer.state", "THAWED"); + + printf("hit return to finish"); + ret = scanf("%c", &mychar); + if (ret < 0) + goto out; + c->stop(c); + + /* feh - multilib has moved the lxc-init crap */ +#if 0 + goto ok; + + ret = system("mkdir -p " LXCPATH "/lxctest1/rootfs//usr/local/libexec/lxc"); + if (!ret) + ret = system("mkdir -p " LXCPATH "/lxctest1/rootfs/usr/lib/lxc/"); + if (!ret) + ret = system("cp src/lxc/lxc-init " LXCPATH "/lxctest1/rootfs//usr/local/libexec/lxc"); + if (!ret) + ret = system("cp src/lxc/liblxc.so " LXCPATH "/lxctest1/rootfs/usr/lib/lxc"); + if (!ret) + ret = system("cp src/lxc/liblxc.so " LXCPATH "/lxctest1/rootfs/usr/lib/lxc/liblxc.so.0"); + if (!ret) + ret = system("cp src/lxc/liblxc.so " LXCPATH "/lxctest1/rootfs/usr/lib"); + if (!ret) + ret = system("mkdir -p " LXCPATH "/lxctest1/rootfs/dev/shm"); + if (!ret) + ret = system("chroot " LXCPATH "/lxctest1/rootfs apt-get install --no-install-recommends lxc"); + if (ret) { + fprintf(stderr, "%d: failed to installing lxc-init in container\n", __LINE__); + goto out; + } + // next write out the config file; does it match? + if (!c->startl(c, 1, "/bin/hostname", NULL)) { + fprintf(stderr, "%d: failed to lxc-execute /bin/hostname\n", __LINE__); + goto out; + } + // auto-check result? ('bobo' is printed on stdout) + +ok: +#endif + fprintf(stderr, "all lxc_container tests passed for %s\n", c->name); + ret = 0; + +out: + if (c) { + c->stop(c); + destroy_ubuntu(); + } + lxc_container_put(c); + exit(ret); +} diff -Nru lxc-0.8.0~rc1/templates/Makefile.am lxc-1.0.0~alpha1/templates/Makefile.am --- lxc-0.8.0~rc1/templates/Makefile.am 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/templates/Makefile.am 2013-09-10 22:22:00.000000000 +0000 @@ -2,12 +2,14 @@ templates_SCRIPTS = \ lxc-debian \ - lxc-lenny \ lxc-ubuntu \ lxc-ubuntu-cloud \ lxc-opensuse \ lxc-fedora \ + lxc-oracle \ lxc-altlinux \ lxc-busybox \ lxc-sshd \ - lxc-archlinux + lxc-archlinux \ + lxc-alpine \ + lxc-cirros diff -Nru lxc-0.8.0~rc1/templates/Makefile.in lxc-1.0.0~alpha1/templates/Makefile.in --- lxc-0.8.0~rc1/templates/Makefile.in 2012-03-01 23:04:43.000000000 +0000 +++ lxc-1.0.0~alpha1/templates/Makefile.in 2013-09-10 22:30:10.000000000 +0000 @@ -1,9 +1,8 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. +# Makefile.in generated by automake 1.13.3 from Makefile.am. # @configure_input@ -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -16,6 +15,51 @@ @SET_MAKE@ VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -35,22 +79,23 @@ build_triplet = @build@ host_triplet = @host@ subdir = templates -DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ - $(srcdir)/lxc-altlinux.in $(srcdir)/lxc-archlinux.in \ - $(srcdir)/lxc-busybox.in $(srcdir)/lxc-debian.in \ - $(srcdir)/lxc-fedora.in $(srcdir)/lxc-lenny.in \ - $(srcdir)/lxc-opensuse.in $(srcdir)/lxc-sshd.in \ - $(srcdir)/lxc-ubuntu-cloud.in $(srcdir)/lxc-ubuntu.in +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(srcdir)/lxc-cirros.in $(srcdir)/lxc-debian.in \ + $(srcdir)/lxc-ubuntu.in $(srcdir)/lxc-ubuntu-cloud.in \ + $(srcdir)/lxc-opensuse.in $(srcdir)/lxc-busybox.in \ + $(srcdir)/lxc-fedora.in $(srcdir)/lxc-oracle.in \ + $(srcdir)/lxc-altlinux.in $(srcdir)/lxc-sshd.in \ + $(srcdir)/lxc-archlinux.in $(srcdir)/lxc-alpine.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/config/acinclude.m4 \ - $(top_srcdir)/config/linux.m4 $(top_srcdir)/configure.ac + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/src/config.h -CONFIG_CLEAN_FILES = lxc-lenny lxc-debian lxc-ubuntu lxc-ubuntu-cloud \ - lxc-opensuse lxc-busybox lxc-fedora lxc-altlinux lxc-sshd \ - lxc-archlinux +CONFIG_CLEAN_FILES = lxc-cirros lxc-debian lxc-ubuntu lxc-ubuntu-cloud \ + lxc-opensuse lxc-busybox lxc-fedora lxc-oracle lxc-altlinux \ + lxc-sshd lxc-archlinux lxc-alpine CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ @@ -73,13 +118,39 @@ am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } am__installdirs = "$(DESTDIR)$(templatesdir)" SCRIPTS = $(templates_SCRIPTS) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = SOURCES = DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +APPARMOR_LIBS = @APPARMOR_LIBS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ @@ -110,19 +181,31 @@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBDIR = @LIBDIR@ +LIBEXECDIR = @LIBEXECDIR@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ -LINUX_DIR = @LINUX_DIR@ -LINUX_SRCARCH = @LINUX_SRCARCH@ LOCALSTATEDIR = @LOCALSTATEDIR@ +LOGPATH = @LOGPATH@ LTLIBOBJS = @LTLIBOBJS@ +LUA_CFLAGS = @LUA_CFLAGS@ +LUA_INSTALL_CMOD = @LUA_INSTALL_CMOD@ +LUA_INSTALL_LMOD = @LUA_INSTALL_LMOD@ +LUA_LIBS = @LUA_LIBS@ +LUA_VERSION = @LUA_VERSION@ +LXCHOOKDIR = @LXCHOOKDIR@ LXCINITDIR = @LXCINITDIR@ LXCPATH = @LXCPATH@ LXCROOTFSMOUNT = @LXCROOTFSMOUNT@ LXCTEMPLATEDIR = @LXCTEMPLATEDIR@ +LXC_DEFAULT_CONFIG = @LXC_DEFAULT_CONFIG@ +LXC_DISTRO_CONF = @LXC_DISTRO_CONF@ LXC_GENERATE_DATE = @LXC_GENERATE_DATE@ +LXC_GLOBAL_CONF = @LXC_GLOBAL_CONF@ +LXC_USERNIC_CONF = @LXC_USERNIC_CONF@ +LXC_USERNIC_DB = @LXC_USERNIC_DB@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +NEWUIDMAP = @NEWUIDMAP@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ @@ -132,8 +215,19 @@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PREFIX = @PREFIX@ -SETCAP = @SETCAP@ +PYTHON = @PYTHON@ +PYTHONDEV_CFLAGS = @PYTHONDEV_CFLAGS@ +PYTHONDEV_LIBS = @PYTHONDEV_LIBS@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +SECCOMP_LIBS = @SECCOMP_LIBS@ +SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ @@ -158,10 +252,11 @@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ +db2xman = @db2xman@ docdir = @docdir@ +docdtd = @docdtd@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ -have_docbook = @have_docbook@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ @@ -179,9 +274,13 @@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ @@ -193,15 +292,17 @@ templatesdir = @LXCTEMPLATEDIR@ templates_SCRIPTS = \ lxc-debian \ - lxc-lenny \ lxc-ubuntu \ lxc-ubuntu-cloud \ lxc-opensuse \ lxc-fedora \ + lxc-oracle \ lxc-altlinux \ lxc-busybox \ lxc-sshd \ - lxc-archlinux + lxc-archlinux \ + lxc-alpine \ + lxc-cirros all: all-am @@ -236,7 +337,7 @@ $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): -lxc-lenny: $(top_builddir)/config.status $(srcdir)/lxc-lenny.in +lxc-cirros: $(top_builddir)/config.status $(srcdir)/lxc-cirros.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ lxc-debian: $(top_builddir)/config.status $(srcdir)/lxc-debian.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ @@ -250,16 +351,23 @@ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ lxc-fedora: $(top_builddir)/config.status $(srcdir)/lxc-fedora.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ +lxc-oracle: $(top_builddir)/config.status $(srcdir)/lxc-oracle.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ lxc-altlinux: $(top_builddir)/config.status $(srcdir)/lxc-altlinux.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ lxc-sshd: $(top_builddir)/config.status $(srcdir)/lxc-sshd.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ lxc-archlinux: $(top_builddir)/config.status $(srcdir)/lxc-archlinux.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ +lxc-alpine: $(top_builddir)/config.status $(srcdir)/lxc-alpine.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ install-templatesSCRIPTS: $(templates_SCRIPTS) @$(NORMAL_INSTALL) - test -z "$(templatesdir)" || $(MKDIR_P) "$(DESTDIR)$(templatesdir)" @list='$(templates_SCRIPTS)'; test -n "$(templatesdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(templatesdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(templatesdir)" || exit 1; \ + fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ @@ -287,14 +395,12 @@ @list='$(templates_SCRIPTS)'; test -n "$(templatesdir)" || exit 0; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 's,.*/,,;$(transform)'`; \ - test -n "$$list" || exit 0; \ - echo " ( cd '$(DESTDIR)$(templatesdir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(templatesdir)" && rm -f $$files -tags: TAGS -TAGS: + dir='$(DESTDIR)$(templatesdir)'; $(am__uninstall_files_from_dir) +tags TAGS: + +ctags CTAGS: -ctags: CTAGS -CTAGS: +cscope cscopelist: distdir: $(DISTFILES) @@ -344,10 +450,15 @@ installcheck: installcheck-am install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi mostlyclean-generic: clean-generic: @@ -427,17 +538,17 @@ .MAKE: install-am install-strip -.PHONY: all all-am check check-am clean clean-generic distclean \ - distclean-generic distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip install-templatesSCRIPTS installcheck \ - installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ - pdf-am ps ps-am uninstall uninstall-am \ - uninstall-templatesSCRIPTS +.PHONY: all all-am check check-am clean clean-generic cscopelist-am \ + ctags-am distclean distclean-generic distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip \ + install-templatesSCRIPTS installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic pdf pdf-am ps ps-am tags-am \ + uninstall uninstall-am uninstall-templatesSCRIPTS # Tell versions [3.59,3.63) of GNU make to not export all variables. diff -Nru lxc-0.8.0~rc1/templates/lxc-alpine.in lxc-1.0.0~alpha1/templates/lxc-alpine.in --- lxc-0.8.0~rc1/templates/lxc-alpine.in 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/templates/lxc-alpine.in 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,349 @@ +#!/bin/sh + +key_sha256sums="9c102bcc376af1498d549b77bdbfa815ae86faa1d2d82f040e616b18ef2df2d4 alpine-devel@lists.alpinelinux.org-4a6a0840.rsa.pub +2adcf7ce224f476330b5360ca5edb92fd0bf91c92d83292ed028d7c4e26333ab alpine-devel@lists.alpinelinux.org-4d07755e.rsa.pub" + +get_static_apk () { + wget="wget -q -O -" + pkglist=alpine-keys:apk-tools-static + auto_repo_dir= + + if [ -z "$repository" ]; then + url=http://wiki.alpinelinux.org/cgi-bin/dl.cgi + if [ -z "$release" ]; then + echo -n "Determining the latest release... " + release=$($wget $url/.latest.$apk_arch.txt | \ + cut -d " " -f 3 | cut -d / -f 1 | uniq) + if [ -z "$release" ]; then + echo failed + return 1 + fi + echo $release + fi + auto_repo_dir=$release/main + repository=$url/$auto_repo_dir + pkglist=$pkglist:alpine-mirrors + fi + + rootfs="$1" + echo "Using static apk from $repository/$apk_arch" + wget="$wget $repository/$apk_arch" + + # parse APKINDEX to find the current versions + static_pkgs=$($wget/APKINDEX.tar.gz | \ + tar -Oxz APKINDEX | \ + awk -F: -v pkglist=$pkglist ' + BEGIN { split(pkglist,pkg) } + $0 != "" { f[$1] = $2 } + $0 == "" { for (i in pkg) + if (pkg[i] == f["P"]) + print(f["P"] "-" f["V"] ".apk") }') + [ "$static_pkgs" ] || return 1 + + mkdir -p "$rootfs" || return 1 + for pkg in $static_pkgs; do + echo "Downloading $pkg" + $wget/$pkg | tar -xz -C "$rootfs" + done + + # clean up .apk meta files + rm -f "$rootfs"/.[A-Z]* + + # verify checksum of the key + keyname=$(echo $rootfs/sbin/apk.static.*.pub | sed 's/.*\.SIGN\.RSA\.//') + checksum=$(echo "$key_sha256sums" | grep -w "$keyname") + if [ -z "$checksum" ]; then + echo "ERROR: checksum is missing for $keyname" + return 1 + fi + (cd $rootfs/etc/apk/keys && echo "$checksum" | sha256sum -c -) || return 1 + + # verify the static apk binary signature + APK=$rootfs/sbin/apk.static + openssl dgst -verify $rootfs/etc/apk/keys/$keyname \ + -signature "$APK.SIGN.RSA.$keyname" "$APK" || return 1 + + if [ "$auto_repo_dir" ]; then + mirror_list=$rootfs/usr/share/alpine-mirrors/MIRRORS.txt + mirror_count=$(wc -l $mirror_list | cut -d " " -f 1) + repository=$(sed $(expr $RANDOM % $mirror_count + 1)\!d \ + $mirror_list)$auto_repo_dir + echo "Selecting mirror $repository" + fi +} + +install_alpine() { + rootfs="$1" + shift + mkdir -p "$rootfs"/etc/apk || return 1 + : ${keys_dir:=/etc/apk/keys} + if ! [ -d "$rootfs"/etc/apk/keys ] && [ -d "$keys_dir" ]; then + cp -r "$keys_dir" "$rootfs"/etc/apk/keys + fi + if [ -n "$repository" ]; then + echo "$repository" > "$rootfs"/etc/apk/repositories + else + cp /etc/apk/repositories "$rootfs"/etc/apk/repositories || return 1 + if [ -n "$release" ]; then + sed -i -e "s:/[^/]\+/\([^/]\+\)$:/$release/\1:" \ + "$rootfs"/etc/apk/repositories + fi + fi + opt_arch= + if [ -n "$apk_arch" ]; then + opt_arch="--arch $apk_arch" + fi + $APK add -U --initdb --root $rootfs $opt_arch "$@" alpine-base +} + +configure_alpine() { + rootfs="$1" + echo "Setting up /etc/inittab" + cat >"$rootfs"/etc/inittab< "$rootfs/etc/resolv.conf" + + # configure the network using the dhcp + # note that lxc will set up lo interface + cat < $rootfs/etc/network/interfaces +#auto lo +iface lo inet loopback + +auto eth0 +iface eth0 inet dhcp +EOF + + # set the hostname + echo $hostname > $rootfs/etc/hostname + + # missing device nodes + echo "Setting up device nodes" + mkdir -p -m 755 "$rootfs/dev/pts" + mkdir -p -m 1777 "$rootfs/dev/shm" + mknod -m 666 "$rootfs/dev/zero" c 1 5 + mknod -m 666 "$rootfs/dev/full" c 1 7 + mknod -m 666 "$rootfs/dev/random" c 1 8 + mknod -m 666 "$rootfs/dev/urandom" c 1 9 + mknod -m 666 "$rootfs/dev/tty0" c 4 0 + mknod -m 666 "$rootfs/dev/tty1" c 4 1 + mknod -m 666 "$rootfs/dev/tty2" c 4 2 + mknod -m 666 "$rootfs/dev/tty3" c 4 3 + mknod -m 666 "$rootfs/dev/tty4" c 4 4 +# mknod -m 600 "$rootfs/dev/initctl" p + mknod -m 666 "$rootfs/dev/tty" c 5 0 + mknod -m 666 "$rootfs/dev/console" c 5 1 + mknod -m 666 "$rootfs/dev/ptmx" c 5 2 + + # start services + ln -s /etc/init.d/syslog "$rootfs"/etc/runlevels/default/syslog + + return 0 +} + +copy_configuration() { + path=$1 + rootfs=$2 + hostname=$3 + + grep -q "^lxc.rootfs" $path/config 2>/dev/null \ + || echo "lxc.rootfs = $rootfs" >> $path/config + if [ -n "$lxc_arch" ]; then + echo "lxc.arch = $lxc_arch" >> $path/config + fi + + lxc_network_link_line="# lxc.network.link = br0" + for br in lxcbr0 virbr0 br0; do + if [ -d /sys/class/net/$br/bridge ]; then + lxc_network_link_line="lxc.network.link = $br" + break + fi + done + + if ! grep -q "^lxc.network.type" $path/config 2>/dev/null; then + cat <> $path/config +lxc.network.type = veth +$lxc_network_link_line +lxc.network.flags = up +EOF + fi + + # if there is exactly one veth or macvlan network entry, make sure + # it has an associated mac address. + nics=$(awk -F '[ \t]*=[ \t]*' \ + '$1=="lxc.network.type" && ($2=="veth" || $2=="macvlan") {print $2}' \ + $path/config | wc -l) + if [ "$nics" -eq 1 ] && ! grep -q "^lxc.network.hwaddr" $path/config; then + # see http://sourceforge.net/tracker/?func=detail&aid=3411497&group_id=163076&atid=826303 + hwaddr="fe:$(dd if=/dev/urandom bs=8 count=1 2>/dev/null |od -t x8 | \ + head -1 |awk '{print $2}' | cut -c1-10 |\ + sed 's/\(..\)/\1:/g; s/.$//')" + echo "lxc.network.hwaddr = $hwaddr" >> $path/config + fi + + cat <> $path/config + +lxc.tty = 4 +lxc.pts = 1024 +lxc.utsname = $hostname +lxc.cap.drop = sys_module mac_admin mac_override sys_time + +# When using LXC with apparmor, uncomment the next line to run unconfined: +#lxc.aa_profile = unconfined + +# devices +lxc.cgroup.devices.deny = a +# /dev/null and zero +lxc.cgroup.devices.allow = c 1:3 rwm +lxc.cgroup.devices.allow = c 1:5 rwm +# consoles +lxc.cgroup.devices.allow = c 5:1 rwm +lxc.cgroup.devices.allow = c 5:0 rwm +lxc.cgroup.devices.allow = c 4:0 rwm +lxc.cgroup.devices.allow = c 4:1 rwm +# /dev/{,u}random +lxc.cgroup.devices.allow = c 1:9 rwm +lxc.cgroup.devices.allow = c 1:8 rwm +lxc.cgroup.devices.allow = c 136:* rwm +lxc.cgroup.devices.allow = c 5:2 rwm +# rtc +lxc.cgroup.devices.allow = c 254:0 rm + +# mounts point +lxc.mount.entry=proc proc proc nodev,noexec,nosuid 0 0 +lxc.mount.entry=run run tmpfs nodev,noexec,nosuid,relatime,size=1m,mode=0755 0 0 +lxc.mount.entry=none dev/pts devpts gid=5,mode=620 0 0 + +EOF + + return 0 +} + +die() { + echo "$@" >&2 + exit 1 +} + +usage() { + cat >&2 <] + [-R|--release ] [-a|--arch ] + [--rootfs ] -p|--path -n|--name + [PKG...] +EOF +} + +usage_err() { + usage + exit 1 +} + +optarg_check() { + if [ -z "$2" ]; then + usage_err "option '$1' requires an argument" + fi +} + +default_path=@LXCPATH@ +release= +arch=$(uname -m) + +# template mknods, requires root +if [ $(id -u) -ne 0 ]; then + echo "$(basename $0): must be run as root" >&2 + exit 1 +fi + +while [ $# -gt 0 ]; do + opt="$1" + shift + case "$opt" in + -h|--help) + usage + exit 0 + ;; + -n|--name) + optarg_check $opt "$1" + name=$1 + shift + ;; + --rootfs) + optarg_check $opt "$1" + rootfs=$1 + shift + ;; + -p|--path) + optarg_check $opt "$1" + path=$1 + shift + ;; + -r|--repository) + optarg_check $opt "$1" + repository=$1 + shift + ;; + -R|--release) + optarg_check $opt "$1" + release=$1 + shift + ;; + -a|--arch) + optarg_check $opt "$1" + arch=$1 + shift + ;; + --) + break;; + --*=*) + # split --myopt=foo=bar into --myopt foo=bar + set -- ${opt%=*} ${opt#*=} "$@" + ;; + -?) + usage_err "unknown option '$opt'" + ;; + -*) + # split opts -abc into -a -b -c + set -- $(echo "${opt#-}" | sed 's/\(.\)/ -\1/g') "$@" + ;; + esac +done + + +[ -z "$name" ] && usage_err + +if [ -z "${path}" ]; then + path="${default_path}/${name}" +fi + +if [ -z "$rootfs" ]; then + rootfs=`awk -F= '$1 ~ /^lxc.rootfs/ { print $2 }' "$path/config" 2>/dev/null` + if [ -z "$rootfs" ]; then + rootfs="${path}/rootfs" + fi +fi + +lxc_arch=$arch +apk_arch=$arch + +case "$arch" in + i[3-6]86) + apk_arch=x86;; + x86) + lxc_arch=i686;; + x86_64|"") ;; + *) die "unsupported architecture: $arch";; +esac + +: ${APK:=apk} +if ! which $APK >/dev/null; then + get_static_apk "$rootfs" || die "Failed to download a valid static apk" +fi + +install_alpine "$rootfs" "$@" || die "Failed to install rootfs for $name" +configure_alpine "$rootfs" "$name" || die "Failed to configure $name" +copy_configuration "$path" "$rootfs" "$name" diff -Nru lxc-0.8.0~rc1/templates/lxc-altlinux.in lxc-1.0.0~alpha1/templates/lxc-altlinux.in --- lxc-0.8.0~rc1/templates/lxc-altlinux.in 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/templates/lxc-altlinux.in 2013-09-10 22:22:00.000000000 +0000 @@ -17,16 +17,16 @@ # 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 +# 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 +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #Configurations -arch=$(arch) -cache_base=/var/cache/lxc/altlinux/$arch +arch=$(uname -m) +cache_base=@LOCALSTATEDIR@/cache/lxc/altlinux/$arch default_path=@LXCPATH@ default_profile=default profile_dir=/etc/lxc/profiles @@ -151,8 +151,8 @@ INSTALL_ROOT=$cache/partial mkdir -p $INSTALL_ROOT if [ $? -ne 0 ]; then - echo "Failed to create '$INSTALL_ROOT' directory" - return 1 + echo "Failed to create '$INSTALL_ROOT' directory" + return 1 fi # download a mini altlinux into a cache @@ -166,8 +166,8 @@ $APT_GET install $PKG_LIST if [ $? -ne 0 ]; then - echo "Failed to download the rootfs, aborting." - return 1 + echo "Failed to download the rootfs, aborting." + return 1 fi mv "$INSTALL_ROOT" "$cache/rootfs" @@ -184,7 +184,7 @@ #cp -a $cache/rootfs-$arch $rootfs_path || return 1 # i prefer rsync (no reason really) mkdir -p $rootfs_path - rsync -a $cache/rootfs/ $rootfs_path/ + rsync -Ha $cache/rootfs/ $rootfs_path/ return 0 } @@ -196,41 +196,39 @@ install_altlinux() { - mkdir -p /var/lock/subsys/ + mkdir -p @LOCALSTATEDIR@/lock/subsys/ ( - flock -n -x 200 - if [ $? -ne 0 ]; then - echo "Cache repository is busy." - return 1 - fi - - echo "Checking cache download in $cache/rootfs ... " - if [ ! -e "$cache/rootfs" ]; then - download_altlinux - if [ $? -ne 0 ]; then - echo "Failed to download 'altlinux base'" - return 1 - fi + flock -x 200 + if [ $? -ne 0 ]; then + echo "Cache repository is busy." + return 1 + fi + + echo "Checking cache download in $cache/rootfs ... " + if [ ! -e "$cache/rootfs" ]; then + download_altlinux + if [ $? -ne 0 ]; then + echo "Failed to download 'altlinux base'" + return 1 + fi else - echo "Cache found. Updating..." + echo "Cache found. Updating..." update_altlinux - if [ $? -ne 0 ]; then - echo "Failed to update 'altlinux base', continuing with last known good cache" + if [ $? -ne 0 ]; then + echo "Failed to update 'altlinux base', continuing with last known good cache" else echo "Update finished" - fi - fi + fi + fi - echo "Copy $cache/rootfs to $rootfs_path ... " - copy_altlinux - if [ $? -ne 0 ]; then - echo "Failed to copy rootfs" - return 1 - fi - - return 0 - - ) 200>/var/lock/subsys/lxc + echo "Copy $cache/rootfs to $rootfs_path ... " + copy_altlinux + if [ $? -ne 0 ]; then + echo "Failed to copy rootfs" + return 1 + fi + return 0 + ) 200>@LOCALSTATEDIR@/lock/subsys/lxc-altlinux return $? } @@ -239,12 +237,17 @@ { mkdir -p $config_path + grep -q "^lxc.rootfs" $config_path/config 2>/dev/null || echo "lxc.rootfs = $rootfs_path" >> $config_path/config cat <> $config_path/config lxc.utsname = $name lxc.tty = 4 lxc.pts = 1024 -lxc.rootfs = $rootfs_path -lxc.mount = $config_path/fstab +lxc.mount = $config_path/fstab +lxc.cap.drop = sys_module mac_admin mac_override sys_time + +# When using LXC with apparmor, uncomment the next line to run unconfined: +#lxc.aa_profile = unconfined + #networking lxc.network.type = $lxc_network_type lxc.network.flags = up @@ -298,8 +301,8 @@ EOF if [ $? -ne 0 ]; then - echo "Failed to add configuration" - return 1 + echo "Failed to add configuration" + return 1 fi return 0 @@ -309,22 +312,21 @@ { if [ ! -e $cache ]; then - exit 0 + exit 0 fi # lock, so we won't purge while someone is creating a repository ( - flock -n -x 200 - if [ $? != 0 ]; then - echo "Cache repository is busy." - exit 1 - fi - - echo -n "Purging the download cache for ALTLinux-$release..." - rm --preserve-root --one-file-system -rf $cache && echo "Done." || exit 1 - exit 0 - - ) 200>/var/lock/subsys/lxc + flock -x 200 + if [ $? != 0 ]; then + echo "Cache repository is busy." + exit 1 + fi + + echo -n "Purging the download cache for ALTLinux-$release..." + rm --preserve-root --one-file-system -rf $cache && echo "Done." || exit 1 + exit 0 + ) 200>@LOCALSTATEDIR@/lock/subsys/lxc-altlinux } usage() @@ -335,13 +337,13 @@ [-p|--path=] [-c|--clean] [-R|--release=] [-4|--ipv4=] [-6|--ipv6=] [-g|--gw=] [-d|--dns=] - [-P|--profile=] + [-P|--profile=] [--rootfs=] [-A|--arch=] [-h|--help] Mandatory args: -n,--name container name, used to as an identifier for that container from now on Optional args: - -p,--path path to where the container rootfs will be created, defaults to /var/lib/lxc. The container config will go under /var/lib/lxc in and case + -p,--path path to where the container rootfs will be created, defaults to @LXCPATH@. The container config will go under @LXCPATH@ in that case -c,--clean clean the cache -R,--release ALTLinux release for the new container. if the host is ALTLinux, then it will defaultto the host's release. -4,--ipv4 specify the ipv4 address to assign to the virtualized interface, eg. 192.168.1.123/24 @@ -351,12 +353,13 @@ -d,--dns specify the DNS server, eg. 192.168.1.2 -P,--profile Profile name is the file name in /etc/lxc/profiles contained packages name for install to cache. -A,--arch NOT USED YET. Define what arch the container will be [i686,x86_64] + ---rootfs rootfs path -h,--help print this help EOF return 0 } -options=$(getopt -o hp:n:P:cR:4:6:g:d: -l help,path:,name:,profile:,clean,release:ipv4:ipv6:gw:dns: -- "$@") +options=$(getopt -o hp:n:P:cR:4:6:g:d: -l help,rootfs:,path:,name:,profile:,clean,release:ipv4:ipv6:gw:dns: -- "$@") if [ $? -ne 0 ]; then usage $(basename $0) exit 1 @@ -366,17 +369,18 @@ while true do case "$1" in - -h|--help) usage $0 && exit 0;; - -p|--path) path=$2; shift 2;; - -n|--name) name=$2; shift 2;; - -P|--profile) profile=$2; shift 2;; - -c|--clean) clean=$2; shift 2;; - -R|--release) release=$2; shift 2;; - -4|--ipv4) ipv4=$2; shift 2;; - -6|--ipv6) ipv6=$2; shift 2;; - -g|--gw) gw=$2; shift 2;; - -d|--dns) dns=$2; shift 2;; - --) shift 1; break ;; + -h|--help) usage $0 && exit 0;; + -p|--path) path=$2; shift 2;; + --rootfs) rootfs_path=$2; shift 2;; + -n|--name) name=$2; shift 2;; + -P|--profile) profile=$2; shift 2;; + -c|--clean) clean=$2; shift 2;; + -R|--release) release=$2; shift 2;; + -4|--ipv4) ipv4=$2; shift 2;; + -6|--ipv6) ipv6=$2; shift 2;; + -g|--gw) gw=$2; shift 2;; + -d|--dns) dns=$2; shift 2;; + --) shift 1; break ;; *) break ;; esac done @@ -420,7 +424,15 @@ exit 1 fi -rootfs_path=$path/$name/rootfs +# check for 'lxc.rootfs' passed in through default config by lxc-create +if [ -z "$rootfs_path" ]; then + if grep -q '^lxc.rootfs' $path/config 2>/dev/null ; then + rootfs_path=`grep 'lxc.rootfs =' $path/config | awk -F= '{ print $2 }'` + else + rootfs_path=$path/$name/rootfs + fi +fi + config_path=$default_path/$name cache=$cache_base/$release/$profile @@ -452,4 +464,4 @@ exit 0 fi echo "container rootfs and config created" -echo "container is configured for lxc.network.type=veth and lxc.network.link=virbr0 (which is default if you have libvirt runnig)" +echo "network configured as $lxc_network_type in the $lxc_network_link" diff -Nru lxc-0.8.0~rc1/templates/lxc-archlinux.in lxc-1.0.0~alpha1/templates/lxc-archlinux.in --- lxc-0.8.0~rc1/templates/lxc-archlinux.in 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/templates/lxc-archlinux.in 2013-09-10 22:22:00.000000000 +0000 @@ -22,29 +22,28 @@ # 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 +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # defaults -arch=$(arch) -cache=/var/cache/lxc/arch/${arch} +arch=$(uname -m) lxc_network_type="veth" lxc_network_link="br0" -default_path=/var/lib/lxc -default_rc_locale="en-US.UTF-8" -default_rc_timezone="UTC" -host_mirror="http://mirrors.kernel.org/archlinux/\$repo/os/$arch" +default_path="@LXCPATH@" +default_locale="en-US.UTF-8" +default_timezone="UTC" +pacman_config="/etc/pacman.conf" # sort of minimal package set base_packages=( + "systemd" + "systemd-sysvcompat" "filesystem" - "initscripts" "coreutils" - "module-init-tools" + "kmod" "procps" "psmisc" "pacman" "bash" - "syslog-ng" "cronie" "iproute2" "iputils" @@ -57,27 +56,11 @@ "gawk" "sed" "tar" - "wget" "gzip" "which" ) declare -a additional_packages -[ -f /etc/arch-release ] && is_arch=true - -# find and extract parameter value from given config file -# ${1} - file to read parameter from -# ${2} - parameter name -# ${result} - result value on success -function read_parameter_value { - [ -f ${1} ] && [ "${2}" ] || return 1 - local pattern="^[[:space:]]*${2}[[:space:]]*=[[:space:]]*" - local str=$(grep "${pattern}" "${1}") - local str=${str/#$(grep -o "${pattern}" "${1}")/} - result=${str//\"/} - return 0 -} - # split comma-separated string into an array # ${1} - string to split # ${2} - separator (default is ",") @@ -90,128 +73,47 @@ return 0 } +[ -f /etc/arch-release ] && is_arch=true + # Arch-specific preconfiguration for container function configure_arch { # read locale and timezone defaults from system rc.conf if running on Arch if [ "${is_arch}" ]; then - read_parameter_value "/etc/rc.conf" "LOCALE" - rc_locale=${result:-${default_rc_locale}} - read_parameter_value "/etc/rc.conf" "TIMEZONE" - rc_timezone=${result:-${default_rc_timezone}} + cp -p /etc/vconsole.conf /etc/locale.conf /etc/locale.gen "${rootfs_path}/etc/" else - rc_locale=${default_rc_locale} - rc_timezone=${default_rc_timezone} - fi - - echo "Setting up rc.conf" - cat > "${rootfs_path}/etc/rc.conf" << EOF -# /etc/rc.conf - Main Configuration for Arch Linux -LOCALE="${rc_locale}" -DAEMON_LOCALE="no" -HARDWARECLOCK="local" -TIMEZONE="${rc_timezone}" -KEYMAP=us -CONSOLEFONT= -CONSOLEMAP= -USECOLOR="yes" -MODULES=() -HOSTNAME="${name}" -interface=eth0 -address= -netmask= -broadcast= -gateway= -DAEMONS=(syslog-ng crond network) + echo "LANG=${default_lang}" > "${rootfs_path}/etc/locale.conf" + echo "KEYMAP=us" > "${rootfs_path}/etc/vconsole.conf" + cat > "${rootfs_path}/etc/adjtime" << EOF +0.0 0.0 0.0 +0 +LOCAL EOF - - if [ -e "${rootfs_path}/etc/locale.gen" ]; then - sed -i 's@^#\(en_US\.UTF-8\)@\1@' "${rootfs_path}/etc/locale.gen" - if [ ! "${rc_locale}" = "en_US.UTF-8" ]; then - echo "${rc_locale} ${rc_locale##*.}" >> "${rootfs_path}/etc/locale.gen" + if [ -e "${rootfs_path}/etc/locale.gen" ]; then + sed -i 's@^#\(en_US\.UTF-8\)@\1@' "${rootfs_path}/etc/locale.gen" + if [ ! "${default_locale}" = "en_US.UTF-8" ]; then + echo "${default_locale} ${default_locale##*.}" >> "${rootfs_path}/etc/locale.gen" + fi fi - chroot "${rootfs_path}" locale-gen fi - cp "${rootfs_path}/usr/share/zoneinfo/${rc_timezone}" \ - "${rootfs_path}/etc/localtime" - - echo "Setting up rc.sysinit" - cat > "${rootfs_path}/etc/rc.sysinit.lxc" << EOF -#!/bin/bash -. /etc/rc.conf -. /etc/rc.d/functions - -echo "starting Arch Linux" -rm -f \$(find /var/run -name '*pid') -rm -f /run/daemons/* -rm -f /var/lock/subsys/* -rm -f /etc/mtab -touch /etc/mtab -run_hook sysinit_end -EOF - - echo "Setting up rc.shutdown" - cat > "${rootfs_path}/etc/rc.shutdown.lxc" << EOF -#!/bin/bash -. /etc/rc.conf -. /etc/rc.d/functions -stty onlcr -run_hook shutdown_start -[[ -x /etc/rc.local.shutdown ]] && /etc/rc.local.shutdown -stop_all_daemons -run_hook shutdown_prekillall -kill_all -run_hook shutdown_postkillall -[[ \${TIMEZONE} ]] && cp --remove-destination "/usr/share/zoneinfo/\${TIMEZONE}" /etc/localtime -halt -w -umount -a -r -t nodevtmpfs,notmpfs,nosysfs,noproc,nodevpts -O no_netdev -run_hook shutdown_postumount -run_hook shutdown_poweroff -if [[ \${RUNLEVEL} = 0 ]]; then - poweroff -d -f -i -else - reboot -d -f -i -fi -# vim: set ts=2 sw=2 noet: -EOF - chmod 755 "${rootfs_path}/etc/rc.shutdown.lxc" "${rootfs_path}/etc/rc.sysinit.lxc" - - echo "Setting up inittab" - cat > "${rootfs_path}/etc/inittab" << EOF -id:3:initdefault: -rc::sysinit:/etc/rc.sysinit.lxc -rs:S1:wait:/etc/rc.single -rm:2345:wait:/etc/rc.multi -rh:06:wait:/etc/rc.shutdown.lxc -su:S:wait:/sbin/sulogin -p -c1:2345:respawn:/sbin/agetty -8 38400 tty1 linux -EOF - - echo "Setting up hosts" + echo "${name}" > "${rootfs_path}/etc/hostname" cat > "${rootfs_path}/etc/hosts" << EOF 127.0.0.1 localhost.localdomain localhost ${name} ::1 localhost.localdomain localhost EOF - - echo "Setting up nameserver" grep nameserver /etc/resolv.conf > "${rootfs_path}/etc/resolv.conf" - echo "Setting up device nodes" - mkdir -m 755 "${rootfs_path}/dev/pts" - mkdir -m 1777 "${rootfs_path}/dev/shm" - mknod -m 666 "${rootfs_path}/dev/null" c 1 3 - mknod -m 666 "${rootfs_path}/dev/full" c 1 7 - mknod -m 666 "${rootfs_path}/dev/random" c 1 8 - mknod -m 666 "${rootfs_path}/dev/urandom" c 1 9 - mknod -m 666 "${rootfs_path}/dev/tty0" c 4 0 - mknod -m 666 "${rootfs_path}/dev/tty1" c 4 1 - mknod -m 666 "${rootfs_path}/dev/tty2" c 4 2 - mknod -m 666 "${rootfs_path}/dev/tty3" c 4 3 - mknod -m 666 "${rootfs_path}/dev/tty4" c 4 4 - mknod -m 600 "${rootfs_path}/dev/initctl" p - mknod -m 666 "${rootfs_path}/dev/tty" c 5 0 - mknod -m 666 "${rootfs_path}/dev/console" c 5 1 - mknod -m 666 "${rootfs_path}/dev/ptmx" c 5 2 - + arch-chroot "${rootfs_path}" /bin/bash -s << EOF +mkdir /run/lock +locale-gen +ln -s /usr/share/zoneinfo/${default_timezone} /etc/localtime +# disable services unavailable for container +ln -s /dev/null /etc/systemd/system/systemd-udevd.service +ln -s /dev/null /etc/systemd/system/systemd-udevd-control.socket +ln -s /dev/null /etc/systemd/system/systemd-udevd-kernel.socket +ln -s /dev/null /etc/systemd/system/proc-sys-fs-binfmt_misc.automount +# set default systemd target +ln -s /lib/systemd/system/multi-user.target /etc/systemd/system/default.target +EOF return 0 } @@ -220,165 +122,77 @@ mkdir -p "${config_path}" cat > "${config_path}/config" << EOF lxc.utsname=${name} -lxc.tty=4 +lxc.autodev=1 +lxc.tty=1 lxc.pts=1024 -lxc.rootfs=${rootfs_path} lxc.mount=${config_path}/fstab +lxc.cap.drop=mknod sys_module mac_admin mac_override sys_time +lxc.kmsg=0 +lxc.stopsignal=SIGRTMIN+4 #networking lxc.network.type=${lxc_network_type} -lxc.network.flags=up lxc.network.link=${lxc_network_link} +lxc.network.flags=up lxc.network.name=eth0 lxc.network.mtu=1500 #cgroups lxc.cgroup.devices.deny = a -# /dev/null and zero +lxc.cgroup.devices.allow = c *:* m +lxc.cgroup.devices.allow = b *:* m lxc.cgroup.devices.allow = c 1:3 rwm lxc.cgroup.devices.allow = c 1:5 rwm -# consoles -lxc.cgroup.devices.allow = c 5:1 rwm -lxc.cgroup.devices.allow = c 5:0 rwm -lxc.cgroup.devices.allow = c 4:0 rwm -lxc.cgroup.devices.allow = c 4:1 rwm -# /dev/{,u}random -lxc.cgroup.devices.allow = c 1:9 rwm +lxc.cgroup.devices.allow = c 1:7 rwm lxc.cgroup.devices.allow = c 1:8 rwm -# /dev/pts -lxc.cgroup.devices.allow = c 136:* rwm +lxc.cgroup.devices.allow = c 1:9 rwm +lxc.cgroup.devices.allow = c 1:9 rwm +lxc.cgroup.devices.allow = c 4:1 rwm +lxc.cgroup.devices.allow = c 5:0 rwm +lxc.cgroup.devices.allow = c 5:1 rwm lxc.cgroup.devices.allow = c 5:2 rwm -# rtc -lxc.cgroup.devices.allow = c 254:0 rwm +lxc.cgroup.devices.allow = c 136:* rwm EOF + grep -q "^lxc.rootfs" ${config_path}/config 2>/dev/null || echo "lxc.rootfs = ${rootfs_path}" >> ${config_path}/config + cat > "${config_path}/fstab" << EOF -none ${rootfs_path}/dev/pts devpts defaults 0 0 -none ${rootfs_path}/proc proc nodev,noexec,nosuid 0 0 -none ${rootfs_path}/sys sysfs defaults 0 0 -none ${rootfs_path}/dev/shm tmpfs defaults 0 0 +sysfs sys sysfs ro,defaults 0 0 +proc proc proc nodev,noexec,nosuid 0 0 +/proc/sys ${rootfs_path}/proc/sys none ro,bind 0 0 +#/var/log/journal ${rootfs_path}/var/log/journal none bind 0 0 EOF - if [ ${?} -ne 0 ]; then - echo "Failed to configure container" - return 1 - fi - return 0 } -# lock chroot and mount subdirectories before installing container -function mount_chroot { - echo "mounting chroot" - umask 0022 - [ -e "${rootfs_path}/sys" ] || mkdir "${rootfs_path}/sys" - mount -t sysfs sysfs "${rootfs_path}/sys" - [ -e "${rootfs_path}/proc" ] || mkdir "${rootfs_path}/proc" - mount -t proc proc "${rootfs_path}/proc" - [ -e "${rootfs_path}/dev" ] || mkdir "${rootfs_path}/dev" - mount -t tmpfs dev "${rootfs_path}/dev" -o mode=0755,size=10M,nosuid - mknod -m 666 "${rootfs_path}/dev/null" c 1 3 - mknod -m 666 "${rootfs_path}/dev/zero" c 1 5 - mknod -m 600 "${rootfs_path}/dev/console" c 5 1 - mknod -m 644 "${rootfs_path}/dev/random" c 1 8 - mknod -m 644 "${rootfs_path}/dev/urandom" c 1 9 - mknod -m 666 "${rootfs_path}/dev/tty" c 5 0 - mknod -m 666 "${rootfs_path}/dev/tty0" c 4 0 - mknod -m 666 "${rootfs_path}/dev/full" c 1 7 - ln -s /proc/kcore "${rootfs_path}/dev/core" - ln -s /proc/self/fd "${rootfs_path}/dev/fd" - ln -s /proc/self/fd/0 "${rootfs_path}/dev/stdin" - ln -s /proc/self/fd/1 "${rootfs_path}/dev/stdout" - ln -s /proc/self/fd/2 "${rootfs_path}/dev/stderr" - [ -e "${rootfs_path}/dev/shm" ] || mkdir "${rootfs_path}/dev/shm" - mount -t tmpfs shm "${rootfs_path}/dev/shm" -o nodev,nosuid,size=128M - [ -e "${rootfs_path}/dev/pts" ] || mkdir "${rootfs_path}/dev/pts" - mount -t devpts devpts "${rootfs_path}/dev/pts" -o newinstance,ptmxmode=666 - ln -s pts/ptmx "${rootfs_path}/dev/ptmx" - [ -e "${cache_dir}" ] || mkdir -p "${cache_dir}" - [ -e "${rootfs_path}/${cache_dir}" ] || mkdir -p "${rootfs_path}/${cache_dir}" - mount -o bind "${cache_dir}" "${rootfs_path}/${cache_dir}" - if [ -n "${host_mirror_path}" ]; then - [ -e "${rootfs_path}/${host_mirror_path}" ] || mkdir -p "${rootfs_path}/${host_mirror_path}" - mount -o bind "${host_mirror_path}" "${rootfs_path}/${host_mirror_path}" - mount -o remount,ro,bind "${host_mirror_path}" "${rootfs_path}/${host_mirror_path}" - fi - trap 'umount_chroot' EXIT INT QUIT TERM HUP -} - -function umount_chroot { - if [ -z "${umount_done}" ]; then - echo "unmounting chroot" - umount "${rootfs_path}/proc" - umount "${rootfs_path}/sys" - umount "${rootfs_path}/dev/pts" - umount "${rootfs_path}/dev/shm" - umount "${rootfs_path}/dev" - umount "${rootfs_path}/${cache_dir}" - [ -n "${host_mirror_path}" ] && umount "${rootfs_path}/${host_mirror_path}" - umount_done=1 - fi -} - # install packages within container chroot function install_arch { - pacman_config=$(mktemp) - - cat < "${pacman_config}" -[options] -HoldPkg = pacman glibc -SyncFirst = pacman -Architecture = auto -#IgnorePkg = udev -[core] -Include = /etc/pacman.d/mirrorlist -Server = ${host_mirror} -[extra] -Include = /etc/pacman.d/mirrorlist -Server = ${host_mirror} -[community] -Include = /etc/pacman.d/mirrorlist -Server = ${host_mirror} -EOF - - mkdir -p "${rootfs_path}/var/lib/pacman/sync" - mkdir -p "${rootfs_path}/etc" - - if echo "${host_mirror}" | grep -q 'file://'; then - host_mirror_path=$(echo "${host_mirror}" | sed -E 's#file://(/.*)/\$repo/os/\$arch#\1#g') - fi - cache_dir=$( (grep -m 1 '^CacheDir' "${pacman_config}" || echo 'CacheDir = /var/cache/pacman/pkg') | sed 's/CacheDir\s*=\s*//') - mount_chroot - params="--root ${rootfs_path} --config=${pacman_config} --noconfirm" - if ! pacman -Sydd ${params} --dbonly udev; then - echo "Failed to preinstall udev package record" - return 1 - fi - if ! pacman -S ${params} ${base_packages[@]}; then + if ! pacstrap -dcC "${pacman_config}" "${rootfs_path}" ${base_packages[@]}; then echo "Failed to install container packages" return 1 fi [ -d "${rootfs_path}/lib/modules" ] && ldconfig -r "${rootfs_path}" - mv "${pacman_config}" "${rootfs_path}/etc/pacman.conf" - umount_chroot return 0 } -usage() -{ +usage() { cat < - [-P|--packages=] [-p|--path=] [-h|--help] + [-P|--packages=] [-p|--path=] [-t|--network_type=] [-l|--network_link=] [-h|--help] Mandatory args: -n,--name container name, used to as an identifier for that container from now on Optional args: - -p,--path path to where the container rootfs will be created, defaults to /var/lib/lxc. The container config will go under /var/lib/lxc in that case + -p,--path path to where the container rootfs will be created, defaults to ${default_path}/rootfs. The container config will go under ${default_path} in that case -P,--packages preinstall additional packages, comma-separated list + -c,--config use specified pacman config when installing container packages + -t,--network_type set container network interface type (${lxc_network_type}) + -l,--network_link set network link device (${lxc_network_link}) -h,--help print this help EOF return 0 } -options=$(getopt -o hp:P:n:cm: -l help,path:,packages:,name:,clean,mirror: -- "${@}") +options=$(getopt -o hp:P:n:c:l:t: -l help,rootfs:,path:,packages:,name:,config:,network_type:,network_link: -- "${@}") if [ ${?} -ne 0 ]; then usage $(basename ${0}) exit 1 @@ -388,11 +202,14 @@ while true do case "${1}" in - -h|--help) usage ${0} && exit 0;; - -p|--path) path=${2}; shift 2;; - -n|--name) name=${2}; shift 2;; - -P|--packages) additional_packages=${2}; shift 2;; - -m|--mirror) host_mirror=${2}; shift 2;; + -h|--help) usage ${0} && exit 0;; + -p|--path) path=${2}; shift 2;; + -n|--name) name=${2}; shift 2;; + --rootfs) rootfs_path=${2}; shift 2;; + -P|--packages) additional_packages=${2}; shift 2;; + -c|--config) pacman_config=${2}; shift 2;; + -t|--network_type) lxc_network_type=${2}; shift 2;; + -l|--network_link) lxc_network_link=${2}; shift 2;; --) shift 1; break ;; *) break ;; esac @@ -403,6 +220,11 @@ exit 1 fi +if [ ! -e /sys/class/net/${lxc_network_link} ]; then + echo "network link interface does not exist" + exit 1 +fi + type pacman >/dev/null 2>&1 if [ ${?} -ne 0 ]; then echo "'pacman' command is missing, refer to wiki.archlinux.org for information about installing pacman" @@ -418,14 +240,14 @@ exit 1 fi -rootfs_path="${path}/rootfs" +if [ -z "$rootfs_path" ]; then + rootfs_path="${path}/rootfs" +fi config_path="${default_path}/${name}" -revert() -{ - echo "Interrupted, so cleaning up" +revert() { + echo "Interrupted, cleaning up" lxc-destroy -n "${name}" - # maybe was interrupted before copy config rm -rf "${path}/${name}" rm -rf "${default_path}/${name}" exit 1 @@ -435,7 +257,7 @@ copy_configuration if [ ${?} -ne 0 ]; then - echo "failed write configuration file" + echo "failed to write configuration file" rm -rf "${config_path}" exit 1 fi @@ -445,18 +267,19 @@ base_packages+=(${result[@]}) fi +mkdir -p "${rootfs_path}" install_arch if [ ${?} -ne 0 ]; then - echo "failed to install Arch linux" + echo "failed to install Arch Linux" rm -rf "${config_path}" "${path}" exit 1 fi configure_arch if [ ${?} -ne 0 ]; then - echo "failed to configure Arch linux for a container" + echo "failed to configure Arch Linux for a container" rm -rf "${config_path}" "${path}" exit 1 fi -echo "container rootfs and config created" +echo "container config is ${config_path}/config" diff -Nru lxc-0.8.0~rc1/templates/lxc-busybox.in lxc-1.0.0~alpha1/templates/lxc-busybox.in --- lxc-0.8.0~rc1/templates/lxc-busybox.in 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/templates/lxc-busybox.in 2013-09-10 22:22:00.000000000 +0000 @@ -18,7 +18,7 @@ # 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 +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA install_busybox() { @@ -33,7 +33,9 @@ $rootfs/etc \ $rootfs/etc/init.d \ $rootfs/bin \ +$rootfs/usr/bin \ $rootfs/sbin \ +$rootfs/usr/sbin \ $rootfs/proc \ $rootfs/mnt \ $rootfs/tmp \ @@ -63,6 +65,8 @@ chmod 600 ram0 || res=1 mknod null c 1 3 || res=1 chmod 666 null || res=1 + mknod urandom c 1 9 || res=1 + chmod 666 urandom || res=1 popd > /dev/null @@ -108,36 +112,34 @@ cat <> $rootfs/usr/share/udhcpc/default.script #!/bin/sh - case "\$1" in - deconfig) - ip addr flush dev \$interface - ;; - - renew|bound) - - # flush all the routes - if [ -n "\$router" ]; then - ip route del default 2> /dev/null - fi - - # check broadcast - if [ -n "\$broadcast" ]; then - broadcast="broadcast \$broadcast" - fi - - # add a new ip address - ip addr add \$ip/\$mask \$broadcast dev \$interface - - if [ -n "\$router" ]; then - ip route add default via \$router dev \$interface - fi - - [ -n "\$domain" ] && echo search \$domain > /etc/resolv.conf - for i in \$dns ; do - echo nameserver \$i >> /etc/resolv.conf - done - ;; + deconfig) + ip addr flush dev \$interface + ;; + + renew|bound) + # flush all the routes + if [ -n "\$router" ]; then + ip route del default 2> /dev/null + fi + + # check broadcast + if [ -n "\$broadcast" ]; then + broadcast="broadcast \$broadcast" + fi + + # add a new ip address + ip addr add \$ip/\$mask \$broadcast dev \$interface + + if [ -n "\$router" ]; then + ip route add default via \$router dev \$interface + fi + + [ -n "\$domain" ] && echo search \$domain > /etc/resolv.conf + for i in \$dns ; do + echo nameserver \$i >> /etc/resolv.conf + done + ;; esac exit 0 EOF @@ -151,63 +153,35 @@ { rootfs=$1 - functions="\ - [ [[ addgroup adduser adjtimex ar arp arping ash awk basename \ - brctl bunzip2 bzcat bzip2 cal cat catv chattr chgrp chmod \ - chown chpasswd chpst chroot chrt chvt cksum clear cmp comm \ - cp cpio crond crontab cryptpw cut date dc dd deallocvt \ - delgroup deluser df dhcprelay diff dirname dmesg dnsd dos2unix \ - du dumpkmap dumpleases echo ed egrep eject env envdir envuidgid \ - ether-wake expand expr fakeidentd false fbset fdformat fdisk \ - fetchmail fgrep find findfs fold free freeramdisk fsck \ - fsck.minix ftpget ftpput fuser getopt getty grep gunzip gzip \ - halt hdparm head hexdump hostid hostname httpd hwclock id \ - ifconfig ifdown ifenslave ifup inetd init insmod install ip \ - ipaddr ipcalc ipcrm ipcs iplink iproute iprule iptunnel \ - kbd_mode kill killall killall5 klogd last length less linux32 \ - linux64 linuxrc ln loadfont loadkmap logger login logname \ - logread losetup lpd lpq lpr ls lsattr lsmod lzmacat makedevs \ - md5sum mdev mesg microcom mkdir mkfifo mkfs.minix mknod mkswap \ - mktemp modprobe more mount mountpoint msh mt mv nameif nc \ - netstat nice nmeter nohup nslookup od openvt passwd patch \ - pgrep pidof ping ping6 pipe_progress pivot_root pkill poweroff \ - printenv printf ps pscan pwd raidautorun rdate readahead \ - readlink readprofile realpath reboot renice reset resize rm \ - rmdir rmmod route rpm rpm2cpio run-parts runlevel runsv \ - runsvdir rx script sed sendmail seq setarch setconsole \ - setkeycodes setlogcons setsid setuidgid sh sha1sum slattach \ - sleep softlimit sort split start-stop-daemon stat strings \ - stty su sulogin sum sv svlogd swapoff swapon switch_root \ - sync sysctl syslogd tac tail tar taskset tcpsvd tee telnet \ - telnetd test tftp tftpd time top touch tr traceroute \ - true tty ttysize udhcpc udhcpd udpsvd umount uname uncompress \ - unexpand uniq unix2dos unlzma unzip uptime usleep uudecode \ - uuencode vconfig vi vlock watch watchdog wc wget which \ - who whoami xargs yes zcat zcip" - - type busybox >/dev/null + which busybox >/dev/null 2>&1 if [ $? -ne 0 ]; then - echo "busybox executable is not accessible" - return 1 + echo "busybox executable is not accessible" + return 1 fi file $(which busybox) | grep -q "statically linked" if [ $? -ne 0 ]; then - echo "warning : busybox is not statically linked." - echo "warning : The template script may not correctly" - echo "warning : setup the container environment." + echo "warning : busybox is not statically linked." + echo "warning : The template script may not correctly" + echo "warning : setup the container environment." fi # copy busybox in the rootfs cp $(which busybox) $rootfs/bin if [ $? -ne 0 ]; then - echo "failed to copy busybox in the rootfs" - return 1 + echo "failed to copy busybox in the rootfs" + return 1 fi - # do hardlink to busybox for the different commands - for i in $functions; do ln $rootfs/bin/busybox $rootfs/bin/$i; done + # symlink busybox for the commands it supports + # it would be nice to just use "chroot $rootfs busybox --install -s /bin" + # but that only works right in a chroot with busybox >= 1.19.0 + pushd $rootfs/bin > /dev/null || return 1 + ./busybox --help | grep 'Currently defined functions:' -A300 | \ + grep -v 'Currently defined functions:' | tr , '\n' | \ + xargs -n1 ln -s busybox + popd > /dev/null # relink /sbin/init ln $rootfs/bin/busybox $rootfs/sbin/init @@ -215,9 +189,63 @@ # passwd exec must be setuid chmod +s $rootfs/bin/passwd touch $rootfs/etc/shadow - chroot $rootfs /bin/passwd -d root - echo "No password for 'root', please change !" + # setting passwd for root + CHPASSWD_FILE=$rootfs/root/chpasswd.sh + + cat <$CHPASSWD_FILE +echo "setting root password to \"root\"" + +mount --bind /lib $rootfs/lib +if [ \$? -ne 0 ]; then + echo "Failed bind-mounting /lib at $rootfs/lib" + exit 1 +fi + +chroot $rootfs chpasswd </dev/null +root:root +EOFF + + +if [ \$? -ne 0 ]; then + echo "Failed to change root password" + exit 1 +fi + +umount $rootfs/lib + +EOF + + lxc-unshare -s MOUNT -- /bin/sh < $CHPASSWD_FILE + rm $CHPASSWD_FILE + + # add ssh functionality if dropbear package available on host + which dropbear >/dev/null 2>&1 + if [ $? -eq 0 ]; then + # copy dropbear binary + cp $(which dropbear) $rootfs/usr/sbin + if [ $? -ne 0 ]; then + echo "Failed to copy dropbear in the rootfs" + return 1 + fi + + # make symlinks to various ssh utilities + utils="\ + $rootfs/usr/bin/dbclient \ + $rootfs/usr/bin/scp \ + $rootfs/usr/bin/ssh \ + $rootfs/usr/sbin/dropbearkey \ + $rootfs/usr/sbin/dropbearconvert \ + " + echo $utils | xargs -n1 ln -s /usr/sbin/dropbear + + # add necessary config files + mkdir $rootfs/etc/dropbear + dropbearkey -t rsa -f $rootfs/etc/dropbear/dropbear_rsa_host_key &> /dev/null + dropbearkey -t dss -f $rootfs/etc/dropbear/dropbear_dss_host_key &> /dev/null + + echo "'dropbear' ssh utility installed" + fi return 0 } @@ -228,26 +256,28 @@ rootfs=$2 name=$3 +grep -q "^lxc.rootfs" $path/config 2>/dev/null || echo "lxc.rootfs = $rootfs" >> $path/config cat <> $path/config lxc.utsname = $name lxc.tty = 1 lxc.pts = 1 -lxc.rootfs = $rootfs -EOF +lxc.cap.drop = sys_module mac_admin mac_override sys_time -if [ -d "$rootfs/lib" ]; then -cat <> $path/config -lxc.mount.entry=/lib $rootfs/lib none ro,bind 0 0 -lxc.mount.entry=/usr/lib $rootfs/usr/lib none ro,bind 0 0 +# When using LXC with apparmor, uncomment the next line to run unconfined: +#lxc.aa_profile = unconfined EOF -fi -if [ -d "/lib64" ] && [ -d "$rootfs/lib64" ]; then -cat <> $path/config -lxc.mount.entry=/lib64 $rootfs/lib64 none ro,bind 0 0 -lxc.mount.entry=/usr/lib64 $rootfs/usr/lib64 none ro,bind 0 0 -EOF -fi + libdirs="\ + lib \ + usr/lib \ + lib64 \ + usr/lib64" + + for dir in $libdirs; do + if [ -d "/$dir" ] && [ -d "$rootfs/$dir" ]; then + echo "lxc.mount.entry = /$dir $dir none ro,bind 0 0" >> $path/config + fi + done } usage() @@ -258,10 +288,10 @@ return 0 } -options=$(getopt -o hp:n: -l help,path:,name: -- "$@") +options=$(getopt -o hp:n: -l help,rootfs:,path:,name: -- "$@") if [ $? -ne 0 ]; then - usage $(basename $0) - exit 1 + usage $(basename $0) + exit 1 fi eval set -- "$options" @@ -270,7 +300,8 @@ case "$1" in -h|--help) usage $0 && exit 0;; -p|--path) path=$2; shift 2;; - -n|--name) name=$2; shift 2;; + --rootfs) rootfs=$2; shift 2;; + -n|--name) name=$2; shift 2;; --) shift 1; break ;; *) break ;; esac @@ -286,7 +317,15 @@ exit 1 fi -rootfs=$path/rootfs +# detect rootfs +config="$path/config" +if [ -z "$rootfs" ]; then + if grep -q '^lxc.rootfs' $config 2>/dev/null ; then + rootfs=`grep 'lxc.rootfs =' $config | awk -F= '{ print $2 }'` + else + rootfs=$path/rootfs + fi +fi install_busybox $rootfs $name if [ $? -ne 0 ]; then diff -Nru lxc-0.8.0~rc1/templates/lxc-cirros.in lxc-1.0.0~alpha1/templates/lxc-cirros.in --- lxc-0.8.0~rc1/templates/lxc-cirros.in 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/templates/lxc-cirros.in 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,321 @@ +#!/bin/bash + +# template script for generating ubuntu container for LXC +# +# This script consolidates and extends the existing lxc ubuntu scripts +# + +# Copyright 2013 Canonical Ltd. +# Author: Scott Moser +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2, as +# published by the Free Software Foundation. + +# 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., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +VERBOSITY=0 +DOWNLOAD_URL="http://download.cirros-cloud.net/" +CACHE_D="@LOCALSTATEDIR@/cache/lxc/cirros" + +UNAME_M=$(uname -m) +ARCHES=( i386 x86_64 amd64 arm ) +STREAMS=( released devel ) +SOURCES=( nocloud none ) +BUILD="standard" + +DEF_VERSION="released" +DEF_SOURCE="nocloud" +case "${UNAME_M}" in + i?86) DEF_ARCH="i386";; + x86_64) DEF_ARCH="x86_64";; + arm*) DEF_ARCH="arm";; + *) DEF_ARCH="i386";; +esac + +error() { echo "$@" 1>&2; } +inargs() { + local needle="$1" x="" + shift + for x in "$@"; do + [ "$needle" = "$x" ] && return 0 + done + return 1 +} + +Usage() { + cat <&2; [ $# -eq 0 ] || error "$@"; return 1; } + +debug() { + local level=${1}; shift; + [ "${level}" -gt "${VERBOSITY}" ] && return + error "${@}" +} +jsondict() { + local k="" v="" ret="{" + for arg in "$@"; do + k="${arg%%=*}" + v="${arg#*=}" + ret="${ret} \"${k}\": \"$v\"," + done + ret="${ret%,} }" + echo "$ret" +} + +copy_configuration() +{ + local path=$1 rootfs=$2 name=$3 arch=$4 release=$5 +cat >> "$path/config" < "$sdir/meta-data" || + { error "failed to write metadata to $sdir/meta-data"; return 1; } + + if [ -n "$udfile" ]; then + cat "$udfile" > "$sdir/user-data" || + { error "failed to write user-data to $sdir"; return 1; } + else + rm -f "$sdir/user-data" + fi +} + +insert_ds() { + local dstype="$1" root_d="$2" authkey="$3" udfile="$4" + case "$dstype" in + nocloud) insert_ds_nocloud "$root_d" "$authkey" "$udfile" + esac +} + +extract_rootfs() { + local tarball="$1" rootfs_d="$2" + mkdir -p "${rootfs_d}" || + { error "failed to make rootfs dir ${rootfs_d}"; return 1; } + + tar -C "${rootfs_d}" -Sxzf "${tarball}" || + { error "failed to populate ${rootfs_d}"; return 1; } + return 0 +} + +download_tarball() { + local arch="$1" ver="$2" cached="$3" baseurl="$4" + local out="" outd="" file="" dlpath="" + file="cirros-$ver-$arch-lxc.tar.gz" + dlpath="$ver/$file" + outd="${cached}/${dlpath%/*}" + if [ -f "$cached/$dlpath" ]; then + _RET="$cached/$dlpath" + return 0 + fi + + mkdir -p "${outd}" || + { error "failed to create ${outd}"; return 1; } + + debug 1 "downloading ${baseurl%/}/$dlpath" to "${cached}/$dlpath" + wget "${baseurl%/}/$dlpath" -O "$cached/${dlpath}.$$" && + mv "$cached/$dlpath.$$" "$cached/$dlpath" || { + rm -f "$cached/$dlpath.$$"; + error "failed to download $dlpath"; + return 1; + } + _RET="$cached/$dlpath" +} + +create_main() { + local short_opts="a:hn:p:S:uvV" + local long_opts="arch:,auth-key:,name:,path:,tarball:,userdata:,verbose,version:,rootfs:" + local getopt_out="" + getopt_out=$(getopt --name "${0##*/}" \ + --options "${short_opts}" --long "${long_opts}" -- "$@") && + eval set -- "${getopt_out}" || + { bad_Usage; return; } + + local arch="${DEF_ARCH}" dsource="${DEF_SOURCE}" version="${DEF_VERSION}" + local authkey_f="" authkeys="" userdata_f="" path="" tarball="" + local cur="" next="" + local rootfs_d="" + + while [ $# -ne 0 ]; do + cur=$1; next=$2; + case "$cur" in + -a|--arch) arch="$next"; shift;; + -h|--help) Usage ; return 0;; + -n|--name) name="$next"; shift;; + -v|--verbose) VERBOSITY=$((${VERBOSITY}+1));; + -S|--auth-key) authkey_f="$next"; shift;; + -p|--path) path=$next; shift;; + -v|--version) version=$next; shift;; + -u|--userdata) userdata_f="$next"; shift;; + --tarball) tarball="$next"; shift;; + --source) dsource="$next"; shift;; + --rootfs) rootfs_d="$next"; shift;; + --) shift; break;; + esac + shift; + done + + [ -n "$rootfs_d" ] || rootfs_d="$path/rootfs" + [ $# -eq 0 ] || { bad_Usage "unexpected arguments: $*"; return; } + [ -n "$path" ] || { error "'path' parameter is required"; return 1; } + + if [ "$(id -u)" != "0" ]; then + { error "must be run as root"; return 1; } + fi + + case "$arch" in + i?86) arch="i386";; + amd64) arch="x86_64";; + esac + + inargs "$arch" "${ARCHES[@]}" || + { error "bad arch '$arch'. allowed: ${ARCHES[*]}"; return 1; } + + inargs "$dsource" "${SOURCES[@]}" || + { error "bad source '$dsource'. allowed: ${SOURCES[*]}"; return 1; } + + if [ "$dsource" = "none" ] && [ -n "$userdata_f" -o -n "$authkey_f" ]; then + error "userdata and authkey are incompatible with --source=none"; + return 1; + fi + + if [ -n "$authkey_f" ]; then + if [ ! -f "$authkey_f" ]; then + error "--auth-key=${authkey_f} must reference a file" + return 1 + fi + authkeys=$(cat "$authkey_f") || + { error "failed to read ${authkey_f}"; return 1; } + fi + + if [ -n "$userdata_f" -a ! -f "${userdata_f}" ]; then + error "${userdata_f}: --userdata arg not a file" + return 1 + fi + + if [ -z "$tarball" ]; then + if inargs "$version" "${STREAMS[@]}"; then + out=$(wget -O - -q "${DOWNLOAD_URL%/}/version/$version") || + { error "failed to convert 'version=$version'"; return 1; } + version="$out" + fi + download_tarball "$arch" "$version" "${CACHE_D}" "${DOWNLOAD_URL}" || + return + tarball="$_RET" + fi + + extract_rootfs "${tarball}" "${rootfs_d}" || return + + # cirros 0.3.1 was broken for /dev/random and /dev/urandom + if [ -b "$rootfs_d/dev/random" ]; then + rm -f "$rootfs_d/dev/random" && + mknod --mode=666 "$rootfs_d/dev/random" c 1 8 || + { error "failed to fix /dev/random"; return 1; } + fi + if [ -b "$rootfs_d/dev/urandom" ]; then + rm -f "$rootfs_d/dev/urandom" && + mknod --mode=666 "$rootfs_d/dev/urandom" c 1 9 || + { error "failed to fix /dev/urandom"; return 1; } + fi + + if [ "$version" = "0.3.2~pre1" ]; then + debug 1 "fixing console for lxc and '$version'" + sed -i 's,^\(#console.* 115200 \)# /dev/console,\1 console,g' \ + "$rootfs_d/etc/inittab" || + { error "failed to fix console entry for $version"; return 1; } + fi + + if [ "$dsource" != "none" ]; then + insert_ds "$dsource" "$path/rootfs" "$authkeys" "$userdata_f" || { + error "failed to insert userdata to $path/rootfs" + return 1 + } + fi + + copy_configuration "$path" "$path/rootfs" "$name" "$arch" "$release" + return +} + +create_main "$@" + +# vi: ts=4 expandtab diff -Nru lxc-0.8.0~rc1/templates/lxc-debian.in lxc-1.0.0~alpha1/templates/lxc-debian.in --- lxc-0.8.0~rc1/templates/lxc-debian.in 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/templates/lxc-debian.in 2013-09-10 22:22:00.000000000 +0000 @@ -13,12 +13,12 @@ # 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 +# 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 +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA SUITE=${SUITE:-squeeze} MIRROR=${MIRROR:-http://cdn.debian.net/debian} @@ -31,9 +31,9 @@ # squeeze only has /dev/tty and /dev/tty0 by default, # therefore creating missing device nodes for tty1-4. for tty in $(seq 1 4); do - if [ ! -e $rootfs/dev/tty$tty ]; then - mknod $rootfs/dev/tty$tty c 4 $tty - fi + if [ ! -e $rootfs/dev/tty$tty ]; then + mknod $rootfs/dev/tty$tty c 4 $tty + fi done # configure the inittab @@ -54,6 +54,8 @@ c2:12345:respawn:/sbin/getty 38400 tty2 linux c3:12345:respawn:/sbin/getty 38400 tty3 linux c4:12345:respawn:/sbin/getty 38400 tty4 linux +p6::ctrlaltdel:/sbin/init 6 +p0::powerfail:/sbin/init 0 EOF # disable selinux in debian @@ -76,11 +78,11 @@ # reconfigure some services if [ -z "$LANG" ]; then - chroot $rootfs locale-gen en_US.UTF-8 UTF-8 - chroot $rootfs update-locale LANG=en_US.UTF-8 + chroot $rootfs locale-gen en_US.UTF-8 UTF-8 + chroot $rootfs update-locale LANG=en_US.UTF-8 else - chroot $rootfs locale-gen $LANG $(echo $LANG | cut -d. -f2) - chroot $rootfs update-locale LANG=$LANG + chroot $rootfs locale-gen $LANG $(echo $LANG | cut -d. -f2) + chroot $rootfs update-locale LANG=$LANG fi # remove pointless services in a container @@ -95,6 +97,12 @@ return 0 } +cleanup() +{ + rm -rf $cache/partial-$SUITE-$arch + rm -rf $cache/rootfs-$SUITE-$arch +} + download_debian() { packages=\ @@ -102,7 +110,7 @@ locales,\ libui-dialog-perl,\ dialog,\ -dhcp3-client,\ +isc-dhcp-client,\ netbase,\ net-tools,\ iproute,\ @@ -111,25 +119,30 @@ cache=$1 arch=$2 + trap cleanup EXIT SIGHUP SIGINT SIGTERM # check the mini debian was not already downloaded mkdir -p "$cache/partial-$SUITE-$arch" if [ $? -ne 0 ]; then - echo "Failed to create '$cache/partial-$SUITE-$arch' directory" - return 1 + echo "Failed to create '$cache/partial-$SUITE-$arch' directory" + return 1 fi # download a mini debian into a cache echo "Downloading debian minimal ..." debootstrap --verbose --variant=minbase --arch=$arch \ - --include=$packages \ - "$SUITE" "$cache/partial-$SUITE-$arch" $MIRROR + --include=$packages \ + "$SUITE" "$cache/partial-$SUITE-$arch" $MIRROR if [ $? -ne 0 ]; then - echo "Failed to download the rootfs, aborting." - return 1 + echo "Failed to download the rootfs, aborting." + return 1 fi mv "$1/partial-$SUITE-$arch" "$1/rootfs-$SUITE-$arch" echo "Download complete." + trap EXIT + trap SIGINT + trap SIGTERM + trap SIGHUP return 0 } @@ -143,7 +156,7 @@ # make a local copy of the minidebian echo -n "Copying rootfs to $rootfs..." mkdir -p $rootfs - rsync -a "$cache/rootfs-$SUITE-$arch"/ $rootfs/ || return 1 + rsync -Ha "$cache/rootfs-$SUITE-$arch"/ $rootfs/ || return 1 return 0 } @@ -153,32 +166,43 @@ rootfs=$1 mkdir -p @LOCALSTATEDIR@/lock/subsys/ ( - flock -n -x 200 - if [ $? -ne 0 ]; then - echo "Cache repository is busy." - return 1 - fi - - arch=$(dpkg --print-architecture) - - echo "Checking cache download in $cache/rootfs-$SUITE-$arch ... " - if [ ! -e "$cache/rootfs-$SUITE-$arch" ]; then - download_debian $cache $arch - if [ $? -ne 0 ]; then - echo "Failed to download 'debian base'" - return 1 - fi - fi - - copy_debian $cache $arch $rootfs - if [ $? -ne 0 ]; then - echo "Failed to copy rootfs" - return 1 - fi + flock -x 200 + if [ $? -ne 0 ]; then + echo "Cache repository is busy." + return 1 + fi + + if which dpkg >/dev/null 2>&1 ; then + arch=$(dpkg --print-architecture) + else + arch=$(uname -m) + if [ "$arch" = "i686" ]; then + arch="i386" + elif [ "$arch" = "x86_64" ]; then + arch="amd64" + elif [ "$arch" = "armv7l" ]; then + arch="armhf" + fi + fi + + echo "Checking cache download in $cache/rootfs-$SUITE-$arch ... " + if [ ! -e "$cache/rootfs-$SUITE-$arch" ]; then + download_debian $cache $arch + if [ $? -ne 0 ]; then + echo "Failed to download 'debian base'" + return 1 + fi + fi + + copy_debian $cache $arch $rootfs + if [ $? -ne 0 ]; then + echo "Failed to copy rootfs" + return 1 + fi - return 0 + return 0 - ) 200>@LOCALSTATEDIR@/lock/subsys/lxc + ) 200>@LOCALSTATEDIR@/lock/subsys/lxc-debian return $? } @@ -189,11 +213,16 @@ rootfs=$2 hostname=$3 + grep -q "^lxc.rootfs" $path/config 2>/dev/null || echo "lxc.rootfs = $rootfs" >> $path/config cat <> $path/config lxc.tty = 4 lxc.pts = 1024 -lxc.rootfs = $rootfs lxc.utsname = $hostname +lxc.cap.drop = sys_module mac_admin mac_override sys_time + +# When using LXC with apparmor, uncomment the next line to run unconfined: +#lxc.aa_profile = unconfined + lxc.cgroup.devices.deny = a # /dev/null and zero lxc.cgroup.devices.allow = c 1:3 rwm @@ -209,16 +238,16 @@ lxc.cgroup.devices.allow = c 136:* rwm lxc.cgroup.devices.allow = c 5:2 rwm # rtc -lxc.cgroup.devices.allow = c 254:0 rwm +lxc.cgroup.devices.allow = c 254:0 rm # mounts point -lxc.mount.entry=proc $rootfs/proc proc nodev,noexec,nosuid 0 0 -lxc.mount.entry=sysfs $rootfs/sys sysfs defaults 0 0 +lxc.mount.entry = proc proc proc nodev,noexec,nosuid 0 0 +lxc.mount.entry = sysfs sys sysfs defaults 0 0 EOF if [ $? -ne 0 ]; then - echo "Failed to add configuration" - return 1 + echo "Failed to add configuration" + return 1 fi return 0 @@ -229,22 +258,22 @@ cache="@LOCALSTATEDIR@/cache/lxc/debian" if [ ! -e $cache ]; then - exit 0 + exit 0 fi # lock, so we won't purge while someone is creating a repository ( - flock -n -x 200 - if [ $? != 0 ]; then - echo "Cache repository is busy." - exit 1 - fi - - echo -n "Purging the download cache..." - rm --preserve-root --one-file-system -rf $cache && echo "Done." || exit 1 - exit 0 + flock -x 200 + if [ $? != 0 ]; then + echo "Cache repository is busy." + exit 1 + fi + + echo -n "Purging the download cache..." + rm --preserve-root --one-file-system -rf $cache && echo "Done." || exit 1 + exit 0 - ) 200>@LOCALSTATEDIR@/lock/subsys/lxc + ) 200>@LOCALSTATEDIR@/lock/subsys/lxc-debian } usage() @@ -255,10 +284,10 @@ return 0 } -options=$(getopt -o hp:n:c -l help,path:,name:,clean -- "$@") +options=$(getopt -o hp:n:c -l help,rootfs:,path:,name:,clean -- "$@") if [ $? -ne 0 ]; then usage $(basename $0) - exit 1 + exit 1 fi eval set -- "$options" @@ -267,8 +296,9 @@ case "$1" in -h|--help) usage $0 && exit 0;; -p|--path) path=$2; shift 2;; - -n|--name) name=$2; shift 2;; - -c|--clean) clean=$2; shift 2;; + --rootfs) rootfs=$2; shift 2;; + -n|--name) name=$2; shift 2;; + -c|--clean) clean=$2; shift 2;; --) shift 1; break ;; *) break ;; esac @@ -295,7 +325,16 @@ exit 1 fi -rootfs=$path/rootfs +# detect rootfs +config="$path/config" +if [ -z "$rootfs" ]; then + if grep -q '^lxc.rootfs' $config 2>/dev/null ; then + rootfs=`grep 'lxc.rootfs =' $config | awk -F= '{ print $2 }'` + else + rootfs=$path/rootfs + fi +fi + install_debian $rootfs if [ $? -ne 0 ]; then diff -Nru lxc-0.8.0~rc1/templates/lxc-fedora.in lxc-1.0.0~alpha1/templates/lxc-fedora.in --- lxc-0.8.0~rc1/templates/lxc-fedora.in 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/templates/lxc-fedora.in 2013-09-10 22:22:00.000000000 +0000 @@ -23,23 +23,72 @@ # 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 +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #Configurations -arch=$(arch) -cache_base=/var/cache/lxc/fedora/$arch -default_path=/var/lib/lxc -root_password=rooter -lxc_network_type=veth -lxc_network_link=virbr0 +arch=$(uname -m) +cache_base=@LOCALSTATEDIR@/cache/lxc/fedora/$arch +default_path=@LXCPATH@ +root_password=root # is this fedora? -[ -f /etc/fedora-release ] && is_fedora=true +# Alow for weird remixes like the Raspberry Pi +# +# Use the Mitre standard CPE identifier for the release ID if possible... +# This may be in /etc/os-release or /etc/system-release-cpe. We +# should be able to use EITHER. Give preference to /etc/os-release for now. + +if [ -e /etc/os-release ] +then +# This is a shell friendly configuration file. We can just source it. +# What we're looking for in here is the ID, VERSION_ID and the CPE_NAME + . /etc/os-release + echo "Host CPE ID from /etc/os-release: ${CPE_NAME}" +fi + +if [ "${CPE_NAME}" = "" -a -e /etc/system-release-cpe ] +then + CPE_NAME=$(head -n1 /etc/system-release-cpe) + CPE_URI=$(expr ${CPE_NAME} : '\([^:]*:[^:*]\)') + if [ "${CPE_URI}" != "cpe:/o" ] + then + CPE_NAME= + else + echo "Host CPE ID from /etc/system-release-cpe: ${CPE_NAME}" + # Probably a better way to do this but sill remain posix + # compatible but this works, shrug... + # Must be nice and not introduce convenient bashisms here. + ID=$(expr ${CPE_NAME} : '[^:]*:[^:]*:[^:]*:\([^:]*\)') + VERSION_ID=$(expr ${CPE_NAME} : '[^:]*:[^:]*:[^:]*:[^:]*:\([^:]*\)') + fi +fi -if [ "$arch" = "i686" ]; then - arch=i386 +if [ "${CPE_NAME}" != "" -a "${ID}" = "fedora" -a "${VERSION_ID}" != "" ] +then + fedora_host_ver=${VERSION_ID} + is_fedora=true +elif [ -e /etc/redhat-release ] +then + # Only if all other methods fail, try to parse the redhat-release file. + fedora_host_ver=$( sed -e '/^Fedora /!d' -e 's/Fedora.*\srelease\s*\([0-9][0-9]*\)\s.*/\1/' < /etc/redhat-release ) + if [ "$fedora_host_ver" != "" ] + then + is_fedora=true + fi fi +# Map a few architectures to their generic Fedora repository archs. +# The two ARM archs are a bit of a guesstimate for the v5 and v6 +# archs. V6 should have hardware floating point (Rasberry Pi). +# The "arm" arch is safer (no hardware floating point). So +# there may be cases where we "get it wrong" for some v6 other +# than RPi. +case "$arch" in +i686) arch=i386 ;; +armv3l|armv4l|armv5l) arch=arm ;; +armv6l|armv7l|armv8l) arch=armhfp ;; +esac + configure_fedora() { @@ -52,7 +101,7 @@ DEVICE=eth0 BOOTPROTO=dhcp ONBOOT=yes -HOSTNAME=${UTSNAME} +HOSTNAME=${utsname} NM_CONTROLLED=no TYPE=Ethernet MTU=${MTU} @@ -61,19 +110,20 @@ # set the hostname cat < ${rootfs_path}/etc/sysconfig/network NETWORKING=yes -HOSTNAME=${UTSNAME} +HOSTNAME=${utsname} EOF + # set hostname on systemd Fedora systems + if [ $release -gt 14 ]; then + echo "${utsname}" > ${rootfs_path}/etc/hostname + fi + # set minimal hosts cat < $rootfs_path/etc/hosts -127.0.0.1 localhost $name +127.0.0.1 localhost.localdomain localhost $utsname +::1 localhost6.localdomain6 localhost6 EOF - sed -i 's|.sbin.start_udev||' ${rootfs_path}/etc/rc.sysinit - sed -i 's|.sbin.start_udev||' ${rootfs_path}/etc/rc.d/rc.sysinit - chroot ${rootfs_path} chkconfig udev-post off - chroot ${rootfs_path} chkconfig network on - dev_path="${rootfs_path}/dev" rm -rf $dev_path mkdir -p $dev_path @@ -97,8 +147,56 @@ echo "setting root passwd to $root_password" echo "root:$root_password" | chroot $rootfs_path chpasswd + # specifying this in the initial packages doesn't always work. + echo "installing fedora-release package" + chroot ${rootfs_path} yum --releasever=${release} -y install fedora-release + + # silence some needless startup errors + touch ${rootfs_path}/etc/fstab + + # give us a console on /dev/console + sed -i 's/ACTIVE_CONSOLES=.*$/ACTIVE_CONSOLES="\/dev\/console \/dev\/tty[1-4]"/' \ + ${rootfs_path}/etc/sysconfig/init + return 0 } +configure_fedora_init() +{ + sed -i 's|.sbin.start_udev||' ${rootfs_path}/etc/rc.sysinit + sed -i 's|.sbin.start_udev||' ${rootfs_path}/etc/rc.d/rc.sysinit + # don't mount devpts, for pete's sake + sed -i 's/^.*dev.pts.*$/#\0/' ${rootfs_path}/etc/rc.sysinit + sed -i 's/^.*dev.pts.*$/#\0/' ${rootfs_path}/etc/rc.d/rc.sysinit + chroot ${rootfs_path} chkconfig udev-post off + chroot ${rootfs_path} chkconfig network on +} + +configure_fedora_systemd() +{ + unlink ${rootfs_path}/etc/systemd/system/default.target + touch ${rootfs_path}/etc/fstab + chroot ${rootfs_path} ln -s /dev/null /etc/systemd/system/udev.service + chroot ${rootfs_path} ln -s /lib/systemd/system/multi-user.target /etc/systemd/system/default.target + #dependency on a device unit fails it specially that we disabled udev + # sed -i 's/After=dev-%i.device/After=/' ${rootfs_path}/lib/systemd/system/getty\@.service + # + # Actually, the After=dev-%i.device line does not appear in the + # Fedora 17 or Fedora 18 systemd getty\@.service file. It may be left + # over from an earlier version and it's not doing any harm. We do need + # to disable the "ConditionalPathExists=/dev/tty0" line or no gettys are + # started on the ttys in the container. Lets do it in an override copy of + # the service so it can still pass rpm verifies and not be automatically + # updated by a new systemd version. -- mhw /\/\|=mhw=|\/\/ + + sed -e 's/^ConditionPathExists=/# ConditionPathExists=/' \ + -e 's/After=dev-%i.device/After=/' \ + < ${rootfs_path}/lib/systemd/system/getty\@.service \ + > ${rootfs_path}/etc/systemd/system/getty\@.service + # Setup getty service on the 4 ttys we are going to allow in the + # default config. Number should match lxc.tty + ( cd ${rootfs_path}/etc/systemd/system/getty.target.wants + for i in 1 2 3 4 ; do ln -sf ../getty\@.service getty@tty${i}.service; done ) +} download_fedora() { @@ -107,34 +205,64 @@ INSTALL_ROOT=$cache/partial mkdir -p $INSTALL_ROOT if [ $? -ne 0 ]; then - echo "Failed to create '$INSTALL_ROOT' directory" - return 1 + echo "Failed to create '$INSTALL_ROOT' directory" + return 1 fi # download a mini fedora into a cache echo "Downloading fedora minimal ..." YUM="yum --installroot $INSTALL_ROOT -y --nogpgcheck" - PKG_LIST="yum initscripts passwd rsyslog vim-minimal dhclient chkconfig rootfiles policycoreutils" + PKG_LIST="yum initscripts passwd rsyslog vim-minimal dhclient chkconfig rootfiles policycoreutils fedora-release" MIRRORLIST_URL="http://mirrors.fedoraproject.org/mirrorlist?repo=fedora-$release&arch=$arch" DOWNLOAD_OK=no - for trynumber in 1 2 3; do + + # We're splitting the old loop into two loops plus a directory retrival. + # First loop... Try and retrive a mirror list with retries and a slight + # delay between attempts... + for trynumber in 1 2 3 4; do [ $trynumber != 1 ] && echo "Trying again..." - MIRROR_URL=$(curl -s -S -f "$MIRRORLIST_URL" | head -n2 | tail -n1) - if [ $? -ne 0 ] || [ -z "$MIRROR_URL" ]; then - echo "Failed to get a mirror" + # This code is mildly "brittle" in that it assumes a certain + # page format and parsing HTML. I've done worse. :-P + MIRROR_URLS=$(curl -s -S -f "$MIRRORLIST_URL" | sed -e '/^http:/!d' -e '2,6!d') + if [ $? -eq 0 ] && [ -n "$MIRROR_URLS" ] + then + break + fi + + echo "Failed to get a mirror on try $trynumber" + sleep 3 + done + + # This will fall through if we didn't get any URLS above + for MIRROR_URL in ${MIRROR_URLS} + do + if [ "$release" -gt "16" ]; then + RELEASE_URL="$MIRROR_URL/Packages/f" + else + RELEASE_URL="$MIRROR_URL/Packages/" + fi + + echo "Fetching rpm name from $RELEASE_URL..." + # This code is mildly "brittle" in that it assumes a certain directory + # page format and parsing HTML. I've done worse. :-P + RELEASE_RPM=$(curl -L -f "$RELEASE_URL" | sed -e "/fedora-release-${release}-/!d" -e 's/.*.*//' ) + if [ $? -ne 0 -o "${RELEASE_RPM}" = "" ]; then + echo "Failed to identify fedora release rpm." continue fi - RELEASE_URL="$MIRROR_URL/Packages/fedora-release-$release-1.noarch.rpm" - echo "Fetching from $RELEASE_URL" - curl -f "$RELEASE_URL" > $INSTALL_ROOT/fedora-release-$release.noarch.rpm + + echo "Fetching fedora release rpm from ${RELEASE_URL}/${RELEASE_RPM}......" + curl -L -f "${RELEASE_URL}/${RELEASE_RPM}" > ${INSTALL_ROOT}/${RELEASE_RPM} if [ $? -ne 0 ]; then - echo "Failed to download fedora release rpm" + echo "Failed to download fedora release rpm ${RELEASE_RPM}." continue fi + DOWNLOAD_OK=yes break done + if [ $DOWNLOAD_OK != yes ]; then echo "Aborting" return 1 @@ -142,12 +270,12 @@ mkdir -p $INSTALL_ROOT/var/lib/rpm rpm --root $INSTALL_ROOT --initdb - rpm --root $INSTALL_ROOT -ivh $INSTALL_ROOT/fedora-release-$release.noarch.rpm + rpm --root $INSTALL_ROOT -ivh ${INSTALL_ROOT}/${RELEASE_RPM} $YUM install $PKG_LIST if [ $? -ne 0 ]; then - echo "Failed to download the rootfs, aborting." - return 1 + echo "Failed to download the rootfs, aborting." + return 1 fi mv "$INSTALL_ROOT" "$cache/rootfs" @@ -164,52 +292,52 @@ #cp -a $cache/rootfs-$arch $rootfs_path || return 1 # i prefer rsync (no reason really) mkdir -p $rootfs_path - rsync -a $cache/rootfs/ $rootfs_path/ + rsync -Ha $cache/rootfs/ $rootfs_path/ return 0 } update_fedora() { - chroot $cache/rootfs yum -y update + YUM="yum --installroot $cache/rootfs -y --nogpgcheck" + $YUM update } install_fedora() { - mkdir -p /var/lock/subsys/ + mkdir -p @LOCALSTATEDIR@/lock/subsys/ ( - flock -n -x 200 - if [ $? -ne 0 ]; then - echo "Cache repository is busy." - return 1 - fi + flock -x 200 + if [ $? -ne 0 ]; then + echo "Cache repository is busy." + return 1 + fi - echo "Checking cache download in $cache/rootfs ... " - if [ ! -e "$cache/rootfs" ]; then - download_fedora - if [ $? -ne 0 ]; then - echo "Failed to download 'fedora base'" - return 1 - fi + echo "Checking cache download in $cache/rootfs ... " + if [ ! -e "$cache/rootfs" ]; then + download_fedora + if [ $? -ne 0 ]; then + echo "Failed to download 'fedora base'" + return 1 + fi else - echo "Cache found. Updating..." + echo "Cache found. Updating..." update_fedora - if [ $? -ne 0 ]; then - echo "Failed to update 'fedora base', continuing with last known good cache" + if [ $? -ne 0 ]; then + echo "Failed to update 'fedora base', continuing with last known good cache" else echo "Update finished" - fi - fi - - echo "Copy $cache/rootfs to $rootfs_path ... " - copy_fedora - if [ $? -ne 0 ]; then - echo "Failed to copy rootfs" - return 1 - fi + fi + fi - return 0 + echo "Copy $cache/rootfs to $rootfs_path ... " + copy_fedora + if [ $? -ne 0 ]; then + echo "Failed to copy rootfs" + return 1 + fi - ) 200>/var/lock/subsys/lxc + return 0 + ) 200>@LOCALSTATEDIR@/lock/subsys/lxc-fedora return $? } @@ -218,18 +346,19 @@ { mkdir -p $config_path + grep -q "^lxc.rootfs" $config_path/config 2>/dev/null || echo "lxc.rootfs = $rootfs_path" >> $config_path/config cat <> $config_path/config -lxc.utsname = $name +lxc.utsname = $utsname lxc.tty = 4 lxc.pts = 1024 -lxc.rootfs = $rootfs_path -lxc.mount = $config_path/fstab -#networking -lxc.network.type = $lxc_network_type -lxc.network.flags = up -lxc.network.link = $lxc_network_link -lxc.network.name = eth0 -lxc.network.mtu = 1500 +lxc.mount = $config_path/fstab +lxc.cap.drop = sys_module mac_admin mac_override sys_time + +lxc.autodev = $auto_dev + +# When using LXC with apparmor, uncomment the next line to run unconfined: +#lxc.aa_profile = unconfined + #cgroups lxc.cgroup.devices.deny = a # /dev/null and zero @@ -246,17 +375,16 @@ lxc.cgroup.devices.allow = c 136:* rwm lxc.cgroup.devices.allow = c 5:2 rwm # rtc -lxc.cgroup.devices.allow = c 254:0 rwm +lxc.cgroup.devices.allow = c 254:0 rm EOF cat < $config_path/fstab -proc $rootfs_path/proc proc nodev,noexec,nosuid 0 0 -devpts $rootfs_path/dev/pts devpts defaults 0 0 -sysfs $rootfs_path/sys sysfs defaults 0 0 +proc proc proc nodev,noexec,nosuid 0 0 +sysfs sys sysfs defaults 0 0 EOF if [ $? -ne 0 ]; then - echo "Failed to add configuration" - return 1 + echo "Failed to add configuration" + return 1 fi return 0 @@ -266,22 +394,21 @@ { if [ ! -e $cache ]; then - exit 0 + exit 0 fi # lock, so we won't purge while someone is creating a repository ( - flock -n -x 200 - if [ $? != 0 ]; then - echo "Cache repository is busy." - exit 1 - fi - - echo -n "Purging the download cache for Fedora-$release..." - rm --preserve-root --one-file-system -rf $cache && echo "Done." || exit 1 - exit 0 + flock -x 200 + if [ $? != 0 ]; then + echo "Cache repository is busy." + exit 1 + fi - ) 200>/var/lock/subsys/lxc + echo -n "Purging the download cache for Fedora-$release..." + rm --preserve-root --one-file-system -rf $cache && echo "Done." || exit 1 + exit 0 + ) 200>@LOCALSTATEDIR@/lock/subsys/lxc-fedora } usage() @@ -289,21 +416,23 @@ cat < - [-p|--path=] [-c|--clean] [-R|--release=] [-A|--arch=] + [-p|--path=] [-c|--clean] [-R|--release=] [--fqdn=] [-A|--arch=] [-h|--help] Mandatory args: -n,--name container name, used to as an identifier for that container from now on Optional args: - -p,--path path to where the container rootfs will be created, defaults to /var/lib/lxc. The container config will go under /var/lib/lxc in that case + -p,--path path to where the container will be created, defaults to @LXCPATH@. The container config will go under @LXCPATH@ in that case + --rootfs path for actual rootfs. -c,--clean clean the cache - -R,--release Fedora release for the new container. if the host is Fedora, then it will defaultto the host's release. + -R,--release Fedora release for the new container. if the host is Fedora, then it will default to the host's release. + --fqdn fully qualified domain name (FQDN) for DNS and system naming -A,--arch NOT USED YET. Define what arch the container will be [i686,x86_64] -h,--help print this help EOF return 0 } -options=$(getopt -o hp:n:cR: -l help,path:,name:,clean,release: -- "$@") +options=$(getopt -o hp:n:cR: -l help,path:,rootfs:,name:,clean,release:,fqdn: -- "$@") if [ $? -ne 0 ]; then usage $(basename $0) exit 1 @@ -313,12 +442,14 @@ while true do case "$1" in - -h|--help) usage $0 && exit 0;; - -p|--path) path=$2; shift 2;; - -n|--name) name=$2; shift 2;; - -c|--clean) clean=$2; shift 2;; + -h|--help) usage $0 && exit 0;; + -p|--path) path=$2; shift 2;; + --rootfs) rootfs=$2; shift 2;; + -n|--name) name=$2; shift 2;; + -c|--clean) clean=$2; shift 2;; -R|--release) release=$2; shift 2;; - --) shift 1; break ;; + --fqdn) utsname=$2; shift 2;; + --) shift 1; break ;; *) break ;; esac done @@ -328,32 +459,80 @@ exit 0 fi +if [ -z "${utsname}" ]; then + utsname=${name} +fi + +# This follows a standard "resolver" convention that an FQDN must have +# at least two dots or it is considered a local relative host name. +# If it doesn't, append the dns domain name of the host system. +# +# This changes one significant behavior when running +# "lxc_create -n Container_Name" without using the +# --fqdn option. +# +# Old behavior: +# utsname and hostname = Container_Name +# New behavior: +# utsname and hostname = Container_Name.Domain_Name + +if [ $(expr "$utsname" : '.*\..*\.') = 0 ]; then + if [ -n "$(dnsdomainname)" ]; then + utsname=${utsname}.$(dnsdomainname) + fi +fi + +needed_pkgs="" type yum >/dev/null 2>&1 if [ $? -ne 0 ]; then - echo "'yum' command is missing" + needed_pkgs="yum $needed_pkgs" +fi + +type curl >/dev/null 2>&1 +if [ $? -ne 0 ]; then + needed_pkgs="curl $needed_pkgs" +fi + +if [ -n "$needed_pkgs" ]; then + echo "Missing commands: $needed_pkgs" + echo "Please install these using \"sudo yum install $needed_pkgs\"" exit 1 fi if [ -z "$path" ]; then - path=$default_path + path=$default_path/$name fi if [ -z "$release" ]; then - if [ "$is_fedora" ]; then - release=$(cat /etc/fedora-release |awk '/^Fedora/ {print $3}') + if [ "$is_fedora" -a "$fedora_host_ver" ]; then + release=$fedora_host_ver else - echo "This is not a fedora host and release missing, defaulting to 14. use -R|--release to specify release" - release=14 + echo "This is not a fedora host and release missing, defaulting to 18. use -R|--release to specify release" + release=18 fi fi +# Fedora 15 and above run systemd. We need autodev enabled to keep +# systemd from causing problems. +if [ $release -gt 14 ]; then + auto_dev="1" +else + auto_dev="0" +fi + if [ "$(id -u)" != "0" ]; then echo "This script should be run as 'root'" exit 1 fi -rootfs_path=$path/$name/rootfs +if [ -z "$rootfs_path" ]; then + rootfs_path=$path/rootfs + # check for 'lxc.rootfs' passed in through default config by lxc-create + if grep -q '^lxc.rootfs' $path/config 2>/dev/null ; then + rootfs_path=`grep 'lxc.rootfs =' $path/config | awk -F= '{ print $2 }'` + fi +fi config_path=$default_path/$name cache=$cache_base/$release @@ -362,7 +541,7 @@ echo "Interrupted, so cleaning up" lxc-destroy -n $name # maybe was interrupted before copy config - rm -rf $path/$name + rm -rf $path rm -rf $default_path/$name echo "exiting..." exit 1 @@ -388,10 +567,22 @@ exit 1 fi +# If the systemd configuration directory exists - set it up for what we need. +if [ -d ${rootfs_path}/etc/systemd/system ] +then + configure_fedora_systemd +fi + +# This configuration (rc.sysinit) is not inconsistent with the systemd stuff +# above and may actually coexist on some upgraded systems. Let's just make +# sure that, if it exists, we update this file, even if it's not used... +if [ -f ${rootfs_path}/etc/rc.sysinit ] +then + configure_fedora_init +fi if [ ! -z $clean ]; then clean || exit 1 exit 0 fi echo "container rootfs and config created" -echo "container is configured for lxc.network.type=veth and lxc.network.link=virbr0 (which is default if you have libvirt runnig)" diff -Nru lxc-0.8.0~rc1/templates/lxc-lenny.in lxc-1.0.0~alpha1/templates/lxc-lenny.in --- lxc-0.8.0~rc1/templates/lxc-lenny.in 2011-10-25 12:02:11.000000000 +0000 +++ lxc-1.0.0~alpha1/templates/lxc-lenny.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,309 +0,0 @@ -#!/bin/bash - -# -# lxc: linux Container library - -# Authors: -# Daniel Lezcano - -# 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 - -SUITE=${SUITE:-lenny} - -configure_debian() -{ - rootfs=$1 - hostname=$2 - - # configure the inittab - cat < $rootfs/etc/inittab -id:3:initdefault: -si::sysinit:/etc/init.d/rcS -l0:0:wait:/etc/init.d/rc 0 -l1:1:wait:/etc/init.d/rc 1 -l2:2:wait:/etc/init.d/rc 2 -l3:3:wait:/etc/init.d/rc 3 -l4:4:wait:/etc/init.d/rc 4 -l5:5:wait:/etc/init.d/rc 5 -l6:6:wait:/etc/init.d/rc 6 -# Normally not reached, but fallthrough in case of emergency. -z6:6:respawn:/sbin/sulogin -1:2345:respawn:/sbin/getty 38400 console -c1:12345:respawn:/sbin/getty 38400 tty1 linux -c2:12345:respawn:/sbin/getty 38400 tty2 linux -c3:12345:respawn:/sbin/getty 38400 tty3 linux -c4:12345:respawn:/sbin/getty 38400 tty4 linux -EOF - - # disable selinux in debian - mkdir -p $rootfs/selinux - echo 0 > $rootfs/selinux/enforce - - # configure the network using the dhcp - cat < $rootfs/etc/network/interfaces -auto lo -iface lo inet loopback - -auto eth0 -iface eth0 inet dhcp -EOF - - # set the hostname - cat < $rootfs/etc/hostname -$hostname -EOF - - # reconfigure some services - if [ -z "$LANG" ]; then - chroot $rootfs locale-gen en_US.UTF-8 - chroot $rootfs update-locale LANG=en_US.UTF-8 - else - chroot $rootfs locale-gen $LANG - chroot $rootfs update-locale LANG=$LANG - fi - - # remove pointless services in a container - chroot $rootfs /usr/sbin/update-rc.d -f umountfs remove - chroot $rootfs /usr/sbin/update-rc.d -f hwclock.sh remove - chroot $rootfs /usr/sbin/update-rc.d -f hwclockfirst.sh remove - - echo "root:root" | chroot $rootfs chpasswd - echo "Root password is 'root', please change !" - - return 0 -} - -download_debian() -{ - packages=\ -ifupdown,\ -locales,\ -libui-dialog-perl,\ -dialog,\ -dhcp3-client,\ -netbase,\ -net-tools,\ -iproute,\ -openssh-server - - cache=$1 - arch=$2 - - # check the mini debian was not already downloaded - mkdir -p "$cache/partial-$SUITE-$arch" - if [ $? -ne 0 ]; then - echo "Failed to create '$cache/partial-$SUITE-$arch' directory" - return 1 - fi - - # download a mini debian into a cache - echo "Downloading debian minimal ..." - debootstrap --verbose --variant=minbase --arch=$arch \ - --include $packages \ - "$SUITE" "$cache/partial-$SUITE-$arch" http://ftp.debian.org/debian - if [ $? -ne 0 ]; then - echo "Failed to download the rootfs, aborting." - return 1 - fi - - mv "$1/partial-$SUITE-$arch" "$1/rootfs-$SUITE-$arch" - echo "Download complete." - - return 0 -} - -copy_debian() -{ - cache=$1 - arch=$2 - rootfs=$3 - - # make a local copy of the minidebian - echo -n "Copying rootfs to $rootfs..." - cp -a "$cache/rootfs-$SUITE-$arch" $rootfs || return 1 - return 0 -} - -install_debian() -{ - cache="@LOCALSTATEDIR@/cache/lxc/$SUITE" - rootfs=$1 - mkdir -p @LOCALSTATEDIR@/lock/subsys/ - ( - flock -n -x 200 - if [ $? -ne 0 ]; then - echo "Cache repository is busy." - return 1 - fi - - arch=$(dpkg --print-architecture) - - echo "Checking cache download in $cache/rootfs-$SUITE-$arch ... " - if [ ! -e "$cache/rootfs-$SUITE-$arch" ]; then - download_debian $cache $arch - if [ $? -ne 0 ]; then - echo "Failed to download 'debian base'" - return 1 - fi - fi - - copy_debian $cache $arch $rootfs - if [ $? -ne 0 ]; then - echo "Failed to copy rootfs" - return 1 - fi - - return 0 - - ) 200>@LOCALSTATEDIR@/lock/subsys/lxc - - return $? -} - -copy_configuration() -{ - path=$1 - rootfs=$2 - name=$3 - - cat <> $path/config -lxc.tty = 4 -lxc.pts = 1024 -lxc.rootfs = $rootfs -lxc.cgroup.devices.deny = a -# /dev/null and zero -lxc.cgroup.devices.allow = c 1:3 rwm -lxc.cgroup.devices.allow = c 1:5 rwm -# consoles -lxc.cgroup.devices.allow = c 5:1 rwm -lxc.cgroup.devices.allow = c 5:0 rwm -lxc.cgroup.devices.allow = c 4:0 rwm -lxc.cgroup.devices.allow = c 4:1 rwm -# /dev/{,u}random -lxc.cgroup.devices.allow = c 1:9 rwm -lxc.cgroup.devices.allow = c 1:8 rwm -lxc.cgroup.devices.allow = c 136:* rwm -lxc.cgroup.devices.allow = c 5:2 rwm -# rtc -lxc.cgroup.devices.allow = c 254:0 rwm - -# mounts point -lxc.mount.entry=proc $rootfs/proc proc nodev,noexec,nosuid 0 0 -lxc.mount.entry=sysfs $rootfs/sys sysfs defaults 0 0 -EOF - - if [ $? -ne 0 ]; then - echo "Failed to add configuration" - return 1 - fi - - return 0 -} - -clean() -{ - cache="@LOCALSTATEDIR@/cache/lxc/$SUITE" - - if [ ! -e $cache ]; then - exit 0 - fi - - # lock, so we won't purge while someone is creating a repository - ( - flock -n -x 200 - if [ $? != 0 ]; then - echo "Cache repository is busy." - exit 1 - fi - - echo -n "Purging the download cache..." - rm --preserve-root --one-file-system -rf $cache && echo "Done." || exit 1 - exit 0 - - ) 200>@LOCALSTATEDIR@/lock/subsys/lxc -} - -usage() -{ - cat < --clean -EOF - return 0 -} - -options=$(getopt -o hp:n:c -l help,path:,name:,clean -- "$@") -if [ $? -ne 0 ]; then - usage $(basename $0) - exit 1 -fi -eval set -- "$options" - -while true -do - case "$1" in - -h|--help) usage $0 && exit 0;; - -p|--path) path=$2; shift 2;; - -n|--name) name=$2; shift 2;; - -c|--clean) clean=$2; shift 2;; - --) shift 1; break ;; - *) break ;; - esac -done - -if [ ! -z "$clean" -a -z "$path" ]; then - clean || exit 1 - exit 0 -fi - -type debootstrap -if [ $? -ne 0 ]; then - echo "'debootstrap' command is missing" - exit 1 -fi - -if [ -z "$path" ]; then - echo "'path' parameter is required" - exit 1 -fi - -if [ "$(id -u)" != "0" ]; then - echo "This script should be run as 'root'" - exit 1 -fi - -rootfs=$path/rootfs - -install_debian $rootfs -if [ $? -ne 0 ]; then - echo "failed to install debian" - exit 1 -fi - -configure_debian $rootfs $name -if [ $? -ne 0 ]; then - echo "failed to configure debian for a container" - exit 1 -fi - -copy_configuration $path $rootfs -if [ $? -ne 0 ]; then - echo "failed write configuration file" - exit 1 -fi - -if [ ! -z $clean ]; then - clean || exit 1 - exit 0 -fi diff -Nru lxc-0.8.0~rc1/templates/lxc-opensuse.in lxc-1.0.0~alpha1/templates/lxc-opensuse.in --- lxc-0.8.0~rc1/templates/lxc-opensuse.in 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/templates/lxc-opensuse.in 2013-09-10 22:22:00.000000000 +0000 @@ -18,14 +18,14 @@ # 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 +# 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 +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -DISTRO=12.1 +DISTRO=12.3 configure_opensuse() { @@ -35,42 +35,18 @@ # set network as static, but everything is done by LXC outside the container cat < $rootfs/etc/sysconfig/network/ifcfg-eth0 STARTMODE='auto' -BOOTPROTO='static' +BOOTPROTO='none' EOF - # set default route - IP=$(/sbin/ip route | awk '/default/ { print $3 }') - echo "default $IP - -" > $rootfs/etc/sysconfig/network/routes - # create empty fstab touch $rootfs/etc/fstab - # create minimal /dev - mknod -m 666 $rootfs/dev/random c 1 8 - mknod -m 666 $rootfs/dev/urandom c 1 9 - mkdir -m 755 $rootfs/dev/pts - mkdir -m 1777 $rootfs/dev/shm - mknod -m 666 $rootfs/dev/tty c 5 0 - mknod -m 600 $rootfs/dev/console c 5 1 - mknod -m 666 $rootfs/dev/tty0 c 4 0 - mknod -m 666 $rootfs/dev/tty1 c 4 1 - mknod -m 666 $rootfs/dev/tty2 c 4 2 - mknod -m 666 $rootfs/dev/tty3 c 4 3 - mknod -m 666 $rootfs/dev/tty4 c 4 4 - ln -s null $rootfs/dev/tty10 - mknod -m 666 $rootfs/dev/full c 1 7 - mknod -m 666 $rootfs/dev/ptmx c 5 2 - ln -s /proc/self/fd $rootfs/dev/fd - ln -s /proc/kcore $rootfs/dev/core - mkdir -m 755 $rootfs/dev/mapper - mknod -m 600 $rootfs/dev/mapper/control c 10 60 - mkdir -m 755 $rootfs/dev/net - mknod -m 666 $rootfs/dev/net/tun c 10 200 - # set the hostname cat < $rootfs/etc/HOSTNAME $hostname EOF + # ensure /etc/hostname is available too + ln -s -f HOSTNAME $rootfs/etc/hostname # do not use hostname from HOSTNAME variable cat <> $rootfs/etc/sysconfig/cron @@ -82,30 +58,12 @@ 127.0.0.1 localhost $hostname EOF - # disable various services # disable yast->bootloader in container cat < $rootfs/etc/sysconfig/bootloader LOADER_TYPE=none LOADER_LOCATION=none EOF - # cut down inittab - cat < $rootfs/etc/inittab -id:3:initdefault: -si::bootwait:/etc/init.d/boot -l0:0:wait:/etc/init.d/rc 0 -l1:1:wait:/etc/init.d/rc 1 -l2:2:wait:/etc/init.d/rc 2 -l3:3:wait:/etc/init.d/rc 3 -l6:6:wait:/etc/init.d/rc 6 -ls:S:wait:/etc/init.d/rc S -~~:S:respawn:/sbin/sulogin -p6::ctrlaltdel:/sbin/init 6 -p0::powerfail:/sbin/init 0 -cons:2345:respawn:/sbin/mingetty --noclear console screen -c1:2345:respawn:/sbin/mingetty --noclear tty1 screen -EOF - # set /dev/console as securetty cat << EOF >> $rootfs/etc/securetty console @@ -119,10 +77,22 @@ # remove pointless services in a container - chroot $rootfs /sbin/insserv -r -f boot.udev boot.loadmodules boot.device-mapper boot.clock boot.swap boot.klog kbd + ln -s /dev/null $rootfs/etc/systemd/system/proc-sys-fs-binfmt_misc.automount + ln -s /dev/null $rootfs/etc/systemd/system/console-shell.service + ln -s /dev/null $rootfs/etc/systemd/system/systemd-vconsole-setup.service + sed -e 's/ConditionPathExists=.*//' /usr/lib/systemd/system/getty@.service > $rootfs/etc/systemd/system/getty@.service + ln -s getty@.service $rootfs/etc/systemd/system/getty@tty1.service + ln -s ../getty@.service $rootfs/etc/systemd/system/getty.target.wants/getty@console.service + ln -s -f ../getty@.service $rootfs/etc/systemd/system/getty.target.wants/getty@tty1.service + ln -s ../getty@.service $rootfs/etc/systemd/system/getty.target.wants/getty@tty2.service + ln -s ../getty@.service $rootfs/etc/systemd/system/getty.target.wants/getty@tty3.service + ln -s ../getty@.service $rootfs/etc/systemd/system/getty.target.wants/getty@tty4.service + + + touch $rootfs/etc/sysconfig/kernel echo "Please change root-password !" - echo "root:root" | chroot $rootfs chpasswd + echo "root:root" | chpasswd -R $rootfs return 0 } @@ -142,40 +112,55 @@ mkdir -p "$cache/partial-$arch" if [ $? -ne 0 ]; then - echo "Failed to create '$cache/partial-$arch' directory" - return 1 + echo "Failed to create '$cache/partial-$arch' directory" + return 1 fi # download a mini opensuse into a cache echo "Downloading opensuse minimal ..." mkdir -p "$cache/partial-$arch-packages" - zypper --quiet --root $cache/partial-$arch-packages --non-interactive ar http://download.opensuse.org/distribution/$DISTRO/repo/oss/ repo-oss - zypper --quiet --root $cache/partial-$arch-packages --non-interactive ar http://download.opensuse.org/update/$DISTRO/ update - zypper --quiet --root $cache/partial-$arch-packages --non-interactive --gpg-auto-import-keys update - zypper --root $cache/partial-$arch-packages --non-interactive in --auto-agree-with-licenses --download-only zypper lxc patterns-openSUSE-base sysvinit-init + zypper --quiet --root $cache/partial-$arch-packages --non-interactive ar http://download.opensuse.org/distribution/$DISTRO/repo/oss/ repo-oss || return 1 + zypper --quiet --root $cache/partial-$arch-packages --non-interactive ar http://download.opensuse.org/update/$DISTRO/ update || return 1 + zypper --quiet --root $cache/partial-$arch-packages --non-interactive --gpg-auto-import-keys update || return 1 + zypper --root $cache/partial-$arch-packages --non-interactive in --auto-agree-with-licenses --download-only zypper lxc patterns-openSUSE-base bash iputils sed tar rsyslog || return 1 cat > $cache/partial-$arch-packages/opensuse.conf << EOF Preinstall: aaa_base bash coreutils diffutils -Preinstall: filesystem fillup glibc grep insserv libacl1 libattr1 -Preinstall: libbz2-1 libgcc46 libxcrypt libncurses5 pam -Preinstall: permissions libreadline6 rpm sed tar zlib libselinux1 -Preinstall: liblzma5 libcap2 libpcre0 +Preinstall: filesystem fillup glibc grep insserv-compat +Preinstall: libbz2-1 libgcc_s1 libncurses5 pam +Preinstall: permissions libreadline6 rpm sed tar libz1 libselinux1 +Preinstall: liblzma5 libcap2 libacl1 libattr1 Preinstall: libpopt0 libelf1 liblua5_1 +Preinstall: libpcre1 RunScripts: aaa_base Support: zypper Support: patterns-openSUSE-base Support: lxc -Prefer: sysvinit-init - -Ignore: patterns-openSUSE-base:patterns-openSUSE-yast2_install_wf -EOF +Support: ncurses-utils +Support: iputils +Support: udev +Support: netcfg +Support: dhcpcd hwinfo insserv-compat module-init-tools openSUSE-release openssh +Support: pwdutils rpcbind sysconfig + +Ignore: rpm:suse-build-key,build-key +Ignore: systemd:systemd-presets-branding +EOF + if [ "$arch" == "i686" ]; then + mkdir -p $cache/partial-$arch-packages/var/cache/zypp/packages/repo-oss/suse/i686/ + for i in "$cache/partial-$arch-packages/var/cache/zypp/packages/repo-oss/suse/i586/*" ; do + ln -s $i $cache/partial-$arch-packages/var/cache/zypp/packages/repo-oss/suse/i686/ + done + mkdir -p $cache/partial-$arch-packages/var/cache/zypp/packages/update/i686 + for i in "$cache/partial-$arch-packages/var/cache/zypp/packages/update/i586/*" ; do + ln -s $i $cache/partial-$arch-packages/var/cache/zypp/packages/update/i686/ + done + fi - CLEAN_BUILD=1 BUILD_ROOT="$cache/partial-$arch" BUILD_DIST="$cache/partial-$arch-packages/opensuse.conf" /usr/lib/build/init_buildsystem --clean --cachedir $cache/partial-$arch-cache --repository $cache/partial-$arch-packages/var/cache/zypp/packages/repo-oss/suse/$arch --repository $cache/partial-$arch-packages/var/cache/zypp/packages/repo-oss/suse/noarch - chroot $cache/partial-$arch /usr/bin/zypper --quiet --non-interactive ar http://download.opensuse.org/distribution/$DISTRO/repo/oss repo-oss - chroot $cache/partial-$arch /usr/bin/zypper --quiet --non-interactive ar http://download.opensuse.org/update/$DISTRO/ update - chroot $cache/partial-$arch rpm -e patterns-openSUSE-base - umount $cache/partial-$arch/proc + CLEAN_BUILD=1 BUILD_ARCH="$arch" BUILD_ROOT="$cache/partial-$arch" BUILD_DIST="$cache/partial-$arch-packages/opensuse.conf" PATH="$PATH:/usr/lib/build" /usr/lib/build/init_buildsystem --clean --configdir /usr/lib/build/configs --cachedir $cache/partial-$arch-cache --repository $cache/partial-$arch-packages/var/cache/zypp/packages/repo-oss/suse/$arch --repository $cache/partial-$arch-packages/var/cache/zypp/packages/repo-oss/suse/noarch --repository $cache/partial-$arch-packages/var/cache/zypp/packages/update/$arch --repository $cache/partial-$arch-packages/var/cache/zypp/packages/update/noarch || return 1 + chroot $cache/partial-$arch /usr/bin/zypper --quiet --non-interactive ar http://download.opensuse.org/distribution/$DISTRO/repo/oss repo-oss || return 1 + chroot $cache/partial-$arch /usr/bin/zypper --quiet --non-interactive ar http://download.opensuse.org/update/$DISTRO/ update || return 1 # really clean the image rm -fr $cache/partial-$arch/{.build,.guessed_dist,.srcfiles*,installed-pkg} rm -fr $cache/partial-$arch/dev @@ -186,9 +171,13 @@ # create mtab symlink rm -f $cache/partial-$arch/etc/mtab ln -sf /proc/self/mounts $cache/partial-$arch/etc/mtab + +# ensure /var/run and /run are symlinked + rm -fr $cache/partial-$arch/var/run + ln -s -f ../run $cache/partial-$arch/var/run if [ $? -ne 0 ]; then - echo "Failed to download the rootfs, aborting." - return 1 + echo "Failed to download the rootfs, aborting." + return 1 fi rm -fr "$cache/partial-$arch-packages" @@ -205,45 +194,44 @@ rootfs=$3 # make a local copy of the mini opensuse - echo -n "Copying rootfs to $rootfs ..." + echo "Copying rootfs to $rootfs ..." mkdir -p $rootfs - rsync -a $cache/rootfs-$arch/ $rootfs/ || return 1 + rsync -Ha $cache/rootfs-$arch/ $rootfs/ || return 1 return 0 } install_opensuse() { - cache="/var/cache/lxc/opensuse" + cache="@LOCALSTATEDIR@/cache/lxc/opensuse" rootfs=$1 - mkdir -p /var/lock/subsys/ + mkdir -p @LOCALSTATEDIR@/lock/subsys/ ( - flock -n -x 200 - if [ $? -ne 0 ]; then - echo "Cache repository is busy." - return 1 - fi - - arch=$(arch) - - echo "Checking cache download in $cache/rootfs-$arch ... " - if [ ! -e "$cache/rootfs-$arch" ]; then - download_opensuse $cache $arch - if [ $? -ne 0 ]; then - echo "Failed to download 'opensuse base'" - return 1 - fi - fi + flock -x 200 + if [ $? -ne 0 ]; then + echo "Cache repository is busy." + return 1 + fi + + arch=$(uname -m) + + echo "Checking cache download in $cache/rootfs-$arch ... " + if [ ! -e "$cache/rootfs-$arch" ]; then + download_opensuse $cache $arch + if [ $? -ne 0 ]; then + echo "Failed to download 'opensuse base'" + return 1 + fi + fi + + echo "Copy $cache/rootfs-$arch to $rootfs ... " + copy_opensuse $cache $arch $rootfs + if [ $? -ne 0 ]; then + echo "Failed to copy rootfs" + return 1 + fi - echo "Copy $cache/rootfs-$arch to $rootfs ... " - copy_opensuse $cache $arch $rootfs - if [ $? -ne 0 ]; then - echo "Failed to copy rootfs" - return 1 - fi - - return 0 - - ) 200>/var/lock/subsys/lxc + return 0 + ) 200>@LOCALSTATEDIR@/lock/subsys/lxc-opensuse return $? } @@ -254,13 +242,43 @@ rootfs=$2 name=$3 + if grep -q "^lxc.network.type" $path/config; then + TYPE=$(sed '/^#/d; /lxc.network.type/!d; s/.*=[ \t]*//' $path/config) + grep -q "^lxc.network.ipv4" $path/config + IPV4_NOT_CONFIGURED=$? + + if [ ! grep -q "^lxc.network.*.gateway" $path/config ]; then + [ $IPV4_NOT_CONFIGURED -eq 0 ] && IPV4=$(sed '/^#/d; /lxc.network.ipv4/!d; /gateway/d; s/.*=[ \t]*//; s/\([[:digit:]]\+\.[[:digit:]]\+\.[[:digit:]]\+\.[[:digit:]]\+\).*/\1/' $path/config) + if [ "$TYPE" = "veth" -o "$TYPE" = "macvlan" ]; then + if [ $IPV4_NOT_CONFIGURED -eq 0 -a "$IPV4" != "0.0.0.0" ]; then + # set default route + IP=$(/sbin/ip route | awk '/default/ { print $3 }') + echo "lxc.network.ipv4.gateway = $IP " >> $path/config + else + # set network as dhcp + sed -i -e 's/BOOTPROTO=.*/BOOTPROTO=dhcp/' $rootfs/etc/sysconfig/network/ifcfg-eth0 + fi + fi + fi + if [ "$TYPE" != "empty" ]; then + echo "#remove next line if host DNS configuration should not be available to container" >> $path/config + echo "lxc.mount.entry = /etc/resolv.conf etc/resolv.conf none bind,ro 0 0" >> $path/config + fi + else + echo 'lxc.network.type = empty' >> $path/config + fi + + grep -q "^lxc.rootfs" $path/config 2>/dev/null || echo "lxc.rootfs = $rootfs" >> $path/config cat <> $path/config lxc.utsname = $name - +lxc.autodev=1 lxc.tty = 4 lxc.pts = 1024 -lxc.rootfs = $rootfs -lxc.mount = $path/fstab +lxc.mount = $path/fstab +lxc.cap.drop = sys_module mac_admin mac_override mknod sys_time + +# When using LXC with apparmor, uncomment the next line to run unconfined: +#lxc.aa_profile = unconfined lxc.cgroup.devices.deny = a # /dev/null and zero @@ -277,17 +295,18 @@ lxc.cgroup.devices.allow = c 136:* rwm lxc.cgroup.devices.allow = c 5:2 rwm # rtc -lxc.cgroup.devices.allow = c 254:0 rwm +lxc.cgroup.devices.allow = c 254:0 rm EOF cat < $path/fstab -proc $rootfs/proc proc nodev,noexec,nosuid 0 0 -sysfs $rootfs/sys sysfs defaults 0 0 +proc proc proc nodev,noexec,nosuid 0 0 +sysfs sys sysfs defaults 0 0 +tmpfs run tmpfs mode=0755,nodev,nosuid 0 0 EOF if [ $? -ne 0 ]; then - echo "Failed to add configuration" - return 1 + echo "Failed to add configuration" + return 1 fi return 0 @@ -295,25 +314,24 @@ clean() { - cache="/var/cache/lxc/opensuse" + cache="@LOCALSTATEDIR@/cache/lxc/opensuse" if [ ! -e $cache ]; then - exit 0 + exit 0 fi # lock, so we won't purge while someone is creating a repository ( - flock -n -x 200 - if [ $? != 0 ]; then - echo "Cache repository is busy." - exit 1 - fi - - echo -n "Purging the download cache..." - rm --preserve-root --one-file-system -rf $cache && echo "Done." || exit 1 - exit 0 - - ) 200>/var/lock/subsys/lxc + flock -x 200 + if [ $? != 0 ]; then + echo "Cache repository is busy." + exit 1 + fi + + echo -n "Purging the download cache..." + rm --preserve-root --one-file-system -rf $cache && echo "Done." || exit 1 + exit 0 + ) 200>@LOCALSTATEDIR@/lock/subsys/lxc-opensuse } usage() @@ -324,7 +342,7 @@ return 0 } -options=$(getopt -o hp:n:c -l help,path:,name:,clean -- "$@") +options=$(getopt -o hp:n:c -l help,rootfs:,path:,name:,clean -- "$@") if [ $? -ne 0 ]; then usage $(basename $0) exit 1 @@ -334,12 +352,13 @@ while true do case "$1" in - -h|--help) usage $0 && exit 0;; - -p|--path) path=$2; shift 2;; - -n|--name) name=$2; shift 2;; - -c|--clean) clean=$2; shift 2;; - --) shift 1; break ;; - *) break ;; + -h|--help) usage $0 && exit 0;; + -p|--path) path=$2; shift 2;; + --rootfs) rootfs=$2; shift 2;; + -n|--name) name=$2; shift 2;; + -c|--clean) clean=$2; shift 2;; + --) shift 1; break ;; + *) break ;; esac done @@ -364,7 +383,15 @@ exit 1 fi -rootfs=$path/rootfs +# detect rootfs +config="$path/config" +if [ -z "$rootfs" ]; then + if grep -q '^lxc.rootfs' $config 2>/dev/null ; then + rootfs=`grep 'lxc.rootfs =' $config | awk -F= '{ print $2 }'` + else + rootfs=$path/rootfs + fi +fi install_opensuse $rootfs if [ $? -ne 0 ]; then diff -Nru lxc-0.8.0~rc1/templates/lxc-oracle.in lxc-1.0.0~alpha1/templates/lxc-oracle.in --- lxc-0.8.0~rc1/templates/lxc-oracle.in 1970-01-01 00:00:00.000000000 +0000 +++ lxc-1.0.0~alpha1/templates/lxc-oracle.in 2013-09-10 22:22:00.000000000 +0000 @@ -0,0 +1,734 @@ +#!/bin/bash +# +# Template script for generating Oracle Enterprise Linux container for LXC +# based on lxc-fedora, lxc-ubuntu +# +# Copyright 2011 Wim Coekaerts +# Copyright 2012 Dwight Engen +# +# Modified for Oracle Linux 5 +# Wim Coekaerts +# +# Modified for Oracle Linux 6, combined OL4,5,6 into one template script +# Dwight Engen +# +# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# + +# use virbr0 that is setup by default by libvirtd +lxc_network_type=veth +lxc_network_link=virbr0 + +die() +{ + echo "failed: $1" + exit 1 +} + +is_btrfs_subvolume() +{ + if which btrfs >/dev/null 2>&1 && \ + btrfs subvolume list "$1" >/dev/null 2>&1; then + return 0 + fi + return 1 +} + +# fix up the container_rootfs +container_rootfs_configure() +{ + echo "Configuring container for Oracle Linux $container_release_major.$container_release_minor" + + # "disable" selinux. init in OL 5 honors /etc/selinux/config. note that + # this doesnt actually disable it if it's enabled in the host, since + # libselinux::is_selinux_enabled() in the guest will check + # /proc/filesystems and see selinuxfs, thus reporting that it is on + # (ie. check the output of sestatus in the guest) + mkdir -p $container_rootfs/selinux + echo 0 > $container_rootfs/selinux/enforce + if [ -e $container_rootfs/etc/selinux/config ]; then + sed -i 's|SELINUX=enforcing|SELINUX=disabled|' $container_rootfs/etc/selinux/config + else + mkdir -p $container_rootfs/etc/selinux + echo "SELINUX=disabled" >$container_rootfs/etc/selinux/config + fi + sed -i 's|session[ \t]*required[ \t]*pam_selinux.so[ \t]*close|#session required pam_selinux.so close|' $container_rootfs/etc/pam.d/login + sed -i 's|session[ \t]*required[ \t]*pam_selinux.so[ \t]*open|#session required pam_selinux.so open|' $container_rootfs/etc/pam.d/login + sed -i 's|session[ \t]*required[ \t]*pam_loginuid.so|#session required pam_loginuid.so|' $container_rootfs/etc/pam.d/login + + # silence error in checking for selinux + sed -i 's|cat /proc/self/attr/current|cat /proc/self/attr/current 2>/dev/null|' $container_rootfs/etc/rc.sysinit + sed -i 's|cat /proc/self/attr/current|cat /proc/self/attr/current 2>/dev/null|' $container_rootfs/etc/rc.d/rc.sysinit + + # configure the network to use dhcp. we set DHCP_HOSTNAME so the guest + # will report its name and be resolv'able by the hosts dnsmasq + cat < $container_rootfs/etc/sysconfig/network-scripts/ifcfg-eth0 +DEVICE=eth0 +BOOTPROTO=dhcp +ONBOOT=yes +HOSTNAME=$name +DHCP_HOSTNAME=$name +NM_CONTROLLED=no +TYPE=Ethernet +EOF + + # avoid error in ol5 attempting to copy non-existent resolv.conf + if [ $container_release_major = "5" ]; then + sed -i 's|resolv.conf.predhclient|resolv.conf.predhclient 2>/dev/null|' $container_rootfs/sbin/dhclient-script + fi + + # set the hostname + cat < $container_rootfs/etc/sysconfig/network +NETWORKING=yes +NETWORKING_IPV6=no +HOSTNAME=$name +EOF + + # disable interactive ovmd asking questions + if [ -f $container_rootfs/etc/sysconfig/ovmd ]; then + sed -i 's|INITIAL_CONFIG=yes|INITIAL_CONFIG=no|' $container_rootfs/etc/sysconfig/ovmd + fi + + # set minimal hosts + echo "127.0.0.1 localhost $name" > $container_rootfs/etc/hosts + + # disable ipv6 on ol6 + rm -f $container_rootfs/etc/sysconfig/network-scripts/init.ipv6-global + + # this file has to exist for libvirt/Virtual machine monitor to boot the container + touch $container_rootfs/etc/mtab + + # don't put devpts in here, it will already be mounted for us by lxc/libvirt + cat < $container_rootfs/etc/fstab +proc /proc proc nodev,noexec,nosuid 0 0 +sysfs /sys sysfs defaults 0 0 +EOF + + # remove module stuff for iptables it just shows errors that are not + # relevant in a container + if [ -f "$container_rootfs/etc/sysconfig/iptables-config" ]; then + sed -i 's|IPTABLES_MODULES=".*|IPTABLES_MODULES=""|' $container_rootfs/etc/sysconfig/iptables-config + sed -i 's|IPTABLES_MODULES_UNLOAD=".*|IPTABLES_MODULES_UNLOAD="no"|' $container_rootfs/etc/sysconfig/iptables-config + fi + + # disable readahead in the container + if [ $container_release_major = "6" -a -e $container_rootfs/etc/sysconfig/readahead ]; then + rm -f $container_rootfs/etc/init/readahead-collector.conf + rm -f $container_rootfs/etc/init/readahead-disable-services.conf + sed -i 's|READAHEAD="yes"|READAHEAD="no"|' $container_rootfs/etc/sysconfig/readahead + fi + + if [ $container_release_major = "4" ]; then + # enable fastboot always + sed -i 's|\[ -f /fastboot \]|/bin/true|' $container_rootfs/etc/rc.sysinit + sed -i 's|\[ -f /fastboot \]|/bin/true|' $container_rootfs/etc/rc.d/rc.sysinit + + # dont attempt to set kernel parameters + sed -i 's|action $"Configuring kernel parameters|# LXC action $"Configuring kernel parameters|' $container_rootfs/etc/rc.sysinit + sed -i 's|action $"Configuring kernel parameters|# LXC action $"Configuring kernel parameters|' $container_rootfs/etc/rc.d/rc.sysinit + sed -i 's|action $"Setting network parameters|# LXC action $"Setting network parameters|' $container_rootfs/etc/init.d/network 2>/dev/null + sed -i 's|action $"Setting network parameters|# LXC action $"Setting network parameters|' $container_rootfs/etc/init.d/NetworkManager 2>/dev/null + fi + + # sem_open(3) checks that /dev/shm is SHMFS_SUPER_MAGIC, so make sure to mount /dev/shm (normally done by dracut initrd) as tmpfs + if [ $container_release_major = "4" -o $container_release_major = "5" ]; then + echo "mount -t tmpfs tmpfs /dev/shm" >>$container_rootfs/etc/rc.sysinit + echo "mount -t tmpfs tmpfs /dev/shm" >>$container_rootfs/etc/rc.d/rc.sysinit + fi + + if [ $container_release_major = "6" ]; then + sed -i 's|mount -n -o remount /dev/shm >/dev/null 2>&1$|mount -t tmpfs tmpfs /dev/shm # LXC|' $container_rootfs/etc/rc.sysinit + sed -i 's|mount -n -o remount /dev/shm >/dev/null 2>&1$|mount -t tmpfs tmpfs /dev/shm # LXC|' $container_rootfs/etc/rc.d/rc.sysinit + fi + + # no need to attempt to mount / + sed -i 's|mount -f /$|# LXC mount -f /|' $container_rootfs/etc/rc.sysinit + sed -i 's|mount -f /$|# LXC mount -f /|' $container_rootfs/etc/rc.d/rc.sysinit + sed -i 's|action \$"Remounting root filesystem|/bin/true # LXC action $"Remounting root filesystem|' $container_rootfs/etc/rc.sysinit + sed -i 's|action \$"Remounting root filesystem|/bin/true # LXC action $"Remounting root filesystem|' $container_rootfs/etc/rc.d/rc.sysinit + + # disable udev in the container + if [ $container_release_major = "4" ]; then + sed -i 's|\[ -x /sbin/start_udev \]|# LXC no udev|' $container_rootfs/etc/rc.sysinit + sed -i 's|\[ -x /sbin/start_udev \]|# LXC no udev|' $container_rootfs/etc/rc.d/rc.sysinit + else + sed -i 's|.sbin.start_udev||' $container_rootfs/etc/rc.sysinit + sed -i 's|.sbin.start_udev||' $container_rootfs/etc/rc.d/rc.sysinit + fi + + # disable nash raidautorun in the container since no /dev/md* + if [ $container_release_major = "4" -o $container_release_major = "5" ]; then + sed -i 's|echo "raidautorun /dev/md0"|echo ""|' $container_rootfs/etc/rc.sysinit + sed -i 's|echo "raidautorun /dev/md0"|echo ""|' $container_rootfs/etc/rc.d/rc.sysinit + fi + + # prevent rc.sysinit from attempting to loadkeys + if [ \( $container_release_major = "4" -o $container_release_major = "5" \) -a -e $container_rootfs/etc/sysconfig/keyboard ]; then + rm $container_rootfs/etc/sysconfig/keyboard + fi + + # dont use the hwclock, it messes up the host's time + if [ $container_release_major = "4" ]; then + sed -i 's|runcmd $"Syncing hardware clock|# LXC no hwclock runcmd $"Syncing hardware clock|' $container_rootfs/etc/rc.d/init.d/halt + else + sed -i 's|\[ -x /sbin/hwclock|\[ 0 -eq 1|' $container_rootfs/etc/rc.d/init.d/halt + fi + sed -i 's|^\[ -x /sbin/hwclock|\[ 0 -eq 1|' $container_rootfs/etc/rc.sysinit + sed -i 's|^\[ -x /sbin/hwclock|\[ 0 -eq 1|' $container_rootfs/etc/rc.d/rc.sysinit + sed -i 's|^/sbin/hwclock|# LXC /sbin/nohwclock|' $container_rootfs/etc/rc.sysinit + sed -i 's|^/sbin/hwclock|# LXC /sbin/nohwclock|' $container_rootfs/etc/rc.d/rc.sysinit + + # dont start lvm + sed -i 's|action $"Setting up Logical Volume Management:"|#action $"Setting up Logical Volume Management:"|' $container_rootfs/etc/rc.sysinit + sed -i 's|action $"Setting up Logical Volume Management:"|/bin/true #action $"Setting up Logical Volume Management:"|' $container_rootfs/etc/rc.d/rc.sysinit + + # fix assumptions that plymouth is available + sed -i 's|\[ "$PROMPT" != no \] && plymouth|[ "$PROMPT" != no ] \&\& [ -n "$PLYMOUTH" ] \&\& plymouth|' $container_rootfs/etc/rc.sysinit + sed -i 's|\[ "$PROMPT" != no \] && plymouth|[ "$PROMPT" != no ] \&\& [ -n "$PLYMOUTH" ] \&\& plymouth|' $container_rootfs/etc/rc.d/rc.sysinit + rm -f $container_rootfs/etc/init/plymouth-shutdown.conf + rm -f $container_rootfs/etc/init/quit-plymouth.conf + rm -f $container_rootfs/etc/init/splash-manager.conf + + # setup console and tty[1-4] for login. note that /dev/console and + # /dev/tty[1-4] will be symlinks to the ptys /dev/lxc/console and + # /dev/lxc/tty[1-4] so that package updates can overwrite the symlinks. + # lxc will maintain these links and bind mount ptys over /dev/lxc/* + # since lxc.devttydir is specified in the config. + + # allow root login on console, tty[1-4], and pts/0 for libvirt + echo "# LXC (Linux Containers)" >>$container_rootfs/etc/securetty + echo "lxc/console" >>$container_rootfs/etc/securetty + echo "lxc/tty1" >>$container_rootfs/etc/securetty + echo "lxc/tty2" >>$container_rootfs/etc/securetty + echo "lxc/tty3" >>$container_rootfs/etc/securetty + echo "lxc/tty4" >>$container_rootfs/etc/securetty + echo "# For libvirt/Virtual Machine Monitor" >>$container_rootfs/etc/securetty + echo "pts/0" >>$container_rootfs/etc/securetty + + # dont try to unmount /dev/lxc devices + sed -i 's|&& $1 !~ /^\\/dev\\/ram/|\&\& $2 !~ /^\\/dev\\/lxc/ \&\& $1 !~ /^\\/dev\\/ram/|' $container_rootfs/etc/init.d/halt + + # don't try to unmount swap + sed -i 's|\[ -f /proc/swaps \]|# LXC [ -f /proc/swaps ]|' $container_rootfs/etc/init.d/halt + + # start a getty on /dev/console, /dev/tty[1-4] + if [ $container_release_major = "4" -o $container_release_major = "5" ]; then + sed -i '/1:2345:respawn/i cns:2345:respawn:/sbin/mingetty console' $container_rootfs/etc/inittab + sed -i '/5:2345:respawn/d' $container_rootfs/etc/inittab + sed -i '/6:2345:respawn/d' $container_rootfs/etc/inittab + fi + + if [ $container_release_major = "6" ]; then + cat < $container_rootfs/etc/init/console.conf +# console - getty +# +# This service maintains a getty on the console from the point the system is +# started until it is shut down again. + +start on stopped rc RUNLEVEL=[2345] +stop on runlevel [!2345] + +respawn +exec /sbin/mingetty /dev/console +EOF + fi + + # lxc-shutdown sends SIGPWR to init, OL4 and OL5 have SysVInit, just + # make it do shutdown now instead of delaying 2 minutes. OL6 uses + # upstart, so we create an upstart job to handle SIGPWR to shut down + # cleanly. We use "init 0" instead of shutdown -h now to avoid SELinux + # permission denied when upstart's shutdown tries to connect to the + # /com/ubuntu/upstart socket. + if [ $container_release_major = "4" -o $container_release_major = "5" ]; then + sed -i 's|pf::powerfail:/sbin/shutdown -f -h +2 "Power Failure; |pf::powerfail:/sbin/shutdown -f -h now "|' $container_rootfs/etc/inittab + else + cat < $container_rootfs/etc/init/power-status-changed.conf +# power-status-changed - used to cleanly shut down the container +# +# This task is run whenever init receives SIGPWR +# Used to shut down the machine. + +start on power-status-changed + +exec init 0 +EOF + fi + + # there might be other services that are useless but the below set is a good start + # some of these might not exist in the image, so we silence chkconfig complaining + # about the service file not being found + for service in \ + acpid apmd auditd autofs cpuspeed dund gpm haldaemon hidd \ + ip6tables irqbalance iscsi iscsid isdn kdump kudzu \ + lm_sensors lvm2-monitor mdmonitor microcode_ctl \ + ntpd pcmcia postfix sendmail udev-post xfs ; + do + chroot $container_rootfs chkconfig 2>/dev/null $service off + done + + for service in rsyslog ; + do + chroot $container_rootfs chkconfig 2>/dev/null $service on + done + + # create required devices. note that /dev/console will be created by lxc + # or libvirt itself to be a symlink to the right pty. + # take care to not nuke /dev in case $container_rootfs isn't set + dev_path="$container_rootfs/dev" + if [ $container_rootfs != "/" -a -d $dev_path ]; then + rm -rf $dev_path + mkdir -p $dev_path + fi + mknod -m 666 $dev_path/null c 1 3 + mknod -m 666 $dev_path/zero c 1 5 + mknod -m 666 $dev_path/random c 1 8 + mknod -m 666 $dev_path/urandom c 1 9 + mkdir -m 755 $dev_path/pts + mkdir -m 1777 $dev_path/shm + mknod -m 666 $dev_path/tty c 5 0 + mknod -m 666 $dev_path/tty0 c 4 0 + mknod -m 666 $dev_path/tty1 c 4 1 + mknod -m 666 $dev_path/tty2 c 4 2 + mknod -m 666 $dev_path/tty3 c 4 3 + mknod -m 666 $dev_path/tty4 c 4 4 + mknod -m 666 $dev_path/full c 1 7 + mknod -m 600 $dev_path/initctl p + + # set selinux labels same as host + if which chcon >/dev/null 2>&1 ; then + for node in null zero random urandom pts shm \ + tty tty0 tty1 tty2 tty3 tty4 full ; + do + chcon --reference /dev/$node $dev_path/$node 2>/dev/null + done + fi + + # ensure /dev/ptmx refers to the newinstance devpts of the container, or + # pty's will get crossed up with the hosts (https://lkml.org/lkml/2012/1/23/512) + rm -f $container_rootfs/dev/ptmx + ln -s pts/ptmx $container_rootfs/dev/ptmx + + # start with a clean /var/log/messages + rm -f $container_rootfs/var/log/messages + + # add oracle user, set root password + chroot $container_rootfs useradd -m -s /bin/bash oracle + echo "oracle:oracle" | chroot $container_rootfs chpasswd + echo "root:root" | chroot $container_rootfs chpasswd + echo -e "Added container user:\033[1moracle\033[0m password:\033[1moracle\033[0m" + echo -e "Added container user:\033[1mroot\033[0m password:\033[1mroot\033[0m" +} + +# create the container's lxc config file +container_config_create() +{ + echo "Create configuration file $cfg_dir/config" + # generate a hwaddr for the container with a high mac address + # see http://sourceforge.net/tracker/?func=detail&aid=3411497&group_id=163076&atid=826303 + local hwaddr="fe:`dd if=/dev/urandom bs=8 count=1 2>/dev/null |od -t x8 | \ + head -1 |awk '{print $2}' | cut -c1-10 |\ + sed 's/\(..\)/\1:/g; s/.$//'`" + mkdir -p $cfg_dir || die "unable to create config dir $cfg_dir" + cat <> $cfg_dir/config || die "unable to create $cfg_dir/config" +# Container configuration for Oracle Linux $container_release_major.$container_release_minor +lxc.arch = $arch +lxc.utsname = $name +lxc.devttydir = lxc +lxc.tty = 4 +lxc.pts = 1024 +lxc.mount = $cfg_dir/fstab +lxc.hook.clone = @DATADIR@/lxc/hooks/clonehostname +# Uncomment these if you don't run anything that needs the capability, and +# would like the container to run with less privilege. +# +# Dropping sys_admin disables container root from doing a lot of things +# that could be bad like re-mounting lxc fstab entries rw for example, +# but also disables some useful things like being able to nfs mount, and +# things that are already namespaced with ns_capable() kernel checks, like +# hostname(1). +# lxc.cap.drop = sys_admin +# lxc.cap.drop = net_raw # breaks dhcp/ping +# lxc.cap.drop = setgid # breaks login (initgroups/setgroups) +# lxc.cap.drop = dac_read_search # breaks login (pam unix_chkpwd) +# lxc.cap.drop = setuid # breaks sshd,nfs statd +# lxc.cap.drop = audit_control # breaks sshd (set_loginuid failed) +# lxc.cap.drop = audit_write +# +lxc.cap.drop = mac_admin mac_override setfcap setpcap +lxc.cap.drop = sys_module sys_nice sys_pacct +lxc.cap.drop = sys_rawio sys_time +EOF + grep -q "^lxc.rootfs" $cfg_dir/config 2>/dev/null || echo "lxc.rootfs = $container_rootfs" >> $cfg_dir/config + + if [ $container_release_major != "4" ]; then + echo "lxc.cap.drop = sys_resource" >>$cfg_dir/config + fi + + echo "# Networking" >>$cfg_dir/config + # see if the network settings were already specified + lxc_network_type=`grep '^lxc.network.type' $cfg_dir/config | awk -F'[= \t]+' '{ print $2 }'` + if [ -z "$lxc_network_type" -a \ + \( $host_distribution = "OracleServer" -o \ + $host_distribution = "Fedora" \) ]; then + echo "lxc.network.type = veth" >>$cfg_dir/config + echo "lxc.network.flags = up" >>$cfg_dir/config + echo "lxc.network.link = virbr0" >>$cfg_dir/config + fi + + cat <> $cfg_dir/config || die "unable to create $cfg_dir/config" +lxc.network.name = eth0 +lxc.network.mtu = 1500 +lxc.network.hwaddr = $hwaddr +# Control Group devices: all denied except those whitelisted +lxc.cgroup.devices.deny = a +lxc.cgroup.devices.allow = c 1:3 rwm # /dev/null +lxc.cgroup.devices.allow = c 1:5 rwm # /dev/zero +lxc.cgroup.devices.allow = c 1:7 rwm # /dev/full +lxc.cgroup.devices.allow = c 5:0 rwm # /dev/tty +lxc.cgroup.devices.allow = c 1:8 rwm # /dev/random +lxc.cgroup.devices.allow = c 1:9 rwm # /dev/urandom +lxc.cgroup.devices.allow = c 136:* rwm # /dev/tty[1-4] ptys and lxc console +lxc.cgroup.devices.allow = c 5:2 rwm # /dev/ptmx pty master +EOF + + cat < $cfg_dir/fstab || die "unable to create $cfg_dir/fstab" +proc $container_rootfs/proc proc nodev,noexec,nosuid 0 0 +devpts $container_rootfs/dev/pts devpts defaults 0 0 +sysfs $container_rootfs/sys sysfs defaults 0 0 +EOF +} + +container_rootfs_clone() +{ + if is_btrfs_subvolume $template_rootfs; then + # lxc-create already made $container_rootfs a btrfs subvolume, but + # in this case we want to snapshot the original subvolume so we we + # have to delete the one that lxc-create made + btrfs subvolume delete $container_rootfs + btrfs subvolume snapshot $template_rootfs $container_rootfs || die "btrfs clone template" + else + echo "Copying rootfs ..." + cp -axT $template_rootfs $container_rootfs || die "copy template" + fi +} + +container_rootfs_create() +{ + cmds="rpm wget yum" + if [ $container_release_major -lt "6" ]; then + if [ $host_distribution = "Ubuntu" -o $host_distribution = "Debian" ]; then + db_dump_cmd="db5.1_dump" + db_load_cmd="db4.3_load" + fi + if [ $host_distribution = "OracleServer" -o \ + $host_distribution = "Fedora" ]; then + db_dump_cmd="db_dump" + db_load_cmd="db43_load" + fi + + cmds="$cmds $db_dump_cmd $db_load_cmd file" + fi + for cmd in $cmds; do + which $cmd >/dev/null 2>&1 + if [ $? -ne 0 ]; then + die "The $cmd command is required, please install it" + fi + done + + mkdir -p @LOCALSTATEDIR@/lock/subsys/lxc + ( + flock -x 200 + if [ $? -ne 0 ]; then + die "The template is busy." + fi + + echo "Downloading release $container_release_major.$container_release_minor for $basearch" + + # get yum repo file + if [ -n "$repourl" ]; then + yum_url=$repourl + else + yum_url=http://public-yum.oracle.com + fi + if [ $container_release_major = "4" ]; then + repofile=public-yum-el4.repo + elif [ $container_release_major = "5" ]; then + repofile=public-yum-el5.repo + elif [ $container_release_major = "6" ]; then + repofile=public-yum-ol6.repo + else + die "Unsupported release $container_release_major" + fi + mkdir -p $container_rootfs/etc/yum.repos.d + wget -q $yum_url/$repofile -O $container_rootfs/etc/yum.repos.d/$repofile + if [ $? -ne 0 ]; then + die "Failed to download repo file $yum_url/$repofile" + fi + + # yum will take $basearch from host, so force the arch we want + sed -i "s|\$basearch|$basearch|" $container_rootfs/etc/yum.repos.d/$repofile + + # replace url if they specified one + if [ -n "$repourl" ]; then + sed -i "s|baseurl=http://public-yum.oracle.com/repo|baseurl=$repourl/repo|" $container_rootfs/etc/yum.repos.d/$repofile + sed -i "s|gpgkey=http://public-yum.oracle.com|gpgkey=$repourl|" $container_rootfs/etc/yum.repos.d/$repofile + fi + + # disable all repos, then enable the repo for the version we are installing. + if [ $container_release_minor = "latest" ]; then + if [ $container_release_major = "4" -o $container_release_major = "5" ]; then + repo="el"$container_release_major"_"$container_release_minor + else + repo="ol"$container_release_major"_"$container_release_minor + fi + elif [ $container_release_major = "6" ]; then + if [ $container_release_minor = "0" ]; then + repo="ol"$container_release_major"_ga_base" + else + repo="ol"$container_release_major"_u"$container_release_minor"_base" + fi + elif [ $container_release_major = "5" ]; then + if [ $container_release_minor = "0" ]; then + repo="el"$container_release_major"_ga_base" + elif [ $container_release_minor -lt "6" ]; then + repo="el"$container_release_major"_u"$container_release_minor"_base" + else + repo="ol"$container_release_major"_u"$container_release_minor"_base" + fi + elif [ $container_release_major = "4" -a $container_release_minor -gt "5" ]; then + repo="el"$container_release_major"_u"$container_release_minor"_base" + else + die "Unsupported release $container_release_major.$container_release_minor" + fi + sed -i "s|enabled=1|enabled=0|" $container_rootfs/etc/yum.repos.d/$repofile + sed -i "/\[$repo\]/,/\[/ s/enabled=0/enabled=1/" $container_rootfs/etc/yum.repos.d/$repofile + + # create rpm db, download and yum install minimal packages + mkdir -p $container_rootfs/var/lib/rpm + rpm --root $container_rootfs --initdb + yum_args="--installroot $container_rootfs --disablerepo=* --enablerepo=$repo -y --nogpgcheck" + min_pkgs="yum initscripts passwd rsyslog vim-minimal openssh-server dhclient chkconfig rootfiles policycoreutils oraclelinux-release" + + # we unshare the mount namespace because yum installing the ol4 + # packages causes $rootfs/proc to be mounted on + lxc-unshare -s MOUNT yum -- $yum_args install $min_pkgs $user_pkgs + if [ $? -ne 0 ]; then + die "Failed to download and install the rootfs, aborting." + fi + + # rsyslog and pam depend on coreutils for some common commands in + # their POSTIN scriptlets, but coreutils wasn't installed yet. now + # that coreutils is installed, reinstall the packages so their POSTIN + # runs right. similarly, libutempter depends on libselinux.so.1 when + # it runs /usr/sbin/groupadd, so reinstall it too + redo_pkgs="" + if [ $container_release_major = "5" ]; then + if [ $container_release_minor = "latest" ]; then + redo_pkgs="pam rsyslog libutempter" + elif [ $container_release_minor -lt 2 ]; then + redo_pkgs="pam" + elif [ $container_release_minor -lt 6 ]; then + redo_pkgs="pam rsyslog" + elif [ $container_release_minor -gt 5 ]; then + redo_pkgs="pam rsyslog libutempter" + fi + fi + # shadow utils fails on ol4 and ol6.1 + if [ $container_release_major = "4" -o \ + $container_release_major = "6" -a $container_release_minor = "1" ]; then + redo_pkgs="shadow-utils" + fi + if [ x"$redo_pkgs" != x ]; then + rpm --root $container_rootfs --nodeps -e $redo_pkgs + yum $yum_args install $redo_pkgs + if [ $? -ne 0 ]; then + die "Unable to reinstall packages" + fi + fi + + # these distributions put the rpm database in a place the guest is + # not expecting it, so move it + if [ $host_distribution = "Ubuntu" -o $host_distribution = "Debian" ]; then + mv $container_rootfs/$HOME/.rpmdb/* $container_rootfs/var/lib/rpm + fi + + # if the native rpm created the db with Hash version 9, we need to + # downgrade it to Hash version 8 for use with OL5.x + db_version=`file $container_rootfs/var/lib/rpm/Packages | \ + grep -o 'version [0-9]*' |awk '{print $2}'` + if [ $container_release_major -lt "6" -a $db_version != "8" ]; then + echo "Fixing (downgrading) rpm database from version $db_version" + rm -f $container_rootfs/var/lib/rpm/__db* + for db in $container_rootfs/var/lib/rpm/* ; do + $db_dump_cmd $db |$db_load_cmd $db.new + mv $db.new $db + done + fi + + # the host rpm may not be the same as the guest, rebuild the db with + # the guest rpm version + echo "Rebuilding rpm database" + rm -f $container_rootfs/var/lib/rpm/__db* + chroot $container_rootfs rpm --rebuilddb >/dev/null 2>&1 + + ) 200>@LOCALSTATEDIR@/lock/subsys/lxc-oracle-$name +} + +container_release_get() +{ + if [ -f $1/etc/oracle-release ]; then + container_release_version=`cat $1/etc/oracle-release |awk '/^Oracle/ {print $5}'` + container_release_major=`echo $container_release_version |awk -F '.' '{print $1}'` + container_release_minor=`echo $container_release_version |awk -F '.' '{print $2}'` + elif grep -q "Enterprise Linux AS" $1/etc/redhat-release; then + container_release_major=`cat $1/etc/redhat-release |awk '{print $7}'` + container_release_minor=`cat $1/etc/redhat-release |awk '{print $10}' |tr -d ")"` + container_release_version="$container_release_major.$container_release_minor" + elif grep -q "Enterprise Linux Server" $1/etc/redhat-release; then + container_release_version=`cat $1/etc/redhat-release |awk '{print $7}'` + container_release_major=`echo $container_release_version |awk -F '.' '{print $1}'` + container_release_minor=`echo $container_release_version |awk -F '.' '{print $2}'` + else + echo "Unable to determine container release version" + exit 1 + fi +} + +usage() +{ + cat < architecture (ie. i386, x86_64) + -R|--release= release to download for the new container + --rootfs= rootfs path + -r|--rpms= additional rpms to install into container + -u|--url= replace yum repo url (ie. local yum mirror) + -t|--templatefs= copy/clone rootfs at path instead of downloading + -h|--help + +Release is of the format "major.minor", for example "5.8", "6.3", or "6.latest" +EOF + return 0 +} + +options=$(getopt -o hp:n:a:R:r:u:t: -l help,rootfs:,path:,name:,arch:,release:,rpms:,url:,templatefs: -- "$@") +if [ $? -ne 0 ]; then + usage $(basename $0) + exit 1 +fi + +arch=$(uname -m) +eval set -- "$options" +while true +do + case "$1" in + -h|--help) usage $0 && exit 0;; + -p|--path) cfg_dir=$2; shift 2;; + --rootfs) container_rootfs=$2; shift 2;; + -n|--name) name=$2; shift 2;; + -a|--arch) arch=$2; shift 2;; + -R|--release) container_release_version=$2; shift 2;; + -r|--rpms) user_pkgs=$2; shift 2;; + -u|--url) repourl=$2; shift 2;; + -t|--templatefs) template_rootfs=$2; shift 2;; + --) shift 1; break ;; + *) break ;; + esac +done + +# make sure mandatory args are given and valid +if [ "$(id -u)" != "0" ]; then + echo "This script should be run as 'root'" + exit 1 +fi + +if [ -z $name ]; then + echo "Container name must be given" + usage + exit 1 +fi + +if [ -z $cfg_dir ]; then + echo "Configuration directory must be given, check lxc-create" + usage + exit 1 +fi + +basearch=$arch +if [ "$arch" = "i686" ]; then + basearch="i386" +fi + +if [ "$arch" != "i386" -a "$arch" != "x86_64" ]; then + echo "Bad architecture given, check lxc-create" + usage + exit 1 +fi + +if which lsb_release >/dev/null 2>&1; then + host_distribution=`lsb_release --id |awk '{print $3}'` + host_release_version=`lsb_release --release |awk '{print $2}'` + host_release_major=`echo $host_release_version |awk -F '.' '{print $1}'` + host_release_minor=`echo $host_release_version |awk -F '.' '{print $2}'` +else + if [ -f /etc/fedora-release ]; then + host_distribution="Fedora" + host_release_version=`cat /etc/fedora-release |awk '{print $3}'` + host_release_major=$host_release_version + host_release_minor=0 + elif [ -f /etc/oracle-release ]; then + host_distribution="OracleServer" + host_release_version=`cat /etc/oracle-release |awk '{print $5}'` + host_release_major=`echo $host_release_version |awk -F '.' '{print $1}'` + host_release_minor=`echo $host_release_version |awk -F '.' '{print $2}'` + else + echo "Unable to determine host distribution, ensure lsb_release is installed" + exit 1 + fi +fi +echo "Host is $host_distribution $host_release_version" + +if [ -z "$container_rootfs" ]; then + container_rootfs="$cfg_dir/rootfs" +fi + +if [ -n "$template_rootfs" ]; then + container_release_get $template_rootfs +else + if [ -z "$container_release_version" ]; then + if [ $host_distribution = "OracleServer" ]; then + container_release_version=$host_release_version + else + echo "No release specified with -R, defaulting to 6.4" + container_release_version="6.4" + fi + fi + container_release_major=`echo $container_release_version |awk -F '.' '{print $1}'` + container_release_minor=`echo $container_release_version |awk -F '.' '{print $2}'` +fi + +container_config_create +if [ -n "$template_rootfs" ]; then + container_rootfs_clone +else + container_rootfs_create +fi + +container_release_get $container_rootfs + +container_rootfs_configure + +echo "Container : $container_rootfs" +echo "Config : $cfg_dir/config" +echo "Network : eth0 ($lxc_network_type) on $lxc_network_link" diff -Nru lxc-0.8.0~rc1/templates/lxc-sshd.in lxc-1.0.0~alpha1/templates/lxc-sshd.in --- lxc-0.8.0~rc1/templates/lxc-sshd.in 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/templates/lxc-sshd.in 2013-09-10 22:22:00.000000000 +0000 @@ -18,7 +18,7 @@ # 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 +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA install_sshd() { @@ -28,10 +28,14 @@ $rootfs/var/run/sshd \ $rootfs/var/empty/sshd \ $rootfs/var/lib/empty/sshd \ +$rootfs/etc/init.d \ +$rootfs/etc/rc.d \ $rootfs/etc/ssh \ +$rootfs/etc/sysconfig/network-scripts \ $rootfs/dev/shm \ $rootfs/run/shm \ $rootfs/proc \ +$rootfs/sys \ $rootfs/bin \ $rootfs/sbin \ $rootfs/usr \ @@ -43,7 +47,7 @@ mkdir -p $tree if [ $? -ne 0 ]; then - return 1 + return 1 fi return 0 @@ -63,8 +67,8 @@ sshd:x:74: EOF -ssh-keygen -t rsa -f $rootfs/etc/ssh/ssh_host_rsa_key -ssh-keygen -t dsa -f $rootfs/etc/ssh/ssh_host_dsa_key +ssh-keygen -t rsa -N "" -f $rootfs/etc/ssh/ssh_host_rsa_key +ssh-keygen -t dsa -N "" -f $rootfs/etc/ssh/ssh_host_dsa_key # by default setup root password with no password cat < $rootfs/etc/ssh/sshd_config @@ -88,6 +92,17 @@ PermitEmptyPasswords yes ChallengeResponseAuthentication no EOF + + if [ -n "$auth_key" -a -f "$auth_key" ]; then + u_path="/root/.ssh" + root_u_path="$rootfs/$u_path" + mkdir -p $root_u_path + cp $auth_key "$root_u_path/authorized_keys" + chown -R 0:0 "$rootfs/$u_path" + chmod 700 "$rootfs/$u_path" + echo "Inserted SSH public key from $auth_key into $rootfs/$u_path" + fi + return 0 } @@ -97,38 +112,75 @@ rootfs=$2 name=$3 + grep -q "^lxc.rootfs" $path/config 2>/dev/null || echo "lxc.rootfs = $rootfs" >> $path/config cat <> $path/config lxc.utsname = $name lxc.pts = 1024 -lxc.rootfs = $rootfs -lxc.mount.entry=/dev $rootfs/dev none ro,bind 0 0 -lxc.mount.entry=/lib $rootfs/lib none ro,bind 0 0 -lxc.mount.entry=/bin $rootfs/bin none ro,bind 0 0 -lxc.mount.entry=/usr /$rootfs/usr none ro,bind 0 0 -lxc.mount.entry=/sbin $rootfs/sbin none ro,bind 0 0 -lxc.mount.entry=tmpfs $rootfs/var/run/sshd tmpfs mode=0644 0 0 -lxc.mount.entry=@LXCTEMPLATEDIR@/lxc-sshd $rootfs/sbin/init none bind 0 0 +lxc.kmsg = 0 +lxc.cap.drop = sys_module mac_admin mac_override sys_time + +# When using LXC with apparmor, uncomment the next line to run unconfined: +#lxc.aa_profile = unconfined + +lxc.mount.entry = /dev dev none ro,bind 0 0 +lxc.mount.entry = /lib lib none ro,bind 0 0 +lxc.mount.entry = /bin bin none ro,bind 0 0 +lxc.mount.entry = /usr usr none ro,bind 0 0 +lxc.mount.entry = /sbin sbin none ro,bind 0 0 +lxc.mount.entry = tmpfs var/run/sshd tmpfs mode=0644 0 0 +lxc.mount.entry = @LXCTEMPLATEDIR@/lxc-sshd sbin/init none bind 0 0 +lxc.mount.entry = proc proc proc nodev,noexec,nosuid 0 0 +lxc.mount.entry = sysfs sys sysfs ro 0 0 +lxc.mount.entry = /etc/init.d etc/init.d none ro,bind 0 0 +EOF + + # Oracle Linux and Fedora need the following two bind mounted + if [ -d /etc/sysconfig/network-scripts ]; then + cat <> $path/config +lxc.mount.entry = /etc/sysconfig/network-scripts etc/sysconfig/network-scripts none ro,bind 0 0 +EOF + fi + + if [ -d /etc/rc.d ]; then + cat <> $path/config +lxc.mount.entry = /etc/rc.d etc/rc.d none ro,bind 0 0 EOF + fi -if [ "$(uname -m)" = "x86_64" ]; then - cat <> $path/config -lxc.mount.entry=/lib64 $rootfs/lib64 none ro,bind 0 0 + # if no .ipv4 section in config, then have the container run dhcp + grep -q "^lxc.network.ipv4" $path/config || touch $rootfs/run-dhcp + + if [ "$(uname -m)" = "x86_64" ]; then + cat <> $path/config +lxc.mount.entry = /lib64 lib64 none ro,bind 0 0 EOF -fi + fi } usage() { cat < +$1 -h|--help -p|--path= [--rootfs=] EOF return 0 } -options=$(getopt -o hp:n: -l help,path:,name: -- "$@") +check_for_cmd() +{ + cmd_path=`type $1` + if [ $? -ne 0 ]; then + echo "The command '$1' $cmd_path is not accessible on the system" + exit 1 + fi + # we use cut instead of awk because awk is alternatives symlink on ubuntu + # and /etc/alternatives isn't bind mounted + cmd_path=`echo $cmd_path |cut -d ' ' -f 3` +} + +options=$(getopt -o hp:n:S: -l help,rootfs:,path:,name:,auth-key: -- "$@") if [ $? -ne 0 ]; then usage $(basename $0) - exit 1 + exit 1 fi eval set -- "$options" @@ -137,7 +189,9 @@ case "$1" in -h|--help) usage $0 && exit 0;; -p|--path) path=$2; shift 2;; - -n|--name) name=$2; shift 2;; + --rootfs) rootfs=$2; shift 2;; + -n|--name) name=$2; shift 2;; + -S|--auth-key) auth_key=$2; shift 2;; --) shift 1; break ;; *) break ;; esac @@ -150,19 +204,27 @@ if [ $0 == "/sbin/init" ]; then - type @LXCINITDIR@/lxc-init - if [ $? -ne 0 ]; then - echo "'lxc-init is not accessible on the system" - exit 1 - fi - - type sshd - if [ $? -ne 0 ]; then - echo "'sshd' is not accessible on the system " - exit 1 + PATH="$PATH:/bin:/sbin:/usr/sbin" + check_for_cmd @LXCINITDIR@/lxc/lxc-init + check_for_cmd sshd + sshd_path=$cmd_path + + # run dhcp? + if [ -f /run-dhcp ]; then + check_for_cmd dhclient + check_for_cmd ifconfig + touch /etc/fstab + rm -f /dhclient.conf + cat > /dhclient.conf << EOF +send host-name ""; +EOF + ifconfig eth0 up + dhclient eth0 -cf /dhclient.conf + echo "Container IP address:" + ifconfig eth0 |grep inet fi - exec @LXCINITDIR@/lxc-init -- /usr/sbin/sshd + exec @LXCINITDIR@/lxc/lxc-init -- $sshd_path exit 1 fi @@ -171,7 +233,15 @@ exit 1 fi -rootfs=$path/rootfs +# detect rootfs +config="$path/config" +if [ -z "$rootfs" ]; then + if grep -q '^lxc.rootfs' $config 2>/dev/null ; then + rootfs=`grep 'lxc.rootfs =' $config | awk -F= '{ print $2 }'` + else + rootfs=$path/rootfs + fi +fi install_sshd $rootfs if [ $? -ne 0 ]; then diff -Nru lxc-0.8.0~rc1/templates/lxc-ubuntu-cloud.in lxc-1.0.0~alpha1/templates/lxc-ubuntu-cloud.in --- lxc-0.8.0~rc1/templates/lxc-ubuntu-cloud.in 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/templates/lxc-ubuntu-cloud.in 2013-09-10 22:22:00.000000000 +0000 @@ -1,36 +1,52 @@ #!/bin/bash -# template script for generating ubuntu container for LXC based on daily cloud -# images +# template script for generating ubuntu container for LXC based on released +# cloud images. # # Copyright © 2012 Serge Hallyn # -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2, as -# published by the Free Software Foundation. - -# 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., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -# +# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA set -e +STATE_DIR="@LOCALSTATEDIR@" +HOOK_DIR="@LXCHOOKDIR@" +CLONE_HOOK_FN="$HOOK_DIR/ubuntu-cloud-prep" + if [ -r /etc/default/lxc ]; then . /etc/default/lxc fi +am_in_userns() { + [ -e /proc/self/uid_map ] || { echo no; return; } + [ "$(wc -l /proc/self/uid_map | awk '{ print $1 }')" -eq 1 ] || { echo yes; return; } + line=$(awk '{ print $1 " " $2 " " $3 }' /proc/self/uid_map) + [ "$line" = "0 0 4294967295" ] && { echo no; return; } + echo yes +} + +in_userns=0 +[ $(am_in_userns) = "yes" ] && in_userns=1 + copy_configuration() { path=$1 rootfs=$2 name=$3 arch=$4 + release=$5 if [ $arch = "i386" ]; then arch="i686" @@ -40,20 +56,30 @@ # associated hwaddr. nics=`grep -e '^lxc\.network\.type[ \t]*=[ \t]*veth' $path/config | wc -l` if [ $nics -eq 1 ]; then - grep -q "^lxc.network.hwaddr" $path/config || cat <> $path/config -lxc.network.hwaddr= 00:16:3e:$(openssl rand -hex 3| sed 's/\(..\)/\1:/g; s/.$//') -EOF + grep -q "^lxc.network.hwaddr" $path/config || sed -i -e "/^lxc\.network\.type[ \t]*=[ \t]*veth/a lxc.network.hwaddr = 00:16:3e:$(openssl rand -hex 3| sed 's/\(..\)/\1:/g; s/.$//')" $path/config fi + grep -q "^lxc.rootfs" $path/config 2>/dev/null || echo "lxc.rootfs = $rootfs" >> $path/config cat <> $path/config -lxc.utsname = $name +lxc.mount = $path/fstab +lxc.pivotdir = lxc_putold +lxc.devttydir =$ttydir lxc.tty = 4 lxc.pts = 1024 -lxc.rootfs = $rootfs -lxc.mount = $path/fstab + +lxc.utsname = $name lxc.arch = $arch -lxc.cap.drop = sys_module mac_admin +lxc.cap.drop = sys_module mac_admin mac_override sys_time + +# When using LXC with apparmor, uncomment the next line to run unconfined: +#lxc.aa_profile = unconfined + +# To support container nesting on an Ubuntu host, uncomment next two lines: +#lxc.aa_profile = lxc-container-default-with-nesting +#lxc.hook.mount = /usr/share/lxc/hooks/mountcgroups + +lxc.hook.clone = ${CLONE_HOOK_FN} lxc.cgroup.devices.deny = a # Allow any mknod (but not using the node) @@ -65,32 +91,52 @@ # consoles lxc.cgroup.devices.allow = c 5:1 rwm lxc.cgroup.devices.allow = c 5:0 rwm -#lxc.cgroup.devices.allow = c 4:0 rwm -#lxc.cgroup.devices.allow = c 4:1 rwm # /dev/{,u}random lxc.cgroup.devices.allow = c 1:9 rwm lxc.cgroup.devices.allow = c 1:8 rwm lxc.cgroup.devices.allow = c 136:* rwm lxc.cgroup.devices.allow = c 5:2 rwm # rtc -lxc.cgroup.devices.allow = c 254:0 rwm -#fuse +lxc.cgroup.devices.allow = c 254:0 rm +# fuse lxc.cgroup.devices.allow = c 10:229 rwm -#tun +# tun lxc.cgroup.devices.allow = c 10:200 rwm -#full +# full lxc.cgroup.devices.allow = c 1:7 rwm -#hpet +# hpet lxc.cgroup.devices.allow = c 10:228 rwm -#kvm +# kvm lxc.cgroup.devices.allow = c 10:232 rwm EOF cat < $path/fstab -proc $rootfs/proc proc nodev,noexec,nosuid 0 0 -sysfs $rootfs/sys sysfs defaults 0 0 +proc proc proc nodev,noexec,nosuid 0 0 +sysfs sys sysfs defaults 0 0 +/sys/fs/fuse/connections sys/fs/fuse/connections none bind 0 0 +/sys/kernel/debug sys/kernel/debug none bind 0 0 +/sys/kernel/security sys/kernel/security none bind 0 0 EOF + # unprivileged user can't mknod these. One day we may allow + # that in the kernel, but not right now. So let's just bind + # mount the files from the host. + if [ $in_userns -eq 1 ]; then + for dev in null tty urandom console; do + touch $rootfs/dev/$dev + echo "/dev/$dev dev/$dev none bind 0 0" >> $path/fstab + done + fi + + # rmdir /dev/shm for containers that have /run/shm + # I'm afraid of doing rm -rf $rootfs/dev/shm, in case it did + # get bind mounted to the host's /run/shm. So try to rmdir + # it, and in case that fails move it out of the way. + if [ ! -L $rootfs/dev/shm ] && [ -d $rootfs/run/shm ] && [ -e $rootfs/dev/shm ]; then + mv $rootfs/dev/shm $rootfs/dev/shm.bak + ln -s /run/shm $rootfs/dev/shm + fi + return 0 } @@ -101,59 +147,64 @@ Generic Options [ -r | --release ]: Release name of container, defaults to host -[ -a | --arch ]: Arhcitecture of container, defaults to host arcitecture -[ -C | --cloud ]: Configure container for use with meta-data service, defaults to no +[ --rootfs ]: Path in which rootfs will be placed +[ -a | --arch ]: Arhcitecture of container, defaults to host architecture [ -T | --tarball ]: Location of tarball +[ -d | --debug ]: Run with 'set -x' to debug errors +[ -s | --stream]: Use specified stream rather than 'released' -Options, mutually exclusive of "-C" and "--cloud": - [ -i | --hostid ]: HostID for cloud-init, defaults to random string - [ -u | --userdata ]: Cloud-init user-data file to configure container on start - [ -S | --auth_key ]: SSH Public key file to inject into container - [ -L | --nolocales ]: Do not copy host's locales into container - +Additionally, clone hooks can be passed through (ie, --userdata). For those, +see: + $CLONE_HOOK_FN --help EOF return 0 } -options=$(getopt -o a:hp:r:n:Fi:CLS:T: -l arch:,help,path:,release:,name:,flush-cache,hostid:,auth-key:,cloud,no_locales,tarball: -- "$@") +options=$(getopt -o a:hp:r:n:Fi:CLS:T:ds:u: -l arch:,help,rootfs:,path:,release:,name:,flush-cache,hostid:,auth-key:,cloud,no_locales,tarball:,debug,stream:,userdata: -- "$@") if [ $? -ne 0 ]; then usage $(basename $0) exit 1 fi eval set -- "$options" -release=lucid +# default release is precise, or the systems release if recognized +release=precise if [ -f /etc/lsb-release ]; then . /etc/lsb-release - case "$DISTRIB_CODENAME" in - lucid|maverick|natty|oneiric|precise) - release=$DISTRIB_CODENAME - ;; - esac + rels=$(ubuntu-distro-info --supported 2>/dev/null) || + rels="lucid natty oneiric precise quantal raring saucy" + for r in $rels; do + [ "$DISTRIB_CODENAME" = "$r" ] && release="$r" + done fi -arch=$(arch) - # Code taken from debootstrap if [ -x /usr/bin/dpkg ] && /usr/bin/dpkg --print-architecture >/dev/null 2>&1; then arch=`/usr/bin/dpkg --print-architecture` elif type udpkg >/dev/null 2>&1 && udpkg --print-architecture >/dev/null 2>&1; then arch=`/usr/bin/udpkg --print-architecture` else - arch=$(arch) + arch=$(uname -m) if [ "$arch" = "i686" ]; then arch="i386" elif [ "$arch" = "x86_64" ]; then arch="amd64" elif [ "$arch" = "armv7l" ]; then - arch="armel" + # note: arm images don't exist before oneiric; are called armhf in + # precise and later; and are not supported by the query, so we don't actually + # support them yet (see check later on). When Query2 is available, + # we'll use that to enable arm images. + arch="armhf" fi fi +debug=0 hostarch=$arch cloud=0 locales=1 flushcache=0 +stream="released" +cloneargs=() while true do case "$1" in @@ -163,28 +214,58 @@ -F|--flush-cache) flushcache=1; shift 1;; -r|--release) release=$2; shift 2;; -a|--arch) arch=$2; shift 2;; - -i|--hostid) host_id=$2; shift 2;; - -u|--userdata) userdata=$2; shift 2;; - -C|--cloud) cloud=1; shift 1;; - -S|--auth_key) auth_key=$2; shift 2;; - -L|--no_locales) locales=0; shift 2;; -T|--tarball) tarball=$2; shift 2;; + -d|--debug) debug=1; shift 1;; + -s|--stream) stream=$2; shift 2;; + --rootfs) rootfs=$2; shift 2;; + -L|--no?locales) cloneargs[${#cloneargs[@]}]="--no-locales"; shift 1;; + -i|--hostid) cloneargs[${#cloneargs[@]}]="--hostid=$2"; shift 2;; + -u|--userdata) cloneargs[${#cloneargs[@]}]="--userdata=$2"; shift 2;; + -C|--cloud) cloneargs[${#cloneargs[@]}]="--cloud"; shift 1;; + -S|--auth-key) cloneargs[${#cloneargs[@]}]="--auth-key=$2"; shift 2;; --) shift 1; break ;; *) break ;; esac done +cloneargs=( "--name=$name" "${cloneargs[@]}" ) + +if [ $debug -eq 1 ]; then + set -x +fi + if [ "$arch" == "i686" ]; then arch=i386 fi -if [ $hostarch = "i386" -a $arch = "amd64" ]; then - echo "can't create amd64 container on i386" +if [ $arch != "i386" -a $arch != "amd64" -a $arch != "armhf" -a $arch != "armel" ]; then + echo "Only i386, amd64, armel and armhf are supported by the ubuntu cloud template." + exit 1 +fi + +if [ $hostarch != "i386" -a $hostarch != "amd64" -a $hostarch != "armhf" -a $hostarch != "armel" ]; then + echo "Only i386, amd64, armel and armhf are supported as host." + exit 1 +fi + +if [ $hostarch = "amd64" -a $arch != "amd64" -a $arch != "i386" ]; then + echo "can't create $arch container on $hostarch" + exit 1 +fi + +if [ $hostarch = "i386" -a $arch != "i386" ]; then + echo "can't create $arch container on $hostarch" + exit 1 +fi + +if [ $hostarch = "armhf" -o $hostarch = "armel" ] && \ + [ $arch != "armhf" -a $arch != "armel" ]; then + echo "can't create $arch container on $hostarch" exit 1 fi -if [ $arch != "i386" -a $arch != "amd64" ]; then - echo "Only i386 and amd64 are supported by the ubuntu cloud template." +if [ "$stream" != "daily" -a "$stream" != "released" ]; then + echo "Only 'daily' and 'released' streams are supported" exit 1 fi @@ -198,29 +279,78 @@ exit 1 fi -rootfs=$path/rootfs +# detect rootfs +config="$path/config" +if [ -z "$rootfs" ]; then + if grep -q '^lxc.rootfs' $config 2>/dev/null ; then + rootfs=`grep 'lxc.rootfs =' $config | awk -F= '{ print $2 }'` + else + rootfs=$path/rootfs + fi +fi type ubuntu-cloudimg-query type wget # determine the url, tarball, and directory names # download if needed -cache="/var/cache/lxc/cloud-$release" +cache="$STATE_DIR/cache/lxc/cloud-$release" mkdir -p $cache if [ -n "$tarball" ]; then - url2="$tarball" + url2="$tarball" else - url1=`ubuntu-cloudimg-query precise daily $arch --format "%{url}\n"` - url2=`echo $url1 | sed -e 's/.tar.gz/-root\0/'` + url1=`ubuntu-cloudimg-query $release $stream $arch --format "%{url}\n"` + url2=`echo $url1 | sed -e 's/.tar.gz/-root\0/'` fi filename=`basename $url2` -mkdir -p /var/lock/subsys/ -( - flock -n -x 200 +wgetcleanup() +{ + rm -f $filename +} + +buildcleanup() +{ + cd $rootfs + umount -l $cache/$xdir || true + rm -rf $cache +} + +# if the release doesn't have a *-rootfs.tar.gz, then create one from the +# cloudimg.tar.gz by extracting the .img, mounting it loopback, and creating +# a tarball from the mounted image. +build_root_tgz() +{ + url=$1 + filename=$2 + + xdir=`mktemp -d -p .` + tarname=`basename $url` + imgname="$release-*-cloudimg-$arch.img" + trap buildcleanup EXIT SIGHUP SIGINT SIGTERM + if [ $flushcache -eq 1 -o ! -f $cache/$tarname ]; then + rm -f $tarname + echo "Downloading cloud image from $url" + wget $url || { echo "Couldn't find cloud image $url."; exit 1; } + fi + echo "Creating new cached cloud image rootfs" + tar --wildcards -zxf $tarname $imgname + mount -o loop $imgname $xdir + (cd $xdir; tar zcf ../$filename .) + umount $xdir + rm -f $tarname $imgname + rmdir $xdir + echo "New cloud image cache created" + trap EXIT + trap SIGHUP + trap SIGINT + trap SIGTERM +} + +do_extract_rootfs() { cd $cache if [ $flushcache -eq 1 ]; then @@ -228,77 +358,36 @@ rm -f $filename fi + trap wgetcleanup EXIT SIGHUP SIGINT SIGTERM if [ ! -f $filename ]; then - wget $url2 + wget $url2 || build_root_tgz $url1 $filename fi + trap EXIT + trap SIGHUP + trap SIGINT + trap SIGTERM - echo "Extracting rootfs" + echo "Extracting container rootfs" mkdir -p $rootfs cd $rootfs tar -zxf $cache/$filename +} +if [ -n "$tarball" ]; then + do_extract_rootfs +else + mkdir -p "$STATE_DIR/lock/subsys/" + ( + flock -x 200 + do_extract_rootfs + ) 200>"$STATE_DIR/lock/subsys/lxc-ubuntu-cloud" +fi - if [ $cloud -eq 0 ]; then - echo "Configuring for running outside of a cloud environment" - echo "If you want to configure for a cloud evironment, please use '-- -C' to create the container" - - seed_d=$rootfs/var/lib/cloud/seed/nocloud-net - rhostid=$(uuidgen | cut -c -8) - host_id=${hostid:-$rhostid} - mkdir -p $seed_d - - cat > "$seed_d/meta-data" < "$seed_d/user-data" </var/lock/subsys/lxc-ubucloud +copy_configuration $path $rootfs $name $arch $release -copy_configuration $path $rootfs $name $arch +"$CLONE_HOOK_FN" "${cloneargs[@]}" "$rootfs" echo "Container $name created." exit 0 + +# vi: ts=4 expandtab diff -Nru lxc-0.8.0~rc1/templates/lxc-ubuntu.in lxc-1.0.0~alpha1/templates/lxc-ubuntu.in --- lxc-0.8.0~rc1/templates/lxc-ubuntu.in 2012-03-01 21:42:19.000000000 +0000 +++ lxc-1.0.0~alpha1/templates/lxc-ubuntu.in 2013-09-10 22:22:00.000000000 +0000 @@ -10,19 +10,21 @@ # Copyright 2010 Wilhelm Meier # Author: Wilhelm Meier # -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2, as -# published by the Free Software Foundation. - -# 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., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -# +# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +set -e if [ -r /etc/default/lxc ]; then . /etc/default/lxc @@ -34,8 +36,12 @@ hostname=$2 release=$3 - # configure the network using the dhcp + # configure the network using the dhcp cat < $rootfs/etc/network/interfaces +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +# The loopback network interface auto lo iface lo inet loopback @@ -49,14 +55,18 @@ EOF # set minimal hosts cat < $rootfs/etc/hosts -127.0.0.1 localhost $hostname -EOF +127.0.0.1 localhost +127.0.1.1 $hostname - if [ "$release" = "precise" ]; then - group="sudo" - else - group="admin" +# The following lines are desirable for IPv6 capable hosts +::1 ip6-localhost ip6-loopback +fe00::0 ip6-localnet +ff00::0 ip6-mcastprefix +ff02::1 ip6-allnodes +ff02::2 ip6-allrouters +EOF + if [ ! -f $rootfs/etc/init/container-detect.conf ]; then # suppress log level output for udev sed -i "s/=\"err\"/=0/" $rootfs/etc/udev/udev.conf @@ -65,44 +75,118 @@ rm -f $rootfs/etc/init/tty{5,6}.conf fi - chroot $rootfs groupadd --system $group >/dev/null 2>&1 || true - chroot $rootfs useradd --create-home -s /bin/bash -G $group ubuntu - echo "ubuntu:ubuntu" | chroot $rootfs chpasswd + if [ -z "$bindhome" ]; then + chroot $rootfs useradd --create-home -s /bin/bash ubuntu + echo "ubuntu:ubuntu" | chroot $rootfs chpasswd + fi + + # make sure we have the current locale defined in the container + if [ -z "$LANG" ] || echo $LANG | grep -E -q "^C(\..+)*$"; then + chroot $rootfs locale-gen en_US.UTF-8 + chroot $rootfs update-locale LANG=en_US.UTF-8 + else + chroot $rootfs locale-gen $LANG + chroot $rootfs update-locale LANG=$LANG + fi + + # generate new SSH keys + if [ -x $rootfs@LOCALSTATEDIR@/lib/dpkg/info/openssh-server.postinst ]; then + cat > $rootfs/usr/sbin/policy-rc.d << EOF +#!/bin/sh +exit 101 +EOF + chmod +x $rootfs/usr/sbin/policy-rc.d + + rm -f $rootfs/etc/ssh/ssh_host_*key* + mv $rootfs/etc/init/ssh.conf $rootfs/etc/init/ssh.conf.disabled + DPKG_MAINTSCRIPT_PACKAGE=openssh DPKG_MAINTSCRIPT_NAME=postinst chroot $rootfs @LOCALSTATEDIR@/lib/dpkg/info/openssh-server.postinst configure + mv $rootfs/etc/init/ssh.conf.disabled $rootfs/etc/init/ssh.conf + + rm -f $rootfs/usr/sbin/policy-rc.d + fi + + return 0 +} + +# finish setting up the user in the container by injecting ssh key and +# adding sudo group membership. +# passed-in user is either 'ubuntu' or the user to bind in from host. +finalize_user() +{ + user=$1 + + sudo_version=$(chroot $rootfs dpkg-query -W -f='${Version}' sudo) + + if chroot $rootfs dpkg --compare-versions $sudo_version gt "1.8.3p1-1"; then + groups="sudo" + else + groups="sudo admin" + fi + + for group in $groups; do + chroot $rootfs groupadd --system $group >/dev/null 2>&1 || true + chroot $rootfs adduser ${user} $group >/dev/null 2>&1 || true + done + if [ -n "$auth_key" -a -f "$auth_key" ]; then - u_path="/home/ubuntu/.ssh" - root_u_path="$rootfs/$u_path" - mkdir -p $root_u_path - cp $auth_key "$root_u_path/authorized_keys" - chroot $rootfs chown -R ubuntu: "$u_path" + u_path="/home/${user}/.ssh" + root_u_path="$rootfs/$u_path" + mkdir -p $root_u_path + cp $auth_key "$root_u_path/authorized_keys" + chroot $rootfs chown -R ${user}: "$u_path" - echo "Inserted SSH public key from $auth_key into /home/ubuntu/.ssh/authorized_keys" + echo "Inserted SSH public key from $auth_key into /home/${user}/.ssh/authorized_keys" fi return 0 } +# +# Choose proxies for container +# http_proxy will be used by debootstrap on the host. +# APT_PROXY will be used to set /etc/apt/apt.conf.d/70proxy in the container. +# +choose_container_proxy() +{ + local rootfs=$1 + local arch=$2 + + if [ -z "$HTTP_PROXY" ]; then + HTTP_PROXY="none" + fi + case "$HTTP_PROXY" in + none) + APT_PROXY= + ;; + apt) + RES=`apt-config shell APT_PROXY Acquire::http::Proxy` + eval $RES + [ -z "$APT_PROXY" ] || export http_proxy=$APT_PROXY + ;; + *) + APT_PROXY=$HTTP_PROXY + export http_proxy=$HTTP_PROXY + ;; + esac +} + write_sourceslist() { # $1 => path to the rootfs # $2 => architecture we want to add # $3 => whether to use the multi-arch syntax or not + if [ -n "$APT_PROXY" ]; then + mkdir -p $rootfs/etc/apt/apt.conf.d + cat > $rootfs/etc/apt/apt.conf.d/70proxy << EOF +Acquire::http::Proxy "$APT_PROXY" ; +EOF + fi + case $2 in amd64|i386) MIRROR=${MIRROR:-http://archive.ubuntu.com/ubuntu} SECURITY_MIRROR=${SECURITY_MIRROR:-http://security.ubuntu.com/ubuntu} ;; - sparc) - case $SUITE in - gutsy) - MIRROR=${MIRROR:-http://archive.ubuntu.com/ubuntu} - SECURITY_MIRROR=${SECURITY_MIRRORMIRROR:-http://security.ubuntu.com/ubuntu} - ;; - *) - MIRROR=${MIRROR:-http://ports.ubuntu.com/ubuntu-ports} - SECURITY_MIRROR=${SECURITY_MIRROR:-http://ports.ubuntu.com/ubuntu-ports} - ;; - esac - ;; *) MIRROR=${MIRROR:-http://ports.ubuntu.com/ubuntu-ports} SECURITY_MIRROR=${SECURITY_MIRROR:-http://ports.ubuntu.com/ubuntu-ports} @@ -123,23 +207,40 @@ fi } +cleanup() +{ + rm -rf $cache/partial-$arch + rm -rf $cache/rootfs-$arch +} + +suggest_flush() +{ + echo "Container upgrade failed. The container cache may be out of date," + echo "in which case flushing the case (see -F in the hep output) may help." +} + download_ubuntu() { cache=$1 arch=$2 release=$3 - if [ $release = "lucid" ]; then - packages=dialog,apt,apt-utils,resolvconf,iproute,inetutils-ping,vim,dhcp3-client,ssh,lsb-release,gnupg - elif [ $release = "maverick" ]; then - packages=dialog,apt,apt-utils,resolvconf,iproute,inetutils-ping,vim,dhcp3-client,ssh,lsb-release,gnupg,netbase - elif [ $release = "natty" ]; then - packages=dialog,apt,apt-utils,resolvconf,iproute,inetutils-ping,vim,isc-dhcp-client,isc-dhcp-common,ssh,lsb-release,gnupg,netbase - else - packages=dialog,apt,apt-utils,iproute,inetutils-ping,vim,isc-dhcp-client,isc-dhcp-common,ssh,lsb-release,gnupg,netbase,ubuntu-keyring + packages=vim,ssh + + # Try to guess a list of langpacks to install + langpacks="language-pack-en" + + if which dpkg >/dev/null 2>&1; then + langpacks=`(echo $langpacks && + dpkg -l | grep -E "^ii language-pack-[a-z]* " | + cut -d ' ' -f3) | sort -u` fi + packages="$packages,$(echo $langpacks | sed 's/ /,/g')" + + echo "installing packages: $packages" + trap cleanup EXIT SIGHUP SIGINT SIGTERM # check the mini ubuntu was not already downloaded mkdir -p "$cache/partial-$arch" if [ $? -ne 0 ]; then @@ -147,6 +248,7 @@ return 1 fi + choose_container_proxy $cache/partial-$arch/ $arch # download a mini ubuntu into a cache echo "Downloading ubuntu $release minimal ..." if [ -n "$(which qemu-debootstrap)" ]; then @@ -160,34 +262,6 @@ return 1 fi - echo "Installing updates" - if [ -z "$MIRROR" ]; then - MIRROR="http://archive.ubuntu.com/ubuntu" - fi - cat >> "$1/partial-${arch}/etc/apt/sources.list" << EOF -deb $MIRROR ${release}-updates main universe -deb http://security.ubuntu.com/ubuntu ${release}-security main universe -EOF - chroot "$1/partial-${arch}" apt-get update - if [ $? -ne 0 ]; then - echo "Failed to update the apt cache" - return 1 - fi - cat > "$1/partial-${arch}"/usr/sbin/policy-rc.d << EOF -#!/bin/sh -exit 101 -EOF - chmod +x "$1/partial-${arch}"/usr/sbin/policy-rc.d - - chroot "$1/partial-${arch}" apt-get dist-upgrade -y - ret=$? - - rm -f "$1/partial-${arch}"/usr/sbin/policy-rc.d - if [ $ret -ne 0 ]; then - echo "Failed to upgrade the cache" - return 1 - fi - # Serge isn't sure whether we should avoid doing this when # $release == `distro-info -d` echo "Installing updates" @@ -205,16 +279,16 @@ EOF chmod +x "$1/partial-${arch}"/usr/sbin/policy-rc.d - lxc-unshare -s MOUNT -- chroot "$1/partial-${arch}" apt-get dist-upgrade -y - ret=$? + lxc-unshare -s MOUNT -- chroot "$1/partial-${arch}" apt-get dist-upgrade -y || { suggest_flush; false; } rm -f "$1/partial-${arch}"/usr/sbin/policy-rc.d - if [ $ret -ne 0 ]; then - echo "Failed to upgrade the cache" - return 1 - fi + chroot "$1/partial-${arch}" apt-get clean mv "$1/partial-$arch" "$1/rootfs-$arch" + trap EXIT + trap SIGINT + trap SIGTERM + trap SIGHUP echo "Download complete" return 0 } @@ -228,7 +302,7 @@ # make a local copy of the miniubuntu echo "Copying rootfs to $rootfs ..." mkdir -p $rootfs - rsync -a $cache/rootfs-$arch/ $rootfs/ || return 1 + rsync -Ha $cache/rootfs-$arch/ $rootfs/ || return 1 return 0 } @@ -237,41 +311,42 @@ rootfs=$1 release=$2 flushcache=$3 - cache="/var/cache/lxc/$release" - mkdir -p /var/lock/subsys/ + cache="@LOCALSTATEDIR@/cache/lxc/$release" + mkdir -p @LOCALSTATEDIR@/lock/subsys/ + ( - flock -n -x 200 - if [ $? -ne 0 ]; then - echo "Cache repository is busy." - return 1 - fi - - - if [ $flushcache -eq 1 ]; then - echo "Flushing cache..." - rm -rf "$cache/partial-$arch" - rm -rf "$cache/rootfs-$arch" - fi - - echo "Checking cache download in $cache/rootfs-$arch ... " - if [ ! -e "$cache/rootfs-$arch" ]; then - download_ubuntu $cache $arch $release - if [ $? -ne 0 ]; then - echo "Failed to download 'ubuntu $release base'" - return 1 - fi - fi - - echo "Copy $cache/rootfs-$arch to $rootfs ... " - copy_ubuntu $cache $arch $rootfs - if [ $? -ne 0 ]; then - echo "Failed to copy rootfs" - return 1 - fi + flock -x 200 + if [ $? -ne 0 ]; then + echo "Cache repository is busy." + return 1 + fi + - return 0 + if [ $flushcache -eq 1 ]; then + echo "Flushing cache..." + rm -rf "$cache/partial-$arch" + rm -rf "$cache/rootfs-$arch" + fi + + echo "Checking cache download in $cache/rootfs-$arch ... " + if [ ! -e "$cache/rootfs-$arch" ]; then + download_ubuntu $cache $arch $release + if [ $? -ne 0 ]; then + echo "Failed to download 'ubuntu $release base'" + return 1 + fi + fi - ) 200>/var/lock/subsys/lxc + echo "Copy $cache/rootfs-$arch to $rootfs ... " + copy_ubuntu $cache $arch $rootfs + if [ $? -ne 0 ]; then + echo "Failed to copy rootfs" + return 1 + fi + + return 0 + + ) 200>@LOCALSTATEDIR@/lock/subsys/lxc-ubuntu return $? } @@ -289,7 +364,7 @@ fi ttydir="" - if [ $release = "precise" ]; then + if [ -f $rootfs/etc/init/container-detect.conf ]; then ttydir=" lxc" fi @@ -297,21 +372,28 @@ # associated hwaddr. nics=`grep -e '^lxc\.network\.type[ \t]*=[ \t]*veth' $path/config | wc -l` if [ $nics -eq 1 ]; then - grep -q "^lxc.network.hwaddr" $path/config || cat <> $path/config -lxc.network.hwaddr= 00:16:3e:$(openssl rand -hex 3| sed 's/\(..\)/\1:/g; s/.$//') -EOF + grep -q "^lxc.network.hwaddr" $path/config || sed -i -e "/^lxc\.network\.type[ \t]*=[ \t]*veth/a lxc.network.hwaddr = 00:16:3e:$(openssl rand -hex 3| sed 's/\(..\)/\1:/g; s/.$//')" $path/config fi + grep -q "^lxc.rootfs" $path/config 2>/dev/null || echo "lxc.rootfs = $rootfs" >> $path/config cat <> $path/config -lxc.utsname = $name +lxc.mount = $path/fstab +lxc.pivotdir = lxc_putold -lxc.devttydir = $ttydir +lxc.devttydir =$ttydir lxc.tty = 4 lxc.pts = 1024 -lxc.rootfs = $rootfs -lxc.mount = $path/fstab + +lxc.utsname = $name lxc.arch = $arch -lxc.cap.drop = sys_module mac_admin mac_override +lxc.cap.drop = sys_module mac_admin mac_override sys_time + +# When using LXC with apparmor, uncomment the next line to run unconfined: +#lxc.aa_profile = unconfined + +# To support container nesting on an Ubuntu host, uncomment next two lines: +#lxc.aa_profile = lxc-container-default-with-nesting +#lxc.hook.mount = /usr/share/lxc/hooks/mountcgroups lxc.cgroup.devices.deny = a # Allow any mknod (but not using the node) @@ -323,35 +405,36 @@ # consoles lxc.cgroup.devices.allow = c 5:1 rwm lxc.cgroup.devices.allow = c 5:0 rwm -#lxc.cgroup.devices.allow = c 4:0 rwm -#lxc.cgroup.devices.allow = c 4:1 rwm # /dev/{,u}random lxc.cgroup.devices.allow = c 1:9 rwm lxc.cgroup.devices.allow = c 1:8 rwm lxc.cgroup.devices.allow = c 136:* rwm lxc.cgroup.devices.allow = c 5:2 rwm # rtc -lxc.cgroup.devices.allow = c 254:0 rwm -#fuse +lxc.cgroup.devices.allow = c 254:0 rm +# fuse lxc.cgroup.devices.allow = c 10:229 rwm -#tun +# tun lxc.cgroup.devices.allow = c 10:200 rwm -#full +# full lxc.cgroup.devices.allow = c 1:7 rwm -#hpet +# hpet lxc.cgroup.devices.allow = c 10:228 rwm -#kvm +# kvm lxc.cgroup.devices.allow = c 10:232 rwm EOF cat < $path/fstab -proc $rootfs/proc proc nodev,noexec,nosuid 0 0 -sysfs $rootfs/sys sysfs defaults 0 0 +proc proc proc nodev,noexec,nosuid 0 0 +sysfs sys sysfs defaults 0 0 +/sys/fs/fuse/connections sys/fs/fuse/connections none bind 0 0 +/sys/kernel/debug sys/kernel/debug none bind 0 0 +/sys/kernel/security sys/kernel/security none bind 0 0 EOF if [ $? -ne 0 ]; then - echo "Failed to add configuration" - return 1 + echo "Failed to add configuration" + return 1 fi return 0 @@ -426,15 +509,6 @@ # /lib/init/fstab: cleared out for bare-bones lxc EOF - # reconfigure some services - if [ -z "$LANG" ]; then - chroot $rootfs locale-gen en_US.UTF-8 - chroot $rootfs update-locale LANG=en_US.UTF-8 - else - chroot $rootfs locale-gen $LANG - chroot $rootfs update-locale LANG=$LANG - fi - # remove pointless services in a container chroot $rootfs /usr/sbin/update-rc.d -f ondemand remove @@ -458,23 +532,37 @@ if [ $trim_container -eq 1 ]; then trim $rootfs $release - elif [ $release = "lucid" -o $release = "maverick" -o $release = "natty" \ - -o $release = "oneiric" ]; then - # for lucid and maverick, if not trimming, then add the ubuntu-virt + elif [ ! -f $rootfs/etc/init/container-detect.conf ]; then + # Make sure we have a working resolv.conf + cresolvonf="${rootfs}/etc/resolv.conf" + mv $cresolvonf ${cresolvonf}.lxcbak + cat /etc/resolv.conf > ${cresolvonf} + + # for lucid, if not trimming, then add the ubuntu-virt # ppa and install lxcguest - if [ $release = "lucid" -o $release = "maverick" ]; then + if [ $release = "lucid" ]; then + chroot $rootfs apt-get update chroot $rootfs apt-get install --force-yes -y python-software-properties chroot $rootfs add-apt-repository ppa:ubuntu-virt/ppa fi - cp /etc/resolv.conf "${rootfs}/etc" + chroot $rootfs apt-get update chroot $rootfs apt-get install --force-yes -y lxcguest + + # Restore old resolv.conf + rm -f ${cresolvonf} + mv ${cresolvonf}.lxcbak ${cresolvonf} fi # If the container isn't running a native architecture, setup multiarch if [ -x "$(ls -1 ${rootfs}/usr/bin/qemu-*-static 2>/dev/null)" ]; then - mkdir -p ${rootfs}/etc/dpkg/dpkg.cfg.d - echo "foreign-architecture ${hostarch}" > ${rootfs}/etc/dpkg/dpkg.cfg.d/lxc-multiarch + dpkg_version=$(chroot $rootfs dpkg-query -W -f='${Version}' dpkg) + if chroot $rootfs dpkg --compare-versions $dpkg_version ge "1.16.2"; then + chroot $rootfs dpkg --add-architecture ${hostarch} + else + mkdir -p ${rootfs}/etc/dpkg/dpkg.cfg.d + echo "foreign-architecture ${hostarch}" > ${rootfs}/etc/dpkg/dpkg.cfg.d/lxc-multiarch + fi # Save existing value of MIRROR and SECURITY_MIRROR DEFAULT_MIRROR=$MIRROR @@ -489,8 +577,23 @@ write_sourceslist $rootfs $hostarch "multiarch" # Finally update the lists and install upstart using the host architecture + HOST_PACKAGES="upstart:${hostarch} mountall:${hostarch} isc-dhcp-client:${hostarch}" chroot $rootfs apt-get update - chroot $rootfs apt-get install --force-yes -y --no-install-recommends upstart:${hostarch} mountall:amd64 iproute:amd64 isc-dhcp-client:amd64 + if chroot $rootfs dpkg -l iproute2 | grep -q ^ii; then + HOST_PACKAGES="$HOST_PACKAGES iproute2:${hostarch}" + else + HOST_PACKAGES="$HOST_PACKAGES iproute:${hostarch}" + fi + chroot $rootfs apt-get install --force-yes -y --no-install-recommends $HOST_PACKAGES + fi + + # rmdir /dev/shm for containers that have /run/shm + # I'm afraid of doing rm -rf $rootfs/dev/shm, in case it did + # get bind mounted to the host's /run/shm. So try to rmdir + # it, and in case that fails move it out of the way. + if [ ! -L $rootfs/dev/shm ] && [ -d $rootfs/run/shm ] && [ -e $rootfs/dev/shm ]; then + mv $rootfs/dev/shm $rootfs/dev/shm.bak + ln -s /run/shm $rootfs/dev/shm fi } @@ -500,72 +603,89 @@ user=$2 # copy /etc/passwd, /etc/shadow, and /etc/group entries into container - pwd=`getent passwd $user` - if [ $? -ne 0 ]; then - echo 'Warning: failed to copy password entry for $user' - return - else - echo $pwd >> $rootfs/etc/passwd + pwd=`getent passwd $user` || { echo "Failed to copy password entry for $user"; false; } + echo $pwd >> $rootfs/etc/passwd + + # make sure user's shell exists in the container + shell=`echo $pwd | cut -d: -f 7` + if [ ! -x $rootfs/$shell ]; then + echo "shell $shell for user $user was not found in the container." + pkg=`dpkg -S $(readlink -m $shell) | cut -d ':' -f1` + echo "Installing $pkg" + chroot $rootfs apt-get --force-yes -y install $pkg fi + shad=`getent shadow $user` - echo $shad >> $rootfs/etc/shadow + echo "$shad" >> $rootfs/etc/shadow # bind-mount the user's path into the container's /home h=`getent passwd $user | cut -d: -f 6` mkdir -p $rootfs/$h - echo "$h $rootfs/$h none bind 0 0" >> $path/fstab + + # use relative path in container + h2=${h#/} + while [ ${h2:0:1} = "/" ]; do + h2=${h2#/} + done + echo "$h $h2 none bind 0 0" >> $path/fstab + + # Make sure the group exists in container + grp=`echo $pwd | cut -d: -f 4` # group number for $user + grpe=`getent group $grp` || return 0 # if host doesn't define grp, ignore in container + chroot $rootfs getent group "$grpe" || echo "$grpe" >> $rootfs/etc/group } usage() { cat <] [--trim] - [-F | --flush-cache] [-r|--release ] [ -S | --auth_key ] -release: lucid | maverick | natty | oneiric | precise +$1 -h|--help [-a|--arch] [-b|--bindhome ] [--trim] [-d|--debug] + [-F | --flush-cache] [-r|--release ] [ -S | --auth-key ] + [--rootfs ] +release: the ubuntu release (e.g. precise): defaults to host release on ubuntu, otherwise uses latest LTS trim: make a minimal (faster, but not upgrade-safe) container bindhome: bind 's home into the container -arch: amd64 or i386: defaults to host arch -auth_key: SSH Public key file to inject into container + The ubuntu user will not be created, and will have + sudo access. +arch: the container architecture (e.g. amd64): defaults to host arch +auth-key: SSH Public key file to inject into container EOF return 0 } -options=$(getopt -o a:b:hp:r:xn:FS: -l arch:,bindhome:,help,path:,release:,trim,name:,flush-cache,auth-key: -- "$@") +options=$(getopt -o a:b:hp:r:xn:FS:d -l arch:,bindhome:,help,path:,release:,trim,name:,flush-cache,auth-key:,debug,rootfs: -- "$@") if [ $? -ne 0 ]; then usage $(basename $0) exit 1 fi eval set -- "$options" -release=lucid +release=precise # Default to the last Ubuntu LTS release for non-Ubuntu systems if [ -f /etc/lsb-release ]; then . /etc/lsb-release - case "$DISTRIB_CODENAME" in - lucid|maverick|natty|oneiric|precise) - release=$DISTRIB_CODENAME - ;; - esac + if [ "$DISTRIB_ID" = "Ubuntu" ]; then + release=$DISTRIB_CODENAME + fi fi bindhome= -arch=$(arch) # Code taken from debootstrap if [ -x /usr/bin/dpkg ] && /usr/bin/dpkg --print-architecture >/dev/null 2>&1; then arch=`/usr/bin/dpkg --print-architecture` -elif type udpkg >/dev/null 2>&1 && udpkg --print-architecture >/dev/null 2>&1; then +elif which udpkg >/dev/null 2>&1 && udpkg --print-architecture >/dev/null 2>&1; then arch=`/usr/bin/udpkg --print-architecture` else - arch=$(arch) + arch=$(uname -m) if [ "$arch" = "i686" ]; then arch="i386" elif [ "$arch" = "x86_64" ]; then arch="amd64" elif [ "$arch" = "armv7l" ]; then - arch="armel" + arch="armhf" fi fi +debug=0 trim_container=0 hostarch=$arch flushcache=0 @@ -573,6 +693,7 @@ do case "$1" in -h|--help) usage $0 && exit 0;; + --rootfs) rootfs=$2; shift 2;; -p|--path) path=$2; shift 2;; -n|--name) name=$2; shift 2;; -F|--flush-cache) flushcache=1; shift 1;; @@ -580,16 +701,23 @@ -b|--bindhome) bindhome=$2; shift 2;; -a|--arch) arch=$2; shift 2;; -x|--trim) trim_container=1; shift 1;; - -S|--auth_key) auth_key=$2; shift 2;; + -S|--auth-key) auth_key=$2; shift 2;; + -d|--debug) debug=1; shift 1;; --) shift 1; break ;; *) break ;; esac done -pwd=`getent passwd $bindhome` -if [ $? -ne 0 ]; then - echo "Error: no password entry found for $bindhome" - exit 1 +if [ $debug -eq 1 ]; then + set -x +fi + +if [ -n "$bindhome" ]; then + pwd=`getent passwd $bindhome` + if [ $? -ne 0 ]; then + echo "Error: no password entry found for $bindhome" + exit 1 + fi fi @@ -598,16 +726,23 @@ fi if [ $hostarch = "i386" -a $arch = "amd64" ]; then - echo "can't create amd64 container on i386" + echo "can't create $arch container on $hostarch" exit 1 fi -type debootstrap -if [ $? -ne 0 ]; then - echo "'debootstrap' command is missing" +if [ $hostarch = "armhf" -o $hostarch = "armel" ] && \ + [ $arch != "armhf" -a $arch != "armel" ]; then + echo "can't create $arch container on $hostarch" + exit 1 +fi + +if [ $hostarch = "powerpc" -a $arch != "powerpc" ]; then + echo "can't create $arch container on $hostarch" exit 1 fi +which debootstrap >/dev/null 2>&1 || { echo "'debootstrap' command is missing" >&2; false; } + if [ -z "$path" ]; then echo "'path' parameter is required" exit 1 @@ -618,7 +753,16 @@ exit 1 fi -rootfs=$path/rootfs +# detect rootfs +config="$path/config" +# if $rootfs exists here, it was passed in with --rootfs +if [ -z "$rootfs" ]; then + if grep -q '^lxc.rootfs' $config 2>/dev/null ; then + rootfs=`grep 'lxc.rootfs =' $config | awk -F= '{ print $2 }'` + else + rootfs=$path/rootfs + fi +fi install_ubuntu $rootfs $release $flushcache if [ $? -ne 0 ]; then @@ -639,13 +783,21 @@ fi post_process $rootfs $release $trim_container -if [ ! -z $bindhome ]; then - do_bindhome $rootfs $bindhome + +if [ -n "$bindhome" ]; then + do_bindhome $rootfs $bindhome + finalize_user $bindhome +else + finalize_user ubuntu fi echo "" echo "##" -echo "# The default user is 'ubuntu' with password 'ubuntu'!" -echo "# Use the 'sudo' command to run tasks as root in the container." +if [ -n "$bindhome" ]; then + echo "# Log in as user $bindhome" +else + echo "# The default user is 'ubuntu' with password 'ubuntu'!" + echo "# Use the 'sudo' command to run tasks as root in the container." +fi echo "##" echo ""