From 29e8788eb42c73fd037cc9beac33e15116dc53fe Mon Sep 17 00:00:00 2001
From: Michael Hanselmann <hansmi@google.com>
Date: Wed, 10 Nov 2010 19:43:01 +0100
Subject: [PATCH] impexpd: Disable OpenSSL compression in socat if possible

This uses an option only available in patched socat versions. More
information is available from the INSTALL update included in this
patch.

Signed-off-by: Michael Hanselmann <hansmi@google.com>
Reviewed-by: Guido Trotter <ultrotter@google.com>
Reviewed-by: Iustin Pop <iustin@google.com>
---
 INSTALL                 | 26 +++++++++++++++++++++++++-
 Makefile.am             |  1 +
 configure.ac            | 23 +++++++++++++++++++++++
 lib/constants.py        |  1 +
 lib/impexpd/__init__.py |  5 +++++
 5 files changed, 55 insertions(+), 1 deletion(-)

diff --git a/INSTALL b/INSTALL
index 5729386c1..0c44f75ad 100644
--- a/INSTALL
+++ b/INSTALL
@@ -34,7 +34,8 @@ Before installing, please verify that you have the following programs:
 - `ctypes Python module
   <http://starship.python.net/crew/theller/ctypes/>`_, if running on
   python 2.4 (optional, used for node daemon memory locking)
-- `socat <http://www.dest-unreach.org/socat/>`_
+- `socat <http://www.dest-unreach.org/socat/>`_, see :ref:`note
+  <socat-note>` below
 - `Paramiko <http://www.lag.net/paramiko/>`_, if you want automated SSH
   setup; optional otherwise but manual setup of the nodes required
 
@@ -52,6 +53,29 @@ packages, except for DRBD and Xen::
 If you want to build from source, please see doc/devnotes.rst for more
 dependencies.
 
+.. _socat-note:
+.. note::
+  Ganeti's import/export functionality uses ``socat`` with OpenSSL for
+  transferring data between nodes. By default, OpenSSL 0.9.8 and above
+  employ transparent compression of all data using zlib if supported by
+  both sides of a connection. In cases where a lot of data is
+  transferred, this can lead to an increased CPU usage. Additionally,
+  Ganeti already compresses all data using ``gzip`` where it makes sense
+  (for inter-cluster instance moves).
+
+  To remedey this situation, patches implementing a new ``socat`` option
+  for disabling OpenSSL compression have been contributed and will
+  likely be included in the next feature release. Until then, users or
+  distributions need to apply the patches on their own.
+
+  Ganeti will use the option if it's detected by the ``configure``
+  script; auto-detection can be disabled by explicitely passing
+  ``--enable-socat-compress`` (use the option to disable compression) or
+  ``--disable-socat-compress`` (don't use the option).
+
+  The patches and more information can be found on
+  http://www.dest-unreach.org/socat/contrib/socat-opensslcompress.html.
+
 
 Installation of the software
 ----------------------------
diff --git a/Makefile.am b/Makefile.am
index 943642329..011ef7452 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -614,6 +614,7 @@ lib/_autoconf.py: Makefile vcs-version | lib/.dir
 	  echo "KVM_PATH = '$(KVM_PATH)'"; \
 	  echo "SOCAT_PATH = '$(SOCAT)'"; \
 	  echo "SOCAT_USE_ESCAPE = $(SOCAT_USE_ESCAPE)"; \
+	  echo "SOCAT_USE_COMPRESS = $(SOCAT_USE_COMPRESS)"; \
 	  echo "LVM_STRIPECOUNT = $(LVM_STRIPECOUNT)"; \
 	  echo "TOOLSDIR = '$(toolsdir)'"; \
 	  echo "GNT_SCRIPTS = [$(foreach i,$(notdir $(gnt_scripts)),'$(i)',)]"; \
diff --git a/configure.ac b/configure.ac
index 15d9cf065..2abed5f5d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -297,6 +297,29 @@ fi
 
 AC_SUBST(SOCAT_USE_ESCAPE)
 
+SOCAT_USE_COMPRESS=
+AC_ARG_ENABLE([socat-compress],
+  [AS_HELP_STRING([--enable-socat-compress],
+    [use OpenSSL compression option available in patched socat builds
+     (see INSTALL for details; default: detect automatically)])],
+  [[if test "$enableval" = yes; then
+      SOCAT_USE_COMPRESS=True
+    else
+      SOCAT_USE_COMPRESS=False
+    fi
+  ]])
+
+if test -z "$SOCAT_USE_COMPRESS"
+then
+  if $SOCAT -hhh | grep -w -q openssl-compress; then
+    SOCAT_USE_COMPRESS=True
+  else
+    SOCAT_USE_COMPRESS=False
+  fi
+fi
+
+AC_SUBST(SOCAT_USE_COMPRESS)
+
 if man --help | grep -q -e --warnings
 then
   MAN_HAS_WARNINGS=1
diff --git a/lib/constants.py b/lib/constants.py
index 1935064f9..334fae3e2 100644
--- a/lib/constants.py
+++ b/lib/constants.py
@@ -220,6 +220,7 @@ XEN_INITRD = _autoconf.XEN_INITRD
 KVM_PATH = _autoconf.KVM_PATH
 SOCAT_PATH = _autoconf.SOCAT_PATH
 SOCAT_USE_ESCAPE = _autoconf.SOCAT_USE_ESCAPE
+SOCAT_USE_COMPRESS = _autoconf.SOCAT_USE_COMPRESS
 SOCAT_ESCAPE_CODE = "0x1d"
 
 # For RSA keys more bits are better, but they also make operations more
diff --git a/lib/impexpd/__init__.py b/lib/impexpd/__init__.py
index 5b14adcb3..983640e7e 100644
--- a/lib/impexpd/__init__.py
+++ b/lib/impexpd/__init__.py
@@ -80,6 +80,11 @@ SOCAT_TCP_OPTS = ["keepalive", "keepidle=60", "keepintvl=10", "keepcnt=5"]
 SOCAT_OPENSSL_OPTS = ["verify=1", "method=TLSv1",
                       "cipher=%s" % constants.OPENSSL_CIPHERS]
 
+if constants.SOCAT_USE_COMPRESS:
+  # Disables all compression in by OpenSSL. Only supported in patched versions
+  # of socat (as of November 2010). See INSTALL for more information.
+  SOCAT_OPENSSL_OPTS.append("compress=none")
+
 SOCAT_OPTION_MAXLEN = 400
 
 (PROG_OTHER,
-- 
GitLab