
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@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