From d16bf1551b713d14b5a60aa176ca5c6df3a21fb1 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Fri, 26 Aug 2011 11:17:19 +0100 Subject: [PATCH 01/16] Version 3.9. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index c8164a5..1ba8e99 100644 --- a/configure.ac +++ b/configure.ac @@ -17,7 +17,7 @@ dnl Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. dnl dnl Written by Richard W.M. Jones -AC_INIT(febootstrap,3.8) +AC_INIT(febootstrap,3.9) AM_INIT_AUTOMAKE dnl Check for basic C environment. -- 1.8.3.1 From e4c7daf8bcdcf094719b3169ed79aece64a933bd Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Thu, 1 Sep 2011 10:23:36 +0100 Subject: [PATCH 02/16] debian: Detect apt-cache in configure. --- config.ml.in | 1 + configure.ac | 1 + febootstrap_debian.ml | 5 +++-- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/config.ml.in b/config.ml.in index a8c008a..fc8fbfe 100644 --- a/config.ml.in +++ b/config.ml.in @@ -23,6 +23,7 @@ let yum = "@YUM@" let rpm = "@RPM@" let yumdownloader = "@YUMDOWNLOADER@" let aptitude = "@APTITUDE@" +let apt_cache = "@APT_CACHE@" let dpkg = "@DPKG@" let pacman = "@PACMAN@" let host_cpu = "@host_cpu@" diff --git a/configure.ac b/configure.ac index 1ba8e99..6f0cdc7 100644 --- a/configure.ac +++ b/configure.ac @@ -62,6 +62,7 @@ AC_CHECK_PROG(YUMDOWNLOADER,[yumdownloader],[yumdownloader],[no]) dnl For Debian handler. AC_CHECK_PROG(APTITUDE,[aptitude],[aptitude],[no]) +AC_CHECK_PROG(APT_CACHE,[apt-cache],[apt-cache],[no]) AC_CHECK_PROG(DPKG,[dpkg],[dpkg],[no]) dnl For ArchLinux handler. diff --git a/febootstrap_debian.ml b/febootstrap_debian.ml index 4aa7389..06fcbc3 100644 --- a/febootstrap_debian.ml +++ b/febootstrap_debian.ml @@ -30,11 +30,12 @@ let tmpdir = tmpdir () let debian_detect () = file_exists "/etc/debian_version" && - Config.aptitude <> "no" && Config.dpkg <> "no" + Config.aptitude <> "no" && Config.apt_cache <> "no" && Config.dpkg <> "no" let debian_resolve_dependencies_and_download names = let cmd = - sprintf "apt-cache depends --recurse -i %s | grep -v '^[<[:space:]]'" + sprintf "%s depends --recurse -i %s | grep -v '^[<[:space:]]'" + Config.apt_cache (String.concat " " (List.map Filename.quote names)) in let pkgs = run_command_get_lines cmd in -- 1.8.3.1 From 72101b100aa33b0b9879f9b18edfdd88c1aa2755 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Thu, 1 Sep 2011 10:24:21 +0100 Subject: [PATCH 03/16] debian: Use configured aptitude program instead of just "aptitude". --- febootstrap_debian.ml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/febootstrap_debian.ml b/febootstrap_debian.ml index 06fcbc3..f26df4a 100644 --- a/febootstrap_debian.ml +++ b/febootstrap_debian.ml @@ -48,8 +48,9 @@ let debian_resolve_dependencies_and_download names = (* Download the packages. *) let cmd = - sprintf "umask 0000; cd %s && aptitude download %s" + sprintf "umask 0000; cd %s && %s download %s" (Filename.quote tmpdir) + Config.aptitude (String.concat " " (List.map Filename.quote pkgs)) in run_command cmd; -- 1.8.3.1 From 3ac623701e5fe5ce94b22b4f40f72ee0161d5184 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Thu, 1 Sep 2011 10:43:46 +0100 Subject: [PATCH 04/16] debian: Include workaround for broken apt-cache depends --recurse. Ubuntu 10.04 LTS has a broken apt-cache depends --recurse command which does not in fact recurse deeply enough to find all dependencies (this is fixed in Ubuntu 11.04). Include a workaround for this so we can use febootstrap on old Ubuntu versions. --- config.ml.in | 1 + configure.ac | 13 +++++++++++++ febootstrap_debian.ml | 30 +++++++++++++++++++++++++++++- 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/config.ml.in b/config.ml.in index fc8fbfe..26a8e3d 100644 --- a/config.ml.in +++ b/config.ml.in @@ -25,5 +25,6 @@ let yumdownloader = "@YUMDOWNLOADER@" let aptitude = "@APTITUDE@" let apt_cache = "@APT_CACHE@" let dpkg = "@DPKG@" +let apt_cache_depends_recurse_broken = @APT_CACHE_DEPENDS_RECURSE_BROKEN@ let pacman = "@PACMAN@" let host_cpu = "@host_cpu@" diff --git a/configure.ac b/configure.ac index 6f0cdc7..0096a6f 100644 --- a/configure.ac +++ b/configure.ac @@ -65,6 +65,19 @@ AC_CHECK_PROG(APTITUDE,[aptitude],[aptitude],[no]) AC_CHECK_PROG(APT_CACHE,[apt-cache],[apt-cache],[no]) AC_CHECK_PROG(DPKG,[dpkg],[dpkg],[no]) +dnl Include workaround for broken apt-cache depends --recurse (Ubuntu 10.04)? +if test "x$APT_CACHE" != "xno"; then + AC_MSG_CHECKING([if apt-cache depends --recurse is broken]) + if ! $APT_CACHE depends --recurse -i bash | grep -q '^libc6$'; then + AC_MSG_RESULT([yes]) + APT_CACHE_DEPENDS_RECURSE_BROKEN=true + else + AC_MSG_RESULT([no]) + APT_CACHE_DEPENDS_RECURSE_BROKEN=false + fi + AC_SUBST([APT_CACHE_DEPENDS_RECURSE_BROKEN]) +fi + dnl For ArchLinux handler. AC_CHECK_PROG(PACMAN,[pacman],[pacman],[no]) diff --git a/febootstrap_debian.ml b/febootstrap_debian.ml index f26df4a..23f3593 100644 --- a/febootstrap_debian.ml +++ b/febootstrap_debian.ml @@ -32,12 +32,17 @@ let debian_detect () = file_exists "/etc/debian_version" && Config.aptitude <> "no" && Config.apt_cache <> "no" && Config.dpkg <> "no" -let debian_resolve_dependencies_and_download names = +let rec debian_resolve_dependencies_and_download names = let cmd = sprintf "%s depends --recurse -i %s | grep -v '^[<[:space:]]'" Config.apt_cache (String.concat " " (List.map Filename.quote names)) in let pkgs = run_command_get_lines cmd in + let pkgs = + if Config.apt_cache_depends_recurse_broken then + workaround_broken_apt_cache_depends_recurse (sort_uniq pkgs) + else + pkgs in (* Exclude packages matching [--exclude] regexps on the command line. *) let pkgs = @@ -78,6 +83,29 @@ let debian_resolve_dependencies_and_download names = List.sort compare pkgs +(* On Ubuntu 10.04 LTS, apt-cache depends --recurse is broken. It + * doesn't return the full list of dependencies. Therefore recurse + * into these dependencies one by one until we reach a fixpoint. + *) +and workaround_broken_apt_cache_depends_recurse names = + debug "workaround for broken 'apt-cache depends --recurse' command:\n %s" + (String.concat " " names); + + let names' = + List.map ( + fun name -> + let cmd = + sprintf "%s depends --recurse -i %s | grep -v '^[<[:space:]]'" + Config.apt_cache (Filename.quote name) in + run_command_get_lines cmd + ) names in + let names' = List.flatten names' in + let names' = sort_uniq names' in + if names <> names' then + workaround_broken_apt_cache_depends_recurse names' + else + names + let debian_list_files pkg = debug "unpacking %s ..." pkg; -- 1.8.3.1 From dad47f9be6822834c397f66a06f73a69f8efc996 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Thu, 1 Sep 2011 13:57:19 +0100 Subject: [PATCH 05/16] Fix previous commit for non-Debian case. This updates commit 3ac623701e5fe5ce94b22b4f40f72ee0161d5184. --- configure.ac | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 0096a6f..fdcef28 100644 --- a/configure.ac +++ b/configure.ac @@ -75,8 +75,10 @@ if test "x$APT_CACHE" != "xno"; then AC_MSG_RESULT([no]) APT_CACHE_DEPENDS_RECURSE_BROKEN=false fi - AC_SUBST([APT_CACHE_DEPENDS_RECURSE_BROKEN]) +else + APT_CACHE_DEPENDS_RECURSE_BROKEN=false fi +AC_SUBST([APT_CACHE_DEPENDS_RECURSE_BROKEN]) dnl For ArchLinux handler. AC_CHECK_PROG(PACMAN,[pacman],[pacman],[no]) -- 1.8.3.1 From 1d6f1a9cb0fb1be8467d8e2c0fbda1b7eca70c66 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Thu, 1 Sep 2011 14:08:50 +0100 Subject: [PATCH 06/16] Move febootstrap into src/ subdirectory. Now we have src/ for febootstrap and helper/ for febootstrap-supermin-helper. --- .gitignore | 4 +- Makefile.am | 88 +----------------- configure.ac | 7 +- .depend => src/.depend | 0 src/Makefile.am | 103 +++++++++++++++++++++ config.ml.in => src/config.ml.in | 0 febootstrap.ml => src/febootstrap.ml | 0 febootstrap.pod => src/febootstrap.pod | 0 .../febootstrap_cmdline.ml | 0 .../febootstrap_cmdline.mli | 0 febootstrap_debian.ml => src/febootstrap_debian.ml | 0 .../febootstrap_package_handlers.ml | 0 .../febootstrap_package_handlers.mli | 0 febootstrap_pacman.ml => src/febootstrap_pacman.ml | 0 febootstrap_utils.ml => src/febootstrap_utils.ml | 0 febootstrap_utils.mli => src/febootstrap_utils.mli | 0 .../febootstrap_yum_rpm.ml | 0 17 files changed, 112 insertions(+), 90 deletions(-) rename .depend => src/.depend (100%) create mode 100644 src/Makefile.am rename config.ml.in => src/config.ml.in (100%) rename febootstrap.ml => src/febootstrap.ml (100%) rename febootstrap.pod => src/febootstrap.pod (100%) rename febootstrap_cmdline.ml => src/febootstrap_cmdline.ml (100%) rename febootstrap_cmdline.mli => src/febootstrap_cmdline.mli (100%) rename febootstrap_debian.ml => src/febootstrap_debian.ml (100%) rename febootstrap_package_handlers.ml => src/febootstrap_package_handlers.ml (100%) rename febootstrap_package_handlers.mli => src/febootstrap_package_handlers.mli (100%) rename febootstrap_pacman.ml => src/febootstrap_pacman.ml (100%) rename febootstrap_utils.ml => src/febootstrap_utils.ml (100%) rename febootstrap_utils.mli => src/febootstrap_utils.mli (100%) rename febootstrap_yum_rpm.ml => src/febootstrap_yum_rpm.ml (100%) diff --git a/.gitignore b/.gitignore index bfb6c08..22f33b8 100644 --- a/.gitignore +++ b/.gitignore @@ -17,13 +17,11 @@ config.guess config.h.in config.h config.log -config.ml config.status config.sub configure cscope.out depcomp -febootstrap febootstrap*.8 febootstrap*.txt febootstrap-*.tar.gz @@ -50,6 +48,8 @@ INSTALL install-sh missing pod2htm?.tmp +src/config.ml +src/febootstrap stamp-h1 /warn-on-use.h examples/guestfs diff --git a/Makefile.am b/Makefile.am index 7ac5079..c40c769 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,5 +1,5 @@ # febootstrap Makefile.am -# (C) Copyright 2009-2010 Red Hat Inc. +# (C) Copyright 2009-2011 Red Hat 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 @@ -19,98 +19,16 @@ ACLOCAL_AMFLAGS = -I m4 -SUBDIRS = lib helper - -# Note these must be in build dependency order. -SOURCES = \ - config.ml \ - febootstrap_cmdline.mli \ - febootstrap_cmdline.ml \ - febootstrap_utils.mli \ - febootstrap_utils.ml \ - febootstrap_package_handlers.mli \ - febootstrap_package_handlers.ml \ - febootstrap_yum_rpm.ml \ - febootstrap_debian.ml \ - febootstrap_pacman.ml \ - febootstrap.ml - -CLEANFILES = *~ *.cmi *.cmo *.cmx *.o febootstrap +SUBDIRS = lib src helper EXTRA_DIST = \ .gitignore \ .gitmodules \ autogen.sh \ - febootstrap.8 \ - febootstrap.pod \ html/pod.css \ m4/gnulib-cache.m4 \ $(SOURCES) -man_MANS = \ - febootstrap.8 - -bin_SCRIPTS = febootstrap - -SOURCES_ML = $(filter %.ml,$(SOURCES)) -BOBJECTS = $(SOURCES_ML:.ml=.cmo) -XOBJECTS = $(SOURCES_ML:.ml=.cmx) - -if !HAVE_OCAMLOPT -OBJECTS = $(BOBJECTS) -BEST = c -else -OBJECTS = $(XOBJECTS) -BEST = opt -endif - -OCAMLPACKAGES = -package unix,str -OCAMLFLAGS = -warn-error CDEFLMPSUVXYZ - -febootstrap: $(OBJECTS) - $(OCAMLFIND) $(BEST) $(OCAMLFLAGS) $(OCAMLPACKAGES) -linkpkg \ - $^ -o $@ - -.mli.cmi: - $(OCAMLFIND) ocamlc $(OCAMLFLAGS) $(OCAMLPACKAGES) -c $< -o $@ -.ml.cmo: - $(OCAMLFIND) ocamlc $(OCAMLFLAGS) $(OCAMLPACKAGES) -c $< -o $@ -.ml.cmx: - $(OCAMLFIND) ocamlopt $(OCAMLFLAGS) $(OCAMLPACKAGES) -c $< -o $@ - -depend: .depend - -.depend: $(SOURCES) - rm -f $@ $@-t - $(OCAMLFIND) ocamldep $^ > $@-t - mv $@-t $@ - -include .depend - -SUFFIXES = .cmo .cmi .cmx .ml .mli .mll .mly - -if HAVE_PERLDOC - -febootstrap.8: febootstrap.pod - pod2man \ - --section 8 \ - -c "Virtualization Support" \ - --release "$(PACKAGE_NAME)-$(PACKAGE_VERSION)" \ - $< > $@ - -noinst_DATA = \ - html/febootstrap.8.html - -html/febootstrap.8.html: febootstrap.pod - mkdir -p html - pod2html \ - --css 'pod.css' \ - --htmldir html \ - --outfile html/febootstrap.8.html \ - febootstrap.pod - -endif - # Maintainer website update. HTMLFILES = \ html/febootstrap.8.html \ @@ -121,4 +39,4 @@ WEBSITEDIR = $(HOME)/d/redhat/websites/libguestfs website: $(HTMLFILES) cp $(HTMLFILES) $(WEBSITEDIR) -CLEANFILES += $(HTMLFILES) pod2*.tmp +CLEANFILES = $(HTMLFILES) pod2*.tmp diff --git a/configure.ac b/configure.ac index fdcef28..438c549 100644 --- a/configure.ac +++ b/configure.ac @@ -114,9 +114,10 @@ if test "x$GAWK" = "xno" ; then fi AC_CONFIG_HEADERS([config.h]) -AC_CONFIG_FILES([config.ml +AC_CONFIG_FILES([Makefile debian/changelog - Makefile + helper/Makefile lib/Makefile - helper/Makefile]) + src/config.ml + src/Makefile]) AC_OUTPUT diff --git a/.depend b/src/.depend similarity index 100% rename from .depend rename to src/.depend diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..b715c9f --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,103 @@ +# febootstrap Makefile.am +# (C) Copyright 2009-2011 Red Hat 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 +# 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., 675 Mass Ave, Cambridge, MA 02139, USA. +# +# Written by Richard W.M. Jones + +# Note these must be in build dependency order. +SOURCES = \ + config.ml \ + febootstrap_cmdline.mli \ + febootstrap_cmdline.ml \ + febootstrap_utils.mli \ + febootstrap_utils.ml \ + febootstrap_package_handlers.mli \ + febootstrap_package_handlers.ml \ + febootstrap_yum_rpm.ml \ + febootstrap_debian.ml \ + febootstrap_pacman.ml \ + febootstrap.ml + +CLEANFILES = *~ *.cmi *.cmo *.cmx *.o febootstrap + +EXTRA_DIST = \ + febootstrap.8 \ + febootstrap.pod \ + $(SOURCES) + +man_MANS = \ + febootstrap.8 + +bin_SCRIPTS = febootstrap + +SOURCES_ML = $(filter %.ml,$(SOURCES)) +BOBJECTS = $(SOURCES_ML:.ml=.cmo) +XOBJECTS = $(SOURCES_ML:.ml=.cmx) + +if !HAVE_OCAMLOPT +OBJECTS = $(BOBJECTS) +BEST = c +else +OBJECTS = $(XOBJECTS) +BEST = opt +endif + +OCAMLPACKAGES = -package unix,str +OCAMLFLAGS = -warn-error CDEFLMPSUVXYZ + +febootstrap: $(OBJECTS) + $(OCAMLFIND) $(BEST) $(OCAMLFLAGS) $(OCAMLPACKAGES) -linkpkg \ + $^ -o $@ + +.mli.cmi: + $(OCAMLFIND) ocamlc $(OCAMLFLAGS) $(OCAMLPACKAGES) -c $< -o $@ +.ml.cmo: + $(OCAMLFIND) ocamlc $(OCAMLFLAGS) $(OCAMLPACKAGES) -c $< -o $@ +.ml.cmx: + $(OCAMLFIND) ocamlopt $(OCAMLFLAGS) $(OCAMLPACKAGES) -c $< -o $@ + +depend: .depend + +.depend: $(SOURCES) + rm -f $@ $@-t + $(OCAMLFIND) ocamldep $^ > $@-t + mv $@-t $@ + +include .depend + +SUFFIXES = .cmo .cmi .cmx .ml .mli .mll .mly + +if HAVE_PERLDOC + +febootstrap.8: febootstrap.pod + pod2man \ + --section 8 \ + -c "Virtualization Support" \ + --release "$(PACKAGE_NAME)-$(PACKAGE_VERSION)" \ + $< > $@ + +noinst_DATA = \ + ../html/febootstrap.8.html + +../html/febootstrap.8.html: febootstrap.pod + mkdir -p ../html + pod2html \ + --css 'pod.css' \ + --htmldir ../html \ + --outfile ../html/febootstrap.8.html \ + febootstrap.pod + +endif diff --git a/config.ml.in b/src/config.ml.in similarity index 100% rename from config.ml.in rename to src/config.ml.in diff --git a/febootstrap.ml b/src/febootstrap.ml similarity index 100% rename from febootstrap.ml rename to src/febootstrap.ml diff --git a/febootstrap.pod b/src/febootstrap.pod similarity index 100% rename from febootstrap.pod rename to src/febootstrap.pod diff --git a/febootstrap_cmdline.ml b/src/febootstrap_cmdline.ml similarity index 100% rename from febootstrap_cmdline.ml rename to src/febootstrap_cmdline.ml diff --git a/febootstrap_cmdline.mli b/src/febootstrap_cmdline.mli similarity index 100% rename from febootstrap_cmdline.mli rename to src/febootstrap_cmdline.mli diff --git a/febootstrap_debian.ml b/src/febootstrap_debian.ml similarity index 100% rename from febootstrap_debian.ml rename to src/febootstrap_debian.ml diff --git a/febootstrap_package_handlers.ml b/src/febootstrap_package_handlers.ml similarity index 100% rename from febootstrap_package_handlers.ml rename to src/febootstrap_package_handlers.ml diff --git a/febootstrap_package_handlers.mli b/src/febootstrap_package_handlers.mli similarity index 100% rename from febootstrap_package_handlers.mli rename to src/febootstrap_package_handlers.mli diff --git a/febootstrap_pacman.ml b/src/febootstrap_pacman.ml similarity index 100% rename from febootstrap_pacman.ml rename to src/febootstrap_pacman.ml diff --git a/febootstrap_utils.ml b/src/febootstrap_utils.ml similarity index 100% rename from febootstrap_utils.ml rename to src/febootstrap_utils.ml diff --git a/febootstrap_utils.mli b/src/febootstrap_utils.mli similarity index 100% rename from febootstrap_utils.mli rename to src/febootstrap_utils.mli diff --git a/febootstrap_yum_rpm.ml b/src/febootstrap_yum_rpm.ml similarity index 100% rename from febootstrap_yum_rpm.ml rename to src/febootstrap_yum_rpm.ml -- 1.8.3.1 From 5abb2a607dd99f9d660413810f2bd0656ccb0bad Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Thu, 1 Sep 2011 14:08:57 +0100 Subject: [PATCH 07/16] Version 3.10. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 438c549..46039da 100644 --- a/configure.ac +++ b/configure.ac @@ -17,7 +17,7 @@ dnl Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. dnl dnl Written by Richard W.M. Jones -AC_INIT(febootstrap,3.9) +AC_INIT(febootstrap,3.10) AM_INIT_AUTOMAKE dnl Check for basic C environment. -- 1.8.3.1 From 7189eb48dd8f46049d982f1d99e158609409019f Mon Sep 17 00:00:00 2001 From: Richard Jones Date: Mon, 12 Sep 2011 10:00:14 +0100 Subject: [PATCH 08/16] docs: Use multiple =item's instead of =item foo|bar --- helper/febootstrap-supermin-helper.pod | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/helper/febootstrap-supermin-helper.pod b/helper/febootstrap-supermin-helper.pod index b2a687e..6c797cb 100644 --- a/helper/febootstrap-supermin-helper.pod +++ b/helper/febootstrap-supermin-helper.pod @@ -39,7 +39,9 @@ the checksum output C<-f checksum>. =over 4 -=item B<-f fmt> | B<--format fmt> +=item B<-f fmt> + +=item B<--format fmt> Select the output format for the appliance. Possible formats are: @@ -75,7 +77,9 @@ host_cpu and the UID of the current user are included in the checksum. =back -=item B<-k file> | B<--kmods file> +=item B<-k file> + +=item B<--kmods file> If this option is specified, then C should be a list of wildcards matching kernel module names, eg: @@ -93,7 +97,13 @@ If this option is not specified, then every kernel module from the host will be included. This is safer, but can produce rather large appliances which need a lot more memory to boot. -=item B<-u user> | B<--user user> | B<-g group> | B<--group group> +=item B<-u user> + +=item B<--user user> + +=item B<-g group> + +=item B<--group group> Run febootstrap-supermin-helper as an alternate user and/or group. C and C can be specified as either a name, which will -- 1.8.3.1 From 3e6927876b64665fa8a2259707052aec1ff2ef5d Mon Sep 17 00:00:00 2001 From: Richard Jones Date: Mon, 12 Sep 2011 10:07:31 +0100 Subject: [PATCH 09/16] Stable OCaml dependencies. This technique copied from libguestfs/resize/Makefile.am and modified so that it works with old ocamldep that used to add spaces at the end of lines. --- configure.ac | 3 +++ src/.depend | 32 +++++++++++--------------------- src/Makefile.am | 5 ++++- 3 files changed, 18 insertions(+), 22 deletions(-) diff --git a/configure.ac b/configure.ac index 46039da..a75a581 100644 --- a/configure.ac +++ b/configure.ac @@ -37,6 +37,9 @@ AC_SYS_LARGEFILE gl_INIT +# Define $(SED). +AC_PROG_SED + # OCaml and ocamlfind are required to compile. AC_PROG_OCAML if test "$OCAMLC" = "no"; then diff --git a/src/.depend b/src/.depend index e71f272..33b1cfb 100644 --- a/src/.depend +++ b/src/.depend @@ -3,27 +3,17 @@ config.cmx: febootstrap_cmdline.cmi: febootstrap_cmdline.cmo: config.cmo febootstrap_cmdline.cmi febootstrap_cmdline.cmx: config.cmx febootstrap_cmdline.cmi +febootstrap.cmo: febootstrap_utils.cmi febootstrap_package_handlers.cmi febootstrap_cmdline.cmi config.cmo +febootstrap.cmx: febootstrap_utils.cmx febootstrap_package_handlers.cmx febootstrap_cmdline.cmx config.cmx +febootstrap_debian.cmo: febootstrap_utils.cmi febootstrap_package_handlers.cmi febootstrap_cmdline.cmi config.cmo +febootstrap_debian.cmx: febootstrap_utils.cmx febootstrap_package_handlers.cmx febootstrap_cmdline.cmx config.cmx +febootstrap_package_handlers.cmi: +febootstrap_package_handlers.cmo: febootstrap_utils.cmi febootstrap_cmdline.cmi febootstrap_package_handlers.cmi +febootstrap_package_handlers.cmx: febootstrap_utils.cmx febootstrap_cmdline.cmx febootstrap_package_handlers.cmi +febootstrap_pacman.cmo: febootstrap_utils.cmi febootstrap_package_handlers.cmi febootstrap_cmdline.cmi config.cmo +febootstrap_pacman.cmx: febootstrap_utils.cmx febootstrap_package_handlers.cmx febootstrap_cmdline.cmx config.cmx febootstrap_utils.cmi: febootstrap_utils.cmo: febootstrap_cmdline.cmi febootstrap_utils.cmi febootstrap_utils.cmx: febootstrap_cmdline.cmx febootstrap_utils.cmi -febootstrap_package_handlers.cmi: -febootstrap_package_handlers.cmo: febootstrap_utils.cmi \ - febootstrap_cmdline.cmi febootstrap_package_handlers.cmi -febootstrap_package_handlers.cmx: febootstrap_utils.cmx \ - febootstrap_cmdline.cmx febootstrap_package_handlers.cmi -febootstrap_yum_rpm.cmo: febootstrap_utils.cmi \ - febootstrap_package_handlers.cmi febootstrap_cmdline.cmi config.cmo -febootstrap_yum_rpm.cmx: febootstrap_utils.cmx \ - febootstrap_package_handlers.cmx febootstrap_cmdline.cmx config.cmx -febootstrap_debian.cmo: febootstrap_utils.cmi \ - febootstrap_package_handlers.cmi febootstrap_cmdline.cmi config.cmo -febootstrap_debian.cmx: febootstrap_utils.cmx \ - febootstrap_package_handlers.cmx febootstrap_cmdline.cmx config.cmx -febootstrap_pacman.cmo: febootstrap_utils.cmi \ - febootstrap_package_handlers.cmi febootstrap_cmdline.cmi config.cmo -febootstrap_pacman.cmx: febootstrap_utils.cmx \ - febootstrap_package_handlers.cmx febootstrap_cmdline.cmx config.cmx -febootstrap.cmo: febootstrap_utils.cmi febootstrap_package_handlers.cmi \ - febootstrap_cmdline.cmi config.cmo -febootstrap.cmx: febootstrap_utils.cmx febootstrap_package_handlers.cmx \ - febootstrap_cmdline.cmx config.cmx +febootstrap_yum_rpm.cmo: febootstrap_utils.cmi febootstrap_package_handlers.cmi febootstrap_cmdline.cmi config.cmo +febootstrap_yum_rpm.cmx: febootstrap_utils.cmx febootstrap_package_handlers.cmx febootstrap_cmdline.cmx config.cmx diff --git a/src/Makefile.am b/src/Makefile.am index b715c9f..2bcad79 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -73,7 +73,10 @@ depend: .depend .depend: $(SOURCES) rm -f $@ $@-t - $(OCAMLFIND) ocamldep $^ > $@-t + $(OCAMLFIND) ocamldep $^ | \ + $(SED) 's/ *$$//' | \ + $(SED) -e :a -e '/ *\\$$/N; s/ *\\\n */ /; ta' | \ + sort > $@-t mv $@-t $@ include .depend -- 1.8.3.1 From 8ad45af9d37eeed9797e955f75200a244d675f7d Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Wed, 14 Sep 2011 16:04:49 +0100 Subject: [PATCH 10/16] yum-rpm: Add more debugging to the Python code. --- src/febootstrap_yum_rpm.ml | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/febootstrap_yum_rpm.ml b/src/febootstrap_yum_rpm.ml index ca74f4a..028492a 100644 --- a/src/febootstrap_yum_rpm.ml +++ b/src/febootstrap_yum_rpm.ml @@ -40,20 +40,27 @@ import yum import yum.misc import sys +verbose = %d + +if verbose: + print \"febootstrap_yum_rpm: running python code to query yum and resolve deps\" + yb = yum.YumBase () -yb.preconf.debuglevel = %d -yb.preconf.errorlevel = %d +yb.preconf.debuglevel = verbose +yb.preconf.errorlevel = verbose if %s: yb.preconf.fn = %S yb.setCacheDir () -# Look up the base packages from the command line. +if verbose: + print \"febootstrap_yum_rpm: looking up the base packages from the command line\" deps = dict () pkgs = yb.pkgSack.returnPackages (patterns=sys.argv[1:]) for pkg in pkgs: deps[pkg] = False -# Recursively find all the dependencies. +if verbose: + print \"febootstrap_yum_rpm: recursively finding all the dependencies\" stable = False while not stable: stable = True @@ -61,6 +68,9 @@ while not stable: if deps[pkg] == False: deps[pkg] = [] stable = False + if verbose: + print (\"febootstrap_yum_rpm: examining deps of %%s\" %% + pkg.name) for r in pkg.requires: ps = yb.whatProvides (r[0], r[1], r[2]) best = yb._bestPackageFromList (ps.returnPackages ()) @@ -76,9 +86,11 @@ for pkg in deps.keys (): f.write (\"%%s %%s %%s %%s %%s\\n\" %% (pkg.name, pkg.epoch, pkg.version, pkg.release, pkg.arch)) f.close () + +if verbose: + print \"febootstrap_yum_rpm: finished python code\" " (if verbose then 1 else 0) - (if verbose then 1 else 0) (match yum_config with None -> "False" | Some _ -> "True") (match yum_config with None -> "" | Some filename -> filename) tmpfile in -- 1.8.3.1 From bdd7c861768637bbcafdf3f4474944bd4680e13f Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Fri, 23 Sep 2011 09:51:25 +0100 Subject: [PATCH 11/16] Verbose message when adding kernel modules. This step takes a considerable amount of time (about half of the total construction time), so separately display a timestamped message for it. --- helper/appliance.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/helper/appliance.c b/helper/appliance.c index 50d1d78..b2cc840 100644 --- a/helper/appliance.c +++ b/helper/appliance.c @@ -197,6 +197,9 @@ static void add_kernel_modules (const char *whitelist_file, const char *modpath, struct writer *writer) { + if (verbose) + print_timestamped_message ("adding kernel modules"); + char **whitelist = NULL; if (whitelist_file != NULL) whitelist = load_file (whitelist_file); -- 1.8.3.1 From b8cea4656e5bf1b9e7bb2274ef968ea42b10e0df Mon Sep 17 00:00:00 2001 From: Hilko Bengen Date: Mon, 12 Sep 2011 23:58:09 +0200 Subject: [PATCH 12/16] febootstrap: Use contents of installed Debian packages instead of downloading and unpacking them. This also adds --use-installed switch (which for now only works for Debian). --- src/febootstrap.ml | 4 +-- src/febootstrap.pod | 12 +++++++ src/febootstrap_cmdline.ml | 4 +++ src/febootstrap_cmdline.mli | 3 ++ src/febootstrap_debian.ml | 67 +++++++++++++++++++++++++++++------- src/febootstrap_package_handlers.ml | 4 +-- src/febootstrap_package_handlers.mli | 4 +-- src/febootstrap_pacman.ml | 10 ++++-- src/febootstrap_yum_rpm.ml | 10 ++++-- 9 files changed, 96 insertions(+), 22 deletions(-) diff --git a/src/febootstrap.ml b/src/febootstrap.ml index 7e48206..3afb1bb 100644 --- a/src/febootstrap.ml +++ b/src/febootstrap.ml @@ -67,7 +67,7 @@ let () = List.flatten ( List.map ( fun pkg -> - let files = ph.ph_list_files pkg in + let files = ph.ph_list_files ~use_installed pkg in List.map (fun (filename, ft) -> filename, ft, pkg) files ) packages ) in @@ -320,7 +320,7 @@ let () = * original file from the package. *) else if config then ( - let outfile = ph.ph_get_file_from_package pkg path in + let outfile = ph.ph_get_file_from_package ~use_installed pkg path in (* Note that the output config file might not be a regular file. *) let statbuf = lstat outfile in diff --git a/src/febootstrap.pod b/src/febootstrap.pod index ac97f48..68ad367 100644 --- a/src/febootstrap.pod +++ b/src/febootstrap.pod @@ -96,6 +96,18 @@ output directory then they will be overwritten. Don't remove temporary files and directories on exit. This is useful for debugging. +=item B<--use-installed> + +If packages are already installed, use the contents (from the local +filesystem) instead of downloading them. + +Note that this can cause malformed appliances if local files have been +changed from what was originally in the package. This is particularly +a problem for configuration files. + +However this option is useful in some controlled situations: for +example when using febootstrap inside a freshly installed chroot. + =item B<-v> =item B<--verbose> diff --git a/src/febootstrap_cmdline.ml b/src/febootstrap_cmdline.ml index 667e297..fc18bbd 100644 --- a/src/febootstrap_cmdline.ml +++ b/src/febootstrap_cmdline.ml @@ -23,6 +23,7 @@ let names_mode = ref false let outputdir = ref "." let packages = ref [] let save_temps = ref false +let use_installed = ref false let verbose = ref false let warnings = ref true let yum_config = ref None @@ -50,6 +51,8 @@ let argspec = Arg.align [ " Don't delete temporary files and directories on exit."; "--save-temps", Arg.Set save_temps, " Don't delete temporary files and directories on exit."; + "--use-installed", Arg.Set use_installed, + " Inspect already installed packages for determining contents."; "-v", Arg.Set verbose, " Enable verbose output"; "--verbose", Arg.Set verbose, @@ -89,6 +92,7 @@ let names_mode = !names_mode let outputdir = !outputdir let packages = List.rev !packages let save_temps = !save_temps +let use_installed = !use_installed let verbose = !verbose let warnings = !warnings let yum_config = !yum_config diff --git a/src/febootstrap_cmdline.mli b/src/febootstrap_cmdline.mli index d948d80..a545012 100644 --- a/src/febootstrap_cmdline.mli +++ b/src/febootstrap_cmdline.mli @@ -38,6 +38,9 @@ val packages : string list val save_temps : bool (** True if [--save-temps] was given on the command line. *) +val use_installed : bool + (** True if [--use-installed] was given on the command line *) + val verbose : bool (** True if [--verbose] was given on the command line. See also {!debug}. *) diff --git a/src/febootstrap_debian.ml b/src/febootstrap_debian.ml index 23f3593..7482ed4 100644 --- a/src/febootstrap_debian.ml +++ b/src/febootstrap_debian.ml @@ -28,6 +28,9 @@ open Febootstrap_cmdline (* Create a temporary directory for use by all the functions in this file. *) let tmpdir = tmpdir () +let installed_pkgs = + run_command_get_lines "dpkg-query --show --showformat='${Package}\\n'" + let debian_detect () = file_exists "/etc/debian_version" && Config.aptitude <> "no" && Config.apt_cache <> "no" && Config.dpkg <> "no" @@ -51,18 +54,29 @@ let rec debian_resolve_dependencies_and_download names = not (List.exists (fun re -> Str.string_match re name 0) excludes) ) pkgs in + let present_pkgs, download_pkgs = List.partition ( + fun pkg -> List.exists ((=) pkg) installed_pkgs + ) pkgs in + + debug "wanted packages (present / download): %s / %s\n" + (String.concat " " present_pkgs) + (String.concat " " download_pkgs); + (* Download the packages. *) - let cmd = - sprintf "umask 0000; cd %s && %s download %s" - (Filename.quote tmpdir) - Config.aptitude - (String.concat " " (List.map Filename.quote pkgs)) in - run_command cmd; + if (List.length download_pkgs > 0) + then ( + let cmd = + sprintf "umask 0000; cd %s && %s download %s" + (Filename.quote tmpdir) + Config.aptitude + (String.concat " " (List.map Filename.quote download_pkgs)) in + run_command cmd + ); (* Find out what aptitude downloaded. *) let files = Sys.readdir tmpdir in - let pkgs = List.map ( + let download_pkgs = List.map ( fun pkg -> (* Look for 'pkg_*.deb' in the list of files. *) let pre = pkg ^ "_" in @@ -79,9 +93,9 @@ let rec debian_resolve_dependencies_and_download names = exit 1 with Exit -> !r - ) pkgs in + ) download_pkgs in - List.sort compare pkgs + List.sort compare (List.append present_pkgs download_pkgs) (* On Ubuntu 10.04 LTS, apt-cache depends --recurse is broken. It * doesn't return the full list of dependencies. Therefore recurse @@ -106,7 +120,7 @@ and workaround_broken_apt_cache_depends_recurse names = else names -let debian_list_files pkg = +let debian_list_files_downloaded pkg = debug "unpacking %s ..." pkg; (* We actually need to extract the file in order to get the @@ -147,9 +161,38 @@ let debian_list_files pkg = files +let debian_list_files_installed pkg = + debug "using installed package %s ..." pkg; + let cmd = sprintf "dpkg-query --listfiles %s" pkg in + let lines = run_command_get_lines cmd in + (* filter out lines not directly describing fs objects such as + "package diverts others to: /path/to/..." *) + let lines = List.filter ( + fun l -> l.[0] = '/' && l.[1] != '.' + ) lines in + let files = List.map ( + fun path -> + let statbuf = lstat path in + let is_dir = statbuf.st_kind = S_DIR in + let config = statbuf.st_kind = S_REG && string_prefix "/etc/" path in + let mode = statbuf.st_perm in + (path, { ft_dir = is_dir; ft_config = config; ft_mode = mode; + ft_ghost = false; ft_size = statbuf.st_size }) + ) lines in + files + +let debian_list_files ?(use_installed=false) pkg = + if use_installed && List.exists ((=) pkg) installed_pkgs then + debian_list_files_installed pkg + else + debian_list_files_downloaded pkg + (* Easy because we already unpacked the archive above. *) -let debian_get_file_from_package pkg file = - tmpdir // pkg ^ ".d" // file +let debian_get_file_from_package ?(use_installed=false) pkg file = + if use_installed && List.exists (fun p -> p = pkg) installed_pkgs then + file + else + tmpdir // pkg ^ ".d" // file let () = let ph = { diff --git a/src/febootstrap_package_handlers.ml b/src/febootstrap_package_handlers.ml index ad3a233..f627d2f 100644 --- a/src/febootstrap_package_handlers.ml +++ b/src/febootstrap_package_handlers.ml @@ -25,8 +25,8 @@ open Febootstrap_cmdline type package_handler = { ph_detect : unit -> bool; ph_resolve_dependencies_and_download : string list -> string list; - ph_list_files : string -> (string * file_type) list; - ph_get_file_from_package : string -> string -> string + ph_list_files : ?use_installed:bool -> string -> (string * file_type) list; + ph_get_file_from_package : ?use_installed:bool -> string -> string -> string } and file_type = { ft_dir : bool; diff --git a/src/febootstrap_package_handlers.mli b/src/febootstrap_package_handlers.mli index c28d81f..ebf0386 100644 --- a/src/febootstrap_package_handlers.mli +++ b/src/febootstrap_package_handlers.mli @@ -31,11 +31,11 @@ type package_handler = { Note this should also process the [excludes] list. *) - ph_list_files : string -> (string * file_type) list; + ph_list_files : ?use_installed:bool -> string -> (string * file_type) list; (** [ph_list_files pkg] lists the files and file metadata in the package called [pkg] (a package file). *) - ph_get_file_from_package : string -> string -> string; + ph_get_file_from_package : ?use_installed:bool -> string -> string -> string; (** [ph_get_file_from_package pkg file] extracts the single named file [file] from [pkg]. The path of the extracted file is returned. *) diff --git a/src/febootstrap_pacman.ml b/src/febootstrap_pacman.ml index 6691ebe..657f4d7 100644 --- a/src/febootstrap_pacman.ml +++ b/src/febootstrap_pacman.ml @@ -71,7 +71,10 @@ let pacman_resolve_dependencies_and_download names = List.sort compare pkgs -let pacman_list_files pkg = +let pacman_list_files ?(use_installed=false) pkg = + if use_installed then + failwith "pacman driver doesn't support --use-installed"; + debug "unpacking %s ..." pkg; (* We actually need to extract the file in order to get the @@ -117,7 +120,10 @@ let pacman_list_files pkg = files (* Easy because we already unpacked the archive above. *) -let pacman_get_file_from_package pkg file = +let pacman_get_file_from_package ?(use_installed=false) pkg file = + if use_installed then + failwith "pacman driver doesn't support --use-installed"; + tmpdir // pkg ^ ".d" // file let () = diff --git a/src/febootstrap_yum_rpm.ml b/src/febootstrap_yum_rpm.ml index 028492a..815c5ba 100644 --- a/src/febootstrap_yum_rpm.ml +++ b/src/febootstrap_yum_rpm.ml @@ -172,7 +172,10 @@ if verbose: sprintf "%s/%s-%s-%s.%s.rpm" tmpdir name version release arch ) pkgs -let rec yum_rpm_list_files pkg = +let rec yum_rpm_list_files ?(use_installed=false) pkg = + if use_installed then + failwith "yum_rpm driver doesn't support --use-installed"; + (* Run rpm -qlp with some extra magic. *) let cmd = sprintf "rpm -q --qf '[%%{FILENAMES} %%{FILEFLAGS:fflags} %%{FILEMODES} %%{FILESIZES}\\n]' -p %s" @@ -228,7 +231,10 @@ let rec yum_rpm_list_files pkg = files -let yum_rpm_get_file_from_package pkg file = +let yum_rpm_get_file_from_package ?(use_installed=false) pkg file = + if use_installed then + failwith "yum_rpm driver doesn't support --use-installed"; + debug "extracting %s from %s ..." file (Filename.basename pkg); let outfile = tmpdir // file in -- 1.8.3.1 From e576d2ec46adefa14b2d9c3d51e7f19a7810f909 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Fri, 23 Sep 2011 11:25:27 +0100 Subject: [PATCH 13/16] Use ext2fs_close2 API if available to avoid unnecessary fsync. This saves over 5 seconds during the slow path construction of the appliance. The ext2fs_close2 API is present in the e2fsprogs 'next' branch and will be in a later e2fsprogs release (thanks Ted Ts'o). --- configure.ac | 1 + helper/ext2.c | 10 +++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index a75a581..23c876b 100644 --- a/configure.ac +++ b/configure.ac @@ -105,6 +105,7 @@ old_LIBS="$LIBS" AC_CHECK_LIB([ext2fs],[ext2fs_file_open2],[],[ AC_MSG_FAILURE([libext2fs library not found (part of e2fsprogs)]) ]) +AC_CHECK_FUNCS([ext2fs_close2]) LIBS="$old_LIBS" AC_CHECK_HEADER([ext2fs/ext2fs.h],[],[ diff --git a/helper/ext2.c b/helper/ext2.c index 2395871..56ad5e5 100644 --- a/helper/ext2.c +++ b/helper/ext2.c @@ -107,8 +107,16 @@ ext2_start (const char *hostcpu, const char *appliance, static void ext2_end (void) { + if (verbose) + print_timestamped_message ("closing ext2 filesystem"); + /* Write out changes and close. */ - errcode_t err = ext2fs_close (fs); + errcode_t err; +#ifdef HAVE_EXT2FS_CLOSE2 + err = ext2fs_close2 (fs, EXT2_FLAG_FLUSH_NO_SYNC); +#else + err = ext2fs_close (fs); +#endif if (err != 0) error (EXIT_FAILURE, 0, "ext2fs_close: %s", error_message (err)); } -- 1.8.3.1 From 6d9051df32b90c6a4fe6ca1ff9e771b7dfe004fa Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Thu, 6 Oct 2011 13:50:45 +0100 Subject: [PATCH 14/16] helper: Improve error message when run on random files (thanks Alexey Torkhov). --- helper/appliance.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/helper/appliance.c b/helper/appliance.c index b2cc840..c4d0b32 100644 --- a/helper/appliance.c +++ b/helper/appliance.c @@ -284,7 +284,9 @@ add_hostfiles (const char *hostfiles_file, struct writer *writer) if (strchr (hostfile, '*') || strchr (hostfile, '?')) { char *dirname = xstrdup (hostfile); char *patt = strrchr (dirname, '/'); - assert (patt); + if (!patt) + error (EXIT_FAILURE, 0, "%s: line %zu: invalid pattern\n(is this file a supermin appliance hostfiles file?)", + hostfiles_file, i+1); *patt++ = '\0'; char **files = read_dir (dirname); -- 1.8.3.1 From 359718fa6c7ff177ef3413552f57a174d7205102 Mon Sep 17 00:00:00 2001 From: Erik Nolte Date: Thu, 6 Oct 2011 14:29:54 -0600 Subject: [PATCH 15/16] Checkout gnulib if the directory is empty. --- autogen.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/autogen.sh b/autogen.sh index 0afb7ed..fce31bb 100755 --- a/autogen.sh +++ b/autogen.sh @@ -1,5 +1,10 @@ #!/bin/sh - +if [ -z "$(ls gnulib 2>/dev/null)" ] +then + git clone git://git.savannah.gnu.org/gnulib.git +fi + ./gnulib/gnulib-tool --update export AUTOMAKE='automake --foreign --add-missing' -- 1.8.3.1 From a98be5ba1deea4f0b46eb4273ea278e3e0eb87ea Mon Sep 17 00:00:00 2001 From: Erik Nolte Date: Thu, 6 Oct 2011 14:31:37 -0600 Subject: [PATCH 16/16] helper/init: Handle compressed modules transparently. Detect libz and, if present, define HAS_LIBZ and add -lz to Makefile's LIBS variable. Add entry on optional zlib package requirement. Detect both uncompressed and gzipped kernel modules. Some Linux distros (like ArchLinux) use gzipped kernel modules with filenames like ext2.ko.gz. This change modifies the filename pattern from (e.g.) "ext2.ko" to "ext2.ko*". When available, use libz to read the module. The init_module system call requires uncompressed kernel module bytes. On some systems (e.g. ArchLinux) the modules are gzipped on disk. Libz is used to read and uncompress gzipped disk files (*.ko.gz) or transparently read uncompressed modules (*.ko). --- README | 2 ++ configure.ac | 3 +++ helper/ext2initrd.c | 30 +++++++++++++++--------------- helper/init.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++----- 4 files changed, 66 insertions(+), 20 deletions(-) diff --git a/README b/README index 99c4d36..2c42b2e 100644 --- a/README +++ b/README @@ -59,6 +59,8 @@ are building: qemu >= 0.13 kernel >= 2.6.36 + zlib - if your kernel uses gzipped modules + Building and installing ----------------------- diff --git a/configure.ac b/configure.ac index 23c876b..dca5032 100644 --- a/configure.ac +++ b/configure.ac @@ -86,6 +86,9 @@ AC_SUBST([APT_CACHE_DEPENDS_RECURSE_BROKEN]) dnl For ArchLinux handler. AC_CHECK_PROG(PACMAN,[pacman],[pacman],[no]) +dnl Support for gzipped kernel modules. +AC_CHECK_LIB([z],[gzopen]) + dnl Required programs, libraries. AC_PATH_PROG([MKE2FS],[mke2fs],[no], [$PATH$PATH_SEPARATOR/sbin$PATH_SEPARATOR]) diff --git a/helper/ext2initrd.c b/helper/ext2initrd.c index c4fc353..bb00c72 100644 --- a/helper/ext2initrd.c +++ b/helper/ext2initrd.c @@ -52,21 +52,21 @@ extern char _binary_init_start, _binary_init_end, _binary_init_size; * ext2 filesystem on it. */ static const char *kmods[] = { - "ext2.ko", - "ext4.ko", /* CONFIG_EXT4_USE_FOR_EXT23=y option might be set */ - "virtio*.ko", - "ide*.ko", - "libata*.ko", - "piix*.ko", - "scsi_transport_spi.ko", - "scsi_mod.ko", - "sd_mod.ko", - "sym53c8xx.ko", - "ata_piix.ko", - "sr_mod.ko", - "mbcache.ko", - "crc*.ko", - "libcrc*.ko", + "ext2.ko*", + "ext4.ko*", /* CONFIG_EXT4_USE_FOR_EXT23=y option might be set */ + "virtio*.ko*", + "ide*.ko*", + "libata*.ko*", + "piix*.ko*", + "scsi_transport_spi.ko*", + "scsi_mod.ko*", + "sd_mod.ko*", + "sym53c8xx.ko*", + "ata_piix.ko*", + "sr_mod.ko*", + "mbcache.ko*", + "crc*.ko*", + "libcrc*.ko*", NULL }; diff --git a/helper/init.c b/helper/init.c index 34a8450..447df8e 100644 --- a/helper/init.c +++ b/helper/init.c @@ -38,6 +38,10 @@ #include +#ifdef HAVE_LIBZ +#include +#endif + extern long init_module (void *, unsigned long, const char *); /* translation taken from module-init-tools/insmod.c */ @@ -201,9 +205,40 @@ main () static void insmod (const char *filename) { + size_t size; + if (verbose) fprintf (stderr, "febootstrap: internal insmod %s\n", filename); +#ifdef HAVE_LIBZ + gzFile gzfp = gzopen (filename, "rb"); + int capacity = 64*1024; + char *buf = (char *) malloc (capacity); + int tmpsize = 8 * 1024; + char tmp[tmpsize]; + int num; + + size = 0; + + if (gzfp == NULL) { + fprintf (stderr, "insmod: gzopen failed: %s", filename); + exit (EXIT_FAILURE); + } + while ((num = gzread (gzfp, tmp, tmpsize)) > 0) { + if (num > capacity) { + buf = (char*) realloc (buf, size*2); + capacity = size; + } + memcpy (buf+size, tmp, num); + capacity -= num; + size += num; + } + if (num == -1) { + perror ("insmod: gzread"); + exit (EXIT_FAILURE); + } + gzclose (gzfp); +#else int fd = open (filename, O_RDONLY); if (fd == -1) { fprintf (stderr, "insmod: open: %s: %m\n", filename); @@ -214,24 +249,30 @@ insmod (const char *filename) perror ("insmod: fstat"); exit (EXIT_FAILURE); } - char buf[st.st_size]; - long offset = 0; + size = st.st_size; + char buf[size]; + size_t offset = 0; do { - long rc = read (fd, buf + offset, st.st_size - offset); + ssize_t rc = read (fd, buf + offset, size - offset); if (rc == -1) { perror ("insmod: read"); exit (EXIT_FAILURE); } offset += rc; - } while (offset < st.st_size); + } while (offset < size); close (fd); +#endif - if (init_module (buf, st.st_size, "") != 0) { + if (init_module (buf, size, "") != 0) { fprintf (stderr, "insmod: init_module: %s: %s\n", filename, moderror (errno)); /* However ignore the error because this can just happen because * of a missing device. */ } + +#ifdef HAVE_LIBZ + free (buf); +#endif } /* Mount /proc unless it's mounted already. */ -- 1.8.3.1