]> xenbits.xensource.com Git - libvirt.git/commitdiff
virsh: Add keepalive in new vshConnect function
authorMartin Kletzander <mkletzan@redhat.com>
Thu, 6 Mar 2014 16:20:11 +0000 (17:20 +0100)
committerMartin Kletzander <mkletzan@redhat.com>
Tue, 18 Mar 2014 07:27:29 +0000 (08:27 +0100)
Introducing keepalive similarly to Guannan around 2 years ago.  Since
we want to introduce keepalive for every connection, it makes sense to
wrap the connecting function into new virsh one that can deal
keepalive as well.

Function vshConnect() is now used for connecting and keepalive added
in that function (if possible) helps preventing long waits e.g. while
nework goes down during migration.

This patch also adds the options for keepalive tuning into virsh and
fails connecting only when keepalives are explicitly requested and
cannot be set (whether it is due to missing support in connected
driver or remote server).  If not explicitely requested, a debug
message is printed (hence the addition to virsh-optparse test).

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1073506
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=822839

Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
tests/virsh-optparse
tools/virsh-domain.c
tools/virsh.c
tools/virsh.h
tools/virsh.pod

index 214ae41ab871a22b60c1f2660de5644a7b58cf2c..39e6cde951cc4cf0bece18059bcca1533902cd4d 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh
 # Ensure that virsh option parsing doesn't regress
 
-# Copyright (C) 2011-2012 Red Hat, Inc.
+# Copyright (C) 2011-2012, 2014 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
@@ -65,7 +65,7 @@ for args in \
     '--count 2 test' \
     '--count=2 test' \
 ; do
-  virsh -d0 -c $test_url setvcpus $args >out 2>>err || fail=1
+  virsh -k0 -d0 -c $test_url setvcpus $args >out 2>>err || fail=1
   LC_ALL=C sort out | compare exp-out - || fail=1
 done
 
index f2a26f9e3ee0460f72881e24d65dfbeec94f8b66..fbde3da0db867048e5dfb84a8d620a0e14ca5716 100644 (file)
@@ -8785,7 +8785,7 @@ doMigrate(void *opaque)
         virConnectPtr dconn = NULL;
         virDomainPtr ddom = NULL;
 
-        dconn = virConnectOpenAuth(desturi, virConnectAuthPtrDefault, 0);
+        dconn = vshConnect(ctl, desturi, false);
         if (!dconn)
             goto out;
 
index 9b8429f87502c70e12f0850b00c493ca6cc05047..02835d9cec4fd6c67b74ec7d9368e7a2e5a0afaa 100644 (file)
@@ -315,6 +315,46 @@ vshCatchDisconnect(virConnectPtr conn ATTRIBUTE_UNUSED,
         disconnected++;
 }
 
+/* Main Function which should be used for connecting.
+ * This function properly handles keepalive settings. */
+virConnectPtr
+vshConnect(vshControl *ctl, const char *uri, bool readonly)
+{
+    virConnectPtr c = NULL;
+    int interval = 5; /* Default */
+    int count = 6;    /* Default */
+    bool keepalive_forced = false;
+
+    if (ctl->keepalive_interval >= 0) {
+        interval = ctl->keepalive_interval;
+        keepalive_forced = true;
+    }
+    if (ctl->keepalive_count >= 0) {
+        count = ctl->keepalive_count;
+        keepalive_forced = true;
+    }
+
+    c = virConnectOpenAuth(uri, virConnectAuthPtrDefault,
+                           readonly ? VIR_CONNECT_RO : 0);
+    if (!c)
+        return NULL;
+
+    if (interval > 0 &&
+        virConnectSetKeepAlive(c, interval, count) != 0) {
+        if (keepalive_forced) {
+            vshError(ctl, "%s",
+                     _("Cannot setup keepalive on connection "
+                       "as requested, disconnecting"));
+            virConnectClose(c);
+            return NULL;
+        }
+        vshDebug(ctl, VSH_ERR_INFO, "%s",
+                 _("Failed to setup keepalive on connection\n"));
+    }
+
+    return c;
+}
+
 /*
  * vshReconnect:
  *
@@ -340,9 +380,8 @@ vshReconnect(vshControl *ctl)
                                   "disconnect from the hypervisor"));
     }
 
-    ctl->conn = virConnectOpenAuth(ctl->name,
-                                   virConnectAuthPtrDefault,
-                                   ctl->readonly ? VIR_CONNECT_RO : 0);
+    ctl->conn = vshConnect(ctl, ctl->name, ctl->readonly);
+
     if (!ctl->conn) {
         if (disconnected)
             vshError(ctl, "%s", _("Failed to reconnect to the hypervisor"));
@@ -417,8 +456,7 @@ cmdConnect(vshControl *ctl, const vshCmd *cmd)
     ctl->useSnapshotOld = false;
     ctl->readonly = ro;
 
-    ctl->conn = virConnectOpenAuth(ctl->name, virConnectAuthPtrDefault,
-                                   ctl->readonly ? VIR_CONNECT_RO : 0);
+    ctl->conn = vshConnect(ctl, ctl->name, ctl->readonly);
 
     if (!ctl->conn) {
         vshError(ctl, "%s", _("Failed to connect to the hypervisor"));
@@ -3113,6 +3151,10 @@ vshUsage(void)
                       "    -d | --debug=NUM        debug level [0-4]\n"
                       "    -e | --escape <char>    set escape sequence for console\n"
                       "    -h | --help             this help\n"
+                      "    -k | --keepalive-interval=NUM\n"
+                      "                            keepalive interval in seconds, 0 for disable\n"
+                      "    -K | --keepalive-count=NUM\n"
+                      "                            number of possible missed keepalive messages\n"
                       "    -l | --log=FILE         output logging to file\n"
                       "    -q | --quiet            quiet mode\n"
                       "    -r | --readonly         connect readonly\n"
@@ -3302,7 +3344,7 @@ vshAllowedEscapeChar(char c)
 static bool
 vshParseArgv(vshControl *ctl, int argc, char **argv)
 {
-    int arg, len, debug;
+    int arg, len, debug, keepalive;
     size_t i;
     int longindex = -1;
     struct option opt[] = {
@@ -3310,6 +3352,8 @@ vshParseArgv(vshControl *ctl, int argc, char **argv)
         {"debug", required_argument, NULL, 'd'},
         {"escape", required_argument, NULL, 'e'},
         {"help", no_argument, NULL, 'h'},
+        {"keepalive-interval", required_argument, NULL, 'k'},
+        {"keepalive-count", required_argument, NULL, 'K'},
         {"log", required_argument, NULL, 'l'},
         {"quiet", no_argument, NULL, 'q'},
         {"readonly", no_argument, NULL, 'r'},
@@ -3321,7 +3365,7 @@ vshParseArgv(vshControl *ctl, int argc, char **argv)
     /* Standard (non-command) options. The leading + ensures that no
      * argument reordering takes place, so that command options are
      * not confused with top-level virsh options. */
