[libvirt] [PATCH 0/3] Fix license violation of virsh when vbox is enabled

See the big hairy analysis here: https://www.redhat.com/archives/libvir-list/2013-May/msg00030.html I feel comfortable enough with these patches that I'm hoping to get them into libvirt 1.0.5, while saving the bigger task of refactoring vbox support into libvirtd out to libvirt 1.0.6. Eric Blake (3): build: move readline check into its own macro build: check for libedit build: fall back to libedit if libvirt.so is crippled configure.ac | 54 +++++++++++++------------------------------- libvirt.spec.in | 8 +++++++ m4/virt-edit.m4 | 26 +++++++++++++++++++++ m4/virt-readline.m4 | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++ tools/virsh.c | 21 ++++++++++++----- 5 files changed, 131 insertions(+), 43 deletions(-) create mode 100644 m4/virt-edit.m4 create mode 100644 m4/virt-readline.m4 -- 1.8.1.4

Future patches will allow the use of editline in place of readline; doing this in an isolated file instead of configure.ac will make the task easier. We can't quite use LIBVIRT_CHECK_LIB, since we do a double probe based on what other libraries might be needed for successful linking; as such, I also didn't modernize the C code conditionals (these days, we would have prefered 'WITH_READLINE' in config.h instead of '-DUSE_READLINE' on the command line). It may be worth cleaning this up in a future patch. * configure.ac: Move readline code... * m4/virt-readline.m4: ...here. Signed-off-by: Eric Blake <eblake@redhat.com> --- configure.ac | 43 +++-------------------------------- m4/virt-readline.m4 | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 40 deletions(-) create mode 100644 m4/virt-readline.m4 diff --git a/configure.ac b/configure.ac index 229b3f7..8331184 100644 --- a/configure.ac +++ b/configure.ac @@ -162,6 +162,7 @@ LIBVIRT_CHECK_NETCF LIBVIRT_CHECK_NUMACTL LIBVIRT_CHECK_OPENWSMAN LIBVIRT_CHECK_PCIACCESS +LIBVIRT_CHECK_READLINE LIBVIRT_CHECK_SANLOCK LIBVIRT_CHECK_SASL LIBVIRT_CHECK_SELINUX @@ -1404,45 +1405,7 @@ fi AM_CONDITIONAL([WITH_PHYP],[test "$with_phyp" = "yes"]) dnl virsh libraries -AC_CHECK_HEADERS([readline/readline.h]) - -# Check for readline. -AC_CHECK_LIB([readline], [readline], - [lv_use_readline=yes; VIRSH_LIBS="$VIRSH_LIBS -lreadline"], - [lv_use_readline=no]) - -# If the above test failed, it may simply be that -lreadline requires -# some termcap-related code, e.g., from one of the following libraries. -# See if adding one of them to LIBS helps. -if test $lv_use_readline = no; then - lv_saved_libs=$LIBS - LIBS= - AC_SEARCH_LIBS([tgetent], [ncurses curses termcap termlib]) - case $LIBS in - no*) ;; # handle "no" and "none required" - *) # anything else is a -lLIBRARY - # Now, check for -lreadline again, also using $LIBS. - # Note: this time we use a different function, so that - # we don't get a cached "no" result. - AC_CHECK_LIB([readline], [rl_initialize], - [lv_use_readline=yes - VIRSH_LIBS="$VIRSH_LIBS -lreadline $LIBS"],, - [$LIBS]) - ;; - esac - test $lv_use_readline = no && - AC_MSG_WARN([readline library not found]) - LIBS=$lv_saved_libs -fi - -if test $lv_use_readline = yes; then - AC_DEFINE_UNQUOTED([USE_READLINE], 1, - [whether virsh can use readline]) - READLINE_CFLAGS=-DUSE_READLINE -else - READLINE_CFLAGS= -fi -AC_SUBST([READLINE_CFLAGS]) +VIRSH_LIBS="$VIRSH_LIBS $READLINE_LIBS" AC_SUBST([VIRSH_LIBS]) dnl check if the network driver should be compiled @@ -2491,6 +2454,7 @@ LIBVIRT_RESULT_NETCF LIBVIRT_RESULT_NUMACTL LIBVIRT_RESULT_OPENWSMAN LIBVIRT_RESULT_PCIACCESS +LIBVIRT_RESULT_READLINE LIBVIRT_RESULT_SANLOCK LIBVIRT_RESULT_SASL LIBVIRT_RESULT_SELINUX @@ -2571,7 +2535,6 @@ AC_MSG_NOTICE([]) AC_MSG_NOTICE([ Debug: $enable_debug]) AC_MSG_NOTICE([ Use -Werror: $set_werror]) AC_MSG_NOTICE([ Warning Flags: $WARN_CFLAGS]) -AC_MSG_NOTICE([ Readline: $lv_use_readline]) AC_MSG_NOTICE([ Python: $with_python]) AC_MSG_NOTICE([ DTrace: $with_dtrace]) AC_MSG_NOTICE([ numad: $with_numad]) diff --git a/m4/virt-readline.m4 b/m4/virt-readline.m4 new file mode 100644 index 0000000..8f5a884 --- /dev/null +++ b/m4/virt-readline.m4 @@ -0,0 +1,65 @@ +dnl The readline library +dnl +dnl Copyright (C) 2005-2013 Red Hat, Inc. +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License, or (at your option) any later version. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library. If not, see +dnl <http://www.gnu.org/licenses/>. +dnl + +AC_DEFUN([LIBVIRT_CHECK_READLINE],[ + READLINE_LIBS= + AC_CHECK_HEADERS([readline/readline.h]) + + AC_CHECK_LIB([readline], [readline], + [lv_use_readline=yes; READLINE_LIBS=-lreadline], + [lv_use_readline=no]) + + # If the above test failed, it may simply be that -lreadline requires + # some termcap-related code, e.g., from one of the following libraries. + # See if adding one of them to LIBS helps. + if test $lv_use_readline = no; then + lv_saved_libs=$LIBS + LIBS= + AC_SEARCH_LIBS([tgetent], [ncurses curses termcap termlib]) + case $LIBS in + no*) ;; # handle "no" and "none required" + *) # anything else is a -lLIBRARY + # Now, check for -lreadline again, also using $LIBS. + # Note: this time we use a different function, so that + # we don't get a cached "no" result. + AC_CHECK_LIB([readline], [rl_initialize], + [lv_use_readline=yes + READLINE_LIBS="-lreadline $LIBS"],, + [$LIBS]) + ;; + esac + test $lv_use_readline = no && + AC_MSG_WARN([readline library not found]) + LIBS=$lv_saved_libs + fi + + if test $lv_use_readline = yes; then + AC_DEFINE_UNQUOTED([USE_READLINE], 1, + [whether virsh can use readline]) + READLINE_CFLAGS=-DUSE_READLINE + else + READLINE_CFLAGS= + fi + AC_SUBST([READLINE_CFLAGS]) +]) + +AC_DEFUN([LIBVIRT_RESULT_READLINE],[ + LIBVIRT_RESULT([readline], [$lv_use_readline], + [CFLAGS='$READLINE_CFLAGS' LIBS='$READLINE_LIBS']) +]) -- 1.8.1.4

