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@xxxxxxxxxx> 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list