On 06.11.2015 12:46, Erik Skultety wrote:
This patch introduces virt-admin client which is based on virsh
client,
but had to reimplement several methods to meet virt-admin specific needs
or remove unnecessary virsh specific logic.
---
.gitignore | 1 +
po/POTFILES.in | 1 +
tools/Makefile.am | 26 ++-
tools/virt-admin.c | 556 +++++++++++++++++++++++++++++++++++++++++++++++++++++
tools/virt-admin.h | 46 +++++
5 files changed, 628 insertions(+), 2 deletions(-)
create mode 100644 tools/virt-admin.c
create mode 100644 tools/virt-admin.h
diff --git a/tools/virt-admin.c b/tools/virt-admin.c
new file mode 100644
index 0000000..ddfba91
--- /dev/null
+++ b/tools/virt-admin.c
@@ -0,0 +1,556 @@
+/*
+ * virt-admin.c: a shell to exercise the libvirt admin API
+ *
+ * Copyright (C) 2015 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <
http://www.gnu.org/licenses/>.
+ *
+ * Erik Skultety <eskultet(a)redhat.com>
We usually prepend this line with "Authors: ".
+ */
+
+#include <config.h>
+#include "virt-admin.h"
+
+#include <errno.h>
+#include <getopt.h>
+#include <locale.h>
+
+#if WITH_READLINE
+# include <readline/readline.h>
+# include <readline/history.h>
+#endif
+
+#include "configmake.h"
+#include "internal.h"
+#include "viralloc.h"
+#include "virerror.h"
+#include "virfile.h"
+#include "virstring.h"
+#include "virthread.h"
+
+/* Gnulib doesn't guarantee SA_SIGINFO support. */
+#ifndef SA_SIGINFO
+# define SA_SIGINFO 0
+#endif
+
+#define VIRT_ADMIN_PROMPT "virt-admin # "
+
+static char *progname;
+
+static const vshCmdGrp cmdGroups[];
+static const vshClientHooks hooks;
+
+static int
+vshAdmConnect(vshControl *ctl, unsigned int flags)
+{
+ vshAdmControlPtr priv = ctl->privData;
+
+ priv->conn = virAdmConnectOpen(ctl->connname, flags);
+
+ if (!priv->conn) {
+ if (priv->wantReconnect)
+ vshError(ctl, "%s", _("Failed to reconnect to the admin
server"));
+ else
+ vshError(ctl, "%s", _("Failed to connect to the admin
server"));
+ return -1;
+ } else {
+ if (priv->wantReconnect)
+ vshPrint(ctl, "%s\n", _("Reconnected to the admin
server"));
+ else
+ vshPrint(ctl, "%s\n", _("Connected to the admin
server"));
+ }
+
+ return 0;
+}
+
+static int
+vshAdmDisconnect(vshControl *ctl)
+{
+ int ret = 0;
+ vshAdmControlPtr priv = ctl->privData;
+
+ if (!priv->conn)
+ return ret;
+
+ ret = virAdmConnectClose(priv->conn);
+ if (ret < 0)
+ vshError(ctl, "%s", _("Failed to disconnect from the admin
server"));
+ else if (ret > 0)
+ vshError(ctl, "%s", _("One or more references were leaked after
"
+ "disconnect from the hypervisor"));
+ priv->conn = NULL;
+ return ret;
+}
+
+/*
+ * vshAdmReconnect:
+ *
+ * Reconnect to a daemon's admin server
+ *
+ */
+static void
+vshAdmReconnect(vshControl *ctl)
+{
+ vshAdmControlPtr priv = ctl->privData;
+ if (priv->conn)
+ priv->wantReconnect = true;
+
+ vshAdmDisconnect(ctl);
+ vshAdmConnect(ctl, 0);
+
+ priv->wantReconnect = false;
+}
+
+/* ---------------
+ * Command Connect
+ * ---------------
+ */
+
+static const vshCmdOptDef opts_connect[] = {
+ {.name = "name",
+ .type = VSH_OT_STRING,
+ .flags = VSH_OFLAG_EMPTY_OK,
+ .help = N_("daemon's admin server connection URI")
+ },
+ {.name = NULL}
+};
+
+static const vshCmdInfo info_connect[] = {
+ {.name = "help",
+ .data = N_("connect to daemon's admin server")
+ },
+ {.name = "desc",
+ .data = N_("Connect to a daemon's administrating server.")
+ },
+ {.name = NULL}
+};
+
+static bool
+cmdConnect(vshControl *ctl, const vshCmd *cmd)
+{
+ const char *name = NULL;
+ vshAdmControlPtr priv = ctl->privData;
+
+ VIR_FREE(ctl->connname);
+ if (vshCommandOptStringReq(ctl, cmd, "name", &name) < 0)
+ return false;
I think the VIR_FREE() should go after option acquiring. Otherwise we
will lose it if vshCommand... fails.
+
+ ctl->connname = vshStrdup(ctl, name);
+
+ vshAdmReconnect(ctl);
+
+ return !!priv->conn;
+}
ACK
Michal