libedit is a BSD library that provides partial functionality of readline; useful if you can't use GPLv3 readline. The next patch will need to know if this library is present. * m4/virt-edit.m4: New file. * configure.ac: Use it. Signed-off-by: Eric Blake <eblake@redhat.com> --- configure.ac | 2 ++ m4/virt-edit.m4 | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 m4/virt-edit.m4 diff --git a/configure.ac b/configure.ac index 8331184..3feed8b 100644 --- a/configure.ac +++ b/configure.ac @@ -156,6 +156,7 @@ LIBVIRT_CHECK_BLKID LIBVIRT_CHECK_CAPNG LIBVIRT_CHECK_CURL LIBVIRT_CHECK_DBUS +LIBVIRT_CHECK_EDIT LIBVIRT_CHECK_FUSE LIBVIRT_CHECK_HAL LIBVIRT_CHECK_NETCF @@ -2448,6 +2449,7 @@ LIBVIRT_RESULT_BLKID LIBVIRT_RESULT_CAPNG LIBVIRT_RESULT_CURL LIBVIRT_RESULT_DBUS +LIBVIRT_RESULT_EDIT LIBVIRT_RESULT_FUSE LIBVIRT_RESULT_HAL LIBVIRT_RESULT_NETCF diff --git a/m4/virt-edit.m4 b/m4/virt-edit.m4 new file mode 100644 index 0000000..d483ab5 --- /dev/null +++ b/m4/virt-edit.m4 @@ -0,0 +1,26 @@ +dnl The libedit.so library +dnl +dnl Copyright (C) 2013 Red Hat, Inc. +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License, or (at your option) any later version. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library. If not, see +dnl <http://www.gnu.org/licenses/>. +dnl + +AC_DEFUN([LIBVIRT_CHECK_EDIT],[ + LIBVIRT_CHECK_PKG([EDIT], [libedit], [3.0]) +]) + +AC_DEFUN([LIBVIRT_RESULT_EDIT],[ + LIBVIRT_RESULT_LIB([EDIT]) +]) -- 1.8.1.4

