Richard W.M. Jones
2015-Oct-29 15:02 UTC
[Libguestfs] [PATCH 00/16] Refactoring of configure.ac and guestfs.pod
Two (not related to each other) refactorings: Patches 1-12 split configure.ac into smaller files using the m4_include mechanism. Patches 13-15 split out parts of guestfs.pod (ie. guestfs(3)) into three new manual pages: guestfs-hacking(3) - how to extend and contribute to libguestfs guestfs-internals(3) - architecture and internals guestfs-security(3) - security and CVEs Patch 16 is a minor tidy up of guestfs.pod. Rich.
Richard W.M. Jones
2015-Oct-29 15:02 UTC
[Libguestfs] [PATCH 01/16] configure: Move language binding detection to separate files.
The extra files don't have to be added to EXTRA_DIST, as it appears that autotools already knows that it has to add them. --- configure.ac | 560 ++------------------------------------------------ m4/guestfs_erlang.m4 | 35 ++++ m4/guestfs_gobject.m4 | 68 ++++++ m4/guestfs_golang.m4 | 44 ++++ m4/guestfs_haskell.m4 | 28 +++ m4/guestfs_java.m4 | 174 ++++++++++++++++ m4/guestfs_lua.m4 | 47 +++++ m4/guestfs_ocaml.m4 | 104 ++++++++++ m4/guestfs_perl.m4 | 41 ++++ m4/guestfs_php.m4 | 29 +++ m4/guestfs_python.m4 | 104 ++++++++++ m4/guestfs_ruby.m4 | 51 +++++ 12 files changed, 737 insertions(+), 548 deletions(-) create mode 100644 m4/guestfs_erlang.m4 create mode 100644 m4/guestfs_gobject.m4 create mode 100644 m4/guestfs_golang.m4 create mode 100644 m4/guestfs_haskell.m4 create mode 100644 m4/guestfs_java.m4 create mode 100644 m4/guestfs_lua.m4 create mode 100644 m4/guestfs_ocaml.m4 create mode 100644 m4/guestfs_perl.m4 create mode 100644 m4/guestfs_php.m4 create mode 100644 m4/guestfs_python.m4 create mode 100644 m4/guestfs_ruby.m4 diff --git a/configure.ac b/configure.ac index 637f2f1..5a3ba96 100644 --- a/configure.ac +++ b/configure.ac @@ -1081,502 +1081,18 @@ AS_IF([test "x$VALGRIND" != "xno"],[ AC_SUBST([VG]) AM_SUBST_NOTMAKE([VG]) -dnl Check for OCaml (optional, for OCaml bindings and OCaml tools). -OCAMLC=no -OCAMLFIND=no -AC_ARG_ENABLE([ocaml], - AS_HELP_STRING([--disable-ocaml], [disable OCaml language bindings]), - [], - [enable_ocaml=yes]) -AS_IF([test "x$enable_ocaml" != "xno"],[ - dnl OCAMLC and OCAMLFIND have to be unset first, otherwise - dnl AC_CHECK_TOOL (inside AC_PROG_OCAML) will not look. - OCAMLC- OCAMLFIND- AC_PROG_OCAML - AC_PROG_FINDLIB - - dnl OCaml >= 3.11 is required. - AC_MSG_CHECKING([if OCaml version >= 3.11]) - ocaml_major="`echo $OCAMLVERSION | $AWK -F. '{print $1}'`" - ocaml_minor="`echo $OCAMLVERSION | $AWK -F. '{print $2}'`" - AS_IF([test "$ocaml_major" -ge 4 || ( test "$ocaml_major" -eq 3 && test "$ocaml_minor" -ge 11 )],[ - AC_MSG_RESULT([yes]) - ],[ - AC_MSG_RESULT([no]) - AC_MSG_FAILURE([OCaml compiler is not new enough. At least OCaml 3.11 is required]) - ]) -]) -AM_CONDITIONAL([HAVE_OCAML], - [test "x$OCAMLC" != "xno" && test "x$OCAMLFIND" != "xno"]) -AM_CONDITIONAL([HAVE_OCAMLOPT], - [test "x$OCAMLOPT" != "xno" && test "x$OCAMLFIND" != "xno"]) -AM_CONDITIONAL([HAVE_OCAMLDOC], - [test "x$OCAMLDOC" != "xno"]) - -dnl OCaml is required if we need to run the generator. -AS_IF([test "x$OCAMLC" = "xno" || test "x$OCAMLFIND" = "xno"],[ - AS_IF([! test -f $srcdir/src/guestfs_protocol.x],[ - AC_MSG_FAILURE([OCaml compiler and findlib is required to build from git. -If you don't have OCaml available, you should build from a tarball from -http://libguestfs.org/download]) - ]) -]) - -AS_IF([test "x$OCAMLC" != "xno"],[ - dnl Check for <caml/unixsupport.h> header. - old_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I`$OCAMLC -where`" - AC_CHECK_HEADERS([caml/unixsupport.h],[],[],[#include <caml/mlvalues.h>]) - CPPFLAGS="$old_CPPFLAGS" -]) - -OCAML_PKG_gettext=no -OCAML_PKG_libvirt=no -OCAML_PKG_oUnit=no -ounit_is_v2=no -AS_IF([test "x$OCAMLC" != "xno"],[ - # Create mllib/common_gettext.ml, gettext functions or stubs. - - # If we're building in a different directory, then mllib/ might - # not exist yet, so create it: - mkdir -p mllib - - GUESTFS_CREATE_COMMON_GETTEXT_ML([mllib/common_gettext.ml]) - - AC_CHECK_OCAML_PKG(libvirt) - AC_CHECK_OCAML_PKG(oUnit) - - # oUnit >= 2 is required, so check that it has OUnit2. - if test "x$OCAML_PKG_oUnit" != "xno"; then - AC_CHECK_OCAML_MODULE(ounit_is_v2,[OUnit.OUnit2],OUnit2,[+oUnit]) - fi -]) -AM_CONDITIONAL([HAVE_OCAML_PKG_GETTEXT], - [test "x$OCAMLC" != "xno" && test "x$OCAMLFIND" != "xno" && test "x$OCAML_PKG_gettext" != "xno"]) -AM_CONDITIONAL([HAVE_OCAML_PKG_LIBVIRT], - [test "x$OCAMLC" != "xno" && test "x$OCAMLFIND" != "xno" && test "x$OCAML_PKG_libvirt" != "xno"]) -AM_CONDITIONAL([HAVE_OCAML_PKG_OUNIT], - [test "x$OCAMLC" != "xno" && test "x$OCAMLFIND" != "xno" && test "x$OCAML_PKG_oUnit" != "xno" && test "x$ounit_is_v2" != "xno"]) - -AC_CHECK_PROG([OCAML_GETTEXT],[ocaml-gettext],[ocaml-gettext],[no]) -AM_CONDITIONAL([HAVE_OCAML_GETTEXT], - [test "x$OCAMLC" != "xno" && test "x$OCAMLFIND" != "xno" && test "x$OCAML_PKG_gettext" != "xno" && test "x$OCAML_GETTEXT" != "xno"]) - -dnl Flags we want to pass to every OCaml compiler call. -OCAML_WARN_ERROR="-warn-error CDEFLMPSUVYZX-3" -AC_SUBST([OCAML_WARN_ERROR]) -OCAML_FLAGS="-g -annot" -AC_SUBST([OCAML_FLAGS]) - -dnl Check for Perl (optional, for Perl bindings and Perl tools). -AC_ARG_ENABLE([perl], - AS_HELP_STRING([--disable-perl], [disable Perl language bindings]), - [], - [enable_perl=yes]) -AS_IF([test "x$enable_perl" != "xno"],[ - dnl Check for Perl modules that must be present to compile and - dnl test the Perl bindings. - missing_perl_modules=no - for pm in Test::More Module::Build; do - AC_MSG_CHECKING([for $pm]) - if ! $PERL -M$pm -e1 >&AS_MESSAGE_LOG_FD 2>&1; then - AC_MSG_RESULT([no]) - missing_perl_modules=yes - else - AC_MSG_RESULT([yes]) - fi - done - if test "x$missing_perl_modules" = "xyes"; then - AC_MSG_WARN([some Perl modules required to compile or test the Perl bindings are missing]) - fi -]) -AM_CONDITIONAL([HAVE_PERL], - [test "x$enable_perl" != "xno" && test "x$PERL" != "xno" && test "x$missing_perl_modules" != "xyes"]) - -dnl Check for Python (optional, for Python bindings). -PYTHON_PREFIX-PYTHON_VERSION-PYTHON_INSTALLDIR- -AC_ARG_ENABLE([python], - AS_HELP_STRING([--disable-python], [disable Python language bindings]), - [], - [enable_python=yes]) -AS_IF([test "x$enable_python" != "xno"],[ - AC_CHECK_PROG([PYTHON],[python],[python],[no]) - - if test "x$PYTHON" != "xno"; then - AC_MSG_CHECKING([Python version]) - PYTHON_VERSION_MAJOR=`$PYTHON -c "import sys; print (sys.version_info@<:@0@:>@)"` - PYTHON_VERSION_MINOR=`$PYTHON -c "import sys; print (sys.version_info@<:@1@:>@)"` - PYTHON_VERSION="$PYTHON_VERSION_MAJOR.$PYTHON_VERSION_MINOR" - AC_MSG_RESULT([$PYTHON_VERSION]) - # Debian: python-2.7.pc, python-3.2.pc - PKG_CHECK_MODULES([PYTHON], [python-"$PYTHON_VERSION"],[ - AC_SUBST([PYTHON_CFLAGS]) - AC_SUBST([PYTHON_LIBS]) - AC_SUBST([PYTHON_VERSION]) - AC_DEFINE([HAVE_PYTHON],[1],[Python library found at compile time]) - ],[ - PKG_CHECK_MODULES([PYTHON], [python],[ - AC_SUBST([PYTHON_CFLAGS]) - AC_SUBST([PYTHON_LIBS]) - AC_SUBST([PYTHON_VERSION]) - AC_DEFINE([HAVE_PYTHON],[1],[Python library found at compile time]) - ],[ - AC_MSG_WARN([python $PYTHON_VERSION not found]) - ]) - ]) - AC_MSG_CHECKING([Python prefix]) - PYTHON_PREFIX=`$PYTHON -c "import sys; print (sys.prefix)"` - AC_MSG_RESULT([$PYTHON_PREFIX]) - - AC_ARG_WITH([python-installdir], - [AS_HELP_STRING([--with-python-installdir], - [directory to install python modules @<:@default=check@:>@])], - [PYTHON_INSTALLDIR="$withval" - AC_MSG_NOTICE([Python install dir $PYTHON_INSTALLDIR])], - [PYTHON_INSTALLDIR=check]) - - if test "x$PYTHON_INSTALLDIR" = "xcheck"; then - PYTHON_INSTALLDIR- AC_MSG_CHECKING([for Python site-packages path]) - if test -z "$PYTHON_INSTALLDIR"; then - PYTHON_INSTALLDIR=`$PYTHON -c "import distutils.sysconfig; \ - print (distutils.sysconfig.get_python_lib(1,0));"` - fi - AC_MSG_RESULT([$PYTHON_INSTALLDIR]) - fi - - AC_MSG_CHECKING([for Python extension suffix (PEP-3149)]) - if test -z "$PYTHON_EXT_SUFFIX"; then - python_ext_suffix=`$PYTHON -c "import distutils.sysconfig; \ - print (distutils.sysconfig.get_config_var('EXT_SUFFIX') or distutils.sysconfig.get_config_var('SO'))"` - PYTHON_EXT_SUFFIX=$python_ext_suffix - fi - AC_MSG_RESULT([$PYTHON_EXT_SUFFIX]) - - dnl Look for some optional symbols in libpython. - old_LIBS="$LIBS" - - PYTHON_BLDLIBRARY=`$PYTHON -c "import distutils.sysconfig; \ - print (distutils.sysconfig.get_config_var('BLDLIBRARY'))"` - AC_CHECK_LIB([c],[PyCapsule_New], - [AC_DEFINE([HAVE_PYCAPSULE_NEW],1, - [Found PyCapsule_New in libpython.])], - [],[$PYTHON_BLDLIBRARY]) - AC_CHECK_LIB([c],[PyString_AsString], - [AC_DEFINE([HAVE_PYSTRING_ASSTRING],1, - [Found PyString_AsString in libpython.])], - [],[$PYTHON_BLDLIBRARY]) - - LIBS="$old_LIBS" - fi - - AC_SUBST(PYTHON_PREFIX) - AC_SUBST(PYTHON_VERSION) - AC_SUBST(PYTHON_INSTALLDIR) - AC_SUBST(PYTHON_EXT_SUFFIX) -]) -AM_CONDITIONAL([HAVE_PYTHON], - [test "x$PYTHON" != "xno" && test "x$PYTHON_LIBS" != "x" ]) - -dnl Check for Ruby and rake (optional, for Ruby bindings). -AC_ARG_ENABLE([ruby], - AS_HELP_STRING([--disable-ruby], [disable Ruby language bindings]), - [], - [enable_ruby=yes]) -AS_IF([test "x$enable_ruby" != "xno"],[ - AC_CHECK_PROG([RUBY],[ruby],[ruby],[no]) - AC_CHECK_PROG([RAKE],[rake],[rake],[no]) - - AS_IF([test -n "$RUBY" && test -n "$RAKE"],[ - dnl Find the library. Note on Debian it's not -lruby. - AC_MSG_CHECKING([for C library for Ruby extensions]) - ruby_cmd='puts RbConfig::CONFIG@<:@"RUBY_SO_NAME"@:>@' - echo running: $RUBY -rrbconfig -e \'$ruby_cmd\' >&AS_MESSAGE_LOG_FD - $RUBY -rrbconfig -e "$ruby_cmd" >conftest 2>&AS_MESSAGE_LOG_FD - libruby="$(cat conftest)" - rm conftest - AS_IF([test -n "$libruby"],[ - ruby_cmd='puts RbConfig::CONFIG@<:@"libdir"@:>@' - echo running: $RUBY -rrbconfig -e \'$ruby_cmd\' >&AS_MESSAGE_LOG_FD - $RUBY -rrbconfig -e "$ruby_cmd" >conftest 2>&AS_MESSAGE_LOG_FD - libruby_libdir="$(cat conftest)" - rm conftest - test -n "$libruby_libdir" && libruby_libdir="-L$libruby_libdir" - AC_MSG_RESULT([-l$libruby]) - AC_CHECK_LIB([$libruby],[ruby_init], - [have_libruby=1],[have_libruby=],[$libruby_libdir]) - ],[ - AC_MSG_RESULT([not found]) - ]) - ]) -]) -AM_CONDITIONAL([HAVE_RUBY], - [test -n "$RUBY" && test -n "$RAKE" && test -n "$have_libruby"]) - -dnl Check for Java. -AC_ARG_WITH(java, - [AS_HELP_STRING([--with-java], - [specify path to JDK directory (for the Java language bindings) @<:@default=check@:>@])], - [], - [with_java=check]) - -if test "x$with_java" != "xno"; then - if test "x$with_java" != "xyes" && test "x$with_java" != "xcheck" - then - # Reject unsafe characters in $JAVA - jh_lf=' -' - case $JAVA in - *[\\\"\#\$\&\'\`$jh_lf\ \ ]*) - AC_MSG_FAILURE([unsafe \$JAVA directory (use --without-java to disable Java support)]);; - esac - if test -d "$with_java"; then - JAVA="$with_java" - else - AC_MSG_FAILURE([$with_java is not a directory (use --without-java to disable Java support)]) - fi - fi - - if test "x$JAVA" = "x"; then - # Look for Java in some likely locations. - for d in \ - /usr/lib/jvm/java \ - /usr/lib64/jvm/java \ - /usr/lib/jvm/default-java \ - /usr/lib/jvm/default \ - /usr/lib/jvm/java-8-openjdk \ - /usr/lib/jvm/java-7-openjdk \ - /usr/lib/jvm/java-6-openjdk - do - if test -d $d && test -f $d/bin/java; then - JAVA=$d - break - fi - done - fi - - if test "x$JAVA" != "x"; then - AC_MSG_CHECKING(for JDK in $JAVA) - if test ! -x "$JAVA/bin/java"; then - AC_MSG_ERROR([missing $JAVA/bin/java binary (use --without-java to disable Java support)]) - else - JAVA_EXE="$JAVA/bin/java" - fi - if test ! -x "$JAVA/bin/javac"; then - AC_MSG_ERROR([missing $JAVA/bin/javac binary]) - else - JAVAC="$JAVA/bin/javac" - fi - if test ! -x "$JAVA/bin/javah"; then - AC_MSG_ERROR([missing $JAVA/bin/javah binary]) - else - JAVAH="$JAVA/bin/javah" - fi - if test ! -x "$JAVA/bin/javadoc"; then - AC_MSG_ERROR([missing $JAVA/bin/javadoc binary]) - else - JAVADOC="$JAVA/bin/javadoc" - fi - if test ! -x "$JAVA/bin/jar"; then - AC_MSG_ERROR([missing $JAVA/bin/jar binary]) - else - JAR="$JAVA/bin/jar" - fi - java_version=`$JAVA_EXE -version 2>&1 | grep "java version"` - AC_MSG_RESULT(found $java_version in $JAVA) - - dnl Find jni.h. - AC_MSG_CHECKING([for jni.h]) - if test -f "$JAVA/include/jni.h"; then - JNI_CFLAGS="-I$JAVA/include" - else - if test "`find $JAVA -name jni.h`" != ""; then - head=`find $JAVA -name jni.h | tail -1` - dir=`dirname "$head"` - JNI_CFLAGS="-I$dir" - else - AC_MSG_FAILURE([missing jni.h header file]) - fi - fi - AC_MSG_RESULT([$JNI_CFLAGS]) - - dnl Find jni_md.h. - AC_MSG_CHECKING([for jni_md.h]) - case "$build_os" in - *linux*) system="linux" ;; - *SunOS*) system="solaris" ;; - *cygwin*) system="win32" ;; - *) system="$build_os" ;; - esac - if test -f "$JAVA/include/$system/jni_md.h"; then - JNI_CFLAGS="$JNI_CFLAGS -I$JAVA/include/$system" - else - if test "`find $JAVA -name jni_md.h`" != ""; then - head=`find $JAVA -name jni_md.h | tail -1` - dir=`dirname "$head"` - JNI_CFLAGS="$JNI_CFLAGS -I$dir" - else - AC_MSG_FAILURE([missing jni_md.h header file]) - fi - fi - AC_MSG_RESULT([$JNI_CFLAGS]) - - dnl Need extra version flag? - AC_MSG_CHECKING([extra javac flags]) - EXTRA_JAVAC_FLAGS- javac_version=`$JAVAC -version 2>&1` - case "$javac_version" in - *Eclipse*) - EXTRA_JAVAC_FLAGS="-source 1.5" ;; - esac - AC_MSG_RESULT([$EXTRA_JAVAC_FLAGS]) - - dnl Extra lint flags? - AC_MSG_CHECKING([extra javac lint flags]) - if $JAVAC -X >/dev/null 2>&1 && \ - $JAVAC -X 2>&1 | grep -q -- '-Xlint:.*all'; then - AC_MSG_RESULT([-Xlint:all]) - EXTRA_JAVAC_FLAGS="$EXTRA_JAVAC_FLAGS -Xlint:all" - else - AC_MSG_RESULT([no]) - fi - - dnl Where to install jarfiles, jnifiles - if test -z $JAR_INSTALL_DIR; then - JAR_INSTALL_DIR=\${prefix}/share/java - fi - if test -z $JNI_INSTALL_DIR; then - JNI_INSTALL_DIR=\${libdir} - fi - - dnl JNI version. - jni_major_version=`echo "$VERSION" | $AWK -F. '{print $1}'` - jni_minor_version=`echo "$VERSION" | $AWK -F. '{print $2}'` - jni_micro_version=`echo "$VERSION" | $AWK -F. '{print $3}'` - JNI_VERSION_INFO=`expr "$jni_major_version" + "$jni_minor_version"`":$jni_micro_version:$jni_minor_version" - fi - - AC_SUBST(JAVA) - AC_SUBST(JAVA_EXE) - AC_SUBST(JAVAC) - AC_SUBST(JAVAH) - AC_SUBST(JAVADOC) - AC_SUBST(JAR) - AC_SUBST(JNI_CFLAGS) - AC_SUBST(EXTRA_JAVAC_FLAGS) - AC_SUBST(JAR_INSTALL_DIR) - AC_SUBST(JNI_INSTALL_DIR) - AC_SUBST(JNI_VERSION_INFO) -fi - -AM_CONDITIONAL([HAVE_JAVA],[test "x$with_java" != "xno" && test -n "$JAVAC"]) - -dnl Check for Haskell (GHC). -GHC=no -AC_ARG_ENABLE([haskell], - AS_HELP_STRING([--disable-haskell], [disable Haskell language bindings]), - [], - [enable_haskell=yes]) -AS_IF([test "x$enable_haskell" != "xno"],[ - GHC- AC_CHECK_PROG([GHC],[ghc],[ghc],[no]) -]) -AM_CONDITIONAL([HAVE_HASKELL],[test "x$GHC" != "xno"]) - -dnl PHP -PHP=no -AC_ARG_ENABLE([php], - AS_HELP_STRING([--disable-php], [disable PHP language bindings]), - [], - [enable_php=yes]) -AS_IF([test "x$enable_php" != "xno"],[ - PHP- AC_CHECK_PROG([PHP],[php],[php],[no]) - AC_CHECK_PROG([PHPIZE],[phpize],[phpize],[no]) -]) -AM_CONDITIONAL([HAVE_PHP], [test "x$PHP" != "xno" && test "x$PHPIZE" != "xno"]) - -dnl Erlang -ERLANG=no -AC_ARG_ENABLE([erlang], - AS_HELP_STRING([--disable-erlang], [disable Erlang language bindings]), - [], - [enable_erlang=yes]) -# NB: Don't use AS_IF here: it doesn't work. -if test "x$enable_erlang" != "xno"; then - ERLANG- AC_ERLANG_PATH_ERLC([no]) - - if test "x$ERLC" != "xno"; then - AC_ERLANG_CHECK_LIB([erl_interface], [], - [AC_MSG_FAILURE([Erlang erl_interface library not installed. Use --disable-erlang to disable.])]) - AC_ERLANG_SUBST_LIB_DIR - fi -fi -AM_CONDITIONAL([HAVE_ERLANG], [test "x$ERLANG" != "xno" && test "x$ERLC" != "xno"]) - -dnl Lua -AC_ARG_ENABLE([lua], - AS_HELP_STRING([--disable-lua], [disable Lua language bindings]), - [], - [enable_lua=yes]) -AS_IF([test "x$enable_lua" != "xno"],[ - AC_CHECK_PROG([LUA],[lua],[lua],[no]) - AS_IF([test "x$LUA" != "xno"],[ - AC_MSG_CHECKING([for Lua version]) - LUA_VERSION=`$LUA -e 'print(_VERSION)' | $AWK '{print $2}'` - AC_MSG_RESULT([$LUA_VERSION]) - dnl On Debian it's 'lua5.1', 'lua5.2' etc. On Fedora, just 'lua'. - PKG_CHECK_MODULES([LUA], [lua$LUA_VERSION],[ - AC_SUBST([LUA_CFLAGS]) - AC_SUBST([LUA_LIBS]) - AC_SUBST([LUA_VERSION]) - AC_DEFINE([HAVE_LUA],[1],[Lua library found at compile time]) - ],[ - PKG_CHECK_MODULES([LUA], [lua],[ - AC_SUBST([LUA_CFLAGS]) - AC_SUBST([LUA_LIBS]) - AC_SUBST([LUA_VERSION]) - AC_DEFINE([HAVE_LUA],[1],[Lua library found at compile time]) - ],[ - AC_MSG_WARN([lua $LUA_VERSION not found]) - ]) - ]) - ]) -]) -AM_CONDITIONAL([HAVE_LUA],[test "x$LUA_LIBS" != "x"]) - -dnl Golang -AC_ARG_ENABLE([golang], - AS_HELP_STRING([--disable-golang], [disable Go language bindings]), - [], - [enable_golang=yes]) -AS_IF([test "x$enable_golang" != "xno"],[ - AC_CHECK_PROG([GOLANG],[go],[go],[no]) - AS_IF([test "x$GOLANG" != "xno"],[ - AC_MSG_CHECKING([if $GOLANG is usable]) - AS_IF([$GOLANG run $srcdir/golang/config-test.go 2>&AS_MESSAGE_LOG_FD],[ - AC_MSG_RESULT([yes]) - - # Substitute some golang environment. - GOOS=`$GOLANG env GOOS` - GOARCH=`$GOLANG env GOARCH` - GOROOT=`$GOLANG env GOROOT` - AC_SUBST([GOOS]) - AC_SUBST([GOARCH]) - AC_SUBST([GOROOT]) - ],[ - AC_MSG_RESULT([no]) - AC_MSG_WARN([golang ($GOLANG) is installed but not usable]) - GOLANG=no - ]) - ]) -],[GOLANG=no]) -AM_CONDITIONAL([HAVE_GOLANG],[test "x$GOLANG" != "xno"]) +dnl Check for language bindings. +m4_include([m4/guestfs_ocaml.m4]) +m4_include([m4/guestfs_perl.m4]) +m4_include([m4/guestfs_python.m4]) +m4_include([m4/guestfs_ruby.m4]) +m4_include([m4/guestfs_java.m4]) +m4_include([m4/guestfs_haskell.m4]) +m4_include([m4/guestfs_php.m4]) +m4_include([m4/guestfs_erlang.m4]) +m4_include([m4/guestfs_lua.m4]) +m4_include([m4/guestfs_golang.m4]) +m4_include([m4/guestfs_gobject.m4]) dnl Check for Perl modules needed by Perl virt tools (virt-df, etc.) AS_IF([test "x$PERL" != "xno"],[ @@ -1598,58 +1114,6 @@ AS_IF([test "x$PERL" != "xno"],[ AM_CONDITIONAL([HAVE_TOOLS], [test "x$PERL" != "xno" && test "x$missing_perl_modules" != "xyes"]) -dnl gobject library -AC_ARG_ENABLE([gobject], - AS_HELP_STRING([--disable-gobject], [disable GObject bindings]), - [], - [enable_gobject=yes]) -AS_IF([test "x$enable_gobject" != "xno"],[ - PKG_CHECK_MODULES([GOBJECT], [gobject-2.0 >= 2.26.0],[ - AC_SUBST([GOBJECT_CFLAGS]) - AC_SUBST([GOBJECT_LIBS]) - AC_DEFINE([HAVE_GOBJECT],[1], - [GObject library found at compile time.]) - ], - [AC_MSG_WARN([gobject library not found, gobject binding will be disabled])]) - - PKG_CHECK_MODULES([GIO], [gio-2.0 >= 2.26.0],[ - AC_SUBST([GIO_CFLAGS]) - AC_SUBST([GIO_LIBS]) - AC_DEFINE([HAVE_GIO],[1], - [gio library found at compile time.]) - ], - [AC_MSG_WARN([gio library not found, gobject binding will be disabled])]) -]) -AM_CONDITIONAL([HAVE_GOBJECT], - [test "x$GOBJECT_LIBS" != "x" -a "x$GIO_LIBS" != "x"]) - -AC_CHECK_PROG([GJS],[gjs],[gjs]) -AS_IF([test "x$GJS" = "x"], - [AC_MSG_WARN([gjs not found, gobject bindtests will not run])]) - -dnl gobject introspection -m4_ifdef([GOBJECT_INTROSPECTION_CHECK], [ - GOBJECT_INTROSPECTION_CHECK([1.30.0]) - - dnl The above check automatically sets HAVE_INTROSPECTION, but we - dnl want this to be conditional on gobject also being - dnl available. We can't move the above check inside the gobject if - dnl block above or HAVE_INTROSPECTION ends up undefined, so we - dnl recheck it here. - AM_CONDITIONAL([HAVE_INTROSPECTION], - [test "x$HAVE_INTROSPECTION_TRUE" = "x" && - test "x$HAVE_GOBJECT_TRUE" = "x"]) -],[ - AM_CONDITIONAL([HAVE_INTROSPECTION], [false]) -]) - -# check for gtk-doc -m4_ifdef([GTK_DOC_CHECK], [ - GTK_DOC_CHECK([1.14],[--flavour no-tmpl]) -],[ - AM_CONDITIONAL([ENABLE_GTK_DOC], false) -]) - dnl Bash completion. PKG_CHECK_MODULES([BASH_COMPLETION], [bash-completion >= 2.0], [ bash_completion=yes diff --git a/m4/guestfs_erlang.m4 b/m4/guestfs_erlang.m4 new file mode 100644 index 0000000..018f391 --- /dev/null +++ b/m4/guestfs_erlang.m4 @@ -0,0 +1,35 @@ +# libguestfs +# Copyright (C) 2009-2015 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +dnl Erlang +ERLANG=no +AC_ARG_ENABLE([erlang], + AS_HELP_STRING([--disable-erlang], [disable Erlang language bindings]), + [], + [enable_erlang=yes]) +# NB: Don't use AS_IF here: it doesn't work. +if test "x$enable_erlang" != "xno"; then + ERLANG+ AC_ERLANG_PATH_ERLC([no]) + + if test "x$ERLC" != "xno"; then + AC_ERLANG_CHECK_LIB([erl_interface], [], + [AC_MSG_FAILURE([Erlang erl_interface library not installed. Use --disable-erlang to disable.])]) + AC_ERLANG_SUBST_LIB_DIR + fi +fi +AM_CONDITIONAL([HAVE_ERLANG], [test "x$ERLANG" != "xno" && test "x$ERLC" != "xno"]) diff --git a/m4/guestfs_gobject.m4 b/m4/guestfs_gobject.m4 new file mode 100644 index 0000000..a845b8d --- /dev/null +++ b/m4/guestfs_gobject.m4 @@ -0,0 +1,68 @@ +# libguestfs +# Copyright (C) 2009-2015 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +dnl gobject library +AC_ARG_ENABLE([gobject], + AS_HELP_STRING([--disable-gobject], [disable GObject bindings]), + [], + [enable_gobject=yes]) +AS_IF([test "x$enable_gobject" != "xno"],[ + PKG_CHECK_MODULES([GOBJECT], [gobject-2.0 >= 2.26.0],[ + AC_SUBST([GOBJECT_CFLAGS]) + AC_SUBST([GOBJECT_LIBS]) + AC_DEFINE([HAVE_GOBJECT],[1], + [GObject library found at compile time.]) + ], + [AC_MSG_WARN([gobject library not found, gobject binding will be disabled])]) + + PKG_CHECK_MODULES([GIO], [gio-2.0 >= 2.26.0],[ + AC_SUBST([GIO_CFLAGS]) + AC_SUBST([GIO_LIBS]) + AC_DEFINE([HAVE_GIO],[1], + [gio library found at compile time.]) + ], + [AC_MSG_WARN([gio library not found, gobject binding will be disabled])]) +]) +AM_CONDITIONAL([HAVE_GOBJECT], + [test "x$GOBJECT_LIBS" != "x" -a "x$GIO_LIBS" != "x"]) + +AC_CHECK_PROG([GJS],[gjs],[gjs]) +AS_IF([test "x$GJS" = "x"], + [AC_MSG_WARN([gjs not found, gobject bindtests will not run])]) + +dnl gobject introspection +m4_ifdef([GOBJECT_INTROSPECTION_CHECK], [ + GOBJECT_INTROSPECTION_CHECK([1.30.0]) + + dnl The above check automatically sets HAVE_INTROSPECTION, but we + dnl want this to be conditional on gobject also being + dnl available. We can't move the above check inside the gobject if + dnl block above or HAVE_INTROSPECTION ends up undefined, so we + dnl recheck it here. + AM_CONDITIONAL([HAVE_INTROSPECTION], + [test "x$HAVE_INTROSPECTION_TRUE" = "x" && + test "x$HAVE_GOBJECT_TRUE" = "x"]) +],[ + AM_CONDITIONAL([HAVE_INTROSPECTION], [false]) +]) + +# check for gtk-doc +m4_ifdef([GTK_DOC_CHECK], [ + GTK_DOC_CHECK([1.14],[--flavour no-tmpl]) +],[ + AM_CONDITIONAL([ENABLE_GTK_DOC], false) +]) diff --git a/m4/guestfs_golang.m4 b/m4/guestfs_golang.m4 new file mode 100644 index 0000000..961d982 --- /dev/null +++ b/m4/guestfs_golang.m4 @@ -0,0 +1,44 @@ +# libguestfs +# Copyright (C) 2009-2015 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +dnl Golang +AC_ARG_ENABLE([golang], + AS_HELP_STRING([--disable-golang], [disable Go language bindings]), + [], + [enable_golang=yes]) +AS_IF([test "x$enable_golang" != "xno"],[ + AC_CHECK_PROG([GOLANG],[go],[go],[no]) + AS_IF([test "x$GOLANG" != "xno"],[ + AC_MSG_CHECKING([if $GOLANG is usable]) + AS_IF([$GOLANG run $srcdir/golang/config-test.go 2>&AS_MESSAGE_LOG_FD],[ + AC_MSG_RESULT([yes]) + + # Substitute some golang environment. + GOOS=`$GOLANG env GOOS` + GOARCH=`$GOLANG env GOARCH` + GOROOT=`$GOLANG env GOROOT` + AC_SUBST([GOOS]) + AC_SUBST([GOARCH]) + AC_SUBST([GOROOT]) + ],[ + AC_MSG_RESULT([no]) + AC_MSG_WARN([golang ($GOLANG) is installed but not usable]) + GOLANG=no + ]) + ]) +],[GOLANG=no]) +AM_CONDITIONAL([HAVE_GOLANG],[test "x$GOLANG" != "xno"]) diff --git a/m4/guestfs_haskell.m4 b/m4/guestfs_haskell.m4 new file mode 100644 index 0000000..8f62c10 --- /dev/null +++ b/m4/guestfs_haskell.m4 @@ -0,0 +1,28 @@ +# libguestfs +# Copyright (C) 2009-2015 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +dnl Check for Haskell (GHC). +GHC=no +AC_ARG_ENABLE([haskell], + AS_HELP_STRING([--disable-haskell], [disable Haskell language bindings]), + [], + [enable_haskell=yes]) +AS_IF([test "x$enable_haskell" != "xno"],[ + GHC+ AC_CHECK_PROG([GHC],[ghc],[ghc],[no]) +]) +AM_CONDITIONAL([HAVE_HASKELL],[test "x$GHC" != "xno"]) diff --git a/m4/guestfs_java.m4 b/m4/guestfs_java.m4 new file mode 100644 index 0000000..ac7159a --- /dev/null +++ b/m4/guestfs_java.m4 @@ -0,0 +1,174 @@ +# libguestfs +# Copyright (C) 2009-2015 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +dnl Check for Java. +AC_ARG_WITH(java, + [AS_HELP_STRING([--with-java], + [specify path to JDK directory (for the Java language bindings) @<:@default=check@:>@])], + [], + [with_java=check]) + +if test "x$with_java" != "xno"; then + if test "x$with_java" != "xyes" && test "x$with_java" != "xcheck" + then + # Reject unsafe characters in $JAVA + jh_lf=' +' + case $JAVA in + *[\\\"\#\$\&\'\`$jh_lf\ \ ]*) + AC_MSG_FAILURE([unsafe \$JAVA directory (use --without-java to disable Java support)]);; + esac + if test -d "$with_java"; then + JAVA="$with_java" + else + AC_MSG_FAILURE([$with_java is not a directory (use --without-java to disable Java support)]) + fi + fi + + if test "x$JAVA" = "x"; then + # Look for Java in some likely locations. + for d in \ + /usr/lib/jvm/java \ + /usr/lib64/jvm/java \ + /usr/lib/jvm/default-java \ + /usr/lib/jvm/default \ + /usr/lib/jvm/java-8-openjdk \ + /usr/lib/jvm/java-7-openjdk \ + /usr/lib/jvm/java-6-openjdk + do + if test -d $d && test -f $d/bin/java; then + JAVA=$d + break + fi + done + fi + + if test "x$JAVA" != "x"; then + AC_MSG_CHECKING(for JDK in $JAVA) + if test ! -x "$JAVA/bin/java"; then + AC_MSG_ERROR([missing $JAVA/bin/java binary (use --without-java to disable Java support)]) + else + JAVA_EXE="$JAVA/bin/java" + fi + if test ! -x "$JAVA/bin/javac"; then + AC_MSG_ERROR([missing $JAVA/bin/javac binary]) + else + JAVAC="$JAVA/bin/javac" + fi + if test ! -x "$JAVA/bin/javah"; then + AC_MSG_ERROR([missing $JAVA/bin/javah binary]) + else + JAVAH="$JAVA/bin/javah" + fi + if test ! -x "$JAVA/bin/javadoc"; then + AC_MSG_ERROR([missing $JAVA/bin/javadoc binary]) + else + JAVADOC="$JAVA/bin/javadoc" + fi + if test ! -x "$JAVA/bin/jar"; then + AC_MSG_ERROR([missing $JAVA/bin/jar binary]) + else + JAR="$JAVA/bin/jar" + fi + java_version=`$JAVA_EXE -version 2>&1 | grep "java version"` + AC_MSG_RESULT(found $java_version in $JAVA) + + dnl Find jni.h. + AC_MSG_CHECKING([for jni.h]) + if test -f "$JAVA/include/jni.h"; then + JNI_CFLAGS="-I$JAVA/include" + else + if test "`find $JAVA -name jni.h`" != ""; then + head=`find $JAVA -name jni.h | tail -1` + dir=`dirname "$head"` + JNI_CFLAGS="-I$dir" + else + AC_MSG_FAILURE([missing jni.h header file]) + fi + fi + AC_MSG_RESULT([$JNI_CFLAGS]) + + dnl Find jni_md.h. + AC_MSG_CHECKING([for jni_md.h]) + case "$build_os" in + *linux*) system="linux" ;; + *SunOS*) system="solaris" ;; + *cygwin*) system="win32" ;; + *) system="$build_os" ;; + esac + if test -f "$JAVA/include/$system/jni_md.h"; then + JNI_CFLAGS="$JNI_CFLAGS -I$JAVA/include/$system" + else + if test "`find $JAVA -name jni_md.h`" != ""; then + head=`find $JAVA -name jni_md.h | tail -1` + dir=`dirname "$head"` + JNI_CFLAGS="$JNI_CFLAGS -I$dir" + else + AC_MSG_FAILURE([missing jni_md.h header file]) + fi + fi + AC_MSG_RESULT([$JNI_CFLAGS]) + + dnl Need extra version flag? + AC_MSG_CHECKING([extra javac flags]) + EXTRA_JAVAC_FLAGS+ javac_version=`$JAVAC -version 2>&1` + case "$javac_version" in + *Eclipse*) + EXTRA_JAVAC_FLAGS="-source 1.5" ;; + esac + AC_MSG_RESULT([$EXTRA_JAVAC_FLAGS]) + + dnl Extra lint flags? + AC_MSG_CHECKING([extra javac lint flags]) + if $JAVAC -X >/dev/null 2>&1 && \ + $JAVAC -X 2>&1 | grep -q -- '-Xlint:.*all'; then + AC_MSG_RESULT([-Xlint:all]) + EXTRA_JAVAC_FLAGS="$EXTRA_JAVAC_FLAGS -Xlint:all" + else + AC_MSG_RESULT([no]) + fi + + dnl Where to install jarfiles, jnifiles + if test -z $JAR_INSTALL_DIR; then + JAR_INSTALL_DIR=\${prefix}/share/java + fi + if test -z $JNI_INSTALL_DIR; then + JNI_INSTALL_DIR=\${libdir} + fi + + dnl JNI version. + jni_major_version=`echo "$VERSION" | $AWK -F. '{print $1}'` + jni_minor_version=`echo "$VERSION" | $AWK -F. '{print $2}'` + jni_micro_version=`echo "$VERSION" | $AWK -F. '{print $3}'` + JNI_VERSION_INFO=`expr "$jni_major_version" + "$jni_minor_version"`":$jni_micro_version:$jni_minor_version" + fi + + AC_SUBST(JAVA) + AC_SUBST(JAVA_EXE) + AC_SUBST(JAVAC) + AC_SUBST(JAVAH) + AC_SUBST(JAVADOC) + AC_SUBST(JAR) + AC_SUBST(JNI_CFLAGS) + AC_SUBST(EXTRA_JAVAC_FLAGS) + AC_SUBST(JAR_INSTALL_DIR) + AC_SUBST(JNI_INSTALL_DIR) + AC_SUBST(JNI_VERSION_INFO) +fi + +AM_CONDITIONAL([HAVE_JAVA],[test "x$with_java" != "xno" && test -n "$JAVAC"]) diff --git a/m4/guestfs_lua.m4 b/m4/guestfs_lua.m4 new file mode 100644 index 0000000..a07cb51 --- /dev/null +++ b/m4/guestfs_lua.m4 @@ -0,0 +1,47 @@ +# libguestfs +# Copyright (C) 2009-2015 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +dnl Lua +AC_ARG_ENABLE([lua], + AS_HELP_STRING([--disable-lua], [disable Lua language bindings]), + [], + [enable_lua=yes]) +AS_IF([test "x$enable_lua" != "xno"],[ + AC_CHECK_PROG([LUA],[lua],[lua],[no]) + AS_IF([test "x$LUA" != "xno"],[ + AC_MSG_CHECKING([for Lua version]) + LUA_VERSION=`$LUA -e 'print(_VERSION)' | $AWK '{print $2}'` + AC_MSG_RESULT([$LUA_VERSION]) + dnl On Debian it's 'lua5.1', 'lua5.2' etc. On Fedora, just 'lua'. + PKG_CHECK_MODULES([LUA], [lua$LUA_VERSION],[ + AC_SUBST([LUA_CFLAGS]) + AC_SUBST([LUA_LIBS]) + AC_SUBST([LUA_VERSION]) + AC_DEFINE([HAVE_LUA],[1],[Lua library found at compile time]) + ],[ + PKG_CHECK_MODULES([LUA], [lua],[ + AC_SUBST([LUA_CFLAGS]) + AC_SUBST([LUA_LIBS]) + AC_SUBST([LUA_VERSION]) + AC_DEFINE([HAVE_LUA],[1],[Lua library found at compile time]) + ],[ + AC_MSG_WARN([lua $LUA_VERSION not found]) + ]) + ]) + ]) +]) +AM_CONDITIONAL([HAVE_LUA],[test "x$LUA_LIBS" != "x"]) diff --git a/m4/guestfs_ocaml.m4 b/m4/guestfs_ocaml.m4 new file mode 100644 index 0000000..b3e9387 --- /dev/null +++ b/m4/guestfs_ocaml.m4 @@ -0,0 +1,104 @@ +# libguestfs +# Copyright (C) 2009-2015 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +dnl Check for OCaml (optional, for OCaml bindings and OCaml tools). +OCAMLC=no +OCAMLFIND=no +AC_ARG_ENABLE([ocaml], + AS_HELP_STRING([--disable-ocaml], [disable OCaml language bindings]), + [], + [enable_ocaml=yes]) +AS_IF([test "x$enable_ocaml" != "xno"],[ + dnl OCAMLC and OCAMLFIND have to be unset first, otherwise + dnl AC_CHECK_TOOL (inside AC_PROG_OCAML) will not look. + OCAMLC+ OCAMLFIND+ AC_PROG_OCAML + AC_PROG_FINDLIB + + dnl OCaml >= 3.11 is required. + AC_MSG_CHECKING([if OCaml version >= 3.11]) + ocaml_major="`echo $OCAMLVERSION | $AWK -F. '{print $1}'`" + ocaml_minor="`echo $OCAMLVERSION | $AWK -F. '{print $2}'`" + AS_IF([test "$ocaml_major" -ge 4 || ( test "$ocaml_major" -eq 3 && test "$ocaml_minor" -ge 11 )],[ + AC_MSG_RESULT([yes]) + ],[ + AC_MSG_RESULT([no]) + AC_MSG_FAILURE([OCaml compiler is not new enough. At least OCaml 3.11 is required]) + ]) +]) +AM_CONDITIONAL([HAVE_OCAML], + [test "x$OCAMLC" != "xno" && test "x$OCAMLFIND" != "xno"]) +AM_CONDITIONAL([HAVE_OCAMLOPT], + [test "x$OCAMLOPT" != "xno" && test "x$OCAMLFIND" != "xno"]) +AM_CONDITIONAL([HAVE_OCAMLDOC], + [test "x$OCAMLDOC" != "xno"]) + +dnl OCaml is required if we need to run the generator. +AS_IF([test "x$OCAMLC" = "xno" || test "x$OCAMLFIND" = "xno"],[ + AS_IF([! test -f $srcdir/src/guestfs_protocol.x],[ + AC_MSG_FAILURE([OCaml compiler and findlib is required to build from git. +If you don't have OCaml available, you should build from a tarball from +http://libguestfs.org/download]) + ]) +]) + +AS_IF([test "x$OCAMLC" != "xno"],[ + dnl Check for <caml/unixsupport.h> header. + old_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS -I`$OCAMLC -where`" + AC_CHECK_HEADERS([caml/unixsupport.h],[],[],[#include <caml/mlvalues.h>]) + CPPFLAGS="$old_CPPFLAGS" +]) + +OCAML_PKG_gettext=no +OCAML_PKG_libvirt=no +OCAML_PKG_oUnit=no +ounit_is_v2=no +AS_IF([test "x$OCAMLC" != "xno"],[ + # Create mllib/common_gettext.ml, gettext functions or stubs. + + # If we're building in a different directory, then mllib/ might + # not exist yet, so create it: + mkdir -p mllib + + GUESTFS_CREATE_COMMON_GETTEXT_ML([mllib/common_gettext.ml]) + + AC_CHECK_OCAML_PKG(libvirt) + AC_CHECK_OCAML_PKG(oUnit) + + # oUnit >= 2 is required, so check that it has OUnit2. + if test "x$OCAML_PKG_oUnit" != "xno"; then + AC_CHECK_OCAML_MODULE(ounit_is_v2,[OUnit.OUnit2],OUnit2,[+oUnit]) + fi +]) +AM_CONDITIONAL([HAVE_OCAML_PKG_GETTEXT], + [test "x$OCAMLC" != "xno" && test "x$OCAMLFIND" != "xno" && test "x$OCAML_PKG_gettext" != "xno"]) +AM_CONDITIONAL([HAVE_OCAML_PKG_LIBVIRT], + [test "x$OCAMLC" != "xno" && test "x$OCAMLFIND" != "xno" && test "x$OCAML_PKG_libvirt" != "xno"]) +AM_CONDITIONAL([HAVE_OCAML_PKG_OUNIT], + [test "x$OCAMLC" != "xno" && test "x$OCAMLFIND" != "xno" && test "x$OCAML_PKG_oUnit" != "xno" && test "x$ounit_is_v2" != "xno"]) + +AC_CHECK_PROG([OCAML_GETTEXT],[ocaml-gettext],[ocaml-gettext],[no]) +AM_CONDITIONAL([HAVE_OCAML_GETTEXT], + [test "x$OCAMLC" != "xno" && test "x$OCAMLFIND" != "xno" && test "x$OCAML_PKG_gettext" != "xno" && test "x$OCAML_GETTEXT" != "xno"]) + +dnl Flags we want to pass to every OCaml compiler call. +OCAML_WARN_ERROR="-warn-error CDEFLMPSUVYZX-3" +AC_SUBST([OCAML_WARN_ERROR]) +OCAML_FLAGS="-g -annot" +AC_SUBST([OCAML_FLAGS]) diff --git a/m4/guestfs_perl.m4 b/m4/guestfs_perl.m4 new file mode 100644 index 0000000..1306dd2 --- /dev/null +++ b/m4/guestfs_perl.m4 @@ -0,0 +1,41 @@ +# libguestfs +# Copyright (C) 2009-2015 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +dnl Check for Perl (optional, for Perl bindings and Perl tools). +AC_ARG_ENABLE([perl], + AS_HELP_STRING([--disable-perl], [disable Perl language bindings]), + [], + [enable_perl=yes]) +AS_IF([test "x$enable_perl" != "xno"],[ + dnl Check for Perl modules that must be present to compile and + dnl test the Perl bindings. + missing_perl_modules=no + for pm in Test::More Module::Build; do + AC_MSG_CHECKING([for $pm]) + if ! $PERL -M$pm -e1 >&AS_MESSAGE_LOG_FD 2>&1; then + AC_MSG_RESULT([no]) + missing_perl_modules=yes + else + AC_MSG_RESULT([yes]) + fi + done + if test "x$missing_perl_modules" = "xyes"; then + AC_MSG_WARN([some Perl modules required to compile or test the Perl bindings are missing]) + fi +]) +AM_CONDITIONAL([HAVE_PERL], + [test "x$enable_perl" != "xno" && test "x$PERL" != "xno" && test "x$missing_perl_modules" != "xyes"]) diff --git a/m4/guestfs_php.m4 b/m4/guestfs_php.m4 new file mode 100644 index 0000000..e88c6e6 --- /dev/null +++ b/m4/guestfs_php.m4 @@ -0,0 +1,29 @@ +# libguestfs +# Copyright (C) 2009-2015 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +dnl PHP +PHP=no +AC_ARG_ENABLE([php], + AS_HELP_STRING([--disable-php], [disable PHP language bindings]), + [], + [enable_php=yes]) +AS_IF([test "x$enable_php" != "xno"],[ + PHP+ AC_CHECK_PROG([PHP],[php],[php],[no]) + AC_CHECK_PROG([PHPIZE],[phpize],[phpize],[no]) +]) +AM_CONDITIONAL([HAVE_PHP], [test "x$PHP" != "xno" && test "x$PHPIZE" != "xno"]) diff --git a/m4/guestfs_python.m4 b/m4/guestfs_python.m4 new file mode 100644 index 0000000..3869905 --- /dev/null +++ b/m4/guestfs_python.m4 @@ -0,0 +1,104 @@ +# libguestfs +# Copyright (C) 2009-2015 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +dnl Check for Python (optional, for Python bindings). +PYTHON_PREFIX+PYTHON_VERSION+PYTHON_INSTALLDIR+ +AC_ARG_ENABLE([python], + AS_HELP_STRING([--disable-python], [disable Python language bindings]), + [], + [enable_python=yes]) +AS_IF([test "x$enable_python" != "xno"],[ + AC_CHECK_PROG([PYTHON],[python],[python],[no]) + + if test "x$PYTHON" != "xno"; then + AC_MSG_CHECKING([Python version]) + PYTHON_VERSION_MAJOR=`$PYTHON -c "import sys; print (sys.version_info@<:@0@:>@)"` + PYTHON_VERSION_MINOR=`$PYTHON -c "import sys; print (sys.version_info@<:@1@:>@)"` + PYTHON_VERSION="$PYTHON_VERSION_MAJOR.$PYTHON_VERSION_MINOR" + AC_MSG_RESULT([$PYTHON_VERSION]) + # Debian: python-2.7.pc, python-3.2.pc + PKG_CHECK_MODULES([PYTHON], [python-"$PYTHON_VERSION"],[ + AC_SUBST([PYTHON_CFLAGS]) + AC_SUBST([PYTHON_LIBS]) + AC_SUBST([PYTHON_VERSION]) + AC_DEFINE([HAVE_PYTHON],[1],[Python library found at compile time]) + ],[ + PKG_CHECK_MODULES([PYTHON], [python],[ + AC_SUBST([PYTHON_CFLAGS]) + AC_SUBST([PYTHON_LIBS]) + AC_SUBST([PYTHON_VERSION]) + AC_DEFINE([HAVE_PYTHON],[1],[Python library found at compile time]) + ],[ + AC_MSG_WARN([python $PYTHON_VERSION not found]) + ]) + ]) + AC_MSG_CHECKING([Python prefix]) + PYTHON_PREFIX=`$PYTHON -c "import sys; print (sys.prefix)"` + AC_MSG_RESULT([$PYTHON_PREFIX]) + + AC_ARG_WITH([python-installdir], + [AS_HELP_STRING([--with-python-installdir], + [directory to install python modules @<:@default=check@:>@])], + [PYTHON_INSTALLDIR="$withval" + AC_MSG_NOTICE([Python install dir $PYTHON_INSTALLDIR])], + [PYTHON_INSTALLDIR=check]) + + if test "x$PYTHON_INSTALLDIR" = "xcheck"; then + PYTHON_INSTALLDIR+ AC_MSG_CHECKING([for Python site-packages path]) + if test -z "$PYTHON_INSTALLDIR"; then + PYTHON_INSTALLDIR=`$PYTHON -c "import distutils.sysconfig; \ + print (distutils.sysconfig.get_python_lib(1,0));"` + fi + AC_MSG_RESULT([$PYTHON_INSTALLDIR]) + fi + + AC_MSG_CHECKING([for Python extension suffix (PEP-3149)]) + if test -z "$PYTHON_EXT_SUFFIX"; then + python_ext_suffix=`$PYTHON -c "import distutils.sysconfig; \ + print (distutils.sysconfig.get_config_var('EXT_SUFFIX') or distutils.sysconfig.get_config_var('SO'))"` + PYTHON_EXT_SUFFIX=$python_ext_suffix + fi + AC_MSG_RESULT([$PYTHON_EXT_SUFFIX]) + + dnl Look for some optional symbols in libpython. + old_LIBS="$LIBS" + + PYTHON_BLDLIBRARY=`$PYTHON -c "import distutils.sysconfig; \ + print (distutils.sysconfig.get_config_var('BLDLIBRARY'))"` + AC_CHECK_LIB([c],[PyCapsule_New], + [AC_DEFINE([HAVE_PYCAPSULE_NEW],1, + [Found PyCapsule_New in libpython.])], + [],[$PYTHON_BLDLIBRARY]) + AC_CHECK_LIB([c],[PyString_AsString], + [AC_DEFINE([HAVE_PYSTRING_ASSTRING],1, + [Found PyString_AsString in libpython.])], + [],[$PYTHON_BLDLIBRARY]) + + LIBS="$old_LIBS" + fi + + AC_SUBST(PYTHON_PREFIX) + AC_SUBST(PYTHON_VERSION) + AC_SUBST(PYTHON_INSTALLDIR) + AC_SUBST(PYTHON_EXT_SUFFIX) +]) +AM_CONDITIONAL([HAVE_PYTHON], + [test "x$PYTHON" != "xno" && test "x$PYTHON_LIBS" != "x" ]) diff --git a/m4/guestfs_ruby.m4 b/m4/guestfs_ruby.m4 new file mode 100644 index 0000000..9b22b95 --- /dev/null +++ b/m4/guestfs_ruby.m4 @@ -0,0 +1,51 @@ +# libguestfs +# Copyright (C) 2009-2015 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +dnl Check for Ruby and rake (optional, for Ruby bindings). +AC_ARG_ENABLE([ruby], + AS_HELP_STRING([--disable-ruby], [disable Ruby language bindings]), + [], + [enable_ruby=yes]) +AS_IF([test "x$enable_ruby" != "xno"],[ + AC_CHECK_PROG([RUBY],[ruby],[ruby],[no]) + AC_CHECK_PROG([RAKE],[rake],[rake],[no]) + + AS_IF([test -n "$RUBY" && test -n "$RAKE"],[ + dnl Find the library. Note on Debian it's not -lruby. + AC_MSG_CHECKING([for C library for Ruby extensions]) + ruby_cmd='puts RbConfig::CONFIG@<:@"RUBY_SO_NAME"@:>@' + echo running: $RUBY -rrbconfig -e \'$ruby_cmd\' >&AS_MESSAGE_LOG_FD + $RUBY -rrbconfig -e "$ruby_cmd" >conftest 2>&AS_MESSAGE_LOG_FD + libruby="$(cat conftest)" + rm conftest + AS_IF([test -n "$libruby"],[ + ruby_cmd='puts RbConfig::CONFIG@<:@"libdir"@:>@' + echo running: $RUBY -rrbconfig -e \'$ruby_cmd\' >&AS_MESSAGE_LOG_FD + $RUBY -rrbconfig -e "$ruby_cmd" >conftest 2>&AS_MESSAGE_LOG_FD + libruby_libdir="$(cat conftest)" + rm conftest + test -n "$libruby_libdir" && libruby_libdir="-L$libruby_libdir" + AC_MSG_RESULT([-l$libruby]) + AC_CHECK_LIB([$libruby],[ruby_init], + [have_libruby=1],[have_libruby=],[$libruby_libdir]) + ],[ + AC_MSG_RESULT([not found]) + ]) + ]) +]) +AM_CONDITIONAL([HAVE_RUBY], + [test -n "$RUBY" && test -n "$RAKE" && test -n "$have_libruby"]) -- 2.5.0
Richard W.M. Jones
2015-Oct-29 15:02 UTC
[Libguestfs] [PATCH 02/16] configure: Move (old, Perl) tools detection into m4/guestfs_perl.m4.
--- configure.ac | 20 -------------------- m4/guestfs_perl.m4 | 20 ++++++++++++++++++++ 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/configure.ac b/configure.ac index 5a3ba96..2862afc 100644 --- a/configure.ac +++ b/configure.ac @@ -1094,26 +1094,6 @@ m4_include([m4/guestfs_lua.m4]) m4_include([m4/guestfs_golang.m4]) m4_include([m4/guestfs_gobject.m4]) -dnl Check for Perl modules needed by Perl virt tools (virt-df, etc.) -AS_IF([test "x$PERL" != "xno"],[ - missing_perl_modules=no - for pm in Pod::Usage Getopt::Long Sys::Virt Locale::TextDomain Win::Hivex Win::Hivex::Regedit ; do - AC_MSG_CHECKING([for $pm]) - if ! $PERL -M$pm -e1 >&AS_MESSAGE_LOG_FD 2>&1; then - AC_MSG_RESULT([no]) - missing_perl_modules=yes - else - AC_MSG_RESULT([yes]) - fi - done - if test "x$missing_perl_modules" = "xyes"; then - AC_MSG_WARN([some Perl modules required to compile the Perl virt-* tools are missing]) - fi -]) - -AM_CONDITIONAL([HAVE_TOOLS], - [test "x$PERL" != "xno" && test "x$missing_perl_modules" != "xyes"]) - dnl Bash completion. PKG_CHECK_MODULES([BASH_COMPLETION], [bash-completion >= 2.0], [ bash_completion=yes diff --git a/m4/guestfs_perl.m4 b/m4/guestfs_perl.m4 index 1306dd2..9951aa0 100644 --- a/m4/guestfs_perl.m4 +++ b/m4/guestfs_perl.m4 @@ -39,3 +39,23 @@ AS_IF([test "x$enable_perl" != "xno"],[ ]) AM_CONDITIONAL([HAVE_PERL], [test "x$enable_perl" != "xno" && test "x$PERL" != "xno" && test "x$missing_perl_modules" != "xyes"]) + +dnl Check for Perl modules needed by Perl virt tools (virt-df, etc.) +AS_IF([test "x$PERL" != "xno"],[ + missing_perl_modules=no + for pm in Pod::Usage Getopt::Long Sys::Virt Locale::TextDomain Win::Hivex Win::Hivex::Regedit ; do + AC_MSG_CHECKING([for $pm]) + if ! $PERL -M$pm -e1 >&AS_MESSAGE_LOG_FD 2>&1; then + AC_MSG_RESULT([no]) + missing_perl_modules=yes + else + AC_MSG_RESULT([yes]) + fi + done + if test "x$missing_perl_modules" = "xyes"; then + AC_MSG_WARN([some Perl modules required to compile the Perl virt-* tools are missing]) + fi +]) + +AM_CONDITIONAL([HAVE_TOOLS], + [test "x$PERL" != "xno" && test "x$missing_perl_modules" != "xyes"]) -- 2.5.0
Richard W.M. Jones
2015-Oct-29 15:02 UTC
[Libguestfs] [PATCH 03/16] configure: Move Perl program / man page detection into m4/guestfs_perl.m4.
--- configure.ac | 23 ----------------------- m4/guestfs_perl.m4 | 25 ++++++++++++++++++++++++- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/configure.ac b/configure.ac index 2862afc..80803c1 100644 --- a/configure.ac +++ b/configure.ac @@ -656,29 +656,6 @@ AC_CHECK_PROG([GPERF],[gperf],[gperf],[no]) test "x$GPERF" = "xno" && AC_MSG_ERROR([gperf must be installed]) -dnl Check for perl. -AC_CHECK_PROG([PERL],[perl],[perl],[no]) -test "x$PERL" = "xno" && - AC_MSG_ERROR([perl must be installed]) - -dnl Check for Pod::Man, Pod::Simple. -AC_MSG_CHECKING([for Pod::Man]) -if ! $PERL -MPod::Man -e1 >&AS_MESSAGE_LOG_FD 2>&1; then - AC_MSG_ERROR([perl Pod::Man must be installed]) -else - AC_MSG_RESULT([yes]) -fi -AC_MSG_CHECKING([for Pod::Simple]) -if ! $PERL -MPod::Simple -e1 >&AS_MESSAGE_LOG_FD 2>&1; then - AC_MSG_ERROR([perl Pod::Simple must be installed]) -else - AC_MSG_RESULT([yes]) -fi - -dnl Define the path to the podwrapper program. -PODWRAPPER="$PERL $(pwd)/podwrapper.pl" -AC_SUBST([PODWRAPPER]) - dnl Check for genisoimage/mkisofs AC_PATH_PROGS([GENISOIMAGE],[genisoimage mkisofs],[no], [$PATH$PATH_SEPARATOR/usr/sbin$PATH_SEPARATOR/sbin]) diff --git a/m4/guestfs_perl.m4 b/m4/guestfs_perl.m4 index 9951aa0..4a1aacd 100644 --- a/m4/guestfs_perl.m4 +++ b/m4/guestfs_perl.m4 @@ -15,7 +15,30 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -dnl Check for Perl (optional, for Perl bindings and Perl tools). +dnl Check for perl (required). +AC_CHECK_PROG([PERL],[perl],[perl],[no]) +test "x$PERL" = "xno" && + AC_MSG_ERROR([perl must be installed]) + +dnl Check for Pod::Man, Pod::Simple (for man pages). +AC_MSG_CHECKING([for Pod::Man]) +if ! $PERL -MPod::Man -e1 >&AS_MESSAGE_LOG_FD 2>&1; then + AC_MSG_ERROR([perl Pod::Man must be installed]) +else + AC_MSG_RESULT([yes]) +fi +AC_MSG_CHECKING([for Pod::Simple]) +if ! $PERL -MPod::Simple -e1 >&AS_MESSAGE_LOG_FD 2>&1; then + AC_MSG_ERROR([perl Pod::Simple must be installed]) +else + AC_MSG_RESULT([yes]) +fi + +dnl Define the path to the podwrapper program. +PODWRAPPER="$PERL $(pwd)/podwrapper.pl" +AC_SUBST([PODWRAPPER]) + +dnl Check for Perl for Perl bindings and Perl tools. AC_ARG_ENABLE([perl], AS_HELP_STRING([--disable-perl], [disable Perl language bindings]), [], -- 2.5.0
Richard W.M. Jones
2015-Oct-29 15:02 UTC
[Libguestfs] [PATCH 04/16] configure: Move bash completion detection to separate file.
--- configure.ac | 12 +----------- m4/guestfs_bash_completion.m4 | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 11 deletions(-) create mode 100644 m4/guestfs_bash_completion.m4 diff --git a/configure.ac b/configure.ac index 80803c1..a86d676 100644 --- a/configure.ac +++ b/configure.ac @@ -1072,17 +1072,7 @@ m4_include([m4/guestfs_golang.m4]) m4_include([m4/guestfs_gobject.m4]) dnl Bash completion. -PKG_CHECK_MODULES([BASH_COMPLETION], [bash-completion >= 2.0], [ - bash_completion=yes - AC_MSG_CHECKING([for bash-completions directory]) - BASH_COMPLETIONS_DIR="`pkg-config --variable=completionsdir bash-completion`" - AC_MSG_RESULT([$BASH_COMPLETIONS_DIR]) - AC_SUBST([BASH_COMPLETIONS_DIR]) -],[ - bash_completion=no - AC_MSG_WARN([bash-completion not installed]) -]) -AM_CONDITIONAL([HAVE_BASH_COMPLETION],[test "x$bash_completion" = "xyes"]) +m4_include([m4/guestfs_bash_completion.m4]) dnl For search paths. AC_DEFINE_UNQUOTED([PATH_SEPARATOR],["$PATH_SEPARATOR"], diff --git a/m4/guestfs_bash_completion.m4 b/m4/guestfs_bash_completion.m4 new file mode 100644 index 0000000..f32fba7 --- /dev/null +++ b/m4/guestfs_bash_completion.m4 @@ -0,0 +1,29 @@ +# libguestfs +# Copyright (C) 2009-2015 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +dnl Bash completion. +PKG_CHECK_MODULES([BASH_COMPLETION], [bash-completion >= 2.0], [ + bash_completion=yes + AC_MSG_CHECKING([for bash-completions directory]) + BASH_COMPLETIONS_DIR="`pkg-config --variable=completionsdir bash-completion`" + AC_MSG_RESULT([$BASH_COMPLETIONS_DIR]) + AC_SUBST([BASH_COMPLETIONS_DIR]) +],[ + bash_completion=no + AC_MSG_WARN([bash-completion not installed]) +]) +AM_CONDITIONAL([HAVE_BASH_COMPLETION],[test "x$bash_completion" = "xyes"]) -- 2.5.0
Richard W.M. Jones
2015-Oct-29 15:02 UTC
[Libguestfs] [PATCH 05/16] configure: Move qemu detection to separate file.
--- configure.ac | 134 +---------------------------------------------- m4/guestfs_qemu.m4 | 149 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 151 insertions(+), 132 deletions(-) create mode 100644 m4/guestfs_qemu.m4 diff --git a/configure.ac b/configure.ac index a86d676..7782c3a 100644 --- a/configure.ac +++ b/configure.ac @@ -741,138 +741,8 @@ AM_CONDITIONAL([HAVE_ZIP],[test "x$ZIP" != "xno"]) AC_PATH_PROGS([UNZIP],[unzip],[no]) AC_DEFINE_UNQUOTED([UNZIP],["$UNZIP"],[Name of unzip program.]) -dnl Check for QEMU for running binaries on this $host_cpu, fall -dnl back to basic 'qemu'. Allow the user to override it. -AS_CASE([$host_cpu], - [i@<:@456@:>@86],[qemu_cpu=i386], - [arm*],[qemu_cpu=arm], - [amd64],[qemu_cpu=x86_64], - [powerpc64 | ppc64le | powerpc64le],[qemu_cpu=ppc64], - [qemu_cpu=$host_cpu]) -default_qemu="qemu-kvm kvm qemu-system-$qemu_cpu qemu" -AC_ARG_WITH([qemu], - [AS_HELP_STRING([--with-qemu="bin1 bin2 ..."], - [set default QEMU binary @<:@default="[qemu-kvm] qemu-system-<host> qemu"@:>@])], - dnl --with-qemu or --without-qemu: - [], - dnl neither option was given: - [with_qemu="$default_qemu"] -) - -AS_IF([test "x$with_qemu" = "xno"],[ - AC_MSG_WARN([qemu was disabled, libguestfs may not work at all]) - QEMU=no -],[ - AC_PATH_PROGS([QEMU],[$with_qemu],[no], - [$PATH$PATH_SEPARATOR/usr/sbin$PATH_SEPARATOR/sbin$PATH_SEPARATOR/usr/libexec]) - test "x$QEMU" = "xno" && AC_MSG_ERROR([qemu must be installed]) - - AC_DEFINE_UNQUOTED([QEMU],["$QEMU"],[Location of qemu binary.]) - - dnl Does the user wish to specify -M, -cpu or other qemu options? - AC_MSG_CHECKING([if the user specified extra options for qemu command line]) - AC_ARG_WITH([qemu-options], - [AS_HELP_STRING([--with-qemu-options="-M ... -cpu ... etc"], - [pass extra options for qemu command line @<:@default=no@:>@])], - [QEMU_OPTIONS="$withval"], - [QEMU_OPTIONS=no]) - AS_IF([test "x$QEMU_OPTIONS" = "xno"],[ - AC_MSG_RESULT([no]) - QEMU_OPTIONS- ],[ - AC_MSG_RESULT([$QEMU_OPTIONS]) - ]) - AC_DEFINE_UNQUOTED([QEMU_OPTIONS],["$QEMU_OPTIONS"], - [Extra options for qemu command line.]) - - dnl Check that the chosen qemu has virtio-serial support. - dnl For historical reasons this can be disabled by setting - dnl vmchannel_test=no. - if test "x$vmchannel_test" != "xno"; then - AC_MSG_CHECKING([that $QEMU -help works]) - if $QEMU -help >&AS_MESSAGE_LOG_FD 2>&1; then - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - AC_MSG_FAILURE( -[$QEMU -help: command failed. - -This could be a very old version of qemu, or qemu might not be -working. -]) - fi - - AC_MSG_CHECKING([that $QEMU -version works]) - if $QEMU -version >&AS_MESSAGE_LOG_FD 2>&1; then - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - AC_MSG_FAILURE( -[$QEMU -version: command failed. - -This could be a very old version of qemu, or qemu might not be -working. -]) - fi - - AC_MSG_CHECKING([for $QEMU version >= 1]) - if $QEMU -version | grep -sq 'version @<:@1-9@:>@'; then - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - AC_MSG_FAILURE([$QEMU version must be >= 1.0.]) - fi - - dnl Unfortunately $QEMU -device \? won't just work. We probably - dnl need to add a cocktail of different arguments which differ - dnl on the various emulators. Thanks, qemu. - AC_MSG_CHECKING([what extra options we need to use for qemu feature tests]) - QEMU_OPTIONS_FOR_CONFIGURE- # Note: the order we test these matters. - for opt in "-machine virt" "-machine accel=kvm:tcg" "-display none"; do - if $QEMU $QEMU_OPTIONS_FOR_CONFIGURE $opt -device \? >&AS_MESSAGE_LOG_FD 2>&1; then - QEMU_OPTIONS_FOR_CONFIGURE="$QEMU_OPTIONS_FOR_CONFIGURE $opt" - fi - done - AC_MSG_RESULT([$QEMU_OPTIONS_FOR_CONFIGURE]) - - AC_MSG_CHECKING([that $QEMU $QEMU_OPTIONS_FOR_CONFIGURE -device ? works]) - if $QEMU $QEMU_OPTIONS_FOR_CONFIGURE -device \? >&AS_MESSAGE_LOG_FD 2>&1; then - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - AC_MSG_FAILURE([$QEMU $QEMU_OPTIONS_FOR_CONFIGURE -device ? doesn't work.]) - fi - - AC_MSG_CHECKING([for virtio-serial support in $QEMU]) - if $QEMU $QEMU_OPTIONS_FOR_CONFIGURE -device \? 2>&1 | grep -sq virtio-serial; then - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - AC_MSG_FAILURE( -[I did not find virtio-serial support in -$QEMU. - -virtio-serial support in qemu or KVM is essential for libguestfs -to operate. - -Usually this means that you have to install a newer version of qemu -and/or KVM. Please read the relevant section in the README file for -more information about this. - -You can override this test by setting the environment variable -vmchannel_test=no - -However if you don't have the right support in your qemu, then this -just delays the pain. - -If I am using the wrong qemu or you want to compile qemu from source -and install it in another location, then you should configure with -the --with-qemu option. -]) - fi - fi -]) +dnl Check for QEMU. +m4_include([m4/guestfs_qemu.m4]) dnl Enable packet dumps when in verbose mode. This generates lots dnl of debug info, only useful for people debugging the RPC mechanism. diff --git a/m4/guestfs_qemu.m4 b/m4/guestfs_qemu.m4 new file mode 100644 index 0000000..20a681e --- /dev/null +++ b/m4/guestfs_qemu.m4 @@ -0,0 +1,149 @@ +# libguestfs +# Copyright (C) 2009-2015 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +dnl Check for QEMU for running binaries on this $host_cpu, fall +dnl back to basic 'qemu'. Allow the user to override it. +AS_CASE([$host_cpu], + [i@<:@456@:>@86],[qemu_cpu=i386], + [arm*],[qemu_cpu=arm], + [amd64],[qemu_cpu=x86_64], + [powerpc64 | ppc64le | powerpc64le],[qemu_cpu=ppc64], + [qemu_cpu=$host_cpu]) +default_qemu="qemu-kvm kvm qemu-system-$qemu_cpu qemu" +AC_ARG_WITH([qemu], + [AS_HELP_STRING([--with-qemu="bin1 bin2 ..."], + [set default QEMU binary @<:@default="[qemu-kvm] qemu-system-<host> qemu"@:>@])], + dnl --with-qemu or --without-qemu: + [], + dnl neither option was given: + [with_qemu="$default_qemu"] +) + +AS_IF([test "x$with_qemu" = "xno"],[ + AC_MSG_WARN([qemu was disabled, libguestfs may not work at all]) + QEMU=no +],[ + AC_PATH_PROGS([QEMU],[$with_qemu],[no], + [$PATH$PATH_SEPARATOR/usr/sbin$PATH_SEPARATOR/sbin$PATH_SEPARATOR/usr/libexec]) + test "x$QEMU" = "xno" && AC_MSG_ERROR([qemu must be installed]) + + AC_DEFINE_UNQUOTED([QEMU],["$QEMU"],[Location of qemu binary.]) + + dnl Does the user wish to specify -M, -cpu or other qemu options? + AC_MSG_CHECKING([if the user specified extra options for qemu command line]) + AC_ARG_WITH([qemu-options], + [AS_HELP_STRING([--with-qemu-options="-M ... -cpu ... etc"], + [pass extra options for qemu command line @<:@default=no@:>@])], + [QEMU_OPTIONS="$withval"], + [QEMU_OPTIONS=no]) + AS_IF([test "x$QEMU_OPTIONS" = "xno"],[ + AC_MSG_RESULT([no]) + QEMU_OPTIONS+ ],[ + AC_MSG_RESULT([$QEMU_OPTIONS]) + ]) + AC_DEFINE_UNQUOTED([QEMU_OPTIONS],["$QEMU_OPTIONS"], + [Extra options for qemu command line.]) + + dnl Check that the chosen qemu has virtio-serial support. + dnl For historical reasons this can be disabled by setting + dnl vmchannel_test=no. + if test "x$vmchannel_test" != "xno"; then + AC_MSG_CHECKING([that $QEMU -help works]) + if $QEMU -help >&AS_MESSAGE_LOG_FD 2>&1; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + AC_MSG_FAILURE( +[$QEMU -help: command failed. + +This could be a very old version of qemu, or qemu might not be +working. +]) + fi + + AC_MSG_CHECKING([that $QEMU -version works]) + if $QEMU -version >&AS_MESSAGE_LOG_FD 2>&1; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + AC_MSG_FAILURE( +[$QEMU -version: command failed. + +This could be a very old version of qemu, or qemu might not be +working. +]) + fi + + AC_MSG_CHECKING([for $QEMU version >= 1]) + if $QEMU -version | grep -sq 'version @<:@1-9@:>@'; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + AC_MSG_FAILURE([$QEMU version must be >= 1.0.]) + fi + + dnl Unfortunately $QEMU -device \? won't just work. We probably + dnl need to add a cocktail of different arguments which differ + dnl on the various emulators. Thanks, qemu. + AC_MSG_CHECKING([what extra options we need to use for qemu feature tests]) + QEMU_OPTIONS_FOR_CONFIGURE+ # Note: the order we test these matters. + for opt in "-machine virt" "-machine accel=kvm:tcg" "-display none"; do + if $QEMU $QEMU_OPTIONS_FOR_CONFIGURE $opt -device \? >&AS_MESSAGE_LOG_FD 2>&1; then + QEMU_OPTIONS_FOR_CONFIGURE="$QEMU_OPTIONS_FOR_CONFIGURE $opt" + fi + done + AC_MSG_RESULT([$QEMU_OPTIONS_FOR_CONFIGURE]) + + AC_MSG_CHECKING([that $QEMU $QEMU_OPTIONS_FOR_CONFIGURE -device ? works]) + if $QEMU $QEMU_OPTIONS_FOR_CONFIGURE -device \? >&AS_MESSAGE_LOG_FD 2>&1; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + AC_MSG_FAILURE([$QEMU $QEMU_OPTIONS_FOR_CONFIGURE -device ? doesn't work.]) + fi + + AC_MSG_CHECKING([for virtio-serial support in $QEMU]) + if $QEMU $QEMU_OPTIONS_FOR_CONFIGURE -device \? 2>&1 | grep -sq virtio-serial; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + AC_MSG_FAILURE( +[I did not find virtio-serial support in +$QEMU. + +virtio-serial support in qemu or KVM is essential for libguestfs +to operate. + +Usually this means that you have to install a newer version of qemu +and/or KVM. Please read the relevant section in the README file for +more information about this. + +You can override this test by setting the environment variable +vmchannel_test=no + +However if you don't have the right support in your qemu, then this +just delays the pain. + +If I am using the wrong qemu or you want to compile qemu from source +and install it in another location, then you should configure with +the --with-qemu option. +]) + fi + fi +]) -- 2.5.0
Richard W.M. Jones
2015-Oct-29 15:02 UTC
[Libguestfs] [PATCH 06/16] configure: Move detection of external programs to a separate file.
Do this early since these tests generally don't depend on anything else (the external program is either there or its not), and because other things depend on some of these tests. --- configure.ac | 114 ++------------------------------------------ m4/guestfs_progs.m4 | 134 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 137 insertions(+), 111 deletions(-) create mode 100644 m4/guestfs_progs.m4 diff --git a/configure.ac b/configure.ac index 7782c3a..2dcb17e 100644 --- a/configure.ac +++ b/configure.ac @@ -15,12 +15,6 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -# NB: AC_CHECK_PROG(S) or AC_PATH_PROG(S)? -# Use AC_CHECK_PROG(S) for programs which are only used during build. -# Use AC_PATH_PROG(S) for program names which are compiled into the -# binary and used at run time. The reason is so that we know which -# programs the binary actually uses. - # The major, minor, and release fields MUST be numbers. Packagers can # add extra information using --with-extra="..." which may be any # freeform string. @@ -94,23 +88,13 @@ PACKAGE_VERSION_FULL="libguestfs_major.libguestfs_minor.libguestfs_release${libg AC_DEFINE_UNQUOTED([PACKAGE_VERSION_FULL],["$PACKAGE_VERSION_FULL"],[Full version string.]) AC_SUBST([PACKAGE_VERSION_FULL]) -# Define $(SED). -m4_ifdef([AC_PROG_SED],[ - AC_PROG_SED -],[ - dnl ... else hope for the best - AC_SUBST([SED], "sed") -]) - -# Define $(AWK). -AC_PROG_AWK - dnl Early gnulib initialization. gl_EARLY gl_INIT -AC_PROG_LIBTOOL -AC_PROG_LN_S +dnl Check for external programs required to either build or run +dnl libguestfs. +m4_include([m4/guestfs_progs.m4]) dnl Define the host CPU architecture (defines 'host_cpu') AC_CANONICAL_HOST @@ -646,68 +630,6 @@ AS_IF([test "x$enable_probes" != "xno"],[ ]) ]) -dnl Check for cpio which isn't in the default Pardus install amazingly. -AC_CHECK_PROG([CPIO],[cpio],[cpio],[no]) -test "x$CPIO" = "xno" && - AC_MSG_ERROR([cpio must be installed]) - -dnl Check for gperf. -AC_CHECK_PROG([GPERF],[gperf],[gperf],[no]) -test "x$GPERF" = "xno" && - AC_MSG_ERROR([gperf must be installed]) - -dnl Check for genisoimage/mkisofs -AC_PATH_PROGS([GENISOIMAGE],[genisoimage mkisofs],[no], - [$PATH$PATH_SEPARATOR/usr/sbin$PATH_SEPARATOR/sbin]) -test "x$GENISOIMAGE" = "xno" && AC_MSG_ERROR([genisoimage must be installed]) - -dnl Check for optional xmllint. -AC_CHECK_PROG([XMLLINT],[xmllint],[xmllint],[no]) -AM_CONDITIONAL([HAVE_XMLLINT],[test "x$XMLLINT" != "xno"]) - -dnl po4a for translating man pages and POD files (optional). -AC_CHECK_PROG([PO4A],[po4a],[po4a],[no]) -AM_CONDITIONAL([HAVE_PO4A], [test "x$PO4A" != "xno"]) - -dnl Check for db_dump, db_load (optional). -GUESTFS_FIND_DB_TOOL([DB_DUMP], [dump]) -GUESTFS_FIND_DB_TOOL([DB_LOAD], [load]) -if test "x$DB_DUMP" != "xno"; then - AC_DEFINE_UNQUOTED([DB_DUMP],["$DB_DUMP"],[Name of db_dump program.]) -fi -if test "x$DB_LOAD" != "xno"; then - AC_DEFINE_UNQUOTED([DB_LOAD],["$DB_LOAD"],[Name of db_load program.]) -fi - -dnl Check for netpbm programs (optional). -AC_PATH_PROGS([PBMTEXT],[pbmtext],[no]) -AC_PATH_PROGS([PNMTOPNG],[pnmtopng],[no]) -AC_PATH_PROGS([BMPTOPNM],[bmptopnm],[no]) -AC_PATH_PROGS([PAMCUT],[pamcut],[no]) -if test "x$PBMTEXT" != "xno"; then - AC_DEFINE_UNQUOTED([PBMTEXT],["$PBMTEXT"],[Name of pbmtext program.]) -fi -if test "x$PNMTOPNG" != "xno"; then - AC_DEFINE_UNQUOTED([PNMTOPNG],["$PNMTOPNG"],[Name of pnmtopng program.]) -fi -if test "x$BMPTOPNM" != "xno"; then - AC_DEFINE_UNQUOTED([BMPTOPNM],["$BMPTOPNM"],[Name of bmptopnm program.]) -fi -if test "x$PAMCUT" != "xno"; then - AC_DEFINE_UNQUOTED([PAMCUT],["$PAMCUT"],[Name of pamcut program.]) -fi - -dnl Check for icoutils (optional). -AC_PATH_PROGS([WRESTOOL],[wrestool],[no]) -if test "x$WRESTOOL" != "xno"; then - AC_DEFINE_UNQUOTED([WRESTOOL],["$WRESTOOL"],[Name of wrestool program.]) -fi - -dnl Check for xzcat (required). -AC_PATH_PROGS([XZCAT],[xzcat],[no]) -test "x$XZCAT" = "xno" && AC_MSG_ERROR([xzcat must be installed]) -AC_DEFINE_UNQUOTED([XZCAT],["$XZCAT"],[Name of xzcat program.]) - dnl liblzma can be used by virt-builder (optional). PKG_CHECK_MODULES([LIBLZMA], [liblzma], [ AC_SUBST([LIBLZMA_CFLAGS]) @@ -722,25 +644,6 @@ PKG_CHECK_MODULES([LIBLZMA], [liblzma], [ ], [AC_MSG_WARN([liblzma not found, virt-builder will be slower])]) -dnl (f)lex and bison for virt-builder (required). -dnl XXX Could be optional with some work. -AC_PROG_LEX -AC_PROG_YACC -dnl These macros don't fail, instead they set some useless defaults. -if test "x$LEX" = "x:"; then - AC_MSG_FAILURE([GNU 'flex' is required.]) -fi -if test "x$YACC" = "xyacc"; then - AC_MSG_FAILURE([GNU 'bison' is required (yacc won't work).]) -fi - -dnl zip/unzip, used by virt-v2v -AC_PATH_PROGS([ZIP],[zip],[no]) -AC_DEFINE_UNQUOTED([ZIP],["$ZIP"],[Name of zip program.]) -AM_CONDITIONAL([HAVE_ZIP],[test "x$ZIP" != "xno"]) -AC_PATH_PROGS([UNZIP],[unzip],[no]) -AC_DEFINE_UNQUOTED([UNZIP],["$UNZIP"],[Name of unzip program.]) - dnl Check for QEMU. m4_include([m4/guestfs_qemu.m4]) @@ -917,17 +820,6 @@ AS_IF([$CXX --version >&AS_MESSAGE_LOG_FD 2>&1],[have_cxx=yes],[have_cxx=no]) AC_MSG_RESULT([$have_cxx]) AM_CONDITIONAL([HAVE_CXX], [test "$have_cxx" = "yes"]) -AC_CHECK_PROG([VALGRIND],[valgrind],[valgrind],[no]) -AS_IF([test "x$VALGRIND" != "xno"],[ - # Substitute the whole valgrind command. - VG='$(VALGRIND) --vgdb=no --log-file=$(abs_top_builddir)/tmp/valgrind-%q{T}-%p.log --leak-check=full --error-exitcode=119 --suppressions=$(abs_top_srcdir)/valgrind-suppressions' - ],[ - # No valgrind, so substitute VG with something that will break. - VG=VALGRIND_IS_NOT_INSTALLED -]) -AC_SUBST([VG]) -AM_SUBST_NOTMAKE([VG]) - dnl Check for language bindings. m4_include([m4/guestfs_ocaml.m4]) m4_include([m4/guestfs_perl.m4]) diff --git a/m4/guestfs_progs.m4 b/m4/guestfs_progs.m4 new file mode 100644 index 0000000..47ba908 --- /dev/null +++ b/m4/guestfs_progs.m4 @@ -0,0 +1,134 @@ +# libguestfs +# Copyright (C) 2009-2015 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +# Check for external programs required to either build or run +# libguestfs. +# +# AC_CHECK_PROG(S) or AC_PATH_PROG(S)? +# +# Use AC_CHECK_PROG(S) for programs which are only used during build. +# +# Use AC_PATH_PROG(S) for program names which are compiled into the +# binary and used at run time. The reason is so that we know which +# programs the binary actually uses. + +# Define $(SED). +m4_ifdef([AC_PROG_SED],[ + AC_PROG_SED +],[ + dnl ... else hope for the best + AC_SUBST([SED], "sed") +]) + +# Define $(AWK). +AC_PROG_AWK + +AC_PROG_LIBTOOL +AC_PROG_LN_S + +dnl Check for cpio which isn't in the default Pardus install amazingly. +AC_CHECK_PROG([CPIO],[cpio],[cpio],[no]) +test "x$CPIO" = "xno" && + AC_MSG_ERROR([cpio must be installed]) + +dnl Check for gperf. +AC_CHECK_PROG([GPERF],[gperf],[gperf],[no]) +test "x$GPERF" = "xno" && + AC_MSG_ERROR([gperf must be installed]) + +dnl Check for genisoimage/mkisofs +AC_PATH_PROGS([GENISOIMAGE],[genisoimage mkisofs],[no], + [$PATH$PATH_SEPARATOR/usr/sbin$PATH_SEPARATOR/sbin]) +test "x$GENISOIMAGE" = "xno" && AC_MSG_ERROR([genisoimage must be installed]) + +dnl Check for optional xmllint. +AC_CHECK_PROG([XMLLINT],[xmllint],[xmllint],[no]) +AM_CONDITIONAL([HAVE_XMLLINT],[test "x$XMLLINT" != "xno"]) + +dnl po4a for translating man pages and POD files (optional). +AC_CHECK_PROG([PO4A],[po4a],[po4a],[no]) +AM_CONDITIONAL([HAVE_PO4A], [test "x$PO4A" != "xno"]) + +dnl Check for db_dump, db_load (optional). +GUESTFS_FIND_DB_TOOL([DB_DUMP], [dump]) +GUESTFS_FIND_DB_TOOL([DB_LOAD], [load]) +if test "x$DB_DUMP" != "xno"; then + AC_DEFINE_UNQUOTED([DB_DUMP],["$DB_DUMP"],[Name of db_dump program.]) +fi +if test "x$DB_LOAD" != "xno"; then + AC_DEFINE_UNQUOTED([DB_LOAD],["$DB_LOAD"],[Name of db_load program.]) +fi + +dnl Check for netpbm programs (optional). +AC_PATH_PROGS([PBMTEXT],[pbmtext],[no]) +AC_PATH_PROGS([PNMTOPNG],[pnmtopng],[no]) +AC_PATH_PROGS([BMPTOPNM],[bmptopnm],[no]) +AC_PATH_PROGS([PAMCUT],[pamcut],[no]) +if test "x$PBMTEXT" != "xno"; then + AC_DEFINE_UNQUOTED([PBMTEXT],["$PBMTEXT"],[Name of pbmtext program.]) +fi +if test "x$PNMTOPNG" != "xno"; then + AC_DEFINE_UNQUOTED([PNMTOPNG],["$PNMTOPNG"],[Name of pnmtopng program.]) +fi +if test "x$BMPTOPNM" != "xno"; then + AC_DEFINE_UNQUOTED([BMPTOPNM],["$BMPTOPNM"],[Name of bmptopnm program.]) +fi +if test "x$PAMCUT" != "xno"; then + AC_DEFINE_UNQUOTED([PAMCUT],["$PAMCUT"],[Name of pamcut program.]) +fi + +dnl Check for icoutils (optional). +AC_PATH_PROGS([WRESTOOL],[wrestool],[no]) +if test "x$WRESTOOL" != "xno"; then + AC_DEFINE_UNQUOTED([WRESTOOL],["$WRESTOOL"],[Name of wrestool program.]) +fi + +dnl Check for xzcat (required). +AC_PATH_PROGS([XZCAT],[xzcat],[no]) +test "x$XZCAT" = "xno" && AC_MSG_ERROR([xzcat must be installed]) +AC_DEFINE_UNQUOTED([XZCAT],["$XZCAT"],[Name of xzcat program.]) + +dnl (f)lex and bison for virt-builder (required). +dnl XXX Could be optional with some work. +AC_PROG_LEX +AC_PROG_YACC +dnl These macros don't fail, instead they set some useless defaults. +if test "x$LEX" = "x:"; then + AC_MSG_FAILURE([GNU 'flex' is required.]) +fi +if test "x$YACC" = "xyacc"; then + AC_MSG_FAILURE([GNU 'bison' is required (yacc won't work).]) +fi + +dnl zip/unzip, used by virt-v2v +AC_PATH_PROGS([ZIP],[zip],[no]) +AC_DEFINE_UNQUOTED([ZIP],["$ZIP"],[Name of zip program.]) +AM_CONDITIONAL([HAVE_ZIP],[test "x$ZIP" != "xno"]) +AC_PATH_PROGS([UNZIP],[unzip],[no]) +AC_DEFINE_UNQUOTED([UNZIP],["$UNZIP"],[Name of unzip program.]) + +dnl Check for valgrind +AC_CHECK_PROG([VALGRIND],[valgrind],[valgrind],[no]) +AS_IF([test "x$VALGRIND" != "xno"],[ + # Substitute the whole valgrind command. + VG='$(VALGRIND) --vgdb=no --log-file=$(abs_top_builddir)/tmp/valgrind-%q{T}-%p.log --leak-check=full --error-exitcode=119 --suppressions=$(abs_top_srcdir)/valgrind-suppressions' + ],[ + # No valgrind, so substitute VG with something that will break. + VG=VALGRIND_IS_NOT_INSTALLED +]) +AC_SUBST([VG]) +AM_SUBST_NOTMAKE([VG]) -- 2.5.0
Richard W.M. Jones
2015-Oct-29 15:02 UTC
[Libguestfs] [PATCH 07/16] configure: Move basic C compiler environment checks to separate file.
Also gnulib stuff. --- configure.ac | 172 +-------------------------------------------------- m4/guestfs_c.m4 | 189 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 191 insertions(+), 170 deletions(-) create mode 100644 m4/guestfs_c.m4 diff --git a/configure.ac b/configure.ac index 2dcb17e..f5303a0 100644 --- a/configure.ac +++ b/configure.ac @@ -96,167 +96,8 @@ dnl Check for external programs required to either build or run dnl libguestfs. m4_include([m4/guestfs_progs.m4]) -dnl Define the host CPU architecture (defines 'host_cpu') -AC_CANONICAL_HOST - -dnl Check for basic C environment. -AC_PROG_CC_STDC -AC_PROG_INSTALL -AC_PROG_CPP - -AC_ARG_ENABLE([werror], - [AS_HELP_STRING([--enable-werror], - [turn GCC warnings into errors (for developers)])], - [case $enableval in - yes|no) ;; - *) AC_MSG_ERROR([bad value $enableval for werror option]) ;; - esac - gl_gcc_werror=$enableval], - [gl_gcc_werror=no] -) - -if test "$gl_gcc_werror" = yes; then - gl_WARN_ADD([-Werror], [WERROR_CFLAGS]) - AC_SUBST([WERROR_CFLAGS]) -fi - -dnl This, $nw, is the list of warnings we disable. -nw-nw="$nw -Waggregate-return" # anachronistic -nw="$nw -Wc++-compat" # We don't care about C++ compilers -nw="$nw -Wundef" # Warns on '#if GNULIB_FOO' etc in gnulib -nw="$nw -Wtraditional" # Warns on #elif which we use often -nw="$nw -Wcast-qual" # Too many warnings for now -nw="$nw -Wconversion" # Too many warnings for now -nw="$nw -Wsystem-headers" # Don't let system headers trigger warnings -nw="$nw -Wsign-conversion" # Not an error -nw="$nw -Wtraditional-conversion" # Don't care about pre-ANSI compilers -nw="$nw -Wpadded" # Our structs are not padded -nw="$nw -Wvla" # two warnings in mount.c -dnl things I might fix soon: -nw="$nw -Wmissing-format-attribute" # daemon.h's asprintf_nowarn -nw="$nw -Winline" # daemon.h's asprintf_nowarn -nw="$nw -Wshadow" # numerous, plus we're not unanimous -nw="$nw -Wunsafe-loop-optimizations" # just a warning that an optimization - # was not possible, safe to ignore -nw="$nw -Wpacked" # Allow attribute((packed)) on structs -nw="$nw -Wlong-long" # Allow long long since it's required - # by Python, Ruby and xstrtoll. -nw="$nw -Wsuggest-attribute=pure" # Don't suggest pure functions. -nw="$nw -Wsuggest-attribute=const" # Don't suggest const functions. -nw="$nw -Wunsuffixed-float-constants" # Don't care about these. -nw="$nw -Wswitch-default" # This warning is actively dangerous. -nw="$nw -Woverlength-strings" # Who cares about stupid ISO C99 limit. - -gl_MANYWARN_ALL_GCC([ws]) -gl_MANYWARN_COMPLEMENT([ws], [$ws], [$nw]) -for w in $ws; do - gl_WARN_ADD([$w]) -done - -dnl Normally we disable warnings in $nw above. However $nw only -dnl filters out exact matching warning strings from a list inside -dnl gnulib (see m4/manywarnings.m4). So we need to explicitly list a -dnl few disabled warnings below. - -dnl Unused parameters are not a bug. -gl_WARN_ADD([-Wno-unused-parameter]) - -dnl Missing field initializers is not a bug in C. -gl_WARN_ADD([-Wno-missing-field-initializers]) - -dnl Display the name of the warning option with the warning. -gl_WARN_ADD([-fdiagnostics-show-option]) - -dnl Now some warnings we want to enable and/or customize ... - -dnl Warn about large stack allocations. 10000 happens to be the -dnl same size as Coverity warns about. -gl_WARN_ADD([-Wframe-larger-than=10000]) - -AC_SUBST([WARN_CFLAGS]) - -AC_DEFINE([lint], [1], [Define to 1 if the compiler is checking for lint.]) -AC_DEFINE([GNULIB_PORTCHECK], [1], [Enable some gnulib portability checks.]) -AH_VERBATIM([FORTIFY_SOURCE],[ -/* Enable compile-time and run-time bounds-checking, and some warnings. */ -#if __OPTIMIZE__ && (! defined (_FORTIFY_SOURCE) || _FORTIFY_SOURCE < 2) -# undef _FORTIFY_SOURCE -# define _FORTIFY_SOURCE 2 -#endif]) - -AC_C_PROTOTYPES -test "x$U" != "x" && AC_MSG_ERROR([Compiler not ANSI compliant]) - -AM_PROG_CC_C_O - -# Provide a global place to set CFLAGS. (Note that setting AM_CFLAGS -# is no use because it doesn't override target_CFLAGS). -#--- -# Kill -fstrict-overflow which is a license for the C compiler to make -# dubious and often unsafe optimizations, in a time-wasting attempt to -# deal with CPU architectures that do not exist. -CFLAGS="$CFLAGS -fno-strict-overflow -Wno-strict-overflow" - -dnl Work out how to specify the linker script to the linker. -VERSION_SCRIPT_FLAGS=-Wl,--version-script-`/usr/bin/ld --help 2>&1 | grep -- --version-script >/dev/null` || \ - VERSION_SCRIPT_FLAGS="-Wl,-M -Wl," -AC_SUBST(VERSION_SCRIPT_FLAGS) - -dnl Use -fvisibility=hidden by default in the library. -dnl http://gcc.gnu.org/wiki/Visibility -AS_IF([test -n "$GCC"], - [AC_SUBST([GCC_VISIBILITY_HIDDEN], [-fvisibility=hidden])], - [AC_SUBST([GCC_VISIBILITY_HIDDEN], [:])]) - -dnl Check support for 64 bit file offsets. -AC_SYS_LARGEFILE - -dnl Check sizeof long. -AC_CHECK_SIZEOF([long]) - -dnl Check if __attribute__((cleanup(...))) works. -dnl XXX It would be nice to use AC_COMPILE_IFELSE here, but gcc just -dnl emits a warning for attributes that it doesn't understand. -AC_MSG_CHECKING([if __attribute__((cleanup(...))) works with this compiler]) -AC_RUN_IFELSE([ -AC_LANG_SOURCE([[ -#include <stdio.h> -#include <stdlib.h> - -void -freep (void *ptr) -{ - exit (EXIT_SUCCESS); -} - -void -test (void) -{ - __attribute__((cleanup(freep))) char *ptr = malloc (100); -} - -int -main (int argc, char *argv[]) -{ - test (); - exit (EXIT_FAILURE); -} -]]) - ],[ - AC_MSG_RESULT([yes]) - AC_DEFINE([HAVE_ATTRIBUTE_CLEANUP],[1],[Define to 1 if '__attribute__((cleanup(...)))' works with this compiler.]) - ],[ - AC_MSG_WARN( -['__attribute__((cleanup(...)))' does not work. - -You may not be using a sufficiently recent version of GCC or CLANG, or -you may be using a C compiler which does not support this attribute, -or the configure test may be wrong. - -The code will still compile, but is likely to leak memory and other -resources when it runs.])]) +dnl The C compiler environment. +m4_include([m4/guestfs_c.m4]) dnl Check if dirent (readdir) supports d_type member. AC_STRUCT_DIRENT_D_TYPE @@ -840,15 +681,6 @@ dnl For search paths. AC_DEFINE_UNQUOTED([PATH_SEPARATOR],["$PATH_SEPARATOR"], [Character that separates path elements in search paths]) -AC_MSG_CHECKING([if we should run the GNUlib tests]) -AC_ARG_ENABLE([gnulib-tests], - [AS_HELP_STRING([--disable-gnulib-tests], - [disable running GNU Portability library tests @<:@default=yes@:>@])], - [ENABLE_GNULIB_TESTS="$enableval"], - [ENABLE_GNULIB_TESTS=yes]) -AM_CONDITIONAL([ENABLE_GNULIB_TESTS],[test "x$ENABLE_GNULIB_TESTS" = "xyes"]) -AC_MSG_RESULT([$ENABLE_GNULIB_TESTS]) - dnl Library versioning. MAX_PROC_NR=`cat $srcdir/src/MAX_PROC_NR` AC_SUBST(MAX_PROC_NR) diff --git a/m4/guestfs_c.m4 b/m4/guestfs_c.m4 new file mode 100644 index 0000000..e91446f --- /dev/null +++ b/m4/guestfs_c.m4 @@ -0,0 +1,189 @@ +# libguestfs +# Copyright (C) 2009-2015 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +dnl The C compiler environment. +dnl Define the host CPU architecture (defines 'host_cpu') +AC_CANONICAL_HOST + +dnl Check for basic C environment. +AC_PROG_CC_STDC +AC_PROG_INSTALL +AC_PROG_CPP + +AC_ARG_ENABLE([werror], + [AS_HELP_STRING([--enable-werror], + [turn GCC warnings into errors (for developers)])], + [case $enableval in + yes|no) ;; + *) AC_MSG_ERROR([bad value $enableval for werror option]) ;; + esac + gl_gcc_werror=$enableval], + [gl_gcc_werror=no] +) + +if test "$gl_gcc_werror" = yes; then + gl_WARN_ADD([-Werror], [WERROR_CFLAGS]) + AC_SUBST([WERROR_CFLAGS]) +fi + +dnl This, $nw, is the list of warnings we disable. +nw+nw="$nw -Waggregate-return" # anachronistic +nw="$nw -Wc++-compat" # We don't care about C++ compilers +nw="$nw -Wundef" # Warns on '#if GNULIB_FOO' etc in gnulib +nw="$nw -Wtraditional" # Warns on #elif which we use often +nw="$nw -Wcast-qual" # Too many warnings for now +nw="$nw -Wconversion" # Too many warnings for now +nw="$nw -Wsystem-headers" # Don't let system headers trigger warnings +nw="$nw -Wsign-conversion" # Not an error +nw="$nw -Wtraditional-conversion" # Don't care about pre-ANSI compilers +nw="$nw -Wpadded" # Our structs are not padded +nw="$nw -Wvla" # two warnings in mount.c +dnl things I might fix soon: +nw="$nw -Wmissing-format-attribute" # daemon.h's asprintf_nowarn +nw="$nw -Winline" # daemon.h's asprintf_nowarn +nw="$nw -Wshadow" # numerous, plus we're not unanimous +nw="$nw -Wunsafe-loop-optimizations" # just a warning that an optimization + # was not possible, safe to ignore +nw="$nw -Wpacked" # Allow attribute((packed)) on structs +nw="$nw -Wlong-long" # Allow long long since it's required + # by Python, Ruby and xstrtoll. +nw="$nw -Wsuggest-attribute=pure" # Don't suggest pure functions. +nw="$nw -Wsuggest-attribute=const" # Don't suggest const functions. +nw="$nw -Wunsuffixed-float-constants" # Don't care about these. +nw="$nw -Wswitch-default" # This warning is actively dangerous. +nw="$nw -Woverlength-strings" # Who cares about stupid ISO C99 limit. + +gl_MANYWARN_ALL_GCC([ws]) +gl_MANYWARN_COMPLEMENT([ws], [$ws], [$nw]) +for w in $ws; do + gl_WARN_ADD([$w]) +done + +dnl Normally we disable warnings in $nw above. However $nw only +dnl filters out exact matching warning strings from a list inside +dnl gnulib (see m4/manywarnings.m4). So we need to explicitly list a +dnl few disabled warnings below. + +dnl Unused parameters are not a bug. +gl_WARN_ADD([-Wno-unused-parameter]) + +dnl Missing field initializers is not a bug in C. +gl_WARN_ADD([-Wno-missing-field-initializers]) + +dnl Display the name of the warning option with the warning. +gl_WARN_ADD([-fdiagnostics-show-option]) + +dnl Now some warnings we want to enable and/or customize ... + +dnl Warn about large stack allocations. 10000 happens to be the +dnl same size as Coverity warns about. +gl_WARN_ADD([-Wframe-larger-than=10000]) + +AC_SUBST([WARN_CFLAGS]) + +AC_DEFINE([lint], [1], [Define to 1 if the compiler is checking for lint.]) +AC_DEFINE([GNULIB_PORTCHECK], [1], [Enable some gnulib portability checks.]) +AH_VERBATIM([FORTIFY_SOURCE],[ +/* Enable compile-time and run-time bounds-checking, and some warnings. */ +#if __OPTIMIZE__ && (! defined (_FORTIFY_SOURCE) || _FORTIFY_SOURCE < 2) +# undef _FORTIFY_SOURCE +# define _FORTIFY_SOURCE 2 +#endif]) + +AC_C_PROTOTYPES +test "x$U" != "x" && AC_MSG_ERROR([Compiler not ANSI compliant]) + +AM_PROG_CC_C_O + +# Provide a global place to set CFLAGS. (Note that setting AM_CFLAGS +# is no use because it doesn't override target_CFLAGS). +#--- +# Kill -fstrict-overflow which is a license for the C compiler to make +# dubious and often unsafe optimizations, in a time-wasting attempt to +# deal with CPU architectures that do not exist. +CFLAGS="$CFLAGS -fno-strict-overflow -Wno-strict-overflow" + +dnl Work out how to specify the linker script to the linker. +VERSION_SCRIPT_FLAGS=-Wl,--version-script+`/usr/bin/ld --help 2>&1 | grep -- --version-script >/dev/null` || \ + VERSION_SCRIPT_FLAGS="-Wl,-M -Wl," +AC_SUBST(VERSION_SCRIPT_FLAGS) + +dnl Use -fvisibility=hidden by default in the library. +dnl http://gcc.gnu.org/wiki/Visibility +AS_IF([test -n "$GCC"], + [AC_SUBST([GCC_VISIBILITY_HIDDEN], [-fvisibility=hidden])], + [AC_SUBST([GCC_VISIBILITY_HIDDEN], [:])]) + +dnl Check support for 64 bit file offsets. +AC_SYS_LARGEFILE + +dnl Check sizeof long. +AC_CHECK_SIZEOF([long]) + +dnl Check if __attribute__((cleanup(...))) works. +dnl XXX It would be nice to use AC_COMPILE_IFELSE here, but gcc just +dnl emits a warning for attributes that it doesn't understand. +AC_MSG_CHECKING([if __attribute__((cleanup(...))) works with this compiler]) +AC_RUN_IFELSE([ +AC_LANG_SOURCE([[ +#include <stdio.h> +#include <stdlib.h> + +void +freep (void *ptr) +{ + exit (EXIT_SUCCESS); +} + +void +test (void) +{ + __attribute__((cleanup(freep))) char *ptr = malloc (100); +} + +int +main (int argc, char *argv[]) +{ + test (); + exit (EXIT_FAILURE); +} +]]) + ],[ + AC_MSG_RESULT([yes]) + AC_DEFINE([HAVE_ATTRIBUTE_CLEANUP],[1],[Define to 1 if '__attribute__((cleanup(...)))' works with this compiler.]) + ],[ + AC_MSG_WARN( +['__attribute__((cleanup(...)))' does not work. + +You may not be using a sufficiently recent version of GCC or CLANG, or +you may be using a C compiler which does not support this attribute, +or the configure test may be wrong. + +The code will still compile, but is likely to leak memory and other +resources when it runs.])]) + +dnl Should we run the gnulib tests? +AC_MSG_CHECKING([if we should run the GNUlib tests]) +AC_ARG_ENABLE([gnulib-tests], + [AS_HELP_STRING([--disable-gnulib-tests], + [disable running GNU Portability library tests @<:@default=yes@:>@])], + [ENABLE_GNULIB_TESTS="$enableval"], + [ENABLE_GNULIB_TESTS=yes]) +AM_CONDITIONAL([ENABLE_GNULIB_TESTS],[test "x$ENABLE_GNULIB_TESTS" = "xyes"]) +AC_MSG_RESULT([$ENABLE_GNULIB_TESTS]) -- 2.5.0
Richard W.M. Jones
2015-Oct-29 15:02 UTC
[Libguestfs] [PATCH 08/16] configure: Move C library checks to separate file.
--- configure.ac | 271 +-------------------------------------------- m4/guestfs_libraries.m4 | 288 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 290 insertions(+), 269 deletions(-) create mode 100644 m4/guestfs_libraries.m4 diff --git a/configure.ac b/configure.ac index f5303a0..f25fdec 100644 --- a/configure.ac +++ b/configure.ac @@ -99,146 +99,8 @@ m4_include([m4/guestfs_progs.m4]) dnl The C compiler environment. m4_include([m4/guestfs_c.m4]) -dnl Check if dirent (readdir) supports d_type member. -AC_STRUCT_DIRENT_D_TYPE - -dnl Check if stat has the required fields. -AC_STRUCT_ST_BLOCKS -AC_CHECK_MEMBER([struct stat.st_blksize],[ - AC_DEFINE([HAVE_STRUCT_STAT_ST_BLKSIZE],[1],[Define to 1 if 'st_blksize' is a member of 'struct stat'.])]) -AC_CHECK_MEMBER([struct stat.st_atim.tv_nsec],[ - AC_DEFINE([HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC],[1],[Define to 1 if 'st_mtim.tv_nsec' is a member of 'struct stat'.])]) -AC_CHECK_MEMBER([struct stat.st_mtim.tv_nsec],[ - AC_DEFINE([HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC],[1],[Define to 1 if 'st_mtim.tv_nsec' is a member of 'struct stat'.])]) -AC_CHECK_MEMBER([struct stat.st_ctim.tv_nsec],[ - AC_DEFINE([HAVE_STRUCT_STAT_ST_CTIM_TV_NSEC],[1],[Define to 1 if 'st_mtim.tv_nsec' is a member of 'struct stat'.])]) - -dnl Define a C symbol for the host CPU architecture. -AC_DEFINE_UNQUOTED([host_cpu],["$host_cpu"],[Host architecture.]) - -dnl Check if libc has program_invocation_short_name. -AC_CHECK_DECLS([program_invocation_short_name], [], [], [#include <errno.h>]) - -dnl Headers. -AC_CHECK_HEADERS([\ - attr/xattr.h \ - byteswap.h \ - endian.h \ - sys/endian.h \ - errno.h \ - linux/fs.h \ - linux/raid/md_u.h \ - printf.h \ - sys/inotify.h \ - sys/resource.h \ - sys/socket.h \ - sys/statvfs.h \ - sys/time.h \ - sys/types.h \ - sys/un.h \ - sys/wait.h \ - windows.h \ - sys/xattr.h]) - -dnl Functions. -AC_CHECK_FUNCS([\ - be32toh \ - fsync \ - futimens \ - getprogname \ - getxattr \ - htonl \ - htons \ - inotify_init1 \ - lgetxattr \ - listxattr \ - llistxattr \ - lsetxattr \ - lremovexattr \ - mknod \ - ntohl \ - ntohs \ - posix_fallocate \ - posix_fadvise \ - removexattr \ - setitimer \ - setrlimit \ - setxattr \ - sigaction \ - statvfs \ - sync]) - -dnl Check for UNIX_PATH_MAX, creating a custom one if not available. -AC_MSG_CHECKING([for UNIX_PATH_MAX]) -AC_COMPILE_IFELSE([ - AC_LANG_PROGRAM([[ -#include <sys/un.h> - ]], [[ -#ifndef UNIX_PATH_MAX -#error UNIX_PATH_MAX not defined -#endif - ]])], [ - AC_MSG_RESULT([yes]) - ], [ - AC_MSG_RESULT([no]) - AC_MSG_CHECKING([for size of sockaddr_un.sun_path]) - AC_COMPUTE_INT(unix_path_max, [sizeof (myaddr.sun_path)], [ -#include <sys/un.h> -struct sockaddr_un myaddr; - ], [ - AC_MSG_ERROR([cannot get it]) - ]) - AC_MSG_RESULT([$unix_path_max]) - AC_DEFINE_UNQUOTED([UNIX_PATH_MAX], $unix_path_max, [Custom value for UNIX_PATH_MAX]) - ]) - -dnl tgetent, tputs and UP [sic] are all required. They come from the lower -dnl tinfo library, but might be part of ncurses directly. -PKG_CHECK_MODULES([LIBTINFO], [tinfo], [], [ - PKG_CHECK_MODULES([LIBTINFO], [ncurses]) -]) -AC_SUBST([LIBTINFO_CFLAGS]) -AC_SUBST([LIBTINFO_LIBS]) - -dnl GNU gettext tools (optional). -AC_CHECK_PROG([XGETTEXT],[xgettext],[xgettext],[no]) -AC_CHECK_PROG([MSGCAT],[msgcat],[msgcat],[no]) -AC_CHECK_PROG([MSGFMT],[msgfmt],[msgfmt],[no]) -AC_CHECK_PROG([MSGMERGE],[msgmerge],[msgmerge],[no]) - -dnl Check they are the GNU gettext tools. -AC_MSG_CHECKING([msgfmt is GNU tool]) -if $MSGFMT --version >/dev/null 2>&1 && $MSGFMT --version | grep -q 'GNU gettext'; then - msgfmt_is_gnu=yes -else - msgfmt_is_gnu=no -fi -AC_MSG_RESULT([$msgfmt_is_gnu]) -AM_CONDITIONAL([HAVE_GNU_GETTEXT], - [test "x$XGETTEXT" != "xno" && test "x$MSGCAT" != "xno" && test "x$MSGFMT" != "xno" && test "x$MSGMERGE" != "xno" && test "x$msgfmt_is_gnu" != "xno"]) - -dnl Check for gettext. -AM_GNU_GETTEXT([external]) - -dnl Default backend. -AC_MSG_CHECKING([if the user specified a default backend]) -AC_ARG_WITH([default-backend], - [AS_HELP_STRING([--with-default-backend="direct|libvirt|..."], - [set default backend @<:@default=direct@:>@])], - [DEFAULT_BACKEND="$withval"], - [DEFAULT_BACKEND=direct]) -AC_MSG_RESULT([$DEFAULT_BACKEND]) -AC_DEFINE_UNQUOTED([DEFAULT_BACKEND],["$DEFAULT_BACKEND"], - [Default backend.]) - -dnl Fail with error if user does --with-default-attach-method. -AC_ARG_WITH([default-attach-method], - [AS_HELP_STRING([--with-default-attach-method="..."], - [use --with-default-backend instead])], - [AC_MSG_FAILURE([--with-default-attach-method no longer works in -this version of libguestfs, use - ./configure --with-default-backend=$withval -instead.])]) +dnl Any C libraries required by the libguestfs C library (not the daemon). +m4_include([m4/guestfs_libraries.m4]) dnl Build the daemon? AC_MSG_CHECKING([if we should build the daemon]) @@ -416,61 +278,6 @@ if test "$ac_cv_search_crypt" = "-lcrypt" ; then fi AC_SUBST([LIBCRYPT_LIBS]) -dnl Check for libdl/dlopen (optional - only used to test if the library -dnl can be used with libdl). -AC_CHECK_LIB([dl],[dlopen],[have_libdl=yes],[have_libdl=no]) -AC_CHECK_HEADERS([dlfcn.h],[have_dlfcn=yes],[have_dlfcn=no]) -AM_CONDITIONAL([HAVE_LIBDL], - [test "x$have_libdl" = "xyes" && test "x$have_dlfcn" = "xyes"]) - -dnl Check for rpcgen and XDR library. rpcgen is optional. -AC_CHECK_PROG([RPCGEN],[rpcgen],[rpcgen],[no]) -AM_CONDITIONAL([HAVE_RPCGEN],[test "x$RPCGEN" != "xno"]) -AC_CHECK_LIB([portablexdr],[xdrmem_create],[],[ - AC_SEARCH_LIBS([xdrmem_create],[rpc xdr nsl]) -]) -AC_SEARCH_LIBS([xdr_u_int64_t],[portablexdr rpc xdr nsl],[ - AC_DEFINE([HAVE_XDR_U_INT64_T],[1],[Define to 1 if xdr_u_int64_t() exists.]) -]) -AC_SEARCH_LIBS([xdr_uint64_t],[portablexdr rpc xdr nsl],[ - AC_DEFINE([HAVE_XDR_UINT64_T],[1],[Define to 1 if xdr_uint64_t() exists.]) -]) -AM_CONDITIONAL([HAVE_XDR_U_INT64_T], - [test "x$ac_cv_search_xdr_u_int64_t" != "xno"]) -AM_CONDITIONAL([HAVE_XDR_UINT64_T], - [test "x$ac_cv_search_xdr_uint64_t" != "xno"]) - -dnl Check for libselinux (optional). -AC_CHECK_HEADERS([selinux/selinux.h]) -AC_CHECK_LIB([selinux],[setexeccon],[ - have_libselinux="$ac_cv_header_selinux_selinux_h" - SELINUX_LIBS="-lselinux" - - old_LIBS="$LIBS" - LIBS="$LIBS $SELINUX_LIBS" - AC_CHECK_FUNCS([setcon getcon]) - LIBS="$old_LIBS" -],[have_libselinux=no]) -if test "x$have_libselinux" = "xyes"; then - AC_DEFINE([HAVE_LIBSELINUX],[1],[Define to 1 if you have libselinux.]) -fi -AC_SUBST([SELINUX_LIBS]) - -dnl Check for systemtap/DTrace userspace probes (optional). -dnl Since the probe points break under clang, allow this to be disabled. -AC_ARG_ENABLE([probes], - AS_HELP_STRING([--disable-probes], [disable systemtap/DTrace userspace probes]), - [], - [enable_probes=yes]) -AS_IF([test "x$enable_probes" != "xno"],[ - dnl http://sourceware.org/systemtap/wiki/AddingUserSpaceProbingToApps - AC_CHECK_HEADERS([sys/sdt.h]) - dnl AC_CHECK_PROG([DTRACE],[dtrace],[dtrace],[no]) - AS_IF([test "x$ac_cv_header_sys_sdt_h" = "xyes"],[ - AC_DEFINE([ENABLE_PROBES],[1],[Enable systemtap/DTrace userspace probes.]) - ]) -]) - dnl liblzma can be used by virt-builder (optional). PKG_CHECK_MODULES([LIBLZMA], [liblzma], [ AC_SUBST([LIBLZMA_CFLAGS]) @@ -488,14 +295,6 @@ PKG_CHECK_MODULES([LIBLZMA], [liblzma], [ dnl Check for QEMU. m4_include([m4/guestfs_qemu.m4]) -dnl Enable packet dumps when in verbose mode. This generates lots -dnl of debug info, only useful for people debugging the RPC mechanism. -AC_ARG_ENABLE([packet-dump],[ - AS_HELP_STRING([--enable-packet-dump], - [enable packet dumps in verbose mode @<:@default=no@:>@])], - [AC_DEFINE([ENABLE_PACKET_DUMP],[1],[Enable packet dumps in verbose mode.])], - []) - dnl Readline. AC_ARG_WITH([readline],[ AS_HELP_STRING([--with-readline], @@ -521,20 +320,6 @@ AS_IF([test "x$with_readline" != xno],[ LIBS="$old_LIBS" ]) -dnl Check for PCRE (required) -PKG_CHECK_MODULES([PCRE], [libpcre]) - -dnl Check for Augeas >= 1.0.0 (required). -PKG_CHECK_MODULES([AUGEAS],[augeas >= 1.0.0]) - -dnl libmagic (highly recommended) -AC_CHECK_LIB([magic],[magic_file],[ - AC_CHECK_HEADER([magic.h],[ - AC_SUBST([MAGIC_LIBS], ["-lmagic"]) - AC_DEFINE([HAVE_LIBMAGIC],[1],[libmagic found at compile time.]) - ], []) -],[AC_MSG_WARN([libmagic not found, some core features will be disabled])]) - dnl POSIX acl library (highly recommended) AC_CHECK_LIB([acl],[acl_from_text],[ AC_CHECK_HEADER([sys/acl.h],[ @@ -551,32 +336,6 @@ AC_CHECK_LIB([cap],[cap_from_text],[ ], []) ],[AC_MSG_WARN([Linux capabilities library (libcap) not found])]) -dnl libvirt (highly recommended) -AC_ARG_WITH([libvirt],[ - AS_HELP_STRING([--without-libvirt], - [disable libvirt support @<:@default=check@:>@])], - [], - [with_libvirt=check]) -AS_IF([test "$with_libvirt" != "no"],[ - PKG_CHECK_MODULES([LIBVIRT], [libvirt],[ - AC_SUBST([LIBVIRT_CFLAGS]) - AC_SUBST([LIBVIRT_LIBS]) - AC_DEFINE([HAVE_LIBVIRT],[1],[libvirt found at compile time.]) - ], - [AC_MSG_WARN([libvirt not found, some core features will be disabled])]) -]) -AM_CONDITIONAL([HAVE_LIBVIRT],[test "x$LIBVIRT_LIBS" != "x"]) - -libvirt_ro_uri='qemu+unix:///system?socket=/var/run/libvirt/libvirt-sock-ro' -AC_SUBST([libvirt_ro_uri]) - -dnl libxml2 (required) -PKG_CHECK_MODULES([LIBXML2], [libxml-2.0]) -old_LIBS="$LIBS" -LIBS="$LIBS $LIBXML2_LIBS" -AC_CHECK_FUNCS([xmlBufferDetach]) -LIBS="$old_LIBS" - dnl libconfig (highly recommended) PKG_CHECK_MODULES([LIBCONFIG], [libconfig],[ AC_SUBST([LIBCONFIG_CFLAGS]) @@ -643,24 +402,6 @@ AS_IF([test "x$enable_fuse" != "xno"],[ ]) AM_CONDITIONAL([HAVE_FUSE],[test "x$enable_fuse" != "xno"]) -dnl Check for yajl JSON library (optional). -PKG_CHECK_MODULES([YAJL], [yajl >= 2.0.4], [ - AC_SUBST([YAJL_CFLAGS]) - AC_SUBST([YAJL_LIBS]) - AC_DEFINE([HAVE_YAJL],[1],[Define to 1 if you have yajl.]) -],[AC_MSG_WARN([yajl not found, some features will be disabled])]) -AM_CONDITIONAL([HAVE_YAJL],[test "x$YAJL_LIBS" != "x"]) - -dnl Check for C++ (optional, we just use this to test the header works). -AC_PROG_CXX - -dnl The C++ compiler test is pretty useless because even if it fails -dnl it sets CXX=g++. So test the compiler actually works. -AC_MSG_CHECKING([if the C++ compiler really really works]) -AS_IF([$CXX --version >&AS_MESSAGE_LOG_FD 2>&1],[have_cxx=yes],[have_cxx=no]) -AC_MSG_RESULT([$have_cxx]) -AM_CONDITIONAL([HAVE_CXX], [test "$have_cxx" = "yes"]) - dnl Check for language bindings. m4_include([m4/guestfs_ocaml.m4]) m4_include([m4/guestfs_perl.m4]) @@ -677,14 +418,6 @@ m4_include([m4/guestfs_gobject.m4]) dnl Bash completion. m4_include([m4/guestfs_bash_completion.m4]) -dnl For search paths. -AC_DEFINE_UNQUOTED([PATH_SEPARATOR],["$PATH_SEPARATOR"], - [Character that separates path elements in search paths]) - -dnl Library versioning. -MAX_PROC_NR=`cat $srcdir/src/MAX_PROC_NR` -AC_SUBST(MAX_PROC_NR) - dnl Replace libtool with a wrapper that clobbers dependency_libs in *.la files dnl http://lists.fedoraproject.org/pipermail/devel/2010-November/146343.html LIBTOOL='bash $(top_srcdir)/libtool-kill-dependency_libs.sh $(top_builddir)/libtool' diff --git a/m4/guestfs_libraries.m4 b/m4/guestfs_libraries.m4 new file mode 100644 index 0000000..21c89a4 --- /dev/null +++ b/m4/guestfs_libraries.m4 @@ -0,0 +1,288 @@ +# libguestfs +# Copyright (C) 2009-2015 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +dnl Any C libraries required by the libguestfs C library (not the daemon). + +dnl Check if dirent (readdir) supports d_type member. +AC_STRUCT_DIRENT_D_TYPE + +dnl Check if stat has the required fields. +AC_STRUCT_ST_BLOCKS +AC_CHECK_MEMBER([struct stat.st_blksize],[ + AC_DEFINE([HAVE_STRUCT_STAT_ST_BLKSIZE],[1],[Define to 1 if 'st_blksize' is a member of 'struct stat'.])]) +AC_CHECK_MEMBER([struct stat.st_atim.tv_nsec],[ + AC_DEFINE([HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC],[1],[Define to 1 if 'st_mtim.tv_nsec' is a member of 'struct stat'.])]) +AC_CHECK_MEMBER([struct stat.st_mtim.tv_nsec],[ + AC_DEFINE([HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC],[1],[Define to 1 if 'st_mtim.tv_nsec' is a member of 'struct stat'.])]) +AC_CHECK_MEMBER([struct stat.st_ctim.tv_nsec],[ + AC_DEFINE([HAVE_STRUCT_STAT_ST_CTIM_TV_NSEC],[1],[Define to 1 if 'st_mtim.tv_nsec' is a member of 'struct stat'.])]) + +dnl Define a C symbol for the host CPU architecture. +AC_DEFINE_UNQUOTED([host_cpu],["$host_cpu"],[Host architecture.]) + +dnl Check if libc has program_invocation_short_name. +AC_CHECK_DECLS([program_invocation_short_name], [], [], [#include <errno.h>]) + +dnl Headers. +AC_CHECK_HEADERS([\ + attr/xattr.h \ + byteswap.h \ + endian.h \ + sys/endian.h \ + errno.h \ + linux/fs.h \ + linux/raid/md_u.h \ + printf.h \ + sys/inotify.h \ + sys/resource.h \ + sys/socket.h \ + sys/statvfs.h \ + sys/time.h \ + sys/types.h \ + sys/un.h \ + sys/wait.h \ + windows.h \ + sys/xattr.h]) + +dnl Functions. +AC_CHECK_FUNCS([\ + be32toh \ + fsync \ + futimens \ + getprogname \ + getxattr \ + htonl \ + htons \ + inotify_init1 \ + lgetxattr \ + listxattr \ + llistxattr \ + lsetxattr \ + lremovexattr \ + mknod \ + ntohl \ + ntohs \ + posix_fallocate \ + posix_fadvise \ + removexattr \ + setitimer \ + setrlimit \ + setxattr \ + sigaction \ + statvfs \ + sync]) + +dnl Check for UNIX_PATH_MAX, creating a custom one if not available. +AC_MSG_CHECKING([for UNIX_PATH_MAX]) +AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ +#include <sys/un.h> + ]], [[ +#ifndef UNIX_PATH_MAX +#error UNIX_PATH_MAX not defined +#endif + ]])], [ + AC_MSG_RESULT([yes]) + ], [ + AC_MSG_RESULT([no]) + AC_MSG_CHECKING([for size of sockaddr_un.sun_path]) + AC_COMPUTE_INT(unix_path_max, [sizeof (myaddr.sun_path)], [ +#include <sys/un.h> +struct sockaddr_un myaddr; + ], [ + AC_MSG_ERROR([cannot get it]) + ]) + AC_MSG_RESULT([$unix_path_max]) + AC_DEFINE_UNQUOTED([UNIX_PATH_MAX], $unix_path_max, [Custom value for UNIX_PATH_MAX]) + ]) + +dnl tgetent, tputs and UP [sic] are all required. They come from the lower +dnl tinfo library, but might be part of ncurses directly. +PKG_CHECK_MODULES([LIBTINFO], [tinfo], [], [ + PKG_CHECK_MODULES([LIBTINFO], [ncurses]) +]) +AC_SUBST([LIBTINFO_CFLAGS]) +AC_SUBST([LIBTINFO_LIBS]) + +dnl GNU gettext tools (optional). +AC_CHECK_PROG([XGETTEXT],[xgettext],[xgettext],[no]) +AC_CHECK_PROG([MSGCAT],[msgcat],[msgcat],[no]) +AC_CHECK_PROG([MSGFMT],[msgfmt],[msgfmt],[no]) +AC_CHECK_PROG([MSGMERGE],[msgmerge],[msgmerge],[no]) + +dnl Check they are the GNU gettext tools. +AC_MSG_CHECKING([msgfmt is GNU tool]) +if $MSGFMT --version >/dev/null 2>&1 && $MSGFMT --version | grep -q 'GNU gettext'; then + msgfmt_is_gnu=yes +else + msgfmt_is_gnu=no +fi +AC_MSG_RESULT([$msgfmt_is_gnu]) +AM_CONDITIONAL([HAVE_GNU_GETTEXT], + [test "x$XGETTEXT" != "xno" && test "x$MSGCAT" != "xno" && test "x$MSGFMT" != "xno" && test "x$MSGMERGE" != "xno" && test "x$msgfmt_is_gnu" != "xno"]) + +dnl Check for gettext. +AM_GNU_GETTEXT([external]) + +dnl Default backend. +AC_MSG_CHECKING([if the user specified a default backend]) +AC_ARG_WITH([default-backend], + [AS_HELP_STRING([--with-default-backend="direct|libvirt|..."], + [set default backend @<:@default=direct@:>@])], + [DEFAULT_BACKEND="$withval"], + [DEFAULT_BACKEND=direct]) +AC_MSG_RESULT([$DEFAULT_BACKEND]) +AC_DEFINE_UNQUOTED([DEFAULT_BACKEND],["$DEFAULT_BACKEND"], + [Default backend.]) + +dnl Fail with error if user does --with-default-attach-method. +AC_ARG_WITH([default-attach-method], + [AS_HELP_STRING([--with-default-attach-method="..."], + [use --with-default-backend instead])], + [AC_MSG_FAILURE([--with-default-attach-method no longer works in +this version of libguestfs, use + ./configure --with-default-backend=$withval +instead.])]) + +dnl Check for libdl/dlopen (optional - only used to test if the library +dnl can be used with libdl). +AC_CHECK_LIB([dl],[dlopen],[have_libdl=yes],[have_libdl=no]) +AC_CHECK_HEADERS([dlfcn.h],[have_dlfcn=yes],[have_dlfcn=no]) +AM_CONDITIONAL([HAVE_LIBDL], + [test "x$have_libdl" = "xyes" && test "x$have_dlfcn" = "xyes"]) + +dnl Check for rpcgen and XDR library. rpcgen is optional. +AC_CHECK_PROG([RPCGEN],[rpcgen],[rpcgen],[no]) +AM_CONDITIONAL([HAVE_RPCGEN],[test "x$RPCGEN" != "xno"]) +AC_CHECK_LIB([portablexdr],[xdrmem_create],[],[ + AC_SEARCH_LIBS([xdrmem_create],[rpc xdr nsl]) +]) +AC_SEARCH_LIBS([xdr_u_int64_t],[portablexdr rpc xdr nsl],[ + AC_DEFINE([HAVE_XDR_U_INT64_T],[1],[Define to 1 if xdr_u_int64_t() exists.]) +]) +AC_SEARCH_LIBS([xdr_uint64_t],[portablexdr rpc xdr nsl],[ + AC_DEFINE([HAVE_XDR_UINT64_T],[1],[Define to 1 if xdr_uint64_t() exists.]) +]) +AM_CONDITIONAL([HAVE_XDR_U_INT64_T], + [test "x$ac_cv_search_xdr_u_int64_t" != "xno"]) +AM_CONDITIONAL([HAVE_XDR_UINT64_T], + [test "x$ac_cv_search_xdr_uint64_t" != "xno"]) + +dnl Check for libselinux (optional). +AC_CHECK_HEADERS([selinux/selinux.h]) +AC_CHECK_LIB([selinux],[setexeccon],[ + have_libselinux="$ac_cv_header_selinux_selinux_h" + SELINUX_LIBS="-lselinux" + + old_LIBS="$LIBS" + LIBS="$LIBS $SELINUX_LIBS" + AC_CHECK_FUNCS([setcon getcon]) + LIBS="$old_LIBS" +],[have_libselinux=no]) +if test "x$have_libselinux" = "xyes"; then + AC_DEFINE([HAVE_LIBSELINUX],[1],[Define to 1 if you have libselinux.]) +fi +AC_SUBST([SELINUX_LIBS]) + +dnl Check for systemtap/DTrace userspace probes (optional). +dnl Since the probe points break under clang, allow this to be disabled. +AC_ARG_ENABLE([probes], + AS_HELP_STRING([--disable-probes], [disable systemtap/DTrace userspace probes]), + [], + [enable_probes=yes]) +AS_IF([test "x$enable_probes" != "xno"],[ + dnl http://sourceware.org/systemtap/wiki/AddingUserSpaceProbingToApps + AC_CHECK_HEADERS([sys/sdt.h]) + dnl AC_CHECK_PROG([DTRACE],[dtrace],[dtrace],[no]) + AS_IF([test "x$ac_cv_header_sys_sdt_h" = "xyes"],[ + AC_DEFINE([ENABLE_PROBES],[1],[Enable systemtap/DTrace userspace probes.]) + ]) +]) + +dnl Enable packet dumps when in verbose mode. This generates lots +dnl of debug info, only useful for people debugging the RPC mechanism. +AC_ARG_ENABLE([packet-dump],[ + AS_HELP_STRING([--enable-packet-dump], + [enable packet dumps in verbose mode @<:@default=no@:>@])], + [AC_DEFINE([ENABLE_PACKET_DUMP],[1],[Enable packet dumps in verbose mode.])], + []) + +dnl Check for PCRE (required) +PKG_CHECK_MODULES([PCRE], [libpcre]) + +dnl Check for Augeas >= 1.0.0 (required). +PKG_CHECK_MODULES([AUGEAS],[augeas >= 1.0.0]) + +dnl libmagic (highly recommended) +AC_CHECK_LIB([magic],[magic_file],[ + AC_CHECK_HEADER([magic.h],[ + AC_SUBST([MAGIC_LIBS], ["-lmagic"]) + AC_DEFINE([HAVE_LIBMAGIC],[1],[libmagic found at compile time.]) + ], []) +],[AC_MSG_WARN([libmagic not found, some core features will be disabled])]) + +dnl libvirt (highly recommended) +AC_ARG_WITH([libvirt],[ + AS_HELP_STRING([--without-libvirt], + [disable libvirt support @<:@default=check@:>@])], + [], + [with_libvirt=check]) +AS_IF([test "$with_libvirt" != "no"],[ + PKG_CHECK_MODULES([LIBVIRT], [libvirt],[ + AC_SUBST([LIBVIRT_CFLAGS]) + AC_SUBST([LIBVIRT_LIBS]) + AC_DEFINE([HAVE_LIBVIRT],[1],[libvirt found at compile time.]) + ], + [AC_MSG_WARN([libvirt not found, some core features will be disabled])]) +]) +AM_CONDITIONAL([HAVE_LIBVIRT],[test "x$LIBVIRT_LIBS" != "x"]) + +libvirt_ro_uri='qemu+unix:///system?socket=/var/run/libvirt/libvirt-sock-ro' +AC_SUBST([libvirt_ro_uri]) + +dnl libxml2 (required) +PKG_CHECK_MODULES([LIBXML2], [libxml-2.0]) +old_LIBS="$LIBS" +LIBS="$LIBS $LIBXML2_LIBS" +AC_CHECK_FUNCS([xmlBufferDetach]) +LIBS="$old_LIBS" + +dnl Check for yajl JSON library (optional). +PKG_CHECK_MODULES([YAJL], [yajl >= 2.0.4], [ + AC_SUBST([YAJL_CFLAGS]) + AC_SUBST([YAJL_LIBS]) + AC_DEFINE([HAVE_YAJL],[1],[Define to 1 if you have yajl.]) +],[AC_MSG_WARN([yajl not found, some features will be disabled])]) +AM_CONDITIONAL([HAVE_YAJL],[test "x$YAJL_LIBS" != "x"]) + +dnl Check for C++ (optional, we just use this to test the header works). +AC_PROG_CXX + +dnl The C++ compiler test is pretty useless because even if it fails +dnl it sets CXX=g++. So test the compiler actually works. +AC_MSG_CHECKING([if the C++ compiler really really works]) +AS_IF([$CXX --version >&AS_MESSAGE_LOG_FD 2>&1],[have_cxx=yes],[have_cxx=no]) +AC_MSG_RESULT([$have_cxx]) +AM_CONDITIONAL([HAVE_CXX], [test "$have_cxx" = "yes"]) + +dnl For search paths. +AC_DEFINE_UNQUOTED([PATH_SEPARATOR],["$PATH_SEPARATOR"], + [Character that separates path elements in search paths]) + +dnl Library versioning. +MAX_PROC_NR=`cat $srcdir/src/MAX_PROC_NR` +AC_SUBST(MAX_PROC_NR) -- 2.5.0
Richard W.M. Jones
2015-Oct-29 15:02 UTC
[Libguestfs] [PATCH 09/16] configure: Move daemon checks to separate file.
--- configure.ac | 103 +------------------------------------------ m4/guestfs_daemon.m4 | 120 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+), 101 deletions(-) create mode 100644 m4/guestfs_daemon.m4 diff --git a/configure.ac b/configure.ac index f25fdec..d70eaf2 100644 --- a/configure.ac +++ b/configure.ac @@ -102,65 +102,8 @@ m4_include([m4/guestfs_c.m4]) dnl Any C libraries required by the libguestfs C library (not the daemon). m4_include([m4/guestfs_libraries.m4]) -dnl Build the daemon? -AC_MSG_CHECKING([if we should build the daemon]) -AC_ARG_ENABLE([daemon], - [AS_HELP_STRING([--enable-daemon], - [enable building the daemon @<:@default=yes@:>@])], - [], - [enable_daemon=yes]) -AM_CONDITIONAL([ENABLE_DAEMON],[test "x$enable_daemon" = "xyes"]) -AC_MSG_RESULT([$enable_daemon]) - -if test "x$enable_daemon" = "xyes"; then - dnl Install the daemon (for libguestfs live service) - AC_MSG_CHECKING([if we should install the daemon]) - AC_ARG_ENABLE([install-daemon], - [AS_HELP_STRING([--enable-install-daemon], - [enable installing the daemon under $sbindir @<:@default=no@:>@])], - [], - [enable_install_daemon=no]) - AC_MSG_RESULT([$enable_install_daemon]) - - dnl Which directory should we put the daemon in? NOTE: This - dnl is the "virtual" directory inside the appliance, not the - dnl install directory for libguestfs live. Since Fedora 17 - dnl /sbin is a symlink to /usr/sbin. We have to put the - dnl daemon into a real (non-symlink) directory. - dirs="/sbin /usr/sbin /bin /usr/bin" - AC_MSG_CHECKING([which of $dirs is a real directory]) - for dir in $dirs; do - parent=`dirname $dir` - if test ! -L $parent && test -d $parent \ - && test ! -L $dir && test -d $dir - then - DAEMON_SUPERMIN_DIR=$dir - break - fi - done - if test "x$DAEMON_SUPERMIN_DIR" = "x"; then - AC_MSG_ERROR([non-symlink binary directory not found]) - fi - AC_MSG_RESULT([$DAEMON_SUPERMIN_DIR]) - AC_SUBST([DAEMON_SUPERMIN_DIR]) - - dnl For modified printf in the daemon, we need glibc either (old-style) - dnl register_printf_function or (new-style) register_printf_specifier. - AC_CHECK_FUNC([register_printf_specifier],[ - AC_DEFINE([HAVE_REGISTER_PRINTF_SPECIFIER],[1], - [Define to 1 if you have new-style register_printf_specifier.]) - ],[ - AC_CHECK_FUNC([register_printf_function],[ - AC_DEFINE([HAVE_REGISTER_PRINTF_FUNCTION],[1], - [Define to 1 if you have old-style register_printf_function.]) - ],[ - AC_MSG_FAILURE( -[No support for glibc-style extended printf formatters. - -This means you either have a very old glibc (pre-2.0) or you -are using some other libc where this is not supported.])])]) -fi -AM_CONDITIONAL([INSTALL_DAEMON],[test "x$enable_install_daemon" = "xyes"]) +dnl The daemon and any dependencies. +m4_include([m4/guestfs_daemon.m4]) dnl Build the appliance? AC_MSG_CHECKING([if we should build the appliance]) @@ -320,22 +263,6 @@ AS_IF([test "x$with_readline" != xno],[ LIBS="$old_LIBS" ]) -dnl POSIX acl library (highly recommended) -AC_CHECK_LIB([acl],[acl_from_text],[ - AC_CHECK_HEADER([sys/acl.h],[ - AC_SUBST([ACL_LIBS], [-lacl]) - AC_DEFINE([HAVE_ACL], [1], [Define to 1 if the POSIX acl library is available.]) - ], []) -],[AC_MSG_WARN([POSIX acl library not found])]) - -dnl Linux capabilities library (libcap) (highly recommended) -AC_CHECK_LIB([cap],[cap_from_text],[ - AC_CHECK_HEADER([sys/capability.h],[ - AC_SUBST([CAP_LIBS], [-lcap]) - AC_DEFINE([HAVE_CAP], [1], [Define to 1 if the Linux capabilities library (libcap) is available.]) - ], []) -],[AC_MSG_WARN([Linux capabilities library (libcap) not found])]) - dnl libconfig (highly recommended) PKG_CHECK_MODULES([LIBCONFIG], [libconfig],[ AC_SUBST([LIBCONFIG_CFLAGS]) @@ -355,32 +282,6 @@ PKG_CHECK_MODULES([GTK2], [gtk+-2.0], [ dnl Can we build virt-p2v? AM_CONDITIONAL([HAVE_P2V], [test "x$GTK2_LIBS" != "x"]) -dnl hivex library (highly recommended) -dnl This used to be a part of libguestfs, but was spun off into its -dnl own separate upstream project in libguestfs 1.0.85. -PKG_CHECK_MODULES([HIVEX], [hivex],[ - AC_SUBST([HIVEX_CFLAGS]) - AC_SUBST([HIVEX_LIBS]) - AC_DEFINE([HAVE_HIVEX],[1],[hivex library found at compile time.]) -], - [AC_MSG_WARN([hivex not found, some core features will be disabled])]) -AM_CONDITIONAL([HAVE_HIVEX],[test "x$HIVEX_LIBS" != "x"]) - -dnl systemd journal library (optional) -PKG_CHECK_MODULES([SD_JOURNAL], [libsystemd],[ - AC_SUBST([SD_JOURNAL_CFLAGS]) - AC_SUBST([SD_JOURNAL_LIBS]) - AC_DEFINE([HAVE_SD_JOURNAL],[1],[systemd journal library found at compile time.]) -],[ - PKG_CHECK_MODULES([SD_JOURNAL], [libsystemd-journal >= 196],[ - AC_SUBST([SD_JOURNAL_CFLAGS]) - AC_SUBST([SD_JOURNAL_LIBS]) - AC_DEFINE([HAVE_SD_JOURNAL],[1],[systemd journal library found at compile time.]) - ],[ - AC_MSG_WARN([systemd journal library not found, some features will be disabled]) - ]) -]) - dnl FUSE is optional to build the FUSE module. AC_ARG_ENABLE([fuse], AS_HELP_STRING([--disable-fuse], [disable FUSE (guestmount) support]), diff --git a/m4/guestfs_daemon.m4 b/m4/guestfs_daemon.m4 new file mode 100644 index 0000000..07bcfdb --- /dev/null +++ b/m4/guestfs_daemon.m4 @@ -0,0 +1,120 @@ +# libguestfs +# Copyright (C) 2009-2015 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +dnl The daemon and any dependencies. + +dnl Build the daemon? +AC_MSG_CHECKING([if we should build the daemon]) +AC_ARG_ENABLE([daemon], + [AS_HELP_STRING([--enable-daemon], + [enable building the daemon @<:@default=yes@:>@])], + [], + [enable_daemon=yes]) +AM_CONDITIONAL([ENABLE_DAEMON],[test "x$enable_daemon" = "xyes"]) +AC_MSG_RESULT([$enable_daemon]) + +if test "x$enable_daemon" = "xyes"; then + dnl Install the daemon (for libguestfs live service) + AC_MSG_CHECKING([if we should install the daemon]) + AC_ARG_ENABLE([install-daemon], + [AS_HELP_STRING([--enable-install-daemon], + [enable installing the daemon under $sbindir @<:@default=no@:>@])], + [], + [enable_install_daemon=no]) + AC_MSG_RESULT([$enable_install_daemon]) + + dnl Which directory should we put the daemon in? NOTE: This + dnl is the "virtual" directory inside the appliance, not the + dnl install directory for libguestfs live. Since Fedora 17 + dnl /sbin is a symlink to /usr/sbin. We have to put the + dnl daemon into a real (non-symlink) directory. + dirs="/sbin /usr/sbin /bin /usr/bin" + AC_MSG_CHECKING([which of $dirs is a real directory]) + for dir in $dirs; do + parent=`dirname $dir` + if test ! -L $parent && test -d $parent \ + && test ! -L $dir && test -d $dir + then + DAEMON_SUPERMIN_DIR=$dir + break + fi + done + if test "x$DAEMON_SUPERMIN_DIR" = "x"; then + AC_MSG_ERROR([non-symlink binary directory not found]) + fi + AC_MSG_RESULT([$DAEMON_SUPERMIN_DIR]) + AC_SUBST([DAEMON_SUPERMIN_DIR]) + + dnl For modified printf in the daemon, we need glibc either (old-style) + dnl register_printf_function or (new-style) register_printf_specifier. + AC_CHECK_FUNC([register_printf_specifier],[ + AC_DEFINE([HAVE_REGISTER_PRINTF_SPECIFIER],[1], + [Define to 1 if you have new-style register_printf_specifier.]) + ],[ + AC_CHECK_FUNC([register_printf_function],[ + AC_DEFINE([HAVE_REGISTER_PRINTF_FUNCTION],[1], + [Define to 1 if you have old-style register_printf_function.]) + ],[ + AC_MSG_FAILURE( +[No support for glibc-style extended printf formatters. + +This means you either have a very old glibc (pre-2.0) or you +are using some other libc where this is not supported.])])]) +fi +AM_CONDITIONAL([INSTALL_DAEMON],[test "x$enable_install_daemon" = "xyes"]) + +dnl POSIX acl library (highly recommended) +AC_CHECK_LIB([acl],[acl_from_text],[ + AC_CHECK_HEADER([sys/acl.h],[ + AC_SUBST([ACL_LIBS], [-lacl]) + AC_DEFINE([HAVE_ACL], [1], [Define to 1 if the POSIX acl library is available.]) + ], []) +],[AC_MSG_WARN([POSIX acl library not found])]) + +dnl Linux capabilities library (libcap) (highly recommended) +AC_CHECK_LIB([cap],[cap_from_text],[ + AC_CHECK_HEADER([sys/capability.h],[ + AC_SUBST([CAP_LIBS], [-lcap]) + AC_DEFINE([HAVE_CAP], [1], [Define to 1 if the Linux capabilities library (libcap) is available.]) + ], []) +],[AC_MSG_WARN([Linux capabilities library (libcap) not found])]) + +dnl hivex library (highly recommended) +dnl This used to be a part of libguestfs, but was spun off into its +dnl own separate upstream project in libguestfs 1.0.85. +PKG_CHECK_MODULES([HIVEX], [hivex],[ + AC_SUBST([HIVEX_CFLAGS]) + AC_SUBST([HIVEX_LIBS]) + AC_DEFINE([HAVE_HIVEX],[1],[hivex library found at compile time.]) +], + [AC_MSG_WARN([hivex not found, some core features will be disabled])]) +AM_CONDITIONAL([HAVE_HIVEX],[test "x$HIVEX_LIBS" != "x"]) + +dnl systemd journal library (optional) +PKG_CHECK_MODULES([SD_JOURNAL], [libsystemd],[ + AC_SUBST([SD_JOURNAL_CFLAGS]) + AC_SUBST([SD_JOURNAL_LIBS]) + AC_DEFINE([HAVE_SD_JOURNAL],[1],[systemd journal library found at compile time.]) +],[ + PKG_CHECK_MODULES([SD_JOURNAL], [libsystemd-journal >= 196],[ + AC_SUBST([SD_JOURNAL_CFLAGS]) + AC_SUBST([SD_JOURNAL_LIBS]) + AC_DEFINE([HAVE_SD_JOURNAL],[1],[systemd journal library found at compile time.]) + ],[ + AC_MSG_WARN([systemd journal library not found, some features will be disabled]) + ]) +]) -- 2.5.0
Richard W.M. Jones
2015-Oct-29 15:02 UTC
[Libguestfs] [PATCH 10/16] configure: Move appliance checks to separate file.
--- configure.ac | 108 +---------------------------------------- m4/guestfs_appliance.m4 | 125 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 127 insertions(+), 106 deletions(-) create mode 100644 m4/guestfs_appliance.m4 diff --git a/configure.ac b/configure.ac index d70eaf2..e6daad0 100644 --- a/configure.ac +++ b/configure.ac @@ -105,112 +105,8 @@ m4_include([m4/guestfs_libraries.m4]) dnl The daemon and any dependencies. m4_include([m4/guestfs_daemon.m4]) -dnl Build the appliance? -AC_MSG_CHECKING([if we should build the appliance]) -AC_ARG_ENABLE([appliance], - [AS_HELP_STRING([--enable-appliance], - [enable building the appliance @<:@default=yes@:>@])], - [ENABLE_APPLIANCE="$enableval"], - [ENABLE_APPLIANCE=yes]) -AM_CONDITIONAL([ENABLE_APPLIANCE],[test "x$ENABLE_APPLIANCE" = "xyes"]) -AC_MSG_RESULT([$ENABLE_APPLIANCE]) -AC_SUBST([ENABLE_APPLIANCE]) - -if test "x$enable_daemon" != "xyes" && test "x$ENABLE_APPLIANCE" = "xyes" ; then - AC_MSG_FAILURE([conflicting ./configure arguments: if you --disable-daemon -then you have to --disable-appliance as well, since the appliance contains -the daemon inside it.]) -fi - -dnl Check for supermin >= 5.1.0. -AC_PATH_PROG([SUPERMIN],[supermin],[no]) - -dnl Pass supermin --packager-config option. -SUPERMIN_PACKAGER_CONFIG=no - -AC_MSG_CHECKING([for --with-supermin-packager-config option]) -AC_ARG_WITH([supermin-packager-config], - [AS_HELP_STRING([--with-supermin-packager-config=FILE], - [pass supermin --packager-config option @<:@default=no@:>@])], - [SUPERMIN_PACKAGER_CONFIG="$withval" - AC_MSG_RESULT([$SUPERMIN_PACKAGER_CONFIG"])], - [AC_MSG_RESULT([not set])]) - -AC_SUBST([SUPERMIN_PACKAGER_CONFIG]) - -dnl Pass additional supermin options. -dnl -SUPERMIN_EXTRA_OPTIONS=no -AC_MSG_CHECKING([for --with-supermin-extra-options option]) -AC_ARG_WITH([supermin-extra-options], - [AS_HELP_STRING([--with-supermin-extra-options="--opt1 --opt2 ..."], - [Pass additional supermin options. @<:@default=no@:>@])], - [SUPERMIN_EXTRA_OPTIONS="$withval" - AC_MSG_RESULT([$SUPERMIN_EXTRA_OPTIONS"])], - [AC_MSG_RESULT([not set])]) - -AC_SUBST([SUPERMIN_EXTRA_OPTIONS]) - -if test "x$ENABLE_APPLIANCE" = "xyes"; then - supermin_major_min=5 - supermin_minor_min=1 - supermin_min=$supermin_major_min.$supermin_minor_min - - test "x$SUPERMIN" = "xno" && - AC_MSG_ERROR([supermin >= $supermin_min must be installed]) - - AC_MSG_CHECKING([supermin is new enough]) - $SUPERMIN --version >&AS_MESSAGE_LOG_FD 2>&1 || - AC_MSG_ERROR([supermin >= $supermin_min must be installed, your version is too old]) - supermin_major="`$SUPERMIN --version | $AWK '{print $2}' | $AWK -F. '{print $1}'`" - supermin_minor="`$SUPERMIN --version | $AWK '{print $2}' | $AWK -F. '{print $2}'`" - AC_MSG_RESULT([$supermin_major.$supermin_minor]) - - if test "$supermin_major" -lt "$supermin_major_min" || \ - ( test "$supermin_major" -eq "$supermin_major_min" && test "$supermin_minor" -lt "$supermin_minor_min" ); then - AC_MSG_ERROR([supermin >= $supermin_min must be installed, your version is too old]) - fi -fi - -AC_DEFINE_UNQUOTED([SUPERMIN],["$SUPERMIN"],[Name of supermin program]) - -dnl Which distro? -dnl -dnl This used to be Very Important but is now just used to select -dnl which packages to install in the appliance, since the package -dnl names vary slightly across distros. (See -dnl appliance/packagelist.in, appliance/excludefiles.in, -dnl appliance/hostfiles.in) -AC_MSG_CHECKING([which Linux distro for package names]) -DISTRO=REDHAT -if test -f /etc/debian_version; then - DISTRO=DEBIAN - if grep -q 'DISTRIB_ID=Ubuntu' /etc/lsb-release 2>&AS_MESSAGE_LOG_FD; then - DISTRO=UBUNTU - fi -fi -if test -f /etc/arch-release; then - DISTRO=ARCHLINUX -fi -if test -f /etc/SuSE-release; then - DISTRO=SUSE -fi -if test -f /etc/frugalware-release; then - DISTRO=FRUGALWARE -fi -if test -f /etc/mageia-release; then - DISTRO=MAGEIA -fi -AC_MSG_RESULT([$DISTRO]) -AC_SUBST([DISTRO]) - -dnl Add extra packages to the appliance. -AC_ARG_WITH([extra-packages], - [AS_HELP_STRING([--with-extra-packages="pkg1 pkg2 ..."], - [add extra packages to the appliance])], - [EXTRA_PACKAGES="$withval"], - [EXTRA_PACKAGES=]) -AC_SUBST([EXTRA_PACKAGES]) +dnl The appliance and any dependencies. +m4_include([m4/guestfs_appliance.m4]) dnl Check if crypt() is provided by a separate library. old_LIBS="$LIBS" diff --git a/m4/guestfs_appliance.m4 b/m4/guestfs_appliance.m4 new file mode 100644 index 0000000..0ab4904 --- /dev/null +++ b/m4/guestfs_appliance.m4 @@ -0,0 +1,125 @@ +# libguestfs +# Copyright (C) 2009-2015 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +dnl The appliance and any dependencies. + +dnl Build the appliance? +AC_MSG_CHECKING([if we should build the appliance]) +AC_ARG_ENABLE([appliance], + [AS_HELP_STRING([--enable-appliance], + [enable building the appliance @<:@default=yes@:>@])], + [ENABLE_APPLIANCE="$enableval"], + [ENABLE_APPLIANCE=yes]) +AM_CONDITIONAL([ENABLE_APPLIANCE],[test "x$ENABLE_APPLIANCE" = "xyes"]) +AC_MSG_RESULT([$ENABLE_APPLIANCE]) +AC_SUBST([ENABLE_APPLIANCE]) + +if test "x$enable_daemon" != "xyes" && test "x$ENABLE_APPLIANCE" = "xyes" ; then + AC_MSG_FAILURE([conflicting ./configure arguments: if you --disable-daemon +then you have to --disable-appliance as well, since the appliance contains +the daemon inside it.]) +fi + +dnl Check for supermin >= 5.1.0. +AC_PATH_PROG([SUPERMIN],[supermin],[no]) + +dnl Pass supermin --packager-config option. +SUPERMIN_PACKAGER_CONFIG=no + +AC_MSG_CHECKING([for --with-supermin-packager-config option]) +AC_ARG_WITH([supermin-packager-config], + [AS_HELP_STRING([--with-supermin-packager-config=FILE], + [pass supermin --packager-config option @<:@default=no@:>@])], + [SUPERMIN_PACKAGER_CONFIG="$withval" + AC_MSG_RESULT([$SUPERMIN_PACKAGER_CONFIG"])], + [AC_MSG_RESULT([not set])]) + +AC_SUBST([SUPERMIN_PACKAGER_CONFIG]) + +dnl Pass additional supermin options. +dnl +SUPERMIN_EXTRA_OPTIONS=no +AC_MSG_CHECKING([for --with-supermin-extra-options option]) +AC_ARG_WITH([supermin-extra-options], + [AS_HELP_STRING([--with-supermin-extra-options="--opt1 --opt2 ..."], + [Pass additional supermin options. @<:@default=no@:>@])], + [SUPERMIN_EXTRA_OPTIONS="$withval" + AC_MSG_RESULT([$SUPERMIN_EXTRA_OPTIONS"])], + [AC_MSG_RESULT([not set])]) + +AC_SUBST([SUPERMIN_EXTRA_OPTIONS]) + +if test "x$ENABLE_APPLIANCE" = "xyes"; then + supermin_major_min=5 + supermin_minor_min=1 + supermin_min=$supermin_major_min.$supermin_minor_min + + test "x$SUPERMIN" = "xno" && + AC_MSG_ERROR([supermin >= $supermin_min must be installed]) + + AC_MSG_CHECKING([supermin is new enough]) + $SUPERMIN --version >&AS_MESSAGE_LOG_FD 2>&1 || + AC_MSG_ERROR([supermin >= $supermin_min must be installed, your version is too old]) + supermin_major="`$SUPERMIN --version | $AWK '{print $2}' | $AWK -F. '{print $1}'`" + supermin_minor="`$SUPERMIN --version | $AWK '{print $2}' | $AWK -F. '{print $2}'`" + AC_MSG_RESULT([$supermin_major.$supermin_minor]) + + if test "$supermin_major" -lt "$supermin_major_min" || \ + ( test "$supermin_major" -eq "$supermin_major_min" && test "$supermin_minor" -lt "$supermin_minor_min" ); then + AC_MSG_ERROR([supermin >= $supermin_min must be installed, your version is too old]) + fi +fi + +AC_DEFINE_UNQUOTED([SUPERMIN],["$SUPERMIN"],[Name of supermin program]) + +dnl Which distro? +dnl +dnl This used to be Very Important but is now just used to select +dnl which packages to install in the appliance, since the package +dnl names vary slightly across distros. (See +dnl appliance/packagelist.in, appliance/excludefiles.in, +dnl appliance/hostfiles.in) +AC_MSG_CHECKING([which Linux distro for package names]) +DISTRO=REDHAT +if test -f /etc/debian_version; then + DISTRO=DEBIAN + if grep -q 'DISTRIB_ID=Ubuntu' /etc/lsb-release 2>&AS_MESSAGE_LOG_FD; then + DISTRO=UBUNTU + fi +fi +if test -f /etc/arch-release; then + DISTRO=ARCHLINUX +fi +if test -f /etc/SuSE-release; then + DISTRO=SUSE +fi +if test -f /etc/frugalware-release; then + DISTRO=FRUGALWARE +fi +if test -f /etc/mageia-release; then + DISTRO=MAGEIA +fi +AC_MSG_RESULT([$DISTRO]) +AC_SUBST([DISTRO]) + +dnl Add extra packages to the appliance. +AC_ARG_WITH([extra-packages], + [AS_HELP_STRING([--with-extra-packages="pkg1 pkg2 ..."], + [add extra packages to the appliance])], + [EXTRA_PACKAGES="$withval"], + [EXTRA_PACKAGES=]) +AC_SUBST([EXTRA_PACKAGES]) -- 2.5.0
Richard W.M. Jones
2015-Oct-29 15:02 UTC
[Libguestfs] [PATCH 11/16] configure: Move misc. library checks to separate file.
--- configure.ac | 68 ++--------------------------------- m4/guestfs_misc_libraries.m4 | 85 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+), 66 deletions(-) create mode 100644 m4/guestfs_misc_libraries.m4 diff --git a/configure.ac b/configure.ac index e6daad0..cd272be 100644 --- a/configure.ac +++ b/configure.ac @@ -108,75 +108,11 @@ m4_include([m4/guestfs_daemon.m4]) dnl The appliance and any dependencies. m4_include([m4/guestfs_appliance.m4]) -dnl Check if crypt() is provided by a separate library. -old_LIBS="$LIBS" -AC_SEARCH_LIBS([crypt],[crypt]) -LIBS="$old_LIBS" -if test "$ac_cv_search_crypt" = "-lcrypt" ; then - LIBCRYPT_LIBS="-lcrypt" -fi -AC_SUBST([LIBCRYPT_LIBS]) - -dnl liblzma can be used by virt-builder (optional). -PKG_CHECK_MODULES([LIBLZMA], [liblzma], [ - AC_SUBST([LIBLZMA_CFLAGS]) - AC_SUBST([LIBLZMA_LIBS]) - AC_DEFINE([HAVE_LIBLZMA],[1],[liblzma found at compile time.]) - - dnl Old lzma in RHEL 6 didn't have some APIs we need. - old_LIBS="$LIBS" - LIBS="$LIBS $LIBLZMA_LIBS" - AC_CHECK_FUNCS([lzma_index_stream_flags lzma_index_stream_padding]) - LIBS="$old_LIBS" -], -[AC_MSG_WARN([liblzma not found, virt-builder will be slower])]) - dnl Check for QEMU. m4_include([m4/guestfs_qemu.m4]) -dnl Readline. -AC_ARG_WITH([readline],[ - AS_HELP_STRING([--with-readline], - [support fancy command line editing @<:@default=check@:>@])], - [], - [with_readline=check]) - -LIBREADLINE-AS_IF([test "x$with_readline" != xno],[ - AC_CHECK_LIB([readline], [main], - [AC_SUBST([LIBREADLINE], ["-lreadline -lncurses"]) - AC_DEFINE([HAVE_LIBREADLINE], [1], - [Define if you have libreadline.]) - ], - [if test "x$with_readline" != xcheck; then - AC_MSG_FAILURE( - [--with-readline was given, but test for readline failed]) - fi - ], -lncurses) - old_LIBS="$LIBS" - LIBS="$LIBS $LIBREADLINE" - AC_CHECK_FUNCS([append_history completion_matches rl_completion_matches]) - LIBS="$old_LIBS" - ]) - -dnl libconfig (highly recommended) -PKG_CHECK_MODULES([LIBCONFIG], [libconfig],[ - AC_SUBST([LIBCONFIG_CFLAGS]) - AC_SUBST([LIBCONFIG_LIBS]) - AC_DEFINE([HAVE_LIBCONFIG],[1],[libconfig found at compile time.]) -], - [AC_MSG_WARN([libconfig not found, some features will be disabled])]) -AM_CONDITIONAL([HAVE_LIBCONFIG],[test "x$LIBCONFIG_LIBS" != "x"]) - -dnl Check for gtk2 library, used by virt-p2v. -PKG_CHECK_MODULES([GTK2], [gtk+-2.0], [ - AC_SUBST([GTK2_CFLAGS]) - AC_SUBST([GTK2_LIBS]) -], - [AC_MSG_WARN([gtk2 not found, virt-p2v will be disabled])]) - -dnl Can we build virt-p2v? -AM_CONDITIONAL([HAVE_P2V], [test "x$GTK2_LIBS" != "x"]) +dnl Miscellaneous libraries used by other programs. +m4_include([m4/guestfs_misc_libraries.m4]) dnl FUSE is optional to build the FUSE module. AC_ARG_ENABLE([fuse], diff --git a/m4/guestfs_misc_libraries.m4 b/m4/guestfs_misc_libraries.m4 new file mode 100644 index 0000000..2759d0d --- /dev/null +++ b/m4/guestfs_misc_libraries.m4 @@ -0,0 +1,85 @@ +# libguestfs +# Copyright (C) 2009-2015 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +dnl Miscellaneous libraries used by other programs. + +dnl Check if crypt() is provided by a separate library. +old_LIBS="$LIBS" +AC_SEARCH_LIBS([crypt],[crypt]) +LIBS="$old_LIBS" +if test "$ac_cv_search_crypt" = "-lcrypt" ; then + LIBCRYPT_LIBS="-lcrypt" +fi +AC_SUBST([LIBCRYPT_LIBS]) + +dnl liblzma can be used by virt-builder (optional). +PKG_CHECK_MODULES([LIBLZMA], [liblzma], [ + AC_SUBST([LIBLZMA_CFLAGS]) + AC_SUBST([LIBLZMA_LIBS]) + AC_DEFINE([HAVE_LIBLZMA],[1],[liblzma found at compile time.]) + + dnl Old lzma in RHEL 6 didn't have some APIs we need. + old_LIBS="$LIBS" + LIBS="$LIBS $LIBLZMA_LIBS" + AC_CHECK_FUNCS([lzma_index_stream_flags lzma_index_stream_padding]) + LIBS="$old_LIBS" +], +[AC_MSG_WARN([liblzma not found, virt-builder will be slower])]) + +dnl Readline (used by guestfish). +AC_ARG_WITH([readline],[ + AS_HELP_STRING([--with-readline], + [support fancy command line editing @<:@default=check@:>@])], + [], + [with_readline=check]) + +LIBREADLINE+AS_IF([test "x$with_readline" != xno],[ + AC_CHECK_LIB([readline], [main], + [AC_SUBST([LIBREADLINE], ["-lreadline -lncurses"]) + AC_DEFINE([HAVE_LIBREADLINE], [1], + [Define if you have libreadline.]) + ], + [if test "x$with_readline" != xcheck; then + AC_MSG_FAILURE( + [--with-readline was given, but test for readline failed]) + fi + ], -lncurses) + old_LIBS="$LIBS" + LIBS="$LIBS $LIBREADLINE" + AC_CHECK_FUNCS([append_history completion_matches rl_completion_matches]) + LIBS="$old_LIBS" + ]) + +dnl libconfig (highly recommended) used by guestfish and others. +PKG_CHECK_MODULES([LIBCONFIG], [libconfig],[ + AC_SUBST([LIBCONFIG_CFLAGS]) + AC_SUBST([LIBCONFIG_LIBS]) + AC_DEFINE([HAVE_LIBCONFIG],[1],[libconfig found at compile time.]) +], + [AC_MSG_WARN([libconfig not found, some features will be disabled])]) +AM_CONDITIONAL([HAVE_LIBCONFIG],[test "x$LIBCONFIG_LIBS" != "x"]) + +dnl Check for gtk2 library, used by virt-p2v. +PKG_CHECK_MODULES([GTK2], [gtk+-2.0], [ + AC_SUBST([GTK2_CFLAGS]) + AC_SUBST([GTK2_LIBS]) +], + [AC_MSG_WARN([gtk2 not found, virt-p2v will be disabled])]) + +dnl Can we build virt-p2v? +AM_CONDITIONAL([HAVE_P2V], [test "x$GTK2_LIBS" != "x"]) -- 2.5.0
Richard W.M. Jones
2015-Oct-29 15:02 UTC
[Libguestfs] [PATCH 12/16] configure: Move FUSE checks to separate file.
This is moved earlier because it's now part of the C library. --- configure.ac | 24 +++--------------------- m4/guestfs_fuse.m4 | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 21 deletions(-) create mode 100644 m4/guestfs_fuse.m4 diff --git a/configure.ac b/configure.ac index cd272be..90bf54b 100644 --- a/configure.ac +++ b/configure.ac @@ -102,6 +102,9 @@ m4_include([m4/guestfs_c.m4]) dnl Any C libraries required by the libguestfs C library (not the daemon). m4_include([m4/guestfs_libraries.m4]) +dnl Check for FUSE. +m4_include([m4/guestfs_fuse.m4]) + dnl The daemon and any dependencies. m4_include([m4/guestfs_daemon.m4]) @@ -114,27 +117,6 @@ m4_include([m4/guestfs_qemu.m4]) dnl Miscellaneous libraries used by other programs. m4_include([m4/guestfs_misc_libraries.m4]) -dnl FUSE is optional to build the FUSE module. -AC_ARG_ENABLE([fuse], - AS_HELP_STRING([--disable-fuse], [disable FUSE (guestmount) support]), - [], - [enable_fuse=yes]) -AS_IF([test "x$enable_fuse" != "xno"],[ - PKG_CHECK_MODULES([FUSE],[fuse],[ - AC_SUBST([FUSE_CFLAGS]) - AC_SUBST([FUSE_LIBS]) - AC_DEFINE([HAVE_FUSE],[1],[Define to 1 if you have FUSE.]) - old_LIBS="$LIBS" - LIBS="$FUSE_LIBS $LIBS" - AC_CHECK_FUNCS([fuse_opt_add_opt_escaped]) - LIBS="$old_LIBS" - ],[ - enable_fuse=no - AC_MSG_WARN([FUSE library and headers are missing, so optional FUSE module won't be built]) - ]) -]) -AM_CONDITIONAL([HAVE_FUSE],[test "x$enable_fuse" != "xno"]) - dnl Check for language bindings. m4_include([m4/guestfs_ocaml.m4]) m4_include([m4/guestfs_perl.m4]) diff --git a/m4/guestfs_fuse.m4 b/m4/guestfs_fuse.m4 new file mode 100644 index 0000000..fcb3a4b --- /dev/null +++ b/m4/guestfs_fuse.m4 @@ -0,0 +1,37 @@ +# libguestfs +# Copyright (C) 2009-2015 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +dnl FUSE is optional to build the FUSE module. +AC_ARG_ENABLE([fuse], + AS_HELP_STRING([--disable-fuse], [disable FUSE (guestmount) support]), + [], + [enable_fuse=yes]) +AS_IF([test "x$enable_fuse" != "xno"],[ + PKG_CHECK_MODULES([FUSE],[fuse],[ + AC_SUBST([FUSE_CFLAGS]) + AC_SUBST([FUSE_LIBS]) + AC_DEFINE([HAVE_FUSE],[1],[Define to 1 if you have FUSE.]) + old_LIBS="$LIBS" + LIBS="$FUSE_LIBS $LIBS" + AC_CHECK_FUNCS([fuse_opt_add_opt_escaped]) + LIBS="$old_LIBS" + ],[ + enable_fuse=no + AC_MSG_WARN([FUSE library and headers are missing, so optional FUSE module won't be built]) + ]) +]) +AM_CONDITIONAL([HAVE_FUSE],[test "x$enable_fuse" != "xno"]) -- 2.5.0
Richard W.M. Jones
2015-Oct-29 15:02 UTC
[Libguestfs] [PATCH 13/16] docs: Move 'extending libguestfs' documentation to guestfs-hacking(1).
Start to split the huge, monolithic guestfs(3) manual page. --- .gitignore | 3 + Makefile.am | 2 +- daemon/daemon.h | 2 +- daemon/guestfsd.c | 2 +- docs/Makefile.am | 15 + docs/guestfs-hacking.pod | 751 +++++++++++++++++++++++++++++++++++++++++++++++ generator/types.ml | 2 +- po-docs/language.mk | 1 + po-docs/podfiles | 1 + src/guestfs.pod | 733 +-------------------------------------------- 10 files changed, 778 insertions(+), 734 deletions(-) create mode 100644 docs/guestfs-hacking.pod diff --git a/.gitignore b/.gitignore index d17f53f..3338d27 100644 --- a/.gitignore +++ b/.gitignore @@ -131,11 +131,13 @@ Makefile.in /diff/virt-diff /diff/virt-diff.1 /docs/guestfs-faq.1 +/docs/guestfs-hacking.1 /docs/guestfs-performance.1 /docs/guestfs-recipes.1 /docs/guestfs-release-notes.1 /docs/guestfs-testing.1 /docs/stamp-guestfs-faq.pod +/docs/stamp-guestfs-hacking.pod /docs/stamp-guestfs-performance.pod /docs/stamp-guestfs-recipes.pod /docs/stamp-guestfs-release-notes.pod @@ -231,6 +233,7 @@ Makefile.in /html/guestfs-erlang.3.html /html/guestfs-examples.3.html /html/guestfs-faq.1.html +/html/guestfs-hacking.1.html /html/guestfs-golang.3.html /html/guestfs-java.3.html /html/guestfs-lua.3.html diff --git a/Makefile.am b/Makefile.am index 713df42..4b3cab3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -600,5 +600,5 @@ help: @echo "To run programs without installing:" @echo " ./run ./fish/guestfish [or any other program]" @echo - @echo "For more information, see EXTENDING LIBGUESTFS in guestfs(3); and README." + @echo "For more information, see guestfs-hacking(1); and README." @echo diff --git a/daemon/daemon.h b/daemon/daemon.h index 1f0cd30..820e9cb 100644 --- a/daemon/daemon.h +++ b/daemon/daemon.h @@ -155,7 +155,7 @@ extern int random_name (char *template); extern char *get_random_uuid (void); /* This just stops gcc from giving a warning about our custom printf - * formatters %Q and %R. See guestfs(3)/EXTENDING LIBGUESTFS for more + * formatters %Q and %R. See guestfs-hacking(1) for more * info about these. In GCC 4.8.0 the warning is even harder to * 'trick', hence the need for the #pragma directives. */ diff --git a/daemon/guestfsd.c b/daemon/guestfsd.c index 4502190..994023d 100644 --- a/daemon/guestfsd.c +++ b/daemon/guestfsd.c @@ -1189,7 +1189,7 @@ trim (char *str) } /* printf helper function so we can use %Q ("quoted") and %R to print - * shell-quoted strings. See guestfs(3)/EXTENDING LIBGUESTFS for more + * shell-quoted strings. See guestfs-hacking(1) for more * details. */ static int diff --git a/docs/Makefile.am b/docs/Makefile.am index 096cbc1..4e6a0b5 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -19,6 +19,7 @@ include $(top_srcdir)/subdir-rules.mk EXTRA_DIST = \ guestfs-faq.pod \ + guestfs-hacking.pod \ guestfs-performance.pod \ guestfs-recipes.pod \ guestfs-release-notes.pod \ @@ -27,6 +28,7 @@ EXTRA_DIST = \ CLEANFILES = \ stamp-guestfs-faq.pod \ + stamp-guestfs-hacking.pod \ stamp-guestfs-performance.pod \ stamp-guestfs-recipes.pod \ stamp-guestfs-release-notes.pod \ @@ -34,12 +36,14 @@ CLEANFILES = \ man_MANS = \ guestfs-faq.1 \ + guestfs-hacking.1 \ guestfs-performance.1 \ guestfs-recipes.1 \ guestfs-release-notes.1 \ guestfs-testing.1 noinst_DATA = \ $(top_builddir)/html/guestfs-faq.1.html \ + $(top_builddir)/html/guestfs-hacking.1.html \ $(top_builddir)/html/guestfs-performance.1.html \ $(top_builddir)/html/guestfs-recipes.1.html \ $(top_builddir)/html/guestfs-release-notes.1.html \ @@ -56,6 +60,17 @@ stamp-guestfs-faq.pod: guestfs-faq.pod $< touch $@ +guestfs-hacking.1 $(top_builddir)/html/guestfs-hacking.1.html: stamp-guestfs-hacking.pod + +stamp-guestfs-hacking.pod: guestfs-hacking.pod + $(PODWRAPPER) \ + --section 1 \ + --man guestfs-hacking.1 \ + --html $(top_builddir)/html/guestfs-hacking.1.html \ + --license LGPLv2+ \ + $< + touch $@ + guestfs-performance.1 $(top_builddir)/html/guestfs-performance.1.html: stamp-guestfs-performance.pod stamp-guestfs-performance.pod: guestfs-performance.pod diff --git a/docs/guestfs-hacking.pod b/docs/guestfs-hacking.pod new file mode 100644 index 0000000..7935b56 --- /dev/null +++ b/docs/guestfs-hacking.pod @@ -0,0 +1,751 @@ +=head1 NAME + +guestfs-hacking - extending and contributing to libguestfs + +=head1 DESCRIPTION + +This manual page is for hackers who want to extend libguestfs itself. + +=head2 OVERVIEW OF THE SOURCE CODE + +Libguestfs source is located in the github repository +L<https://github.com/libguestfs/libguestfs> + +Large amounts of boilerplate code in libguestfs (RPC, bindings, +documentation) are generated. This means that many source files will +appear to be missing from a straightforward git checkout. You have to +run the generator (C<./autogen.sh && make -C generator>) in order to +create those files. + +Libguestfs uses an autotools-based build system, with the main files +being F<configure.ac> and F<Makefile.am>. The F<generator> +subdirectory contains the generator, plus files describing the API. +The F<src> subdirectory contains source for the library. The +F<appliance> and F<daemon> subdirectories contain the source for the +code that builds the appliance, and the code that runs in the +appliance respectively. Other directories are covered in the section +L<SOURCE CODE SUBDIRECTORIES> below. + +Apart from the fact that all API entry points go via some generated +code, the library is straightforward. (In fact, even the generated +code is designed to be readable, and should be read as ordinary code). +Some actions run entirely in the library, and are written as C +functions in files under F<src>. Others are forwarded to the daemon +where (after some generated RPC marshalling) they appear as C +functions in files under F<daemon>. + +To build from source, first read the C<README> file. + +=head2 F<local*> FILES + +Files in the top source directory that begin with the prefix F<local*> +are ignored by git. These files can contain local configuration or +scripts that you need to build libguestfs. + +By convention, I have a file called F<localconfigure> which is a +simple wrapper around F<autogen.sh> containing local configure +customizations that I need: + + . localenv + ./autogen.sh \ + --with-default-backend=libvirt \ + --enable-gcc-warnings \ + --enable-gtk-doc \ + -C \ + "$@" + +So I can use this to build libguestfs: + + ./localconfigure && make + +If there is a file in the top build directory called F<localenv>, then +it will be sourced by C<make>. This file can contain any local +environment variables needed, eg. for skipping tests: + + # Use an alternate python binary. + export PYTHON=python3 + # Skip this test, it is broken. + export SKIP_TEST_BTRFS_FSCK=1 + +Note that F<localenv> is included by the top Makefile (so it's a +Makefile fragment). But if it is also sourced by your +F<localconfigure> script then it is used as a shell script. + +=head2 ADDING A NEW API ACTION + +Because large amounts of boilerplate code in libguestfs are generated, +this makes it easy to extend the libguestfs API. + +To add a new API action there are two changes: + +=over 4 + +=item 1. + +You need to add a description of the call (name, parameters, return +type, tests, documentation) to F<generator/actions.ml>. + +There are two sorts of API action, depending on whether the call goes +through to the daemon in the appliance, or is serviced entirely by the +library (see L<guestfs-internals(3)/ARCHITECTURE>). L<guestfs(3)/guestfs_sync> is an example +of the former, since the sync is done in the appliance. +L<guestfs(3)/guestfs_set_trace> is an example of the latter, since a trace flag +is maintained in the handle and all tracing is done on the library +side. + +Most new actions are of the first type, and get added to the +C<daemon_functions> list. Each function has a unique procedure number +used in the RPC protocol which is assigned to that action when we +publish libguestfs and cannot be reused. Take the latest procedure +number and increment it. + +For library-only actions of the second type, add to the +C<non_daemon_functions> list. Since these functions are serviced by +the library and do not travel over the RPC mechanism to the daemon, +these functions do not need a procedure number, and so the procedure +number is set to C<-1>. + +=item 2. + +Implement the action (in C): + +For daemon actions, implement the function C<do_E<lt>nameE<gt>> in the +C<daemon/> directory. + +For library actions, implement the function C<guestfs_impl_E<lt>nameE<gt>> +(note: double underscore) in the C<src/> directory. + +In either case, use another function as an example of what to do. + +=back + +After making these changes, use C<make> to compile. + +Note that you don't need to implement the RPC, language bindings, +manual pages or anything else. It's all automatically generated from +the OCaml description. + +=head2 ADDING TESTS FOR AN API ACTION + +You can supply zero or as many tests as you want per API call. The +tests can either be added as part of the API description +(F<generator/actions.ml>), or in some rarer cases you may want to drop +a script into C<tests/*/>. Note that adding a script to C<tests/*/> +is slower, so if possible use the first method. + +The following describes the test environment used when you add an API +test in F<actions.ml>. + +The test environment has 4 block devices: + +=over 4 + +=item F</dev/sda> 500MB + +General block device for testing. + +=item F</dev/sdb> 500MB + +F</dev/sdb1> is an ext2 filesystem used for testing +filesystem write operations. + +=item F</dev/sdc> 10MB + +Used in a few tests where two block devices are needed. + +=item F</dev/sdd> + +ISO with fixed content (see F<images/test.iso>). + +=back + +To be able to run the tests in a reasonable amount of time, the +libguestfs appliance and block devices are reused between tests. So +don't try testing L<guestfs(3)/guestfs_kill_subprocess> :-x + +Each test starts with an initial scenario, selected using one of the +C<Init*> expressions, described in F<generator/types.ml>. These +initialize the disks mentioned above in a particular way as documented +in F<types.ml>. You should not assume anything about the previous +contents of other disks that are not initialized. + +You can add a prerequisite clause to any individual test. This is a +run-time check, which, if it fails, causes the test to be skipped. +Useful if testing a command which might not work on all variations of +libguestfs builds. A test that has prerequisite of C<Always> means to +run unconditionally. + +In addition, packagers can skip individual tests by setting +environment variables before running C<make check>. + + SKIP_TEST_<CMD>_<NUM>=1 + +eg: C<SKIP_TEST_COMMAND_3=1> skips test #3 of L<guestfs(3)/guestfs_command>. + +or: + + SKIP_TEST_<CMD>=1 + +eg: C<SKIP_TEST_ZEROFREE=1> skips all L<guestfs(3)/guestfs_zerofree> tests. + +Packagers can run only certain tests by setting for example: + + TEST_ONLY="vfs_type zerofree" + +See F<tests/c-api/tests.c> for more details of how these environment +variables work. + +=head2 DEBUGGING NEW API ACTIONS + +Test new actions work before submitting them. + +You can use guestfish to try out new commands. + +Debugging the daemon is a problem because it runs inside a minimal +environment. However you can fprintf messages in the daemon to +stderr, and they will show up if you use C<guestfish -v>. + +=head2 ADDING A NEW LANGUAGE BINDING + +All language bindings must be generated by the generator +(see the F<generator> subdirectory). + +There is no documentation for this yet. We suggest you look +at an existing binding, eg. F<generator/ocaml.ml> or +F<generator/perl.ml>. + +=head2 ADDING TESTS FOR LANGUAGE BINDINGS + +Language bindings should come with tests. Previously testing of +language bindings was rather ad-hoc, but we have been trying to +formalize the set of tests that every language binding should use. + +Currently only the OCaml and Perl bindings actually implement the full +set of tests, and the OCaml bindings are canonical, so you should +emulate what the OCaml tests do. + +This is the numbering scheme used by the tests: + + - 000+ basic tests: + + 010 load the library + 020 create + 030 create-flags + 040 create multiple handles + 050 test setting and getting config properties + 060 explicit close + 065 implicit close (in GC'd languages) + 070 optargs + + - 100 launch, create partitions and LVs and filesystems + + - 400+ events: + + 410 close event + 420 log messages + 430 progress messages + + - 800+ regression tests (specific to the language) + + - 900+ any other custom tests for the language + +To save time when running the tests, only 100, 430, 800+, 900+ should +launch the handle. + +=head2 FORMATTING CODE + +Our C source code generally adheres to some basic code-formatting +conventions. The existing code base is not totally consistent on this +front, but we do prefer that contributed code be formatted similarly. +In short, use spaces-not-TABs for indentation, use 2 spaces for each +indentation level, and other than that, follow the K&R style. + +If you use Emacs, add the following to one of one of your start-up files +(e.g., ~/.emacs), to help ensure that you get indentation right: + + ;;; In libguestfs, indent with spaces everywhere (not TABs). + ;;; Exceptions: Makefile and ChangeLog modes. + (add-hook 'find-file-hook + '(lambda () (if (and buffer-file-name + (string-match "/libguestfs\\>" + (buffer-file-name)) + (not (string-equal mode-name "Change Log")) + (not (string-equal mode-name "Makefile"))) + (setq indent-tabs-mode nil)))) + + ;;; When editing C sources in libguestfs, use this style. + (defun libguestfs-c-mode () + "C mode with adjusted defaults for use with libguestfs." + (interactive) + (c-set-style "K&R") + (setq c-indent-level 2) + (setq c-basic-offset 2)) + (add-hook 'c-mode-hook + '(lambda () (if (string-match "/libguestfs\\>" + (buffer-file-name)) + (libguestfs-c-mode)))) + +=head2 TESTING YOUR CHANGES + +Enable warnings when compiling (and fix any problems this +finds): + + ./configure --enable-gcc-warnings + +Useful targets are: + +=over 4 + +=item C<make check> + +Runs the regular test suite. + +This is implemented using the regular automake C<TESTS> target. See +the automake documentation for details. + +=item C<make check-valgrind> + +Runs a subset of the test suite under valgrind. + +Any F<Makefile.am> in the tree that has a C<check-valgrind:> target +will be run by this rule. + +=item C<make check-valgrind-local-guests> + +Runs a subset of the test suite under valgrind +using locally installed libvirt guests (read-only). + +=item C<make check-direct> + +Runs all tests using default appliance back-end. This only +has any effect if a non-default backend was selected +using C<./configure --with-default-backend=...> + +=item C<make check-valgrind-direct> + +Run a subset of the test suite under valgrind using the +default appliance back-end. + +=item C<make check-uml> + +Runs all tests using the User-Mode Linux backend. + +As there is no standard location for the User-Mode Linux kernel, you +I<have> to set C<LIBGUESTFS_HV> to point to the kernel image, eg: + + make check-uml LIBGUESTFS_HV=~/d/linux-um/vmlinux + +=item C<make check-valgrind-uml> + +Runs all tests using the User-Mode Linux backend, under valgrind. + +As above, you have to set C<LIBGUESTFS_HV> to point to the kernel. + +=item C<make check-with-upstream-qemu> + +Runs all tests using a local qemu binary. It looks for the qemu +binary in QEMUDIR (defaults to F<$HOME/d/qemu>), but you can set this +to another directory on the command line, eg: + + make check-with-upstream-qemu QEMUDIR=/usr/src/qemu + +=item C<make check-with-upstream-libvirt> + +Runs all tests using a local libvirt. This only has any effect if the +libvirt backend was selected using +C<./configure --with-default-backend=libvirt> + +It looks for libvirt in LIBVIRTDIR (defaults to F<$HOME/d/libvirt>), +but you can set this to another directory on the command line, eg: + + make check-with-upstream-libvirt LIBVIRTDIR=/usr/src/libvirt + +=item C<make check-slow> + +Runs some slow/long-running tests which are not run by default. + +Any F<Makefile.am> in the tree that has a C<check-slow:> target will +be run by this rule. + +=item C<make check-all> + +Equivalent to running all C<make check*> rules. + +=item C<make check-release> + +Runs a subset of C<make check*> rules that are required to pass +before a tarball can be released. Currently this is: + +=over 4 + +=item * + +check + +=item * + +check-valgrind + +=item * + +check-direct + +=item * + +check-valgrind-direct + +=item * + +check-slow + +=back + +=item C<make installcheck> + +Run C<make check> on the installed copy of libguestfs. + +The version of installed libguestfs being tested, and the version of +the libguestfs source tree must be the same. + +Do: + + ./autogen.sh + make clean ||: + make + make installcheck + +=back + +=head2 DAEMON CUSTOM PRINTF FORMATTERS + +In the daemon code we have created custom printf formatters C<%Q> and +C<%R>, which are used to do shell quoting. + +=over 4 + +=item %Q + +Simple shell quoted string. Any spaces or other shell characters are +escaped for you. + +=item %R + +Same as C<%Q> except the string is treated as a path which is prefixed +by the sysroot. + +=back + +For example: + + asprintf (&cmd, "cat %R", path); + +would produce C<cat /sysroot/some\ path\ with\ spaces> + +I<Note:> Do I<not> use these when you are passing parameters to the +C<command{,r,v,rv}()> functions. These parameters do NOT need to be +quoted because they are not passed via the shell (instead, straight to +exec). You probably want to use the C<sysroot_path()> function +however. + +=head2 SUBMITTING YOUR NEW API ACTIONS + +Submit patches to the mailing list: +L<http://www.redhat.com/mailman/listinfo/libguestfs> +and CC to L<rjones@redhat.com>. + +=head2 INTERNATIONALIZATION (I18N) SUPPORT + +We support i18n (gettext anyhow) in the library. + +However many messages come from the daemon, and we don't translate +those at the moment. One reason is that the appliance generally has +all locale files removed from it, because they take up a lot of space. +So we'd have to readd some of those, as well as copying our PO files +into the appliance. + +Debugging messages are never translated, since they are intended for +the programmers. + +=head2 SOURCE CODE SUBDIRECTORIES + +=over 4 + +=item F<align> + +L<virt-alignment-scan(1)> command and documentation. + +=item F<appliance> + +The libguestfs appliance, build scripts and so on. + +=item F<bash> + +Bash tab-completion scripts. + +=item F<build-aux> + +Various build scripts used by autotools. + +=item F<builder> + +L<virt-builder(1)> command and documentation. + +=item F<cat> + +The L<virt-cat(1)>, L<virt-filesystems(1)>, L<virt-log(1)> +and L<virt-ls(1)> commands and documentation. + +=item F<contrib> + +Outside contributions, experimental parts. + +=item F<customize> + +L<virt-customize(1)> command and documentation. + +=item F<daemon> + +The daemon that runs inside the libguestfs appliance and carries out +actions. + +=item F<df> + +L<virt-df(1)> command and documentation. + +=item F<dib> + +L<virt-dib(1)> command and documentation. + +=item F<diff> + +L<virt-diff(1)> command and documentation. + +=item F<doc> + +Miscellaneous manual pages. + +=item F<edit> + +L<virt-edit(1)> command and documentation. + +=item F<examples> + +C API example code. + +=item F<fish> + +L<guestfish(1)>, the command-line shell, and various shell scripts +built on top such as L<virt-copy-in(1)>, L<virt-copy-out(1)>, +L<virt-tar-in(1)>, L<virt-tar-out(1)>. + +=item F<format> + +L<virt-format(1)> command and documentation. + +=item F<fuse> + +L<guestmount(1)>, FUSE (userspace filesystem) built on top of libguestfs. + +=item F<generator> + +The crucially important generator, used to automatically generate +large amounts of boilerplate C code for things like RPC and bindings. + +=item F<get-kernel> + +L<virt-get-kernel(1)> command and documentation. + +=item F<gnulib> + +Gnulib is used as a portability library. A copy of gnulib is included +under here. + +=item F<html> + +Generated HTML manual pages. + +=item F<inspector> + +L<virt-inspector(1)>, the virtual machine image inspector. + +=item F<logo> + +Logo used on the website. The fish is called Arthur by the way. + +=item F<m4> + +M4 macros used by autoconf. + +=item F<make-fs> + +L<virt-make-fs(1)> command and documentation. + +=item F<mllib> + +Various libraries and common code used by L<virt-resize(1)> and +the other tools which are written in OCaml. + +=item F<p2v> + +L<virt-p2v(1)> command, documentation and scripts for building the +virt-p2v ISO or disk image. + +=item F<po> + +Translations of simple gettext strings. + +=item F<po-docs> + +The build infrastructure and PO files for translations of manpages and +POD files. Eventually this will be combined with the F<po> directory, +but that is rather complicated. + +=item F<rescue> + +L<virt-rescue(1)> command and documentation. + +=item F<resize> + +L<virt-resize(1)> command and documentation. + +=item F<sparsify> + +L<virt-sparsify(1)> command and documentation. + +=item F<src> + +Source code to the C library. + +=item F<sysprep> + +L<virt-sysprep(1)> command and documentation. + +=item F<tests> + +Tests. + +=item F<test-tool> + +Test tool for end users to test if their qemu/kernel combination +will work with libguestfs. + +=item F<tmp> + +Used for temporary files when running the tests (instead of F</tmp> +etc). The reason is so that you can run multiple parallel tests of +libguestfs without having one set of tests overwriting the appliance +created by another. + +=item F<tools> + +Command line tools written in Perl (L<virt-win-reg(1)> and many others). + +=item F<v2v> + +L<virt-v2v(1)> command and documentation. + +=item F<csharp> + +=item F<erlang> + +=item F<gobject> + +=item F<golang> + +=item F<haskell> + +=item F<java> + +=item F<lua> + +=item F<ocaml> + +=item F<php> + +=item F<perl> + +=item F<python> + +=item F<ruby> + +Language bindings. + +=back + +=head2 MAKING A STABLE RELEASE + +When we make a stable release, there are several steps documented +here. See L<guestfs(3)/LIBGUESTFS VERSION NUMBERS> for general information +about the stable branch policy. + +=over 4 + +=item * + +Check C<make && make check> works on at least Fedora, Debian and +Ubuntu. + +=item * + +Check C<./configure --without-libvirt> works. + +=item * + +Finalize F<guestfs-release-notes.pod> + +=item * + +Push and pull from Zanata. + +Run: + + zanata push + +to push the latest POT files to Zanata. Then run: + + ./zanata-pull.sh + +which is a wrapper to pull the latest translated F<*.po> files. + +=item * + +Consider updating gnulib to latest upstream version. + +=item * + +Create new stable and development directories under +L<http://libguestfs.org/download>. + +=item * + +Edit F<index.html.in> on website. + +=item * + +Create the branch in git: + + git tag -a 1.XX.0 -m "Version 1.XX.0 (stable)" + git tag -a 1.YY.0 -m "Version 1.YY.0 (development)" + git branch stable-1.XX + git push origin tag 1.XX.0 1.YY.0 stable-1.XX + +=back + +=head1 SEE ALSO + +L<guestfs(3)>, +L<guestfs-examples(3)>, +L<guestfs-performance(1)>, +L<guestfs-release-notes(1)>, +L<guestfs-testing(1)>, +L<libguestfs-test-tool(1)>, +L<libguestfs-make-fixed-appliance(1)>, +L<http://libguestfs.org/>. + +=head1 AUTHORS + +Richard W.M. Jones (C<rjones at redhat dot com>) + +=head1 COPYRIGHT + +Copyright (C) 2009-2015 Red Hat Inc. diff --git a/generator/types.ml b/generator/types.ml index 0d22e0c..f2d9750 100644 --- a/generator/types.ml +++ b/generator/types.ml @@ -212,7 +212,7 @@ type fish_output_t | FishOutputOctal (* for int return, print in octal *) | FishOutputHexadecimal (* for int return, print in hex *) -(* See guestfs(3)/EXTENDING LIBGUESTFS. *) +(* See guestfs-hacking(1). *) type c_api_tests = (c_api_test_init * c_api_test_prereq * c_api_test * c_api_test_cleanup) list and c_api_test (* Run the command sequence and just expect nothing to fail. *) diff --git a/po-docs/language.mk b/po-docs/language.mk index 89a559b..8b70c55 100644 --- a/po-docs/language.mk +++ b/po-docs/language.mk @@ -32,6 +32,7 @@ MANPAGES = \ guestfs-erlang.3 \ guestfs-examples.3 \ guestfs-faq.1 \ + guestfs-hacking.1 \ guestfs-golang.3 \ guestfs-java.3 \ guestfs-lua.3 \ diff --git a/po-docs/podfiles b/po-docs/podfiles index a83761c..2f932fe 100644 --- a/po-docs/podfiles +++ b/po-docs/podfiles @@ -14,6 +14,7 @@ ../dib/virt-dib.pod ../diff/virt-diff.pod ../docs/guestfs-faq.pod +../docs/guestfs-hacking.pod ../docs/guestfs-performance.pod ../docs/guestfs-recipes.pod ../docs/guestfs-release-notes.pod diff --git a/src/guestfs.pod b/src/guestfs.pod index f8d7e2c..b904ce4 100644 --- a/src/guestfs.pod +++ b/src/guestfs.pod @@ -40,7 +40,8 @@ For tips and recipes, see L<guestfs-recipes(1)>. If you are having performance problems, read L<guestfs-performance(1)>. To help test libguestfs, read -L<libguestfs-test-tool(1)> and L<guestfs-testing(1)>. +L<libguestfs-test-tool(1)> and L<guestfs-testing(1)>. To contribute +code to libguestfs, see L<guestfs-hacking(1)>. =head1 API OVERVIEW @@ -3940,735 +3941,6 @@ dot-oh release won't necessarily be so stable at this point, but by backporting fixes from development, that branch will stabilize over time. -=head1 EXTENDING LIBGUESTFS - -This section is for hackers who want to extend libguestfs itself. - -=head2 OVERVIEW OF THE SOURCE CODE - -Libguestfs source is located in the github repository -L<https://github.com/libguestfs/libguestfs> - -Large amounts of boilerplate code in libguestfs (RPC, bindings, -documentation) are generated. This means that many source files will -appear to be missing from a straightforward git checkout. You have to -run the generator (C<./autogen.sh && make -C generator>) in order to -create those files. - -Libguestfs uses an autotools-based build system, with the main files -being F<configure.ac> and F<Makefile.am>. The F<generator> -subdirectory contains the generator, plus files describing the API. -The F<src> subdirectory contains source for the library. The -F<appliance> and F<daemon> subdirectories contain the source for the -code that builds the appliance, and the code that runs in the -appliance respectively. Other directories are covered in the section -L<SOURCE CODE SUBDIRECTORIES> below. - -Apart from the fact that all API entry points go via some generated -code, the library is straightforward. (In fact, even the generated -code is designed to be readable, and should be read as ordinary code). -Some actions run entirely in the library, and are written as C -functions in files under F<src>. Others are forwarded to the daemon -where (after some generated RPC marshalling) they appear as C -functions in files under F<daemon>. - -To build from source, first read the C<README> file. - -=head2 F<local*> FILES - -Files in the top source directory that begin with the prefix F<local*> -are ignored by git. These files can contain local configuration or -scripts that you need to build libguestfs. - -By convention, I have a file called F<localconfigure> which is a -simple wrapper around F<autogen.sh> containing local configure -customizations that I need: - - . localenv - ./autogen.sh \ - --with-default-backend=libvirt \ - --enable-gcc-warnings \ - --enable-gtk-doc \ - -C \ - "$@" - -So I can use this to build libguestfs: - - ./localconfigure && make - -If there is a file in the top build directory called F<localenv>, then -it will be sourced by C<make>. This file can contain any local -environment variables needed, eg. for skipping tests: - - # Use an alternate python binary. - export PYTHON=python3 - # Skip this test, it is broken. - export SKIP_TEST_BTRFS_FSCK=1 - -Note that F<localenv> is included by the top Makefile (so it's a -Makefile fragment). But if it is also sourced by your -F<localconfigure> script then it is used as a shell script. - -=head2 ADDING A NEW API ACTION - -Because large amounts of boilerplate code in libguestfs are generated, -this makes it easy to extend the libguestfs API. - -To add a new API action there are two changes: - -=over 4 - -=item 1. - -You need to add a description of the call (name, parameters, return -type, tests, documentation) to F<generator/actions.ml>. - -There are two sorts of API action, depending on whether the call goes -through to the daemon in the appliance, or is serviced entirely by the -library (see L</ARCHITECTURE> above). L</guestfs_sync> is an example -of the former, since the sync is done in the appliance. -L</guestfs_set_trace> is an example of the latter, since a trace flag -is maintained in the handle and all tracing is done on the library -side. - -Most new actions are of the first type, and get added to the -C<daemon_functions> list. Each function has a unique procedure number -used in the RPC protocol which is assigned to that action when we -publish libguestfs and cannot be reused. Take the latest procedure -number and increment it. - -For library-only actions of the second type, add to the -C<non_daemon_functions> list. Since these functions are serviced by -the library and do not travel over the RPC mechanism to the daemon, -these functions do not need a procedure number, and so the procedure -number is set to C<-1>. - -=item 2. - -Implement the action (in C): - -For daemon actions, implement the function C<do_E<lt>nameE<gt>> in the -C<daemon/> directory. - -For library actions, implement the function C<guestfs_impl_E<lt>nameE<gt>> -(note: double underscore) in the C<src/> directory. - -In either case, use another function as an example of what to do. - -=back - -After making these changes, use C<make> to compile. - -Note that you don't need to implement the RPC, language bindings, -manual pages or anything else. It's all automatically generated from -the OCaml description. - -=head2 ADDING TESTS FOR AN API ACTION - -You can supply zero or as many tests as you want per API call. The -tests can either be added as part of the API description -(F<generator/actions.ml>), or in some rarer cases you may want to drop -a script into C<tests/*/>. Note that adding a script to C<tests/*/> -is slower, so if possible use the first method. - -The following describes the test environment used when you add an API -test in F<actions.ml>. - -The test environment has 4 block devices: - -=over 4 - -=item F</dev/sda> 500MB - -General block device for testing. - -=item F</dev/sdb> 500MB - -F</dev/sdb1> is an ext2 filesystem used for testing -filesystem write operations. - -=item F</dev/sdc> 10MB - -Used in a few tests where two block devices are needed. - -=item F</dev/sdd> - -ISO with fixed content (see F<images/test.iso>). - -=back - -To be able to run the tests in a reasonable amount of time, the -libguestfs appliance and block devices are reused between tests. So -don't try testing L</guestfs_kill_subprocess> :-x - -Each test starts with an initial scenario, selected using one of the -C<Init*> expressions, described in F<generator/types.ml>. These -initialize the disks mentioned above in a particular way as documented -in F<types.ml>. You should not assume anything about the previous -contents of other disks that are not initialized. - -You can add a prerequisite clause to any individual test. This is a -run-time check, which, if it fails, causes the test to be skipped. -Useful if testing a command which might not work on all variations of -libguestfs builds. A test that has prerequisite of C<Always> means to -run unconditionally. - -In addition, packagers can skip individual tests by setting -environment variables before running C<make check>. - - SKIP_TEST_<CMD>_<NUM>=1 - -eg: C<SKIP_TEST_COMMAND_3=1> skips test #3 of L</guestfs_command>. - -or: - - SKIP_TEST_<CMD>=1 - -eg: C<SKIP_TEST_ZEROFREE=1> skips all L</guestfs_zerofree> tests. - -Packagers can run only certain tests by setting for example: - - TEST_ONLY="vfs_type zerofree" - -See F<tests/c-api/tests.c> for more details of how these environment -variables work. - -=head2 DEBUGGING NEW API ACTIONS - -Test new actions work before submitting them. - -You can use guestfish to try out new commands. - -Debugging the daemon is a problem because it runs inside a minimal -environment. However you can fprintf messages in the daemon to -stderr, and they will show up if you use C<guestfish -v>. - -=head2 ADDING A NEW LANGUAGE BINDING - -All language bindings must be generated by the generator -(see the F<generator> subdirectory). - -There is no documentation for this yet. We suggest you look -at an existing binding, eg. F<generator/ocaml.ml> or -F<generator/perl.ml>. - -=head2 ADDING TESTS FOR LANGUAGE BINDINGS - -Language bindings should come with tests. Previously testing of -language bindings was rather ad-hoc, but we have been trying to -formalize the set of tests that every language binding should use. - -Currently only the OCaml and Perl bindings actually implement the full -set of tests, and the OCaml bindings are canonical, so you should -emulate what the OCaml tests do. - -This is the numbering scheme used by the tests: - - - 000+ basic tests: - - 010 load the library - 020 create - 030 create-flags - 040 create multiple handles - 050 test setting and getting config properties - 060 explicit close - 065 implicit close (in GC'd languages) - 070 optargs - - - 100 launch, create partitions and LVs and filesystems - - - 400+ events: - - 410 close event - 420 log messages - 430 progress messages - - - 800+ regression tests (specific to the language) - - - 900+ any other custom tests for the language - -To save time when running the tests, only 100, 430, 800+, 900+ should -launch the handle. - -=head2 FORMATTING CODE - -Our C source code generally adheres to some basic code-formatting -conventions. The existing code base is not totally consistent on this -front, but we do prefer that contributed code be formatted similarly. -In short, use spaces-not-TABs for indentation, use 2 spaces for each -indentation level, and other than that, follow the K&R style. - -If you use Emacs, add the following to one of one of your start-up files -(e.g., ~/.emacs), to help ensure that you get indentation right: - - ;;; In libguestfs, indent with spaces everywhere (not TABs). - ;;; Exceptions: Makefile and ChangeLog modes. - (add-hook 'find-file-hook - '(lambda () (if (and buffer-file-name - (string-match "/libguestfs\\>" - (buffer-file-name)) - (not (string-equal mode-name "Change Log")) - (not (string-equal mode-name "Makefile"))) - (setq indent-tabs-mode nil)))) - - ;;; When editing C sources in libguestfs, use this style. - (defun libguestfs-c-mode () - "C mode with adjusted defaults for use with libguestfs." - (interactive) - (c-set-style "K&R") - (setq c-indent-level 2) - (setq c-basic-offset 2)) - (add-hook 'c-mode-hook - '(lambda () (if (string-match "/libguestfs\\>" - (buffer-file-name)) - (libguestfs-c-mode)))) - -=head2 TESTING YOUR CHANGES - -Enable warnings when compiling (and fix any problems this -finds): - - ./configure --enable-gcc-warnings - -Useful targets are: - -=over 4 - -=item C<make check> - -Runs the regular test suite. - -This is implemented using the regular automake C<TESTS> target. See -the automake documentation for details. - -=item C<make check-valgrind> - -Runs a subset of the test suite under valgrind. - -Any F<Makefile.am> in the tree that has a C<check-valgrind:> target -will be run by this rule. - -=item C<make check-valgrind-local-guests> - -Runs a subset of the test suite under valgrind -using locally installed libvirt guests (read-only). - -=item C<make check-direct> - -Runs all tests using default appliance back-end. This only -has any effect if a non-default backend was selected -using C<./configure --with-default-backend=...> - -=item C<make check-valgrind-direct> - -Run a subset of the test suite under valgrind using the -default appliance back-end. - -=item C<make check-uml> - -Runs all tests using the User-Mode Linux backend. - -As there is no standard location for the User-Mode Linux kernel, you -I<have> to set C<LIBGUESTFS_HV> to point to the kernel image, eg: - - make check-uml LIBGUESTFS_HV=~/d/linux-um/vmlinux - -=item C<make check-valgrind-uml> - -Runs all tests using the User-Mode Linux backend, under valgrind. - -As above, you have to set C<LIBGUESTFS_HV> to point to the kernel. - -=item C<make check-with-upstream-qemu> - -Runs all tests using a local qemu binary. It looks for the qemu -binary in QEMUDIR (defaults to F<$HOME/d/qemu>), but you can set this -to another directory on the command line, eg: - - make check-with-upstream-qemu QEMUDIR=/usr/src/qemu - -=item C<make check-with-upstream-libvirt> - -Runs all tests using a local libvirt. This only has any effect if the -libvirt backend was selected using -C<./configure --with-default-backend=libvirt> - -It looks for libvirt in LIBVIRTDIR (defaults to F<$HOME/d/libvirt>), -but you can set this to another directory on the command line, eg: - - make check-with-upstream-libvirt LIBVIRTDIR=/usr/src/libvirt - -=item C<make check-slow> - -Runs some slow/long-running tests which are not run by default. - -Any F<Makefile.am> in the tree that has a C<check-slow:> target will -be run by this rule. - -=item C<make check-all> - -Equivalent to running all C<make check*> rules. - -=item C<make check-release> - -Runs a subset of C<make check*> rules that are required to pass -before a tarball can be released. Currently this is: - -=over 4 - -=item * - -check - -=item * - -check-valgrind - -=item * - -check-direct - -=item * - -check-valgrind-direct - -=item * - -check-slow - -=back - -=item C<make installcheck> - -Run C<make check> on the installed copy of libguestfs. - -The version of installed libguestfs being tested, and the version of -the libguestfs source tree must be the same. - -Do: - - ./autogen.sh - make clean ||: - make - make installcheck - -=back - -=head2 DAEMON CUSTOM PRINTF FORMATTERS - -In the daemon code we have created custom printf formatters C<%Q> and -C<%R>, which are used to do shell quoting. - -=over 4 - -=item %Q - -Simple shell quoted string. Any spaces or other shell characters are -escaped for you. - -=item %R - -Same as C<%Q> except the string is treated as a path which is prefixed -by the sysroot. - -=back - -For example: - - asprintf (&cmd, "cat %R", path); - -would produce C<cat /sysroot/some\ path\ with\ spaces> - -I<Note:> Do I<not> use these when you are passing parameters to the -C<command{,r,v,rv}()> functions. These parameters do NOT need to be -quoted because they are not passed via the shell (instead, straight to -exec). You probably want to use the C<sysroot_path()> function -however. - -=head2 SUBMITTING YOUR NEW API ACTIONS - -Submit patches to the mailing list: -L<http://www.redhat.com/mailman/listinfo/libguestfs> -and CC to L<rjones@redhat.com>. - -=head2 INTERNATIONALIZATION (I18N) SUPPORT - -We support i18n (gettext anyhow) in the library. - -However many messages come from the daemon, and we don't translate -those at the moment. One reason is that the appliance generally has -all locale files removed from it, because they take up a lot of space. -So we'd have to readd some of those, as well as copying our PO files -into the appliance. - -Debugging messages are never translated, since they are intended for -the programmers. - -=head2 SOURCE CODE SUBDIRECTORIES - -=over 4 - -=item F<align> - -L<virt-alignment-scan(1)> command and documentation. - -=item F<appliance> - -The libguestfs appliance, build scripts and so on. - -=item F<bash> - -Bash tab-completion scripts. - -=item F<build-aux> - -Various build scripts used by autotools. - -=item F<builder> - -L<virt-builder(1)> command and documentation. - -=item F<cat> - -The L<virt-cat(1)>, L<virt-filesystems(1)>, L<virt-log(1)> -and L<virt-ls(1)> commands and documentation. - -=item F<contrib> - -Outside contributions, experimental parts. - -=item F<customize> - -L<virt-customize(1)> command and documentation. - -=item F<daemon> - -The daemon that runs inside the libguestfs appliance and carries out -actions. - -=item F<df> - -L<virt-df(1)> command and documentation. - -=item F<dib> - -L<virt-dib(1)> command and documentation. - -=item F<diff> - -L<virt-diff(1)> command and documentation. - -=item F<doc> - -Miscellaneous manual pages. - -=item F<edit> - -L<virt-edit(1)> command and documentation. - -=item F<examples> - -C API example code. - -=item F<fish> - -L<guestfish(1)>, the command-line shell, and various shell scripts -built on top such as L<virt-copy-in(1)>, L<virt-copy-out(1)>, -L<virt-tar-in(1)>, L<virt-tar-out(1)>. - -=item F<format> - -L<virt-format(1)> command and documentation. - -=item F<fuse> - -L<guestmount(1)>, FUSE (userspace filesystem) built on top of libguestfs. - -=item F<generator> - -The crucially important generator, used to automatically generate -large amounts of boilerplate C code for things like RPC and bindings. - -=item F<get-kernel> - -L<virt-get-kernel(1)> command and documentation. - -=item F<gnulib> - -Gnulib is used as a portability library. A copy of gnulib is included -under here. - -=item F<html> - -Generated HTML manual pages. - -=item F<inspector> - -L<virt-inspector(1)>, the virtual machine image inspector. - -=item F<logo> - -Logo used on the website. The fish is called Arthur by the way. - -=item F<m4> - -M4 macros used by autoconf. - -=item F<make-fs> - -L<virt-make-fs(1)> command and documentation. - -=item F<mllib> - -Various libraries and common code used by L<virt-resize(1)> and -the other tools which are written in OCaml. - -=item F<p2v> - -L<virt-p2v(1)> command, documentation and scripts for building the -virt-p2v ISO or disk image. - -=item F<po> - -Translations of simple gettext strings. - -=item F<po-docs> - -The build infrastructure and PO files for translations of manpages and -POD files. Eventually this will be combined with the F<po> directory, -but that is rather complicated. - -=item F<rescue> - -L<virt-rescue(1)> command and documentation. - -=item F<resize> - -L<virt-resize(1)> command and documentation. - -=item F<sparsify> - -L<virt-sparsify(1)> command and documentation. - -=item F<src> - -Source code to the C library. - -=item F<sysprep> - -L<virt-sysprep(1)> command and documentation. - -=item F<tests> - -Tests. - -=item F<test-tool> - -Test tool for end users to test if their qemu/kernel combination -will work with libguestfs. - -=item F<tmp> - -Used for temporary files when running the tests (instead of F</tmp> -etc). The reason is so that you can run multiple parallel tests of -libguestfs without having one set of tests overwriting the appliance -created by another. - -=item F<tools> - -Command line tools written in Perl (L<virt-win-reg(1)> and many others). - -=item F<v2v> - -L<virt-v2v(1)> command and documentation. - -=item F<csharp> - -=item F<erlang> - -=item F<gobject> - -=item F<golang> - -=item F<haskell> - -=item F<java> - -=item F<lua> - -=item F<ocaml> - -=item F<php> - -=item F<perl> - -=item F<python> - -=item F<ruby> - -Language bindings. - -=back - -=head2 MAKING A STABLE RELEASE - -When we make a stable release, there are several steps documented -here. See L</LIBGUESTFS VERSION NUMBERS> for general information -about the stable branch policy. - -=over 4 - -=item * - -Check C<make && make check> works on at least Fedora, Debian and -Ubuntu. - -=item * - -Check C<./configure --without-libvirt> works. - -=item * - -Finalize F<guestfs-release-notes.pod> - -=item * - -Push and pull from Zanata. - -Run: - - zanata push - -to push the latest POT files to Zanata. Then run: - - ./zanata-pull.sh - -which is a wrapper to pull the latest translated F<*.po> files. - -=item * - -Consider updating gnulib to latest upstream version. - -=item * - -Create new stable and development directories under -L<http://libguestfs.org/download>. - -=item * - -Edit F<index.html.in> on website. - -=item * - -Create the branch in git: - - git tag -a 1.XX.0 -m "Version 1.XX.0 (stable)" - git tag -a 1.YY.0 -m "Version 1.YY.0 (development)" - git branch stable-1.XX - git push origin tag 1.XX.0 1.YY.0 stable-1.XX - -=back - =head1 LIMITS =head2 PROTOCOL LIMITS @@ -4934,6 +4206,7 @@ L<virt-tar-out(1)>, L<virt-v2v(1)>, L<virt-win-reg(1)>, L<guestfs-faq(1)>, +L<guestfs-hacking(1)>, L<guestfs-performance(1)>, L<guestfs-release-notes(1)>, L<guestfs-testing(1)>, -- 2.5.0
Richard W.M. Jones
2015-Oct-29 15:02 UTC
[Libguestfs] [PATCH 14/16] docs: Move architecture and internals documentation to guestfs-internals(1).
--- .gitignore | 3 + docs/Makefile.am | 15 ++ docs/guestfs-faq.pod | 4 +- docs/guestfs-hacking.pod | 1 + docs/guestfs-internals.pod | 415 +++++++++++++++++++++++++++++++++++++++++++ docs/guestfs-performance.pod | 1 + po-docs/language.mk | 1 + po-docs/podfiles | 1 + src/guestfs.pod | 402 +---------------------------------------- 9 files changed, 444 insertions(+), 399 deletions(-) create mode 100644 docs/guestfs-internals.pod diff --git a/.gitignore b/.gitignore index 3338d27..a33a286 100644 --- a/.gitignore +++ b/.gitignore @@ -132,12 +132,14 @@ Makefile.in /diff/virt-diff.1 /docs/guestfs-faq.1 /docs/guestfs-hacking.1 +/docs/guestfs-internals.1 /docs/guestfs-performance.1 /docs/guestfs-recipes.1 /docs/guestfs-release-notes.1 /docs/guestfs-testing.1 /docs/stamp-guestfs-faq.pod /docs/stamp-guestfs-hacking.pod +/docs/stamp-guestfs-internals.pod /docs/stamp-guestfs-performance.pod /docs/stamp-guestfs-recipes.pod /docs/stamp-guestfs-release-notes.pod @@ -234,6 +236,7 @@ Makefile.in /html/guestfs-examples.3.html /html/guestfs-faq.1.html /html/guestfs-hacking.1.html +/html/guestfs-internals.1.html /html/guestfs-golang.3.html /html/guestfs-java.3.html /html/guestfs-lua.3.html diff --git a/docs/Makefile.am b/docs/Makefile.am index 4e6a0b5..9ead4c8 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -20,6 +20,7 @@ include $(top_srcdir)/subdir-rules.mk EXTRA_DIST = \ guestfs-faq.pod \ guestfs-hacking.pod \ + guestfs-internals.pod \ guestfs-performance.pod \ guestfs-recipes.pod \ guestfs-release-notes.pod \ @@ -29,6 +30,7 @@ EXTRA_DIST = \ CLEANFILES = \ stamp-guestfs-faq.pod \ stamp-guestfs-hacking.pod \ + stamp-guestfs-internals.pod \ stamp-guestfs-performance.pod \ stamp-guestfs-recipes.pod \ stamp-guestfs-release-notes.pod \ @@ -37,6 +39,7 @@ CLEANFILES = \ man_MANS = \ guestfs-faq.1 \ guestfs-hacking.1 \ + guestfs-internals.1 \ guestfs-performance.1 \ guestfs-recipes.1 \ guestfs-release-notes.1 \ @@ -44,6 +47,7 @@ man_MANS = \ noinst_DATA = \ $(top_builddir)/html/guestfs-faq.1.html \ $(top_builddir)/html/guestfs-hacking.1.html \ + $(top_builddir)/html/guestfs-internals.1.html \ $(top_builddir)/html/guestfs-performance.1.html \ $(top_builddir)/html/guestfs-recipes.1.html \ $(top_builddir)/html/guestfs-release-notes.1.html \ @@ -71,6 +75,17 @@ stamp-guestfs-hacking.pod: guestfs-hacking.pod $< touch $@ +guestfs-internals.1 $(top_builddir)/html/guestfs-internals.1.html: stamp-guestfs-internals.pod + +stamp-guestfs-internals.pod: guestfs-internals.pod + $(PODWRAPPER) \ + --section 1 \ + --man guestfs-internals.1 \ + --html $(top_builddir)/html/guestfs-internals.1.html \ + --license LGPLv2+ \ + $< + touch $@ + guestfs-performance.1 $(top_builddir)/html/guestfs-performance.1.html: stamp-guestfs-performance.pod stamp-guestfs-performance.pod: guestfs-performance.pod diff --git a/docs/guestfs-faq.pod b/docs/guestfs-faq.pod index 55dfed2..5215e92 100644 --- a/docs/guestfs-faq.pod +++ b/docs/guestfs-faq.pod @@ -990,7 +990,7 @@ F<examples/debug-logging.c> program in the libguestfs sources. =head2 Digging deeper into the appliance boot process. Enable debugging and then read this documentation on the appliance -boot process: L<guestfs(3)/INTERNALS>. +boot process: L<guestfs-internals(1)>. =head2 libguestfs hangs or fails during run/launch. @@ -1015,6 +1015,8 @@ useful debugging information from libvirtd in F</tmp/libvirtd.log> =head1 DESIGN/INTERNALS OF LIBGUESTFS +See also L<guestfs-internals(1)>. + =head2 Why don't you do everything through the FUSE / filesystem interface? diff --git a/docs/guestfs-hacking.pod b/docs/guestfs-hacking.pod index 7935b56..76b1b8d 100644 --- a/docs/guestfs-hacking.pod +++ b/docs/guestfs-hacking.pod @@ -735,6 +735,7 @@ Create the branch in git: L<guestfs(3)>, L<guestfs-examples(3)>, +L<guestfs-internals(3)>, L<guestfs-performance(1)>, L<guestfs-release-notes(1)>, L<guestfs-testing(1)>, diff --git a/docs/guestfs-internals.pod b/docs/guestfs-internals.pod new file mode 100644 index 0000000..a2cc17f --- /dev/null +++ b/docs/guestfs-internals.pod @@ -0,0 +1,415 @@ +=head1 NAME + +guestfs-internals - architecture and internals of libguestfs + +=head1 DESCRIPTION + +This manual page is for hackers who want to understand how libguestfs +works internally. This is just a description of how libguestfs works +now, and it may change at any time in the future. + +=head1 ARCHITECTURE + +Internally, libguestfs is implemented by running an appliance (a +special type of small virtual machine) using L<qemu(1)>. Qemu runs as +a child process of the main program. + + ┌───────────────────┐ + │ main program │ + │ │ + │ │ child process / appliance + │ │ ┌──────────────────────────┐ + │ │ │ qemu │ + ├───────────────────┤ RPC │ ┌─────────────────┐ │ + │ libguestfs ◀╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍▶ guestfsd │ │ + │ │ │ ├─────────────────┤ │ + └───────────────────┘ │ │ Linux kernel │ │ + │ └────────┬────────┘ │ + └───────────────│──────────┘ + │ + │ virtio-scsi + ┌──────┴──────┐ + │ Device or │ + │ disk image │ + └─────────────┘ + +The library, linked to the main program, creates the child process and +hence the appliance in the L</guestfs_launch> function. + +Inside the appliance is a Linux kernel and a complete stack of +userspace tools (such as LVM and ext2 programs) and a small +controlling daemon called L</guestfsd>. The library talks to +L</guestfsd> using remote procedure calls (RPC). There is a mostly +one-to-one correspondence between libguestfs API calls and RPC calls +to the daemon. Lastly the disk image(s) are attached to the qemu +process which translates device access by the appliance's Linux kernel +into accesses to the image. + +A common misunderstanding is that the appliance "is" the virtual +machine. Although the disk image you are attached to might also be +used by some virtual machine, libguestfs doesn't know or care about +this. (But you will care if both libguestfs's qemu process and your +virtual machine are trying to update the disk image at the same time, +since these usually results in massive disk corruption). + +=head1 STATE MACHINE + +libguestfs uses a state machine to model the child process: + + | + guestfs_create / guestfs_create_flags + | + | + ____V_____ + / \ + | CONFIG | + \__________/ + ^ ^ \ + | \ \ guestfs_launch + | _\__V______ + | / \ + | | LAUNCHING | + | \___________/ + | / + | guestfs_launch + | / + __|____V + / \ + | READY | + \________/ + +The normal transitions are (1) CONFIG (when the handle is created, but +there is no child process), (2) LAUNCHING (when the child process is +booting up), (3) READY meaning the appliance is up, actions can be +issued to, and carried out by, the child process. + +The guest may be killed by L</guestfs_kill_subprocess>, or may die +asynchronously at any time (eg. due to some internal error), and that +causes the state to transition back to CONFIG. + +Configuration commands for qemu such as L</guestfs_set_path> can only +be issued when in the CONFIG state. + +The API offers one call that goes from CONFIG through LAUNCHING to +READY. L</guestfs_launch> blocks until the child process is READY to +accept commands (or until some failure or timeout). +L</guestfs_launch> internally moves the state from CONFIG to LAUNCHING +while it is running. + +API actions such as L</guestfs_mount> can only be issued when in the +READY state. These API calls block waiting for the command to be +carried out. There are no non-blocking versions, and no way to issue +more than one command per handle at the same time. + +Finally, the child process sends asynchronous messages back to the +main program, such as kernel log messages. You can register a +callback to receive these messages. + +=head1 INTERNALS + +=head2 APPLIANCE BOOT PROCESS + +This process has evolved and continues to evolve. The description +here corresponds only to the current version of libguestfs and is +provided for information only. + +In order to follow the stages involved below, enable libguestfs +debugging (set the environment variable C<LIBGUESTFS_DEBUG=1>). + +=over 4 + +=item Create the appliance + +C<supermin --build> is invoked to create the kernel, a small initrd +and the appliance. + +The appliance is cached in F</var/tmp/.guestfs-E<lt>UIDE<gt>> (or in +another directory if C<LIBGUESTFS_CACHEDIR> or C<TMPDIR> are set). + +For a complete description of how the appliance is created and cached, +read the L<supermin(1)> man page. + +=item Start qemu and boot the kernel + +qemu is invoked to boot the kernel. + +=item Run the initrd + +C<supermin --build> builds a small initrd. The initrd is not the +appliance. The purpose of the initrd is to load enough kernel modules +in order that the appliance itself can be mounted and started. + +The initrd is a cpio archive called +F</var/tmp/.guestfs-E<lt>UIDE<gt>/appliance.d/initrd>. + +When the initrd has started you will see messages showing that kernel +modules are being loaded, similar to this: + + supermin: ext2 mini initrd starting up + supermin: mounting /sys + supermin: internal insmod libcrc32c.ko + supermin: internal insmod crc32c-intel.ko + +=item Find and mount the appliance device + +The appliance is a sparse file containing an ext2 filesystem which +contains a familiar (although reduced in size) Linux operating system. +It would normally be called +F</var/tmp/.guestfs-E<lt>UIDE<gt>/appliance.d/root>. + +The regular disks being inspected by libguestfs are the first +devices exposed by qemu (eg. as F</dev/vda>). + +The last disk added to qemu is the appliance itself (eg. F</dev/vdb> +if there was only one regular disk). + +Thus the final job of the initrd is to locate the appliance disk, +mount it, and switch root into the appliance, and run F</init> from +the appliance. + +If this works successfully you will see messages such as: + + supermin: picked /sys/block/vdb/dev as root device + supermin: creating /dev/root as block special 252:16 + supermin: mounting new root on /root + supermin: chroot + Starting /init script ... + +Note that C<Starting /init script ...> indicates that the appliance's +init script is now running. + +=item Initialize the appliance + +The appliance itself now initializes itself. This involves starting +certain processes like C<udev>, possibly printing some debug +information, and finally running the daemon (C<guestfsd>). + +=item The daemon + +Finally the daemon (C<guestfsd>) runs inside the appliance. If it +runs you should see: + + verbose daemon enabled + +The daemon expects to see a named virtio-serial port exposed by qemu +and connected on the other end to the library. + +The daemon connects to this port (and hence to the library) and sends +a four byte message C<GUESTFS_LAUNCH_FLAG>, which initiates the +communication protocol (see below). + +=back + +=head2 COMMUNICATION PROTOCOL + +Don't rely on using this protocol directly. This section documents +how it currently works, but it may change at any time. + +The protocol used to talk between the library and the daemon running +inside the qemu virtual machine is a simple RPC mechanism built on top +of XDR (RFC 1014, RFC 1832, RFC 4506). + +The detailed format of structures is in F<src/guestfs_protocol.x> +(note: this file is automatically generated). + +There are two broad cases, ordinary functions that don't have any +C<FileIn> and C<FileOut> parameters, which are handled with very +simple request/reply messages. Then there are functions that have any +C<FileIn> or C<FileOut> parameters, which use the same request and +reply messages, but they may also be followed by files sent using a +chunked encoding. + +=head3 ORDINARY FUNCTIONS (NO FILEIN/FILEOUT PARAMS) + +For ordinary functions, the request message is: + + total length (header + arguments, + but not including the length word itself) + struct guestfs_message_header (encoded as XDR) + struct guestfs_<foo>_args (encoded as XDR) + +The total length field allows the daemon to allocate a fixed size +buffer into which it slurps the rest of the message. As a result, the +total length is limited to C<GUESTFS_MESSAGE_MAX> bytes (currently +4MB), which means the effective size of any request is limited to +somewhere under this size. + +Note also that many functions don't take any arguments, in which case +the C<guestfs_I<foo>_args> is completely omitted. + +The header contains the procedure number (C<guestfs_proc>) which is +how the receiver knows what type of args structure to expect, or none +at all. + +For functions that take optional arguments, the optional arguments are +encoded in the C<guestfs_I<foo>_args> structure in the same way as +ordinary arguments. A bitmask in the header indicates which optional +arguments are meaningful. The bitmask is also checked to see if it +contains bits set which the daemon does not know about (eg. if more +optional arguments were added in a later version of the library), and +this causes the call to be rejected. + +The reply message for ordinary functions is: + + total length (header + ret, + but not including the length word itself) + struct guestfs_message_header (encoded as XDR) + struct guestfs_<foo>_ret (encoded as XDR) + +As above the C<guestfs_I<foo>_ret> structure may be completely omitted +for functions that return no formal return values. + +As above the total length of the reply is limited to +C<GUESTFS_MESSAGE_MAX>. + +In the case of an error, a flag is set in the header, and the reply +message is slightly changed: + + total length (header + error, + but not including the length word itself) + struct guestfs_message_header (encoded as XDR) + struct guestfs_message_error (encoded as XDR) + +The C<guestfs_message_error> structure contains the error message as a +string. + +=head3 FUNCTIONS THAT HAVE FILEIN PARAMETERS + +A C<FileIn> parameter indicates that we transfer a file I<into> the +guest. The normal request message is sent (see above). However this +is followed by a sequence of file chunks. + + total length (header + arguments, + but not including the length word itself, + and not including the chunks) + struct guestfs_message_header (encoded as XDR) + struct guestfs_<foo>_args (encoded as XDR) + sequence of chunks for FileIn param #0 + sequence of chunks for FileIn param #1 etc. + +The "sequence of chunks" is: + + length of chunk (not including length word itself) + struct guestfs_chunk (encoded as XDR) + length of chunk + struct guestfs_chunk (encoded as XDR) + ... + length of chunk + struct guestfs_chunk (with data.data_len == 0) + +The final chunk has the C<data_len> field set to zero. Additionally a +flag is set in the final chunk to indicate either successful +completion or early cancellation. + +At time of writing there are no functions that have more than one +FileIn parameter. However this is (theoretically) supported, by +sending the sequence of chunks for each FileIn parameter one after +another (from left to right). + +Both the library (sender) I<and> the daemon (receiver) may cancel the +transfer. The library does this by sending a chunk with a special +flag set to indicate cancellation. When the daemon sees this, it +cancels the whole RPC, does I<not> send any reply, and goes back to +reading the next request. + +The daemon may also cancel. It does this by writing a special word +C<GUESTFS_CANCEL_FLAG> to the socket. The library listens for this +during the transfer, and if it gets it, it will cancel the transfer +(it sends a cancel chunk). The special word is chosen so that even if +cancellation happens right at the end of the transfer (after the +library has finished writing and has started listening for the reply), +the "spurious" cancel flag will not be confused with the reply +message. + +This protocol allows the transfer of arbitrary sized files (no 32 bit +limit), and also files where the size is not known in advance +(eg. from pipes or sockets). However the chunks are rather small +(C<GUESTFS_MAX_CHUNK_SIZE>), so that neither the library nor the +daemon need to keep much in memory. + +=head3 FUNCTIONS THAT HAVE FILEOUT PARAMETERS + +The protocol for FileOut parameters is exactly the same as for FileIn +parameters, but with the roles of daemon and library reversed. + + total length (header + ret, + but not including the length word itself, + and not including the chunks) + struct guestfs_message_header (encoded as XDR) + struct guestfs_<foo>_ret (encoded as XDR) + sequence of chunks for FileOut param #0 + sequence of chunks for FileOut param #1 etc. + +=head3 INITIAL MESSAGE + +When the daemon launches it sends an initial word +(C<GUESTFS_LAUNCH_FLAG>) which indicates that the guest and daemon is +alive. This is what L</guestfs_launch> waits for. + +=head3 PROGRESS NOTIFICATION MESSAGES + +The daemon may send progress notification messages at any time. These +are distinguished by the normal length word being replaced by +C<GUESTFS_PROGRESS_FLAG>, followed by a fixed size progress message. + +The library turns them into progress callbacks (see +L</GUESTFS_EVENT_PROGRESS>) if there is a callback registered, or +discards them if not. + +The daemon self-limits the frequency of progress messages it sends +(see C<daemon/proto.c:notify_progress>). Not all calls generate +progress messages. + +=head2 FIXED APPLIANCE + +When libguestfs (or libguestfs tools) are run, they search a path +looking for an appliance. The path is built into libguestfs, or can +be set using the C<LIBGUESTFS_PATH> environment variable. + +Normally a supermin appliance is located on this path (see +L<supermin(1)/SUPERMIN APPLIANCE>). libguestfs reconstructs this +into a full appliance by running C<supermin --build>. + +However, a simpler "fixed appliance" can also be used. libguestfs +detects this by looking for a directory on the path containing all +the following files: + +=over 4 + +=item * F<kernel> + +=item * F<initrd> + +=item * F<root> + +=item * F<README.fixed> (note that it B<must> be present as well) + +=back + +If the fixed appliance is found, libguestfs skips supermin entirely +and just runs the virtual machine (using qemu or the current backend, +see L</BACKEND>) with the kernel, initrd and root disk from the fixed +appliance. + +Thus the fixed appliance can be used when a platform or a Linux +distribution does not support supermin. You build the fixed appliance +on a platform that does support supermin using +L<libguestfs-make-fixed-appliance(1)>, copy it over, and use that +to run libguestfs. + +=head1 SEE ALSO + +L<guestfs(3)>, +L<guestfs-hacking(3)>, +L<guestfs-examples(3)>, +L<libguestfs-test-tool(1)>, +L<libguestfs-make-fixed-appliance(1)>, +L<http://libguestfs.org/>. + +=head1 AUTHORS + +Richard W.M. Jones (C<rjones at redhat dot com>) + +=head1 COPYRIGHT + +Copyright (C) 2009-2015 Red Hat Inc. diff --git a/docs/guestfs-performance.pod b/docs/guestfs-performance.pod index 27f24b4..5a7c01b 100644 --- a/docs/guestfs-performance.pod +++ b/docs/guestfs-performance.pod @@ -570,6 +570,7 @@ L<supermin(1)>, L<guestfish(1)>, L<guestfs(3)>, L<guestfs-examples(3)>, +L<guestfs-internals(1)>, L<libguestfs-make-fixed-appliance(1)>, L<stap(1)>, L<qemu(1)>, diff --git a/po-docs/language.mk b/po-docs/language.mk index 8b70c55..73fcacd 100644 --- a/po-docs/language.mk +++ b/po-docs/language.mk @@ -33,6 +33,7 @@ MANPAGES = \ guestfs-examples.3 \ guestfs-faq.1 \ guestfs-hacking.1 \ + guestfs-internals.1 \ guestfs-golang.3 \ guestfs-java.3 \ guestfs-lua.3 \ diff --git a/po-docs/podfiles b/po-docs/podfiles index 2f932fe..611b549 100644 --- a/po-docs/podfiles +++ b/po-docs/podfiles @@ -15,6 +15,7 @@ ../diff/virt-diff.pod ../docs/guestfs-faq.pod ../docs/guestfs-hacking.pod +../docs/guestfs-internals.pod ../docs/guestfs-performance.pod ../docs/guestfs-recipes.pod ../docs/guestfs-release-notes.pod diff --git a/src/guestfs.pod b/src/guestfs.pod index b904ce4..399396e 100644 --- a/src/guestfs.pod +++ b/src/guestfs.pod @@ -41,7 +41,8 @@ For tips and recipes, see L<guestfs-recipes(1)>. If you are having performance problems, read L<guestfs-performance(1)>. To help test libguestfs, read L<libguestfs-test-tool(1)> and L<guestfs-testing(1)>. To contribute -code to libguestfs, see L<guestfs-hacking(1)>. +code to libguestfs, see L<guestfs-hacking(1)>. To find out how +libguestfs works, see L<guestfs-internals(1)>. =head1 API OVERVIEW @@ -3482,402 +3483,6 @@ In the first terminal, stap trace output similar to this is shown: 1318248061071167 (+4233108): launch_end 1318248061280324 (+209157): guestfs_mkfs g=0x1024ab0 fstype=0x46116f device=0x1024e60 -=begin html - -<!-- old anchor for the next section --> -<a name="state_machine_and_low_level_event_api"/> - -=end html - -=head1 ARCHITECTURE - -Internally, libguestfs is implemented by running an appliance (a -special type of small virtual machine) using L<qemu(1)>. Qemu runs as -a child process of the main program. - - ┌───────────────────┐ - │ main program │ - │ │ - │ │ child process / appliance - │ │ ┌──────────────────────────┐ - │ │ │ qemu │ - ├───────────────────┤ RPC │ ┌─────────────────┐ │ - │ libguestfs ◀╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍▶ guestfsd │ │ - │ │ │ ├─────────────────┤ │ - └───────────────────┘ │ │ Linux kernel │ │ - │ └────────┬────────┘ │ - └───────────────│──────────┘ - │ - │ virtio-scsi - ┌──────┴──────┐ - │ Device or │ - │ disk image │ - └─────────────┘ - -The library, linked to the main program, creates the child process and -hence the appliance in the L</guestfs_launch> function. - -Inside the appliance is a Linux kernel and a complete stack of -userspace tools (such as LVM and ext2 programs) and a small -controlling daemon called L</guestfsd>. The library talks to -L</guestfsd> using remote procedure calls (RPC). There is a mostly -one-to-one correspondence between libguestfs API calls and RPC calls -to the daemon. Lastly the disk image(s) are attached to the qemu -process which translates device access by the appliance's Linux kernel -into accesses to the image. - -A common misunderstanding is that the appliance "is" the virtual -machine. Although the disk image you are attached to might also be -used by some virtual machine, libguestfs doesn't know or care about -this. (But you will care if both libguestfs's qemu process and your -virtual machine are trying to update the disk image at the same time, -since these usually results in massive disk corruption). - -=head1 STATE MACHINE - -libguestfs uses a state machine to model the child process: - - | - guestfs_create / guestfs_create_flags - | - | - ____V_____ - / \ - | CONFIG | - \__________/ - ^ ^ \ - | \ \ guestfs_launch - | _\__V______ - | / \ - | | LAUNCHING | - | \___________/ - | / - | guestfs_launch - | / - __|____V - / \ - | READY | - \________/ - -The normal transitions are (1) CONFIG (when the handle is created, but -there is no child process), (2) LAUNCHING (when the child process is -booting up), (3) READY meaning the appliance is up, actions can be -issued to, and carried out by, the child process. - -The guest may be killed by L</guestfs_kill_subprocess>, or may die -asynchronously at any time (eg. due to some internal error), and that -causes the state to transition back to CONFIG. - -Configuration commands for qemu such as L</guestfs_set_path> can only -be issued when in the CONFIG state. - -The API offers one call that goes from CONFIG through LAUNCHING to -READY. L</guestfs_launch> blocks until the child process is READY to -accept commands (or until some failure or timeout). -L</guestfs_launch> internally moves the state from CONFIG to LAUNCHING -while it is running. - -API actions such as L</guestfs_mount> can only be issued when in the -READY state. These API calls block waiting for the command to be -carried out. There are no non-blocking versions, and no way to issue -more than one command per handle at the same time. - -Finally, the child process sends asynchronous messages back to the -main program, such as kernel log messages. You can register a -callback to receive these messages. - -=head1 INTERNALS - -=head2 APPLIANCE BOOT PROCESS - -This process has evolved and continues to evolve. The description -here corresponds only to the current version of libguestfs and is -provided for information only. - -In order to follow the stages involved below, enable libguestfs -debugging (set the environment variable C<LIBGUESTFS_DEBUG=1>). - -=over 4 - -=item Create the appliance - -C<supermin --build> is invoked to create the kernel, a small initrd -and the appliance. - -The appliance is cached in F</var/tmp/.guestfs-E<lt>UIDE<gt>> (or in -another directory if C<LIBGUESTFS_CACHEDIR> or C<TMPDIR> are set). - -For a complete description of how the appliance is created and cached, -read the L<supermin(1)> man page. - -=item Start qemu and boot the kernel - -qemu is invoked to boot the kernel. - -=item Run the initrd - -C<supermin --build> builds a small initrd. The initrd is not the -appliance. The purpose of the initrd is to load enough kernel modules -in order that the appliance itself can be mounted and started. - -The initrd is a cpio archive called -F</var/tmp/.guestfs-E<lt>UIDE<gt>/appliance.d/initrd>. - -When the initrd has started you will see messages showing that kernel -modules are being loaded, similar to this: - - supermin: ext2 mini initrd starting up - supermin: mounting /sys - supermin: internal insmod libcrc32c.ko - supermin: internal insmod crc32c-intel.ko - -=item Find and mount the appliance device - -The appliance is a sparse file containing an ext2 filesystem which -contains a familiar (although reduced in size) Linux operating system. -It would normally be called -F</var/tmp/.guestfs-E<lt>UIDE<gt>/appliance.d/root>. - -The regular disks being inspected by libguestfs are the first -devices exposed by qemu (eg. as F</dev/vda>). - -The last disk added to qemu is the appliance itself (eg. F</dev/vdb> -if there was only one regular disk). - -Thus the final job of the initrd is to locate the appliance disk, -mount it, and switch root into the appliance, and run F</init> from -the appliance. - -If this works successfully you will see messages such as: - - supermin: picked /sys/block/vdb/dev as root device - supermin: creating /dev/root as block special 252:16 - supermin: mounting new root on /root - supermin: chroot - Starting /init script ... - -Note that C<Starting /init script ...> indicates that the appliance's -init script is now running. - -=item Initialize the appliance - -The appliance itself now initializes itself. This involves starting -certain processes like C<udev>, possibly printing some debug -information, and finally running the daemon (C<guestfsd>). - -=item The daemon - -Finally the daemon (C<guestfsd>) runs inside the appliance. If it -runs you should see: - - verbose daemon enabled - -The daemon expects to see a named virtio-serial port exposed by qemu -and connected on the other end to the library. - -The daemon connects to this port (and hence to the library) and sends -a four byte message C<GUESTFS_LAUNCH_FLAG>, which initiates the -communication protocol (see below). - -=back - -=head2 COMMUNICATION PROTOCOL - -Don't rely on using this protocol directly. This section documents -how it currently works, but it may change at any time. - -The protocol used to talk between the library and the daemon running -inside the qemu virtual machine is a simple RPC mechanism built on top -of XDR (RFC 1014, RFC 1832, RFC 4506). - -The detailed format of structures is in F<src/guestfs_protocol.x> -(note: this file is automatically generated). - -There are two broad cases, ordinary functions that don't have any -C<FileIn> and C<FileOut> parameters, which are handled with very -simple request/reply messages. Then there are functions that have any -C<FileIn> or C<FileOut> parameters, which use the same request and -reply messages, but they may also be followed by files sent using a -chunked encoding. - -=head3 ORDINARY FUNCTIONS (NO FILEIN/FILEOUT PARAMS) - -For ordinary functions, the request message is: - - total length (header + arguments, - but not including the length word itself) - struct guestfs_message_header (encoded as XDR) - struct guestfs_<foo>_args (encoded as XDR) - -The total length field allows the daemon to allocate a fixed size -buffer into which it slurps the rest of the message. As a result, the -total length is limited to C<GUESTFS_MESSAGE_MAX> bytes (currently -4MB), which means the effective size of any request is limited to -somewhere under this size. - -Note also that many functions don't take any arguments, in which case -the C<guestfs_I<foo>_args> is completely omitted. - -The header contains the procedure number (C<guestfs_proc>) which is -how the receiver knows what type of args structure to expect, or none -at all. - -For functions that take optional arguments, the optional arguments are -encoded in the C<guestfs_I<foo>_args> structure in the same way as -ordinary arguments. A bitmask in the header indicates which optional -arguments are meaningful. The bitmask is also checked to see if it -contains bits set which the daemon does not know about (eg. if more -optional arguments were added in a later version of the library), and -this causes the call to be rejected. - -The reply message for ordinary functions is: - - total length (header + ret, - but not including the length word itself) - struct guestfs_message_header (encoded as XDR) - struct guestfs_<foo>_ret (encoded as XDR) - -As above the C<guestfs_I<foo>_ret> structure may be completely omitted -for functions that return no formal return values. - -As above the total length of the reply is limited to -C<GUESTFS_MESSAGE_MAX>. - -In the case of an error, a flag is set in the header, and the reply -message is slightly changed: - - total length (header + error, - but not including the length word itself) - struct guestfs_message_header (encoded as XDR) - struct guestfs_message_error (encoded as XDR) - -The C<guestfs_message_error> structure contains the error message as a -string. - -=head3 FUNCTIONS THAT HAVE FILEIN PARAMETERS - -A C<FileIn> parameter indicates that we transfer a file I<into> the -guest. The normal request message is sent (see above). However this -is followed by a sequence of file chunks. - - total length (header + arguments, - but not including the length word itself, - and not including the chunks) - struct guestfs_message_header (encoded as XDR) - struct guestfs_<foo>_args (encoded as XDR) - sequence of chunks for FileIn param #0 - sequence of chunks for FileIn param #1 etc. - -The "sequence of chunks" is: - - length of chunk (not including length word itself) - struct guestfs_chunk (encoded as XDR) - length of chunk - struct guestfs_chunk (encoded as XDR) - ... - length of chunk - struct guestfs_chunk (with data.data_len == 0) - -The final chunk has the C<data_len> field set to zero. Additionally a -flag is set in the final chunk to indicate either successful -completion or early cancellation. - -At time of writing there are no functions that have more than one -FileIn parameter. However this is (theoretically) supported, by -sending the sequence of chunks for each FileIn parameter one after -another (from left to right). - -Both the library (sender) I<and> the daemon (receiver) may cancel the -transfer. The library does this by sending a chunk with a special -flag set to indicate cancellation. When the daemon sees this, it -cancels the whole RPC, does I<not> send any reply, and goes back to -reading the next request. - -The daemon may also cancel. It does this by writing a special word -C<GUESTFS_CANCEL_FLAG> to the socket. The library listens for this -during the transfer, and if it gets it, it will cancel the transfer -(it sends a cancel chunk). The special word is chosen so that even if -cancellation happens right at the end of the transfer (after the -library has finished writing and has started listening for the reply), -the "spurious" cancel flag will not be confused with the reply -message. - -This protocol allows the transfer of arbitrary sized files (no 32 bit -limit), and also files where the size is not known in advance -(eg. from pipes or sockets). However the chunks are rather small -(C<GUESTFS_MAX_CHUNK_SIZE>), so that neither the library nor the -daemon need to keep much in memory. - -=head3 FUNCTIONS THAT HAVE FILEOUT PARAMETERS - -The protocol for FileOut parameters is exactly the same as for FileIn -parameters, but with the roles of daemon and library reversed. - - total length (header + ret, - but not including the length word itself, - and not including the chunks) - struct guestfs_message_header (encoded as XDR) - struct guestfs_<foo>_ret (encoded as XDR) - sequence of chunks for FileOut param #0 - sequence of chunks for FileOut param #1 etc. - -=head3 INITIAL MESSAGE - -When the daemon launches it sends an initial word -(C<GUESTFS_LAUNCH_FLAG>) which indicates that the guest and daemon is -alive. This is what L</guestfs_launch> waits for. - -=head3 PROGRESS NOTIFICATION MESSAGES - -The daemon may send progress notification messages at any time. These -are distinguished by the normal length word being replaced by -C<GUESTFS_PROGRESS_FLAG>, followed by a fixed size progress message. - -The library turns them into progress callbacks (see -L</GUESTFS_EVENT_PROGRESS>) if there is a callback registered, or -discards them if not. - -The daemon self-limits the frequency of progress messages it sends -(see C<daemon/proto.c:notify_progress>). Not all calls generate -progress messages. - -=head2 FIXED APPLIANCE - -When libguestfs (or libguestfs tools) are run, they search a path -looking for an appliance. The path is built into libguestfs, or can -be set using the C<LIBGUESTFS_PATH> environment variable. - -Normally a supermin appliance is located on this path (see -L<supermin(1)/SUPERMIN APPLIANCE>). libguestfs reconstructs this -into a full appliance by running C<supermin --build>. - -However, a simpler "fixed appliance" can also be used. libguestfs -detects this by looking for a directory on the path containing all -the following files: - -=over 4 - -=item * F<kernel> - -=item * F<initrd> - -=item * F<root> - -=item * F<README.fixed> (note that it B<must> be present as well) - -=back - -If the fixed appliance is found, libguestfs skips supermin entirely -and just runs the virtual machine (using qemu or the current backend, -see L</BACKEND>) with the kernel, initrd and root disk from the fixed -appliance. - -Thus the fixed appliance can be used when a platform or a Linux -distribution does not support supermin. You build the fixed appliance -on a platform that does support supermin using -L<libguestfs-make-fixed-appliance(1)>, copy it over, and use that -to run libguestfs. - =head1 LIBGUESTFS VERSION NUMBERS Since April 2010, libguestfs has started to make separate development @@ -3946,7 +3551,7 @@ time. =head2 PROTOCOL LIMITS Internally libguestfs uses a message-based protocol to pass API calls -and their responses to and from a small "appliance" (see L</INTERNALS> +and their responses to and from a small "appliance" (see L<guestfs-internals(1)> for plenty more detail about this). The maximum message size used by the protocol is slightly less than 4 MB. For some API calls you may need to be aware of this limit. The API calls which may be affected @@ -4207,6 +3812,7 @@ L<virt-v2v(1)>, L<virt-win-reg(1)>, L<guestfs-faq(1)>, L<guestfs-hacking(1)>, +L<guestfs-internals(1)>, L<guestfs-performance(1)>, L<guestfs-release-notes(1)>, L<guestfs-testing(1)>, -- 2.5.0
Richard W.M. Jones
2015-Oct-29 15:02 UTC
[Libguestfs] [PATCH 15/16] docs: Move security documentation to guestfs-security(1).
--- .gitignore | 3 + docs/Makefile.am | 15 ++ docs/guestfs-faq.pod | 2 +- docs/guestfs-security.pod | 338 ++++++++++++++++++++++++++++++++++++++++++++++ po-docs/language.mk | 1 + po-docs/podfiles | 1 + src/guestfs.pod | 325 +------------------------------------------- 7 files changed, 364 insertions(+), 321 deletions(-) create mode 100644 docs/guestfs-security.pod diff --git a/.gitignore b/.gitignore index a33a286..701b6eb 100644 --- a/.gitignore +++ b/.gitignore @@ -136,6 +136,7 @@ Makefile.in /docs/guestfs-performance.1 /docs/guestfs-recipes.1 /docs/guestfs-release-notes.1 +/docs/guestfs-security.1 /docs/guestfs-testing.1 /docs/stamp-guestfs-faq.pod /docs/stamp-guestfs-hacking.pod @@ -143,6 +144,7 @@ Makefile.in /docs/stamp-guestfs-performance.pod /docs/stamp-guestfs-recipes.pod /docs/stamp-guestfs-release-notes.pod +/docs/stamp-guestfs-security.pod /docs/stamp-guestfs-testing.pod /edit/stamp-virt-*.pod /edit/virt-edit @@ -247,6 +249,7 @@ Makefile.in /html/guestfs-recipes.1.html /html/guestfs-release-notes.1.html /html/guestfs-ruby.3.html +/html/guestfs-security.1.html /html/guestfs-testing.1.html /html/guestfsd.8.html /html/guestmount.1.html diff --git a/docs/Makefile.am b/docs/Makefile.am index 9ead4c8..2b6484a 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -24,6 +24,7 @@ EXTRA_DIST = \ guestfs-performance.pod \ guestfs-recipes.pod \ guestfs-release-notes.pod \ + guestfs-security.pod \ guestfs-testing.pod \ README @@ -34,6 +35,7 @@ CLEANFILES = \ stamp-guestfs-performance.pod \ stamp-guestfs-recipes.pod \ stamp-guestfs-release-notes.pod \ + stamp-guestfs-security.pod \ stamp-guestfs-testing.pod man_MANS = \ @@ -43,6 +45,7 @@ man_MANS = \ guestfs-performance.1 \ guestfs-recipes.1 \ guestfs-release-notes.1 \ + guestfs-security.1 \ guestfs-testing.1 noinst_DATA = \ $(top_builddir)/html/guestfs-faq.1.html \ @@ -51,6 +54,7 @@ noinst_DATA = \ $(top_builddir)/html/guestfs-performance.1.html \ $(top_builddir)/html/guestfs-recipes.1.html \ $(top_builddir)/html/guestfs-release-notes.1.html \ + $(top_builddir)/html/guestfs-security.1.html \ $(top_builddir)/html/guestfs-testing.1.html guestfs-faq.1 $(top_builddir)/html/guestfs-faq.1.html: stamp-guestfs-faq.pod @@ -119,6 +123,17 @@ stamp-guestfs-release-notes.pod: guestfs-release-notes.pod $< touch $@ +guestfs-security.1 $(top_builddir)/html/guestfs-security.1.html: stamp-guestfs-security.pod + +stamp-guestfs-security.pod: guestfs-security.pod + $(PODWRAPPER) \ + --section 1 \ + --man guestfs-security.1 \ + --html $(top_builddir)/html/guestfs-security.1.html \ + --license LGPLv2+ \ + $< + touch $@ + guestfs-testing.1 $(top_builddir)/html/guestfs-testing.1.html: stamp-guestfs-testing.pod stamp-guestfs-testing.pod: guestfs-testing.pod diff --git a/docs/guestfs-faq.pod b/docs/guestfs-faq.pod index 5215e92..2a80b65 100644 --- a/docs/guestfs-faq.pod +++ b/docs/guestfs-faq.pod @@ -50,7 +50,7 @@ Some virt tools have been ported to Windows. Libguestfs takes a different approach from kpartx. kpartx needs root, and mounts filesystems on the host kernel (which can be insecure - see -L<guestfs(3)/SECURITY>). Libguestfs isolates your host kernel from +L<guestfs-security(1)>). Libguestfs isolates your host kernel from guests, is more flexible, scriptable, supports LVM, doesn't require root, is isolated from other processes, and cleans up after itself. Libguestfs is more than just file access because you can use it to diff --git a/docs/guestfs-security.pod b/docs/guestfs-security.pod new file mode 100644 index 0000000..d34b7b5 --- /dev/null +++ b/docs/guestfs-security.pod @@ -0,0 +1,338 @@ +=head1 NAME + +guestfs-security - security of libguestfs + +=head1 DESCRIPTION + +This manual page discusses security implications of using libguestfs, +particularly with untrusted or malicious guests or disk images. + +=head2 SECURITY OF MOUNTING FILESYSTEMS + +You should never mount an untrusted guest filesystem directly on your +host kernel (eg. using loopback or kpartx). + +When you mount a filesystem, mistakes in the kernel filesystem (VFS) +can be escalated into exploits by attackers creating a malicious +filesystem. These exploits are very severe for two reasons. Firstly +there are very many filesystem drivers in the kernel, and many of them +are infrequently used and not much developer attention has been paid +to the code. Linux userspace helps potential crackers by detecting +the filesystem type and automatically choosing the right VFS driver, +even if that filesystem type is unexpected. Secondly, a kernel-level +exploit is like a local root exploit (worse in some ways), giving +immediate and total access to the system right down to the hardware +level. + +These exploits can be present in the kernel for a very long time +(L<https://lwn.net/Articles/538898/>). + +Libguestfs provides a layered approach to protecting you from +exploits: + + untrusted filesystem + -------------------------------------- + appliance kernel + -------------------------------------- + qemu process running as non-root + -------------------------------------- + sVirt [if using libvirt + SELinux] + -------------------------------------- + host kernel + +We run a Linux kernel inside a qemu virtual machine, usually running +as a non-root user. The attacker would need to write a filesystem +which first exploited the kernel, and then exploited either qemu +virtualization (eg. a faulty qemu driver) or the libguestfs protocol, +and finally to be as serious as the host kernel exploit it would need +to escalate its privileges to root. Additionally if you use the +libvirt back end and SELinux, sVirt is used to confine the qemu +process. This multi-step escalation, performed by a static piece of +data, is thought to be extremely hard to do, although we never say +'never' about security issues. + +Callers can also reduce the attack surface by forcing the filesystem +type when mounting (use L</guestfs_mount_vfs>). + +=head2 GENERAL SECURITY CONSIDERATIONS + +Be careful with any files or data that you download from a guest (by +"download" we mean not just the L</guestfs_download> command but any +command that reads files, filenames, directories or anything else from +a disk image). An attacker could manipulate the data to fool your +program into doing the wrong thing. Consider cases such as: + +=over 4 + +=item * + +the data (file etc) not being present + +=item * + +being present but empty + +=item * + +being much larger than normal + +=item * + +containing arbitrary 8 bit data + +=item * + +being in an unexpected character encoding + +=item * + +containing homoglyphs. + +=back + +=head2 PROTOCOL SECURITY + +The protocol is designed to be secure, being based on RFC 4506 (XDR) +with a defined upper message size. However a program that uses +libguestfs must also take care - for example you can write a program +that downloads a binary from a disk image and executes it locally, and +no amount of protocol security will save you from the consequences. + +=head2 INSPECTION SECURITY + +Parts of the inspection API (see L</INSPECTION>) return untrusted +strings directly from the guest, and these could contain any 8 bit +data. Callers should be careful to escape these before printing them +to a structured file (for example, use HTML escaping if creating a web +page). + +Guest configuration may be altered in unusual ways by the +administrator of the virtual machine, and may not reflect reality +(particularly for untrusted or actively malicious guests). For +example we parse the hostname from configuration files like +F</etc/sysconfig/network> that we find in the guest, but the guest +administrator can easily manipulate these files to provide the wrong +hostname. + +The inspection API parses guest configuration using two external +libraries: Augeas (Linux configuration) and hivex (Windows Registry). +Both are designed to be robust in the face of malicious data, although +denial of service attacks are still possible, for example with +oversized configuration files. + +=head2 RUNNING UNTRUSTED GUEST COMMANDS + +Be very cautious about running commands from the guest. By running a +command in the guest, you are giving CPU time to a binary that you do +not control, under the same user account as the library, albeit +wrapped in qemu virtualization. More information and alternatives can +be found in the section L</RUNNING COMMANDS>. + +=head2 CVE-2010-3851 + +L<https://bugzilla.redhat.com/642934> + +This security bug concerns the automatic disk format detection that +qemu does on disk images. + +A raw disk image is just the raw bytes, there is no header. Other +disk images like qcow2 contain a special header. Qemu deals with this +by looking for one of the known headers, and if none is found then +assuming the disk image must be raw. + +This allows a guest which has been given a raw disk image to write +some other header. At next boot (or when the disk image is accessed +by libguestfs) qemu would do autodetection and think the disk image +format was, say, qcow2 based on the header written by the guest. + +This in itself would not be a problem, but qcow2 offers many features, +one of which is to allow a disk image to refer to another image +(called the "backing disk"). It does this by placing the path to the +backing disk into the qcow2 header. This path is not validated and +could point to any host file (eg. "/etc/passwd"). The backing disk is +then exposed through "holes" in the qcow2 disk image, which of course +is completely under the control of the attacker. + +In libguestfs this is rather hard to exploit except under two +circumstances: + +=over 4 + +=item 1. + +You have enabled the network or have opened the disk in write mode. + +=item 2. + +You are also running untrusted code from the guest (see +L</RUNNING COMMANDS>). + +=back + +The way to avoid this is to specify the expected disk format when +adding disks (the optional C<format> option to +L</guestfs_add_drive_opts>). You should always do this if the disk is +raw format, and it's a good idea for other cases too. +(See also L</DISK IMAGE FORMATS>). + +For disks added from libvirt using calls like L</guestfs_add_domain>, +the format is fetched from libvirt and passed through. + +For libguestfs tools, use the I<--format> command line parameter as +appropriate. + +=head2 CVE-2011-4127 + +L<https://bugzilla.redhat.com/752375> + +This is a bug in the kernel which allowed guests to overwrite +parts of the host's drives which they should not normally +have access to. + +It is sufficient to update libguestfs to any version E<ge> 1.16 which +contains a change that mitigates the problem. + +=head2 CVE-2012-2690 + +L<https://bugzilla.redhat.com/831117> + +Old versions of both virt-edit and the guestfish C<edit> command +created a new file containing the changes but did not set the +permissions, etc of the new file to match the old one. The result of +this was that if you edited a security sensitive file such as +F</etc/shadow> then it would be left world-readable after the edit. + +It is sufficient to update libguestfs to any version E<ge> 1.16. + +=head2 CVE-2013-2124 + +L<https://bugzilla.redhat.com/968306> + +This security bug was a flaw in inspection where an untrusted guest +using a specially crafted file in the guest OS could cause a +double-free in the C library (denial of service). + +It is sufficient to update libguestfs to a version that is not +vulnerable: libguestfs E<ge> 1.20.8, E<ge> 1.22.2 or E<ge> 1.23.2. + +=head2 CVE-2013-4419 + +L<https://bugzilla.redhat.com/1016960> + +When using the L<guestfish(1)> I<--remote> or guestfish I<--listen> +options, guestfish would create a socket in a known location +(F</tmp/.guestfish-$UID/socket-$PID>). + +The location has to be a known one in order for both ends to +communicate. However no checking was done that the containing +directory (F</tmp/.guestfish-$UID>) is owned by the user. Thus +another user could create this directory and potentially hijack +sockets owned by another user's guestfish client or server. + +It is sufficient to update libguestfs to a version that is not +vulnerable: libguestfs E<ge> 1.20.12, E<ge> 1.22.7 or E<ge> 1.24. + +=head2 Denial of service when inspecting disk images with corrupt btrfs volumes + +It was possible to crash libguestfs (and programs that use libguestfs +as a library) by presenting a disk image containing a corrupt btrfs +volume. + +This was caused by a NULL pointer dereference causing a denial of +service, and is not thought to be exploitable any further. + +See commit d70ceb4cbea165c960710576efac5a5716055486 for the fix. This +fix is included in libguestfs stable branches S<E<ge> 1.26.0>, S<E<ge> +1.24.6> and S<E<ge> 1.22.8>, and also in RHEL S<E<ge> 7.0>. +Earlier versions of libguestfs are not vulnerable. + +=head2 CVE-2014-0191 + +Libguestfs previously used unsafe libxml2 APIs for parsing libvirt +XML. These APIs defaulted to allowing network connections to be made +when certain XML documents were presented. Using a malformed XML +document it was also possible to exhaust all CPU, memory or file +descriptors on the machine. + +Since the libvirt XML comes from a trusted source (the libvirt daemon) +it is not thought that this could have been exploitable. + +This was fixed in libguestfs E<ge> 1.27.9 and the fix was backported +to stable versions E<ge> 1.26.2, E<ge> 1.24.9, E<ge> 1.22.10 and E<ge> +1.20.13. + +=head2 Shellshock (bash CVE-2014-6271) + +This bash bug indirectly affects libguestfs. For more information +see: +L<https://www.redhat.com/archives/libguestfs/2014-September/msg00252.html> + +=head2 CVE-2014-8484 + +=head2 CVE-2014-8485 + +These two bugs in binutils affect the GNU L<strings(1)> program, and +thus the L</guestfs_strings> and L</guestfs_strings_e> APIs in +libguestfs. Running strings on an untrusted file could cause +arbitrary code execution (confined to the libguestfs appliance). + +In libguestfs E<ge> 1.29.5 and E<ge> 1.28.3, libguestfs uses the +C<strings> I<-a> option to avoid BFD parsing on the file. + +=head2 CVE-2015-5745 + +L<https://bugzilla.redhat.com/show_bug.cgi?id=1251157> + +This is not a vulnerability in libguestfs, but because we always give +a virtio-serial port to each guest (since that is how guest-host +communication happens), an escalation from the appliance to the host +qemu process is possible. This could affect you if: + +=over 4 + +=item * + +your libguestfs program runs untrusted programs out of the guest +(using L</guestfs_sh> etc), or + +=item * + +another exploit was found in (for example) kernel filesystem code that +allowed a malformed filesystem to take over the appliance. + +=back + +If you use sVirt to confine qemu, that would thwart some attacks. + +=head2 Permissions of F<.ssh> and F<.ssh/authorized_keys> + +L<https://bugzilla.redhat.com/1260778> + +The tools L<virt-customize(1)>, L<virt-sysprep(1)> and +L<virt-builder(1)> have an I<--ssh-inject> option for injecting an SSH +key into virtual machine disk images. They may create a F<~user/.ssh> +directory and F<~user/.ssh/authorized_keys> file in the guest to do +this. + +In libguestfs E<lt> 1.31.5 and libguestfs E<lt> 1.30.2, the new +directory and file would get mode C<0755> and mode C<0644> +respectively. However these permissions (especially for +F<~user/.ssh>) are wider than the permissions that OpenSSH uses. In +current libguestfs, the directory and file are created with mode +C<0700> and mode C<0600>. + +=head1 SEE ALSO + +L<guestfs(3)>, +L<guestfs-internals(3)>, +L<guestfs-release-notes(1)>, +L<guestfs-testing(1)>, +L<http://libguestfs.org/>. + +=head1 AUTHORS + +Richard W.M. Jones (C<rjones at redhat dot com>) + +=head1 COPYRIGHT + +Copyright (C) 2009-2015 Red Hat Inc. diff --git a/po-docs/language.mk b/po-docs/language.mk index 73fcacd..3d3dd6f 100644 --- a/po-docs/language.mk +++ b/po-docs/language.mk @@ -44,6 +44,7 @@ MANPAGES = \ guestfs-recipes.1 \ guestfs-release-notes.1 \ guestfs-ruby.3 \ + guestfs-security.1 \ guestfs-testing.1 \ guestfsd.8 \ guestmount.1 \ diff --git a/po-docs/podfiles b/po-docs/podfiles index 611b549..df0a305 100644 --- a/po-docs/podfiles +++ b/po-docs/podfiles @@ -19,6 +19,7 @@ ../docs/guestfs-performance.pod ../docs/guestfs-recipes.pod ../docs/guestfs-release-notes.pod +../docs/guestfs-security.pod ../docs/guestfs-testing.pod ../edit/virt-edit.pod ../erlang/examples/guestfs-erlang.pod diff --git a/src/guestfs.pod b/src/guestfs.pod index 399396e..c492c06 100644 --- a/src/guestfs.pod +++ b/src/guestfs.pod @@ -44,6 +44,9 @@ L<libguestfs-test-tool(1)> and L<guestfs-testing(1)>. To contribute code to libguestfs, see L<guestfs-hacking(1)>. To find out how libguestfs works, see L<guestfs-internals(1)>. +For security information, including CVEs affecting libguestfs, see +L<guestfs-security(1)>. + =head1 API OVERVIEW This section provides a gentler overview of the libguestfs API. We @@ -443,7 +446,7 @@ A secure alternative is to use libguestfs to install a "firstboot" script (a script which runs when the guest next boots normally), and to have this script run the commands you want in the normal context of the running guest, network security and so on. For information about -other security issues, see L</SECURITY>. +other security issues, see L<guestfs-security(1)>. =back @@ -1947,325 +1950,6 @@ C<qemu-img> since it cannot be parsed reliably and securely. Also do not use the C<file> command since the output of that changes over time. -=head1 SECURITY - -This section discusses security implications of using libguestfs, -particularly with untrusted or malicious guests or disk images. - -=head2 SECURITY OF MOUNTING FILESYSTEMS - -You should never mount an untrusted guest filesystem directly on your -host kernel (eg. using loopback or kpartx). - -When you mount a filesystem, mistakes in the kernel filesystem (VFS) -can be escalated into exploits by attackers creating a malicious -filesystem. These exploits are very severe for two reasons. Firstly -there are very many filesystem drivers in the kernel, and many of them -are infrequently used and not much developer attention has been paid -to the code. Linux userspace helps potential crackers by detecting -the filesystem type and automatically choosing the right VFS driver, -even if that filesystem type is unexpected. Secondly, a kernel-level -exploit is like a local root exploit (worse in some ways), giving -immediate and total access to the system right down to the hardware -level. - -These exploits can be present in the kernel for a very long time -(L<https://lwn.net/Articles/538898/>). - -Libguestfs provides a layered approach to protecting you from -exploits: - - untrusted filesystem - -------------------------------------- - appliance kernel - -------------------------------------- - qemu process running as non-root - -------------------------------------- - sVirt [if using libvirt + SELinux] - -------------------------------------- - host kernel - -We run a Linux kernel inside a qemu virtual machine, usually running -as a non-root user. The attacker would need to write a filesystem -which first exploited the kernel, and then exploited either qemu -virtualization (eg. a faulty qemu driver) or the libguestfs protocol, -and finally to be as serious as the host kernel exploit it would need -to escalate its privileges to root. Additionally if you use the -libvirt back end and SELinux, sVirt is used to confine the qemu -process. This multi-step escalation, performed by a static piece of -data, is thought to be extremely hard to do, although we never say -'never' about security issues. - -Callers can also reduce the attack surface by forcing the filesystem -type when mounting (use L</guestfs_mount_vfs>). - -=head2 GENERAL SECURITY CONSIDERATIONS - -Be careful with any files or data that you download from a guest (by -"download" we mean not just the L</guestfs_download> command but any -command that reads files, filenames, directories or anything else from -a disk image). An attacker could manipulate the data to fool your -program into doing the wrong thing. Consider cases such as: - -=over 4 - -=item * - -the data (file etc) not being present - -=item * - -being present but empty - -=item * - -being much larger than normal - -=item * - -containing arbitrary 8 bit data - -=item * - -being in an unexpected character encoding - -=item * - -containing homoglyphs. - -=back - -=head2 PROTOCOL SECURITY - -The protocol is designed to be secure, being based on RFC 4506 (XDR) -with a defined upper message size. However a program that uses -libguestfs must also take care - for example you can write a program -that downloads a binary from a disk image and executes it locally, and -no amount of protocol security will save you from the consequences. - -=head2 INSPECTION SECURITY - -Parts of the inspection API (see L</INSPECTION>) return untrusted -strings directly from the guest, and these could contain any 8 bit -data. Callers should be careful to escape these before printing them -to a structured file (for example, use HTML escaping if creating a web -page). - -Guest configuration may be altered in unusual ways by the -administrator of the virtual machine, and may not reflect reality -(particularly for untrusted or actively malicious guests). For -example we parse the hostname from configuration files like -F</etc/sysconfig/network> that we find in the guest, but the guest -administrator can easily manipulate these files to provide the wrong -hostname. - -The inspection API parses guest configuration using two external -libraries: Augeas (Linux configuration) and hivex (Windows Registry). -Both are designed to be robust in the face of malicious data, although -denial of service attacks are still possible, for example with -oversized configuration files. - -=head2 RUNNING UNTRUSTED GUEST COMMANDS - -Be very cautious about running commands from the guest. By running a -command in the guest, you are giving CPU time to a binary that you do -not control, under the same user account as the library, albeit -wrapped in qemu virtualization. More information and alternatives can -be found in the section L</RUNNING COMMANDS>. - -=head2 CVE-2010-3851 - -L<https://bugzilla.redhat.com/642934> - -This security bug concerns the automatic disk format detection that -qemu does on disk images. - -A raw disk image is just the raw bytes, there is no header. Other -disk images like qcow2 contain a special header. Qemu deals with this -by looking for one of the known headers, and if none is found then -assuming the disk image must be raw. - -This allows a guest which has been given a raw disk image to write -some other header. At next boot (or when the disk image is accessed -by libguestfs) qemu would do autodetection and think the disk image -format was, say, qcow2 based on the header written by the guest. - -This in itself would not be a problem, but qcow2 offers many features, -one of which is to allow a disk image to refer to another image -(called the "backing disk"). It does this by placing the path to the -backing disk into the qcow2 header. This path is not validated and -could point to any host file (eg. "/etc/passwd"). The backing disk is -then exposed through "holes" in the qcow2 disk image, which of course -is completely under the control of the attacker. - -In libguestfs this is rather hard to exploit except under two -circumstances: - -=over 4 - -=item 1. - -You have enabled the network or have opened the disk in write mode. - -=item 2. - -You are also running untrusted code from the guest (see -L</RUNNING COMMANDS>). - -=back - -The way to avoid this is to specify the expected disk format when -adding disks (the optional C<format> option to -L</guestfs_add_drive_opts>). You should always do this if the disk is -raw format, and it's a good idea for other cases too. -(See also L</DISK IMAGE FORMATS>). - -For disks added from libvirt using calls like L</guestfs_add_domain>, -the format is fetched from libvirt and passed through. - -For libguestfs tools, use the I<--format> command line parameter as -appropriate. - -=head2 CVE-2011-4127 - -L<https://bugzilla.redhat.com/752375> - -This is a bug in the kernel which allowed guests to overwrite -parts of the host's drives which they should not normally -have access to. - -It is sufficient to update libguestfs to any version E<ge> 1.16 which -contains a change that mitigates the problem. - -=head2 CVE-2012-2690 - -L<https://bugzilla.redhat.com/831117> - -Old versions of both virt-edit and the guestfish C<edit> command -created a new file containing the changes but did not set the -permissions, etc of the new file to match the old one. The result of -this was that if you edited a security sensitive file such as -F</etc/shadow> then it would be left world-readable after the edit. - -It is sufficient to update libguestfs to any version E<ge> 1.16. - -=head2 CVE-2013-2124 - -L<https://bugzilla.redhat.com/968306> - -This security bug was a flaw in inspection where an untrusted guest -using a specially crafted file in the guest OS could cause a -double-free in the C library (denial of service). - -It is sufficient to update libguestfs to a version that is not -vulnerable: libguestfs E<ge> 1.20.8, E<ge> 1.22.2 or E<ge> 1.23.2. - -=head2 CVE-2013-4419 - -L<https://bugzilla.redhat.com/1016960> - -When using the L<guestfish(1)> I<--remote> or guestfish I<--listen> -options, guestfish would create a socket in a known location -(F</tmp/.guestfish-$UID/socket-$PID>). - -The location has to be a known one in order for both ends to -communicate. However no checking was done that the containing -directory (F</tmp/.guestfish-$UID>) is owned by the user. Thus -another user could create this directory and potentially hijack -sockets owned by another user's guestfish client or server. - -It is sufficient to update libguestfs to a version that is not -vulnerable: libguestfs E<ge> 1.20.12, E<ge> 1.22.7 or E<ge> 1.24. - -=head2 Denial of service when inspecting disk images with corrupt btrfs volumes - -It was possible to crash libguestfs (and programs that use libguestfs -as a library) by presenting a disk image containing a corrupt btrfs -volume. - -This was caused by a NULL pointer dereference causing a denial of -service, and is not thought to be exploitable any further. - -See commit d70ceb4cbea165c960710576efac5a5716055486 for the fix. This -fix is included in libguestfs stable branches S<E<ge> 1.26.0>, S<E<ge> -1.24.6> and S<E<ge> 1.22.8>, and also in RHEL S<E<ge> 7.0>. -Earlier versions of libguestfs are not vulnerable. - -=head2 CVE-2014-0191 - -Libguestfs previously used unsafe libxml2 APIs for parsing libvirt -XML. These APIs defaulted to allowing network connections to be made -when certain XML documents were presented. Using a malformed XML -document it was also possible to exhaust all CPU, memory or file -descriptors on the machine. - -Since the libvirt XML comes from a trusted source (the libvirt daemon) -it is not thought that this could have been exploitable. - -This was fixed in libguestfs E<ge> 1.27.9 and the fix was backported -to stable versions E<ge> 1.26.2, E<ge> 1.24.9, E<ge> 1.22.10 and E<ge> -1.20.13. - -=head2 Shellshock (bash CVE-2014-6271) - -This bash bug indirectly affects libguestfs. For more information -see: -L<https://www.redhat.com/archives/libguestfs/2014-September/msg00252.html> - -=head2 CVE-2014-8484 - -=head2 CVE-2014-8485 - -These two bugs in binutils affect the GNU L<strings(1)> program, and -thus the L</guestfs_strings> and L</guestfs_strings_e> APIs in -libguestfs. Running strings on an untrusted file could cause -arbitrary code execution (confined to the libguestfs appliance). - -In libguestfs E<ge> 1.29.5 and E<ge> 1.28.3, libguestfs uses the -C<strings> I<-a> option to avoid BFD parsing on the file. - -=head2 CVE-2015-5745 - -L<https://bugzilla.redhat.com/show_bug.cgi?id=1251157> - -This is not a vulnerability in libguestfs, but because we always give -a virtio-serial port to each guest (since that is how guest-host -communication happens), an escalation from the appliance to the host -qemu process is possible. This could affect you if: - -=over 4 - -=item * - -your libguestfs program runs untrusted programs out of the guest -(using L</guestfs_sh> etc), or - -=item * - -another exploit was found in (for example) kernel filesystem code that -allowed a malformed filesystem to take over the appliance. - -=back - -If you use sVirt to confine qemu, that would thwart some attacks. - -=head2 Permissions of F<.ssh> and F<.ssh/authorized_keys> - -L<https://bugzilla.redhat.com/1260778> - -The tools L<virt-customize(1)>, L<virt-sysprep(1)> and -L<virt-builder(1)> have an I<--ssh-inject> option for injecting an SSH -key into virtual machine disk images. They may create a F<~user/.ssh> -directory and F<~user/.ssh/authorized_keys> file in the guest to do -this. - -In libguestfs E<lt> 1.31.5 and libguestfs E<lt> 1.30.2, the new -directory and file would get mode C<0755> and mode C<0644> -respectively. However these permissions (especially for -F<~user/.ssh>) are wider than the permissions that OpenSSH uses. In -current libguestfs, the directory and file are created with mode -C<0700> and mode C<0600>. - =head1 CONNECTION MANAGEMENT =head2 guestfs_h * @@ -3815,6 +3499,7 @@ L<guestfs-hacking(1)>, L<guestfs-internals(1)>, L<guestfs-performance(1)>, L<guestfs-release-notes(1)>, +L<guestfs-security(1)>, L<guestfs-testing(1)>, L<libguestfs-test-tool(1)>, L<libguestfs-make-fixed-appliance(1)>, -- 2.5.0
Richard W.M. Jones
2015-Oct-29 15:02 UTC
[Libguestfs] [PATCH 16/16] docs: Group guestfs(3) 'SEE ALSO' into sections.
--- src/guestfs.pod | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/guestfs.pod b/src/guestfs.pod index c492c06..f9dea92 100644 --- a/src/guestfs.pod +++ b/src/guestfs.pod @@ -3456,7 +3456,10 @@ See L</LIBGUESTFS_CACHEDIR>, L</LIBGUESTFS_TMPDIR>. =head1 SEE ALSO -L<guestfs-examples(3)>, +Examples written in C: +L<guestfs-examples(3)>. + +Language bindings: L<guestfs-erlang(3)>, L<guestfs-golang(3)>, L<guestfs-java(3)>, @@ -3464,7 +3467,9 @@ L<guestfs-lua(3)>, L<guestfs-ocaml(3)>, L<guestfs-perl(3)>, L<guestfs-python(3)>, -L<guestfs-ruby(3)>, +L<guestfs-ruby(3)>. + +Tools: L<guestfish(1)>, L<guestmount(1)>, L<virt-alignment-scan(1)>, @@ -3493,7 +3498,9 @@ L<virt-tar(1)>, L<virt-tar-in(1)>, L<virt-tar-out(1)>, L<virt-v2v(1)>, -L<virt-win-reg(1)>, +L<virt-win-reg(1)>. + +Other libguestfs topics: L<guestfs-faq(1)>, L<guestfs-hacking(1)>, L<guestfs-internals(1)>, @@ -3502,13 +3509,17 @@ L<guestfs-release-notes(1)>, L<guestfs-security(1)>, L<guestfs-testing(1)>, L<libguestfs-test-tool(1)>, -L<libguestfs-make-fixed-appliance(1)>, +L<libguestfs-make-fixed-appliance(1)>. + +Related manual pages: L<supermin(1)>, L<qemu(1)>, L<hivex(3)>, L<stap(1)>, -L<sd-journal(3)>, -L<http://libguestfs.org/>. +L<sd-journal(3)>. + +Website: +L<http://libguestfs.org/> Tools with a similar purpose: L<fdisk(8)>, -- 2.5.0