-    while ((arg = getopt_long(argc, argv, "+:c:d:e:hl:qrtvV", opt, &longindex)) != -1) {
+    while ((arg = getopt_long(argc, argv, "+:c:d:e:hk:K:l:qrtvV", opt, &longindex)) != -1) {
         switch (arg) {
         case 'c':
             VIR_FREE(ctl->name);
@@ -3356,6 +3400,24 @@ vshParseArgv(vshControl *ctl, int argc, char **argv)
             vshUsage();
             exit(EXIT_SUCCESS);
             break;
+        case 'k':
+            if (virStrToLong_i(optarg, NULL, 0, &keepalive) < 0 ||
+                keepalive < 0) {
+                vshError(ctl, _("option -%s requires a positive numeric argument"),
+                         longindex == -1 ? "-k" : "--keepalive-interval");
+                exit(EXIT_FAILURE);
+            }
+            ctl->keepalive_interval = keepalive;
+            break;
+        case 'K':
+            if (virStrToLong_i(optarg, NULL, 0, &keepalive) < 0 ||
+                keepalive < 0) {
+                vshError(ctl, _("option -%s requires a positive numeric argument"),
+                         longindex == -1 ? "-K" : "--keepalive-count");
+                exit(EXIT_FAILURE);
+            }
+            ctl->keepalive_count = keepalive;
+            break;
         case 'l':
             vshCloseLogFile(ctl);
             ctl->logfile = vshStrdup(ctl, optarg);
@@ -3490,6 +3552,11 @@ main(int argc, char **argv)
     ctl->log_fd = -1;           /* Initialize log file descriptor */
     ctl->debug = VSH_DEBUG_DEFAULT;
     ctl->escapeChar = "^]";     /* Same default as telnet */
+
+    /* In order to distinguish default from setting to 0 */
+    ctl->keepalive_interval = -1;
+    ctl->keepalive_count = -1;
+
     ctl->eventPipe[0] = -1;
     ctl->eventPipe[1] = -1;
     ctl->eventTimerId = -1;
index 62a1eed9041ca5912ed7ccc6f03944b30ef14e84..3e0251b621cc4d888c60f3da9fc9b8e772d00a40 100644 (file)
@@ -249,6 +249,9 @@ struct _vshControl {
     const char *escapeChar;     /* String representation of
                                    console escape character */
 
+    int keepalive_interval;     /* Client keepalive interval */
+    int keepalive_count;        /* Client keepalive count */
+
 # ifndef WIN32
     struct termios termattr;    /* settings of the tty terminal */
 # endif
@@ -269,6 +272,8 @@ void vshOutputLogFile(vshControl *ctl, int log_level, const char *format,
     ATTRIBUTE_FMT_PRINTF(3, 0);
 void vshCloseLogFile(vshControl *ctl);
 
+virConnectPtr vshConnect(vshControl *ctl, const char *uri, bool readonly);
+
 const char *vshCmddefGetInfo(const vshCmdDef *cmd, const char *info);
 const vshCmdDef *vshCmddefSearch(const char *cmdname);
 bool vshCmddefHelp(vshControl *ctl, const char *name);
index cefce1bb6ad98bd40138794e296dcdddb0218062..5c74bb328cf69db5f2c6bd0ec86685c508bffd72 100644 (file)
@@ -74,6 +74,18 @@ alphabetic character, @, [, ], \, ^, _.
 Ignore all other arguments, and behave as if the B<help> command were
 given instead.
 
+=item B<-k>, B<--keepalive-interval> I<INTERVAL>
+
+Set an I<INTERVAL> (in seconds) for sending keepalive messages to
+check whether connection to the server is still alive.  Setting the
+interval to 0 disables client keepalive mechanism.
+
+=item B<-K>, B<--keepalive-count> I<COUNT>
+
+Set a number of times keepalive message can be sent without getting an
+answer from the server without marking the connection dead.  There is
+no effect to this setting in case the I<INTERVAL> is set to 0.
+
 =item B<-l>, B<--log> I<FILE>
 
 Output logging details to I<FILE>.