Vbox source code used in libvirt.git is LGPLv2-only. If linked into libvirt.so, then we are legally forbidden from linking an app against both that libvirt.so and any GPLv3 code, such as libreadline. While we'd like to fix libvirt.so to be LGPLv2+ in the future, regardless of whether vbox support was compiled in (by moving vbox support into libvirtd, which can afford to be [L]GPLv2-only), that is a more invasive change; this is a simpler approach that fixes the issue for the libvirt package, even though it doesn't help other GPLv3 apps that want to use libvirt. * configure.ac (VIRSH_LIBS): Prefer the weaker libedit if vbox code is enabled. * tools/virsh.c (vshReadlineInit, vshReadlineDeinit, main): Make history code conditional on actual readline library. (vshShowVersion): Document which library is in use. * libvirt.spec.in (Requires): Use correct library. Signed-off-by: Eric Blake <eblake@redhat.com> --- configure.ac | 15 ++++++++++++++- libvirt.spec.in | 8 ++++++++ tools/virsh.c | 21 ++++++++++++++++----- 3 files changed, 38 insertions(+), 6 deletions(-) diff --git a/configure.ac b/configure.ac index 3feed8b..b2cebf0 100644 --- a/configure.ac +++ b/configure.ac @@ -1406,7 +1406,20 @@ fi AM_CONDITIONAL([WITH_PHYP],[test "$with_phyp" = "yes"]) dnl virsh libraries -VIRSH_LIBS="$VIRSH_LIBS $READLINE_LIBS" +dnl Use of vbox in libvirt.so renders that library LGPLv2-only, which +dnl is incompatible with GPLv3 readline. If that is the case, we must +dnl use libedit or nothing; libedit supports readline() but not history. +if test "x$with_vbox" != xno; then + if test "x$with_edit" = xyes; then + VIRSH_LIBS="$VIRSH_LIBS $EDIT_LIBS" + READLINE_CFLAGS="$READLINE_CFLAGS $EDIT_CFLAGS -DUSE_EDITLINE" + fi +else + if test "x$lv_use_readline" = xyes; then + VIRSH_LIBS="$VIRSH_LIBS $READLINE_LIBS" + READLINE_CFLAGS="$READLINE_CFLAGS -DUSE_READLINE_HISTORY" + fi +fi AC_SUBST([VIRSH_LIBS]) dnl check if the network driver should be compiled diff --git a/libvirt.spec.in b/libvirt.spec.in index ae1bd21..56ef277 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -406,7 +406,11 @@ BuildRequires: xen-devel BuildRequires: libxml2-devel BuildRequires: xhtml1-dtds BuildRequires: libxslt +%if %{with_vbox} +BuildRequires: libedit-devel +%else BuildRequires: readline-devel +%endif BuildRequires: ncurses-devel BuildRequires: gettext BuildRequires: libtasn1-devel @@ -1017,7 +1021,11 @@ capabilities of XEN %package client Summary: Client side library and utilities of the libvirt library Group: Development/Libraries +%if %{with_vbox} +Requires: libedit +%else Requires: readline +%endif Requires: ncurses # So remote clients can access libvirt over SSH tunnel # (client invokes 'nc' against the UNIX socket on the server) diff --git a/tools/virsh.c b/tools/virsh.c index ac86608..56bc239 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -47,7 +47,9 @@ #include <libxml/xpath.h> #include <libxml/xmlsave.h> -#ifdef HAVE_READLINE_READLINE_H +#if USE_EDITLINE +# include <readline.h> +#elif USE_READLINE # include <readline/readline.h> # include <readline/history.h> #endif @@ -2627,16 +2629,19 @@ vshReadlineCompletion(const char *text, int start, static int -vshReadlineInit(vshControl *ctl) +vshReadlineInit(vshControl *ctl ATTRIBUTE_UNUSED) { - char *userdir = NULL; + char name[] = "virsh"; /* Allow conditional parsing of the ~/.inputrc file. */ - rl_readline_name = "virsh"; + rl_readline_name = name; /* Tell the completer that we want a crack first. */ rl_attempted_completion_function = vshReadlineCompletion; +# if USE_READLINE_HISTORY + char *userdir = NULL; + /* Limit the total size of the history buffer */ stifle_history(500); @@ -2663,6 +2668,7 @@ vshReadlineInit(vshControl *ctl) VIR_FREE(userdir); read_history(ctl->historyfile); +# endif /* USE_READLINE_HISTORY */ return 0; } @@ -2670,6 +2676,7 @@ vshReadlineInit(vshControl *ctl) static void vshReadlineDeinit(vshControl *ctl) { +# if USE_READLINE_HISTORY if (ctl->historyfile != NULL) { if (virFileMakePathWithMode(ctl->historydir, 0755) < 0 && errno != EEXIST) { @@ -2680,6 +2687,7 @@ vshReadlineDeinit(vshControl *ctl) write_history(ctl->historyfile); } } +# endif /* USE_READLINE_HISTORY */ VIR_FREE(ctl->historydir); VIR_FREE(ctl->historyfile); @@ -2955,6 +2963,9 @@ vshShowVersion(vshControl *ctl ATTRIBUTE_UNUSED) #ifdef USE_READLINE vshPrint(ctl, " Readline"); #endif +#ifdef USE_READLINE_HISTORY + vshPrint(ctl, " History"); +#endif #ifdef WITH_DRIVER_MODULES vshPrint(ctl, " Modular"); #endif @@ -3228,7 +3239,7 @@ main(int argc, char **argv) if (ctl->cmdstr == NULL) break; /* EOF */ if (*ctl->cmdstr) { -#if USE_READLINE +#if USE_READLINE_HISTORY add_history(ctl->cmdstr); #endif if (vshCommandStringParse(ctl, ctl->cmdstr)) -- 1.8.1.4

On Wed, May 01, 2013 at 10:26:30PM -0600, Eric Blake wrote:
See the big hairy analysis here: https://www.redhat.com/archives/libvir-list/2013-May/msg00030.html
I feel comfortable enough with these patches that I'm hoping to get them into libvirt 1.0.5, while saving the bigger task of refactoring vbox support into libvirtd out to libvirt 1.0.6.
Sorry, that didn't made it into 1.0.5, I prefer to not play game at such a late stage. The issues are identified, we plan to fix them and that's only part of it. Let's get all this cleaned up properly for 1.0.6 (or maybe call it 1.1.0 to raise the point about it). I still think that 1/ making general purpose libs like readline as GPL is counter productive, and I opposed using it at the time (still disabled in libxml2 xmllint --shell for this very reason) 2/ the fact that various (L)GPL licences are somehow incompatible is rather nasty, and well we finally discovered the problem and will act about it, we are making a good effort resolving the problem we are showing good faith there Daniel -- Daniel Veillard | Open Source and Standards, Red Hat veillard@redhat.com | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ http://veillard.com/ | virtualization library http://libvirt.org/
participants (2)
-
Daniel Veillard
-
Eric Blake