[libvirt] [PATCH 0/4] Virsh: Extend command arguments completion

This patchset extends arguments completion for virsh commands. Currently only for domain related (start, destroy, etc.) and 'help'. But if community is satisfied with this little part I'll write follow up patches for other commands as well. This means that for command start not only pre-defined options will be generated (autodestroy, console, paused) but names of inactive domains too. However, this requires virsh to be already connected to daemon. Completers for commands can be easily defined as they follow readline logic. Basically, completer returns on each call one string (=possible argument/option) and it's called repeatedly until NULL is returned. To generate only corresponding values for given prefix, there is @text variable in function prototype. There is also @state variable that is set to zero on the 1st call and to non-zero on any subsequent calls, so completer can set it internal structures. Michal Privoznik (4): virsh: make conn global virsh: Extend virsh commands definition with completer virsh: Create completer for commands related to domains virsh: Create completer for help command tools/virsh.c | 1108 ++++++++++++++++++++++++++++++++++----------------------- 1 files changed, 660 insertions(+), 448 deletions(-) -- 1.7.5.rc3

Since virsh is not multi-threaded, it is safe to have it as global variable. This is going to be needed in some special cases where we can't change function prototype but want to have connection object accessible. --- tools/virsh.c | 555 +++++++++++++++++++++++++++++---------------------------- 1 files changed, 278 insertions(+), 277 deletions(-) diff --git a/tools/virsh.c b/tools/virsh.c index 9a189fd..eeacec3 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -218,7 +218,6 @@ typedef struct __vshCmd { */ typedef struct __vshControl { char *name; /* connection name */ - virConnectPtr conn; /* connection to hypervisor (MAY BE NULL) */ vshCmd *cmd; /* the current command */ char *cmdstr; /* string with command */ bool imode; /* interactive mode? */ @@ -242,6 +241,8 @@ typedef struct vshCmdGrp { const vshCmdDef *commands; } vshCmdGrp; +virConnectPtr conn; /* connection to hypervisor (MAY BE NULL) */ + static const vshCmdGrp cmdGroups[]; static void vshError(vshControl *ctl, const char *format, ...) @@ -354,7 +355,7 @@ static const char *vshDomainStateToString(int state); static const char *vshDomainStateReasonToString(int state, int reason); static const char *vshDomainControlStateToString(int state); static const char *vshDomainVcpuStateToString(int state); -static bool vshConnectionUsability(vshControl *ctl, virConnectPtr conn); +static bool vshConnectionUsability(vshControl *ctl); static char *editWriteToTempFile (vshControl *ctl, const char *doc); static int editFile (vshControl *ctl, const char *filename); @@ -581,15 +582,15 @@ vshReconnect(vshControl *ctl) { bool connected = false; - if (ctl->conn != NULL) { + if (conn != NULL) { connected = true; - virConnectClose(ctl->conn); + virConnectClose(conn); } - ctl->conn = virConnectOpenAuth(ctl->name, - virConnectAuthPtrDefault, - ctl->readonly ? VIR_CONNECT_RO : 0); - if (!ctl->conn) + conn = virConnectOpenAuth(ctl->name, + virConnectAuthPtrDefault, + ctl->readonly ? VIR_CONNECT_RO : 0); + if (!conn) vshError(ctl, "%s", _("Failed to reconnect to the hypervisor")); else if (connected) vshError(ctl, "%s", _("Reconnected to the hypervisor")); @@ -676,7 +677,7 @@ cmdAutostart(vshControl *ctl, const vshCmd *cmd) const char *name; int autostart; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(dom = vshCommandOptDomain(ctl, cmd, &name))) @@ -725,13 +726,13 @@ cmdConnect(vshControl *ctl, const vshCmd *cmd) bool ro = vshCommandOptBool(cmd, "readonly"); const char *name = NULL; - if (ctl->conn) { + if (conn) { int ret; - if ((ret = virConnectClose(ctl->conn)) != 0) { + if ((ret = virConnectClose(conn)) != 0) { vshError(ctl, _("Failed to disconnect from the hypervisor, %d leaked reference(s)"), ret); return false; } - ctl->conn = NULL; + conn = NULL; } VIR_FREE(ctl->name); @@ -744,13 +745,13 @@ cmdConnect(vshControl *ctl, const vshCmd *cmd) ctl->useGetInfo = false; ctl->readonly = ro; - ctl->conn = virConnectOpenAuth(ctl->name, virConnectAuthPtrDefault, - ctl->readonly ? VIR_CONNECT_RO : 0); + conn = virConnectOpenAuth(ctl->name, virConnectAuthPtrDefault, + ctl->readonly ? VIR_CONNECT_RO : 0); - if (!ctl->conn) + if (!conn) vshError(ctl, "%s", _("Failed to connect to the hypervisor")); - return !!ctl->conn; + return !!conn; } #ifndef WIN32 @@ -804,7 +805,7 @@ cmdConsole(vshControl *ctl, const vshCmd *cmd) bool ret = false; const char *name = NULL; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) @@ -852,11 +853,11 @@ cmdList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) int maxname = 0; inactive |= all; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (active) { - maxid = virConnectNumOfDomains(ctl->conn); + maxid = virConnectNumOfDomains(conn); if (maxid < 0) { vshError(ctl, "%s", _("Failed to list active domains")); return false; @@ -864,7 +865,7 @@ cmdList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) if (maxid) { ids = vshMalloc(ctl, sizeof(int) * maxid); - if ((maxid = virConnectListDomains(ctl->conn, &ids[0], maxid)) < 0) { + if ((maxid = virConnectListDomains(conn, &ids[0], maxid)) < 0) { vshError(ctl, "%s", _("Failed to list active domains")); VIR_FREE(ids); return false; @@ -874,7 +875,7 @@ cmdList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) } } if (inactive) { - maxname = virConnectNumOfDefinedDomains(ctl->conn); + maxname = virConnectNumOfDefinedDomains(conn); if (maxname < 0) { vshError(ctl, "%s", _("Failed to list inactive domains")); VIR_FREE(ids); @@ -883,7 +884,7 @@ cmdList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) if (maxname) { names = vshMalloc(ctl, sizeof(char *) * maxname); - if ((maxname = virConnectListDefinedDomains(ctl->conn, names, maxname)) < 0) { + if ((maxname = virConnectListDefinedDomains(conn, names, maxname)) < 0) { vshError(ctl, "%s", _("Failed to list inactive domains")); VIR_FREE(ids); VIR_FREE(names); @@ -897,7 +898,7 @@ cmdList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) vshPrintExtra(ctl, "----------------------------------\n"); for (i = 0; i < maxid; i++) { - virDomainPtr dom = virDomainLookupByID(ctl->conn, ids[i]); + virDomainPtr dom = virDomainLookupByID(conn, ids[i]); /* this kind of work with domains is not atomic operation */ if (!dom) @@ -910,7 +911,7 @@ cmdList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) virDomainFree(dom); } for (i = 0; i < maxname; i++) { - virDomainPtr dom = virDomainLookupByName(ctl->conn, names[i]); + virDomainPtr dom = virDomainLookupByName(conn, names[i]); /* this kind of work with domains is not atomic operation */ if (!dom) { @@ -954,7 +955,7 @@ cmdDomstate(vshControl *ctl, const vshCmd *cmd) int showReason = vshCommandOptBool(cmd, "reason"); int state, reason; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) @@ -1000,7 +1001,7 @@ cmdDomControl(vshControl *ctl, const vshCmd *cmd) bool ret = true; virDomainControlInfo info; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) @@ -1047,7 +1048,7 @@ cmdDomblkstat (vshControl *ctl, const vshCmd *cmd) const char *name = NULL, *device = NULL; struct _virDomainBlockStats stats; - if (!vshConnectionUsability (ctl, ctl->conn)) + if (!vshConnectionUsability (ctl)) return false; if (!(dom = vshCommandOptDomain (ctl, cmd, &name))) @@ -1104,7 +1105,7 @@ cmdDomIfstat (vshControl *ctl, const vshCmd *cmd) const char *name = NULL, *device = NULL; struct _virDomainInterfaceStats stats; - if (!vshConnectionUsability (ctl, ctl->conn)) + if (!vshConnectionUsability (ctl)) return false; if (!(dom = vshCommandOptDomain (ctl, cmd, &name))) @@ -1171,7 +1172,7 @@ cmdDomMemStat(vshControl *ctl, const vshCmd *cmd) struct _virDomainMemoryStat stats[VIR_DOMAIN_MEMORY_STAT_NR]; unsigned int nr_stats, i; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(dom = vshCommandOptDomain(ctl, cmd, &name))) @@ -1228,7 +1229,7 @@ cmdDomblkinfo(vshControl *ctl, const vshCmd *cmd) bool ret = true; const char *device = NULL; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) @@ -1273,7 +1274,7 @@ cmdSuspend(vshControl *ctl, const vshCmd *cmd) const char *name; bool ret = true; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(dom = vshCommandOptDomain(ctl, cmd, &name))) @@ -1321,7 +1322,7 @@ cmdCreate(vshControl *ctl, const vshCmd *cmd) #endif unsigned int flags = VIR_DOMAIN_NONE; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (vshCommandOptString(cmd, "file", &from) <= 0) @@ -1335,7 +1336,7 @@ cmdCreate(vshControl *ctl, const vshCmd *cmd) if (vshCommandOptBool(cmd, "autodestroy")) flags |= VIR_DOMAIN_START_AUTODESTROY; - dom = virDomainCreateXML(ctl->conn, buffer, flags); + dom = virDomainCreateXML(conn, buffer, flags); VIR_FREE(buffer); if (dom != NULL) { @@ -1375,7 +1376,7 @@ cmdDefine(vshControl *ctl, const vshCmd *cmd) bool ret = true; char *buffer; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (vshCommandOptString(cmd, "file", &from) <= 0) @@ -1384,7 +1385,7 @@ cmdDefine(vshControl *ctl, const vshCmd *cmd) if (virFileReadAll(from, VIRSH_MAX_XML_FILE, &buffer) < 0) return false; - dom = virDomainDefineXML(ctl->conn, buffer); + dom = virDomainDefineXML(conn, buffer); VIR_FREE(buffer); if (dom != NULL) { @@ -1420,14 +1421,14 @@ cmdUndefine(vshControl *ctl, const vshCmd *cmd) const char *name = NULL; int id; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (vshCommandOptString(cmd, "domain", &name) <= 0) return false; if (name && virStrToLong_i(name, NULL, 10, &id) == 0 - && id >= 0 && (dom = virDomainLookupByID(ctl->conn, id))) { + && id >= 0 && (dom = virDomainLookupByID(conn, id))) { vshError(ctl, _("a running domain like %s cannot be undefined;\n" "to undefine, first shutdown then undefine" @@ -1483,7 +1484,7 @@ cmdStart(vshControl *ctl, const vshCmd *cmd) #endif unsigned int flags = VIR_DOMAIN_NONE; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(dom = vshCommandOptDomainBy(ctl, cmd, NULL, @@ -1541,7 +1542,7 @@ cmdSave(vshControl *ctl, const vshCmd *cmd) const char *to = NULL; bool ret = true; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (vshCommandOptString(cmd, "file", &to) <= 0) @@ -1585,7 +1586,7 @@ cmdManagedSave(vshControl *ctl, const vshCmd *cmd) const char *name; bool ret = true; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(dom = vshCommandOptDomain(ctl, cmd, &name))) @@ -1624,7 +1625,7 @@ cmdManagedSaveRemove(vshControl *ctl, const vshCmd *cmd) bool ret = false; int hassave; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(dom = vshCommandOptDomain(ctl, cmd, &name))) @@ -1798,7 +1799,7 @@ cmdSchedinfo(vshControl *ctl, const vshCmd *cmd) flags |= VIR_DOMAIN_AFFECT_LIVE; } - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) @@ -1933,13 +1934,13 @@ cmdRestore(vshControl *ctl, const vshCmd *cmd) const char *from = NULL; bool ret = true; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (vshCommandOptString(cmd, "file", &from) <= 0) return false; - if (virDomainRestore(ctl->conn, from) == 0) { + if (virDomainRestore(conn, from) == 0) { vshPrint(ctl, _("Domain restored from %s\n"), from); } else { vshError(ctl, _("Failed to restore domain from %s"), from); @@ -1974,7 +1975,7 @@ cmdDump(vshControl *ctl, const vshCmd *cmd) bool ret = true; int flags = 0; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (vshCommandOptString(cmd, "file", &to) <= 0) @@ -2035,7 +2036,7 @@ vshGenFileName(vshControl *ctl, virDomainPtr dom, const char *mime) /* We should be already connected, but doesn't * hurt to check */ - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return NULL; if (!dom) { @@ -2077,7 +2078,7 @@ cmdScreenshot(vshControl *ctl, const vshCmd *cmd) bool generated = false; char *mime = NULL; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (vshCommandOptString(cmd, "file", (const char **) &file) < 0) { @@ -2093,7 +2094,7 @@ cmdScreenshot(vshControl *ctl, const vshCmd *cmd) if (!(dom = vshCommandOptDomain(ctl, cmd, &name))) return false; - st = virStreamNew(ctl->conn, 0); + st = virStreamNew(conn, 0); mime = virDomainScreenshot(dom, st, screen, flags); if (!mime) { @@ -2167,7 +2168,7 @@ cmdResume(vshControl *ctl, const vshCmd *cmd) bool ret = true; const char *name; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(dom = vshCommandOptDomain(ctl, cmd, &name))) @@ -2205,7 +2206,7 @@ cmdShutdown(vshControl *ctl, const vshCmd *cmd) bool ret = true; const char *name; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(dom = vshCommandOptDomain(ctl, cmd, &name))) @@ -2243,7 +2244,7 @@ cmdReboot(vshControl *ctl, const vshCmd *cmd) bool ret = true; const char *name; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(dom = vshCommandOptDomain(ctl, cmd, &name))) @@ -2281,7 +2282,7 @@ cmdDestroy(vshControl *ctl, const vshCmd *cmd) bool ret = true; const char *name; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(dom = vshCommandOptDomain(ctl, cmd, &name))) @@ -2325,7 +2326,7 @@ cmdDominfo(vshControl *ctl, const vshCmd *cmd) unsigned int id; char *str, uuid[VIR_UUID_STRING_BUFLEN]; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) @@ -2390,7 +2391,7 @@ cmdDominfo(vshControl *ctl, const vshCmd *cmd) /* Security model and label information */ memset(&secmodel, 0, sizeof secmodel); - if (virNodeGetSecurityModel(ctl->conn, &secmodel) == -1) { + if (virNodeGetSecurityModel(conn, &secmodel) == -1) { if (last_error->code != VIR_ERR_NO_SUPPORT) { virDomainFree(dom); return false; @@ -2449,7 +2450,7 @@ cmdDomjobinfo(vshControl *ctl, const vshCmd *cmd) virDomainPtr dom; bool ret = true; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) @@ -2530,7 +2531,7 @@ cmdDomjobabort(vshControl *ctl, const vshCmd *cmd) virDomainPtr dom; bool ret = true; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) @@ -2576,7 +2577,7 @@ cmdFreecell(vshControl *ctl, const vshCmd *cmd) xmlXPathContextPtr ctxt = NULL; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if ( (cell_given = vshCommandOptInt(cmd, "cellno", &cell)) < 0) { @@ -2592,7 +2593,7 @@ cmdFreecell(vshControl *ctl, const vshCmd *cmd) } if (all_given) { - cap_xml = virConnectGetCapabilities(ctl->conn); + cap_xml = virConnectGetCapabilities(conn); if (!cap_xml) { vshError(ctl, "%s", _("unable to get node capabilities")); goto cleanup; @@ -2630,7 +2631,7 @@ cmdFreecell(vshControl *ctl, const vshCmd *cmd) } VIR_FREE(val); nodes_id[i]=id; - ret = virNodeGetCellsFreeMemory(ctl->conn, &(nodes_free[i]), id, 1); + ret = virNodeGetCellsFreeMemory(conn, &(nodes_free[i]), id, 1); if (ret != 1) { vshError(ctl, _("failed to get free memory for NUMA node " "number: %lu"), id); @@ -2649,11 +2650,11 @@ cmdFreecell(vshControl *ctl, const vshCmd *cmd) vshPrintExtra(ctl, "%5s: %10llu kB\n", _("Total"), memory/1024); } else { if (!cell_given) { - memory = virNodeGetFreeMemory(ctl->conn); + memory = virNodeGetFreeMemory(conn); if (memory == 0) goto cleanup; } else { - ret = virNodeGetCellsFreeMemory(ctl->conn, &memory, cell, 1); + ret = virNodeGetCellsFreeMemory(conn, &memory, cell, 1); if (ret != 1) goto cleanup; } @@ -2702,10 +2703,10 @@ cmdMaxvcpus(vshControl *ctl, const vshCmd *cmd) return false; } - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; - vcpus = virConnectGetMaxVcpus(ctl->conn, type); + vcpus = virConnectGetMaxVcpus(conn, type); if (vcpus < 0) return false; vshPrint(ctl, "%d\n", vcpus); @@ -2765,7 +2766,7 @@ cmdVcpucount(vshControl *ctl, const vshCmd *cmd) return false; } - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) @@ -2915,13 +2916,13 @@ cmdVcpuinfo(vshControl *ctl, const vshCmd *cmd) bool ret = true; int n, m; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) return false; - if (virNodeGetInfo(ctl->conn, &nodeinfo) != 0) { + if (virNodeGetInfo(conn, &nodeinfo) != 0) { virDomainFree(dom); return false; } @@ -3052,7 +3053,7 @@ cmdVcpuPin(vshControl *ctl, const vshCmd *cmd) flags = -1; } - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) @@ -3073,7 +3074,7 @@ cmdVcpuPin(vshControl *ctl, const vshCmd *cmd) return false; } - if (virNodeGetInfo(ctl->conn, &nodeinfo) != 0) { + if (virNodeGetInfo(conn, &nodeinfo) != 0) { virDomainFree(dom); return false; } @@ -3269,7 +3270,7 @@ cmdSetvcpus(vshControl *ctl, const vshCmd *cmd) (config ? VIR_DOMAIN_AFFECT_CONFIG : 0) | (live ? VIR_DOMAIN_AFFECT_LIVE : 0)); - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) @@ -3335,7 +3336,7 @@ cmdInjectNMI(vshControl *ctl, const vshCmd *cmd) virDomainPtr dom; int ret = true; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) @@ -3394,7 +3395,7 @@ cmdSetmem(vshControl *ctl, const vshCmd *cmd) flags = -1; } - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) @@ -3482,7 +3483,7 @@ cmdSetmaxmem(vshControl *ctl, const vshCmd *cmd) flags = -1; } - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) @@ -3564,7 +3565,7 @@ cmdBlkiotune(vshControl * ctl, const vshCmd * cmd) flags |= VIR_DOMAIN_AFFECT_LIVE; } - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) @@ -3721,7 +3722,7 @@ cmdMemtune(vshControl * ctl, const vshCmd * cmd) flags |= VIR_DOMAIN_AFFECT_LIVE; } - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) @@ -3870,10 +3871,10 @@ cmdNodeinfo(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) { virNodeInfo info; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; - if (virNodeGetInfo(ctl->conn, &info) < 0) { + if (virNodeGetInfo(conn, &info) < 0) { vshError(ctl, "%s", _("failed to get node information")); return false; } @@ -3924,7 +3925,7 @@ cmdNodeCpuStats(vshControl *ctl, const vshCmd *cmd) double user_time, sys_time, idle_time, iowait_time, total_time; double usage; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (vshCommandOptInt(cmd, "cpu", &cpuNum) < 0) { @@ -3932,7 +3933,7 @@ cmdNodeCpuStats(vshControl *ctl, const vshCmd *cmd) return false; } - if (virNodeGetCPUStats(ctl->conn, cpuNum, NULL, &nparams, 0) != 0) { + if (virNodeGetCPUStats(conn, cpuNum, NULL, &nparams, 0) != 0) { vshError(ctl, "%s", _("Unable to get number of cpu stats")); return false; @@ -3947,7 +3948,7 @@ cmdNodeCpuStats(vshControl *ctl, const vshCmd *cmd) i = 0; do { - if (virNodeGetCPUStats(ctl->conn, cpuNum, params, &nparams, 0) != 0) { + if (virNodeGetCPUStats(conn, cpuNum, params, &nparams, 0) != 0) { vshError(ctl, "%s", _("Unable to get node cpu stats")); goto cleanup; } @@ -4041,7 +4042,7 @@ cmdNodeMemStats(vshControl *ctl, const vshCmd *cmd) virNodeMemoryStatsPtr params = NULL; bool ret = false; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (vshCommandOptInt(cmd, "cell", &cellNum) < 0) { @@ -4050,7 +4051,7 @@ cmdNodeMemStats(vshControl *ctl, const vshCmd *cmd) } /* get the number of memory parameters */ - if (virNodeGetMemoryStats(ctl->conn, cellNum, NULL, &nparams, 0) != 0) { + if (virNodeGetMemoryStats(conn, cellNum, NULL, &nparams, 0) != 0) { vshError(ctl, "%s", _("Unable to get number of memory stats")); goto cleanup; @@ -4064,7 +4065,7 @@ cmdNodeMemStats(vshControl *ctl, const vshCmd *cmd) /* now go get all the memory parameters */ params = vshCalloc(ctl, nparams, sizeof(*params)); - if (virNodeGetMemoryStats(ctl->conn, cellNum, params, &nparams, 0) != 0) { + if (virNodeGetMemoryStats(conn, cellNum, params, &nparams, 0) != 0) { vshError(ctl, "%s", _("Unable to get memory stats")); goto cleanup; } @@ -4093,10 +4094,10 @@ cmdCapabilities (vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) { char *caps; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; - if ((caps = virConnectGetCapabilities (ctl->conn)) == NULL) { + if ((caps = virConnectGetCapabilities (conn)) == NULL) { vshError(ctl, "%s", _("failed to get capabilities")); return false; } @@ -4141,7 +4142,7 @@ cmdDumpXML(vshControl *ctl, const vshCmd *cmd) if (update) flags |= VIR_DOMAIN_XML_UPDATE_CPU; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) @@ -4184,7 +4185,7 @@ cmdDomXMLFromNative(vshControl *ctl, const vshCmd *cmd) char *xmlData; int flags = 0; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (vshCommandOptString(cmd, "format", &format) < 0 || @@ -4194,7 +4195,7 @@ cmdDomXMLFromNative(vshControl *ctl, const vshCmd *cmd) if (virFileReadAll(configFile, 1024*1024, &configData) < 0) return false; - xmlData = virConnectDomainXMLFromNative(ctl->conn, format, configData, flags); + xmlData = virConnectDomainXMLFromNative(conn, format, configData, flags); if (xmlData != NULL) { vshPrint(ctl, "%s", xmlData); VIR_FREE(xmlData); @@ -4230,7 +4231,7 @@ cmdDomXMLToNative(vshControl *ctl, const vshCmd *cmd) char *xmlData; int flags = 0; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (vshCommandOptString(cmd, "format", &format) < 0 @@ -4240,7 +4241,7 @@ cmdDomXMLToNative(vshControl *ctl, const vshCmd *cmd) if (virFileReadAll(xmlFile, 1024*1024, &xmlData) < 0) return false; - configData = virConnectDomainXMLToNative(ctl->conn, format, xmlData, flags); + configData = virConnectDomainXMLToNative(conn, format, xmlData, flags); if (configData != NULL) { vshPrint(ctl, "%s", configData); VIR_FREE(configData); @@ -4270,7 +4271,7 @@ cmdDomname(vshControl *ctl, const vshCmd *cmd) { virDomainPtr dom; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(dom = vshCommandOptDomainBy(ctl, cmd, NULL, VSH_BYID|VSH_BYUUID))) @@ -4301,7 +4302,7 @@ cmdDomid(vshControl *ctl, const vshCmd *cmd) virDomainPtr dom; unsigned int id; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(dom = vshCommandOptDomainBy(ctl, cmd, NULL, VSH_BYNAME|VSH_BYUUID))) @@ -4336,7 +4337,7 @@ cmdDomuuid(vshControl *ctl, const vshCmd *cmd) virDomainPtr dom; char uuid[VIR_UUID_STRING_BUFLEN]; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(dom = vshCommandOptDomainBy(ctl, cmd, NULL, VSH_BYNAME|VSH_BYID))) @@ -4409,7 +4410,7 @@ doMigrate (void *opaque) goto out_sig; #endif - if (!vshConnectionUsability (ctl, ctl->conn)) + if (!vshConnectionUsability (ctl)) goto out; if (!(dom = vshCommandOptDomain (ctl, cmd, NULL))) @@ -4676,7 +4677,7 @@ cmdMigrateSetMaxDowntime(vshControl *ctl, const vshCmd *cmd) long long downtime = 0; bool ret = false; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) @@ -4721,7 +4722,7 @@ cmdMigrateSetMaxSpeed(vshControl *ctl, const vshCmd *cmd) unsigned long bandwidth = 0; bool ret = false; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) @@ -4765,7 +4766,7 @@ cmdNetworkAutostart(vshControl *ctl, const vshCmd *cmd) const char *name; int autostart; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(network = vshCommandOptNetwork(ctl, cmd, &name))) @@ -4813,7 +4814,7 @@ cmdNetworkCreate(vshControl *ctl, const vshCmd *cmd) bool ret = true; char *buffer; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (vshCommandOptString(cmd, "file", &from) <= 0) @@ -4822,7 +4823,7 @@ cmdNetworkCreate(vshControl *ctl, const vshCmd *cmd) if (virFileReadAll(from, VIRSH_MAX_XML_FILE, &buffer) < 0) return false; - network = virNetworkCreateXML(ctl->conn, buffer); + network = virNetworkCreateXML(conn, buffer); VIR_FREE(buffer); if (network != NULL) { @@ -4859,7 +4860,7 @@ cmdNetworkDefine(vshControl *ctl, const vshCmd *cmd) bool ret = true; char *buffer; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (vshCommandOptString(cmd, "file", &from) <= 0) @@ -4868,7 +4869,7 @@ cmdNetworkDefine(vshControl *ctl, const vshCmd *cmd) if (virFileReadAll(from, VIRSH_MAX_XML_FILE, &buffer) < 0) return false; - network = virNetworkDefineXML(ctl->conn, buffer); + network = virNetworkDefineXML(conn, buffer); VIR_FREE(buffer); if (network != NULL) { @@ -4904,7 +4905,7 @@ cmdNetworkDestroy(vshControl *ctl, const vshCmd *cmd) bool ret = true; const char *name; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(network = vshCommandOptNetwork(ctl, cmd, &name))) @@ -4943,7 +4944,7 @@ cmdNetworkDumpXML(vshControl *ctl, const vshCmd *cmd) bool ret = true; char *dump; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(network = vshCommandOptNetwork(ctl, cmd, NULL))) @@ -4985,7 +4986,7 @@ cmdNetworkInfo(vshControl *ctl, const vshCmd *cmd) int active = -1; char *bridge = NULL; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(network = vshCommandOptNetworkBy(ctl, cmd, NULL, @@ -5045,7 +5046,7 @@ cmdInterfaceEdit (vshControl *ctl, const vshCmd *cmd) char *doc_reread = NULL; int flags = VIR_INTERFACE_XML_INACTIVE; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) goto cleanup; iface = vshCommandOptInterface (ctl, cmd, NULL); @@ -5092,7 +5093,7 @@ cmdInterfaceEdit (vshControl *ctl, const vshCmd *cmd) /* Everything checks out, so redefine the interface. */ virInterfaceFree (iface); - iface = virInterfaceDefineXML (ctl->conn, doc_edited, 0); + iface = virInterfaceDefineXML (conn, doc_edited, 0); if (!iface) goto cleanup; @@ -5142,11 +5143,11 @@ cmdNetworkList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) char **activeNames = NULL, **inactiveNames = NULL; inactive |= all; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (active) { - maxactive = virConnectNumOfNetworks(ctl->conn); + maxactive = virConnectNumOfNetworks(conn); if (maxactive < 0) { vshError(ctl, "%s", _("Failed to list active networks")); return false; @@ -5154,7 +5155,7 @@ cmdNetworkList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) if (maxactive) { activeNames = vshMalloc(ctl, sizeof(char *) * maxactive); - if ((maxactive = virConnectListNetworks(ctl->conn, activeNames, + if ((maxactive = virConnectListNetworks(conn, activeNames, maxactive)) < 0) { vshError(ctl, "%s", _("Failed to list active networks")); VIR_FREE(activeNames); @@ -5165,7 +5166,7 @@ cmdNetworkList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) } } if (inactive) { - maxinactive = virConnectNumOfDefinedNetworks(ctl->conn); + maxinactive = virConnectNumOfDefinedNetworks(conn); if (maxinactive < 0) { vshError(ctl, "%s", _("Failed to list inactive networks")); VIR_FREE(activeNames); @@ -5175,7 +5176,7 @@ cmdNetworkList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) inactiveNames = vshMalloc(ctl, sizeof(char *) * maxinactive); if ((maxinactive = - virConnectListDefinedNetworks(ctl->conn, inactiveNames, + virConnectListDefinedNetworks(conn, inactiveNames, maxinactive)) < 0) { vshError(ctl, "%s", _("Failed to list inactive networks")); VIR_FREE(activeNames); @@ -5192,7 +5193,7 @@ cmdNetworkList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) for (i = 0; i < maxactive; i++) { virNetworkPtr network = - virNetworkLookupByName(ctl->conn, activeNames[i]); + virNetworkLookupByName(conn, activeNames[i]); const char *autostartStr; int autostart = 0; @@ -5215,7 +5216,7 @@ cmdNetworkList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) VIR_FREE(activeNames[i]); } for (i = 0; i < maxinactive; i++) { - virNetworkPtr network = virNetworkLookupByName(ctl->conn, inactiveNames[i]); + virNetworkPtr network = virNetworkLookupByName(conn, inactiveNames[i]); const char *autostartStr; int autostart = 0; @@ -5263,7 +5264,7 @@ cmdNetworkName(vshControl *ctl, const vshCmd *cmd) { virNetworkPtr network; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(network = vshCommandOptNetworkBy(ctl, cmd, NULL, VSH_BYUUID))) @@ -5295,7 +5296,7 @@ cmdNetworkStart(vshControl *ctl, const vshCmd *cmd) virNetworkPtr network; bool ret = true; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(network = vshCommandOptNetworkBy(ctl, cmd, NULL, VSH_BYNAME))) @@ -5335,7 +5336,7 @@ cmdNetworkUndefine(vshControl *ctl, const vshCmd *cmd) bool ret = true; const char *name; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(network = vshCommandOptNetwork(ctl, cmd, &name))) @@ -5373,7 +5374,7 @@ cmdNetworkUuid(vshControl *ctl, const vshCmd *cmd) virNetworkPtr network; char uuid[VIR_UUID_STRING_BUFLEN]; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(network = vshCommandOptNetworkBy(ctl, cmd, NULL, @@ -5415,11 +5416,11 @@ cmdInterfaceList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) char **activeNames = NULL, **inactiveNames = NULL; inactive |= all; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (active) { - maxactive = virConnectNumOfInterfaces(ctl->conn); + maxactive = virConnectNumOfInterfaces(conn); if (maxactive < 0) { vshError(ctl, "%s", _("Failed to list active interfaces")); return false; @@ -5427,7 +5428,7 @@ cmdInterfaceList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) if (maxactive) { activeNames = vshMalloc(ctl, sizeof(char *) * maxactive); - if ((maxactive = virConnectListInterfaces(ctl->conn, activeNames, + if ((maxactive = virConnectListInterfaces(conn, activeNames, maxactive)) < 0) { vshError(ctl, "%s", _("Failed to list active interfaces")); VIR_FREE(activeNames); @@ -5438,7 +5439,7 @@ cmdInterfaceList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) } } if (inactive) { - maxinactive = virConnectNumOfDefinedInterfaces(ctl->conn); + maxinactive = virConnectNumOfDefinedInterfaces(conn); if (maxinactive < 0) { vshError(ctl, "%s", _("Failed to list inactive interfaces")); VIR_FREE(activeNames); @@ -5448,7 +5449,7 @@ cmdInterfaceList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) inactiveNames = vshMalloc(ctl, sizeof(char *) * maxinactive); if ((maxinactive = - virConnectListDefinedInterfaces(ctl->conn, inactiveNames, + virConnectListDefinedInterfaces(conn, inactiveNames, maxinactive)) < 0) { vshError(ctl, "%s", _("Failed to list inactive interfaces")); VIR_FREE(activeNames); @@ -5465,7 +5466,7 @@ cmdInterfaceList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) for (i = 0; i < maxactive; i++) { virInterfacePtr iface = - virInterfaceLookupByName(ctl->conn, activeNames[i]); + virInterfaceLookupByName(conn, activeNames[i]); /* this kind of work with interfaces is not atomic */ if (!iface) { @@ -5482,7 +5483,7 @@ cmdInterfaceList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) } for (i = 0; i < maxinactive; i++) { virInterfacePtr iface = - virInterfaceLookupByName(ctl->conn, inactiveNames[i]); + virInterfaceLookupByName(conn, inactiveNames[i]); /* this kind of work with interfaces is not atomic */ if (!iface) { @@ -5522,7 +5523,7 @@ cmdInterfaceName(vshControl *ctl, const vshCmd *cmd) { virInterfacePtr iface; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(iface = vshCommandOptInterfaceBy(ctl, cmd, NULL, VSH_BYMAC))) @@ -5552,7 +5553,7 @@ cmdInterfaceMAC(vshControl *ctl, const vshCmd *cmd) { virInterfacePtr iface; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(iface = vshCommandOptInterfaceBy(ctl, cmd, NULL, VSH_BYNAME))) @@ -5590,7 +5591,7 @@ cmdInterfaceDumpXML(vshControl *ctl, const vshCmd *cmd) if (inactive) flags |= VIR_INTERFACE_XML_INACTIVE; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(iface = vshCommandOptInterface(ctl, cmd, NULL))) @@ -5630,7 +5631,7 @@ cmdInterfaceDefine(vshControl *ctl, const vshCmd *cmd) bool ret = true; char *buffer; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (vshCommandOptString(cmd, "file", &from) <= 0) @@ -5639,7 +5640,7 @@ cmdInterfaceDefine(vshControl *ctl, const vshCmd *cmd) if (virFileReadAll(from, VIRSH_MAX_XML_FILE, &buffer) < 0) return false; - iface = virInterfaceDefineXML(ctl->conn, buffer, 0); + iface = virInterfaceDefineXML(conn, buffer, 0); VIR_FREE(buffer); if (iface != NULL) { @@ -5674,7 +5675,7 @@ cmdInterfaceUndefine(vshControl *ctl, const vshCmd *cmd) bool ret = true; const char *name; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(iface = vshCommandOptInterface(ctl, cmd, &name))) @@ -5712,7 +5713,7 @@ cmdInterfaceStart(vshControl *ctl, const vshCmd *cmd) bool ret = true; const char *name; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(iface = vshCommandOptInterface(ctl, cmd, &name))) @@ -5750,7 +5751,7 @@ cmdInterfaceDestroy(vshControl *ctl, const vshCmd *cmd) bool ret = true; const char *name; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(iface = vshCommandOptInterface(ctl, cmd, &name))) @@ -5785,10 +5786,10 @@ static const vshCmdOptDef opts_interface_begin[] = { static bool cmdInterfaceBegin(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) { - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; - if (virInterfaceChangeBegin(ctl->conn, 0) < 0) { + if (virInterfaceChangeBegin(conn, 0) < 0) { vshError(ctl, "%s", _("Failed to begin network config change transaction")); return false; } @@ -5813,10 +5814,10 @@ static const vshCmdOptDef opts_interface_commit[] = { static bool cmdInterfaceCommit(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) { - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; - if (virInterfaceChangeCommit(ctl->conn, 0) < 0) { + if (virInterfaceChangeCommit(conn, 0) < 0) { vshError(ctl, "%s", _("Failed to commit network config change transaction")); return false; } @@ -5841,10 +5842,10 @@ static const vshCmdOptDef opts_interface_rollback[] = { static bool cmdInterfaceRollback(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) { - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; - if (virInterfaceChangeRollback(ctl->conn, 0) < 0) { + if (virInterfaceChangeRollback(conn, 0) < 0) { vshError(ctl, "%s", _("Failed to rollback network config change transaction")); return false; } @@ -5875,7 +5876,7 @@ cmdNWFilterDefine(vshControl *ctl, const vshCmd *cmd) bool ret = true; char *buffer; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (vshCommandOptString(cmd, "file", &from) <= 0) @@ -5884,7 +5885,7 @@ cmdNWFilterDefine(vshControl *ctl, const vshCmd *cmd) if (virFileReadAll(from, VIRSH_MAX_XML_FILE, &buffer) < 0) return false; - nwfilter = virNWFilterDefineXML(ctl->conn, buffer); + nwfilter = virNWFilterDefineXML(conn, buffer); VIR_FREE(buffer); if (nwfilter != NULL) { @@ -5920,7 +5921,7 @@ cmdNWFilterUndefine(vshControl *ctl, const vshCmd *cmd) bool ret = true; const char *name; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(nwfilter = vshCommandOptNWFilter(ctl, cmd, &name))) @@ -5959,7 +5960,7 @@ cmdNWFilterDumpXML(vshControl *ctl, const vshCmd *cmd) bool ret = true; char *dump; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(nwfilter = vshCommandOptNWFilter(ctl, cmd, NULL))) @@ -5997,10 +5998,10 @@ cmdNWFilterList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) char **names; char uuid[VIR_UUID_STRING_BUFLEN]; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; - numfilters = virConnectNumOfNWFilters(ctl->conn); + numfilters = virConnectNumOfNWFilters(conn); if (numfilters < 0) { vshError(ctl, "%s", _("Failed to list network filters")); return false; @@ -6008,7 +6009,7 @@ cmdNWFilterList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) names = vshMalloc(ctl, sizeof(char *) * numfilters); - if ((numfilters = virConnectListNWFilters(ctl->conn, names, + if ((numfilters = virConnectListNWFilters(conn, names, numfilters)) < 0) { vshError(ctl, "%s", _("Failed to list network filters")); VIR_FREE(names); @@ -6023,7 +6024,7 @@ cmdNWFilterList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) for (i = 0; i < numfilters; i++) { virNWFilterPtr nwfilter = - virNWFilterLookupByName(ctl->conn, names[i]); + virNWFilterLookupByName(conn, names[i]); /* this kind of work with networks is not atomic operation */ if (!nwfilter) { @@ -6068,7 +6069,7 @@ cmdNWFilterEdit (vshControl *ctl, const vshCmd *cmd) char *doc_edited = NULL; char *doc_reread = NULL; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) goto cleanup; nwfilter = vshCommandOptNWFilter (ctl, cmd, NULL); @@ -6115,7 +6116,7 @@ cmdNWFilterEdit (vshControl *ctl, const vshCmd *cmd) /* Everything checks out, so redefine the interface. */ virNWFilterFree (nwfilter); - nwfilter = virNWFilterDefineXML (ctl->conn, doc_edited); + nwfilter = virNWFilterDefineXML (conn, doc_edited); if (!nwfilter) goto cleanup; @@ -6165,7 +6166,7 @@ cmdPoolAutostart(vshControl *ctl, const vshCmd *cmd) const char *name; int autostart; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(pool = vshCommandOptPool(ctl, cmd, "pool", &name))) @@ -6214,7 +6215,7 @@ cmdPoolCreate(vshControl *ctl, const vshCmd *cmd) bool ret = true; char *buffer; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (vshCommandOptString(cmd, "file", &from) <= 0) @@ -6223,7 +6224,7 @@ cmdPoolCreate(vshControl *ctl, const vshCmd *cmd) if (virFileReadAll(from, VIRSH_MAX_XML_FILE, &buffer) < 0) return false; - pool = virStoragePoolCreateXML(ctl->conn, buffer, 0); + pool = virStoragePoolCreateXML(conn, buffer, 0); VIR_FREE(buffer); if (pool != NULL) { @@ -6264,7 +6265,7 @@ cmdNodeDeviceCreate(vshControl *ctl, const vshCmd *cmd) bool ret = true; char *buffer; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (vshCommandOptString(cmd, "file", &from) <= 0) @@ -6273,7 +6274,7 @@ cmdNodeDeviceCreate(vshControl *ctl, const vshCmd *cmd) if (virFileReadAll(from, VIRSH_MAX_XML_FILE, &buffer) < 0) return false; - dev = virNodeDeviceCreateXML(ctl->conn, buffer, 0); + dev = virNodeDeviceCreateXML(conn, buffer, 0); VIR_FREE(buffer); if (dev != NULL) { @@ -6312,14 +6313,14 @@ cmdNodeDeviceDestroy(vshControl *ctl, const vshCmd *cmd) bool ret = true; const char *name = NULL; - if (!vshConnectionUsability(ctl, ctl->conn)) { + if (!vshConnectionUsability(ctl)) { return false; } if (vshCommandOptString(cmd, "name", &name) <= 0) return false; - dev = virNodeDeviceLookupByName(ctl->conn, name); + dev = virNodeDeviceLookupByName(conn, name); if (virNodeDeviceDestroy(dev) == 0) { vshPrint(ctl, _("Destroyed node device '%s'\n"), name); @@ -6426,7 +6427,7 @@ cmdPoolCreateAs(vshControl *ctl, const vshCmd *cmd) char *xml; int printXML = vshCommandOptBool(cmd, "print-xml"); - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!buildPoolXML(cmd, &name, &xml)) @@ -6436,7 +6437,7 @@ cmdPoolCreateAs(vshControl *ctl, const vshCmd *cmd) vshPrint(ctl, "%s", xml); VIR_FREE(xml); } else { - pool = virStoragePoolCreateXML(ctl->conn, xml, 0); + pool = virStoragePoolCreateXML(conn, xml, 0); VIR_FREE(xml); if (pool != NULL) { @@ -6473,7 +6474,7 @@ cmdPoolDefine(vshControl *ctl, const vshCmd *cmd) bool ret = true; char *buffer; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (vshCommandOptString(cmd, "file", &from) <= 0) @@ -6482,7 +6483,7 @@ cmdPoolDefine(vshControl *ctl, const vshCmd *cmd) if (virFileReadAll(from, VIRSH_MAX_XML_FILE, &buffer) < 0) return false; - pool = virStoragePoolDefineXML(ctl->conn, buffer, 0); + pool = virStoragePoolDefineXML(conn, buffer, 0); VIR_FREE(buffer); if (pool != NULL) { @@ -6514,7 +6515,7 @@ cmdPoolDefineAs(vshControl *ctl, const vshCmd *cmd) char *xml; int printXML = vshCommandOptBool(cmd, "print-xml"); - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!buildPoolXML(cmd, &name, &xml)) @@ -6524,7 +6525,7 @@ cmdPoolDefineAs(vshControl *ctl, const vshCmd *cmd) vshPrint(ctl, "%s", xml); VIR_FREE(xml); } else { - pool = virStoragePoolDefineXML(ctl->conn, xml, 0); + pool = virStoragePoolDefineXML(conn, xml, 0); VIR_FREE(xml); if (pool != NULL) { @@ -6560,7 +6561,7 @@ cmdPoolBuild(vshControl *ctl, const vshCmd *cmd) bool ret = true; const char *name; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(pool = vshCommandOptPool(ctl, cmd, "pool", &name))) @@ -6600,7 +6601,7 @@ cmdPoolDestroy(vshControl *ctl, const vshCmd *cmd) bool ret = true; const char *name; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(pool = vshCommandOptPool(ctl, cmd, "pool", &name))) @@ -6639,7 +6640,7 @@ cmdPoolDelete(vshControl *ctl, const vshCmd *cmd) bool ret = true; const char *name; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(pool = vshCommandOptPool(ctl, cmd, "pool", &name))) @@ -6678,7 +6679,7 @@ cmdPoolRefresh(vshControl *ctl, const vshCmd *cmd) bool ret = true; const char *name; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(pool = vshCommandOptPool(ctl, cmd, "pool", &name))) @@ -6717,7 +6718,7 @@ cmdPoolDumpXML(vshControl *ctl, const vshCmd *cmd) bool ret = true; char *dump; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(pool = vshCommandOptPool(ctl, cmd, "pool", NULL))) @@ -6782,12 +6783,12 @@ cmdPoolList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) inactive |= all; /* Check the connection to libvirtd daemon is still working */ - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; /* Retrieve the number of active storage pools */ if (active) { - numActivePools = virConnectNumOfStoragePools(ctl->conn); + numActivePools = virConnectNumOfStoragePools(conn); if (numActivePools < 0) { vshError(ctl, "%s", _("Failed to list active pools")); return false; @@ -6796,7 +6797,7 @@ cmdPoolList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) /* Retrieve the number of inactive storage pools */ if (inactive) { - numInactivePools = virConnectNumOfDefinedStoragePools(ctl->conn); + numInactivePools = virConnectNumOfDefinedStoragePools(conn); if (numInactivePools < 0) { vshError(ctl, "%s", _("Failed to list inactive pools")); return false; @@ -6813,7 +6814,7 @@ cmdPoolList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) /* Retrieve a list of active storage pool names */ if (active) { - if ((virConnectListStoragePools(ctl->conn, + if ((virConnectListStoragePools(conn, poolNames, numActivePools)) < 0) { vshError(ctl, "%s", _("Failed to list active pools")); VIR_FREE(poolInfoTexts); @@ -6824,7 +6825,7 @@ cmdPoolList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) /* Add the inactive storage pools to the end of the name list */ if (inactive) { - if ((virConnectListDefinedStoragePools(ctl->conn, + if ((virConnectListDefinedStoragePools(conn, &poolNames[numActivePools], numInactivePools)) < 0) { vshError(ctl, "%s", _("Failed to list inactive pools")); @@ -6842,7 +6843,7 @@ cmdPoolList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) int autostart = 0, persistent = 0; /* Retrieve a pool object, looking it up by name */ - virStoragePoolPtr pool = virStoragePoolLookupByName(ctl->conn, + virStoragePoolPtr pool = virStoragePoolLookupByName(conn, poolNames[i]); if (!pool) { VIR_FREE(poolNames[i]); @@ -7178,7 +7179,7 @@ cmdPoolDiscoverSourcesAs(vshControl * ctl, const vshCmd * cmd ATTRIBUTE_UNUSED) return false; } - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (host) { @@ -7208,7 +7209,7 @@ cmdPoolDiscoverSourcesAs(vshControl * ctl, const vshCmd * cmd ATTRIBUTE_UNUSED) srcSpec = virBufferContentAndReset(&buf); } - srcList = virConnectFindStoragePoolSources(ctl->conn, type, srcSpec, 0); + srcList = virConnectFindStoragePoolSources(conn, type, srcSpec, 0); VIR_FREE(srcSpec); if (srcList == NULL) { vshError(ctl, _("Failed to find any %s pool sources"), type); @@ -7252,13 +7253,13 @@ cmdPoolDiscoverSources(vshControl * ctl, const vshCmd * cmd ATTRIBUTE_UNUSED) return false; } - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (srcSpecFile && virFileReadAll(srcSpecFile, VIRSH_MAX_XML_FILE, &srcSpec) < 0) return false; - srcList = virConnectFindStoragePoolSources(ctl->conn, type, srcSpec, 0); + srcList = virConnectFindStoragePoolSources(conn, type, srcSpec, 0); VIR_FREE(srcSpec); if (srcList == NULL) { vshError(ctl, _("Failed to find any %s pool sources"), type); @@ -7295,7 +7296,7 @@ cmdPoolInfo(vshControl *ctl, const vshCmd *cmd) bool ret = true; char uuid[VIR_UUID_STRING_BUFLEN]; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(pool = vshCommandOptPool(ctl, cmd, "pool", NULL))) @@ -7387,7 +7388,7 @@ cmdPoolName(vshControl *ctl, const vshCmd *cmd) { virStoragePoolPtr pool; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(pool = vshCommandOptPoolBy(ctl, cmd, "pool", NULL, VSH_BYUUID))) @@ -7419,7 +7420,7 @@ cmdPoolStart(vshControl *ctl, const vshCmd *cmd) virStoragePoolPtr pool; bool ret = true; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(pool = vshCommandOptPoolBy(ctl, cmd, "pool", NULL, VSH_BYNAME))) @@ -7500,7 +7501,7 @@ cmdVolCreateAs(vshControl *ctl, const vshCmd *cmd) unsigned long long capacity, allocation = 0; virBuffer buf = VIR_BUFFER_INITIALIZER; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(pool = vshCommandOptPoolBy(ctl, cmd, "pool", NULL, @@ -7555,7 +7556,7 @@ cmdVolCreateAs(vshControl *ctl, const vshCmd *cmd) * backing-vol parameter as a key */ vshDebug(ctl, 5, "%s: Look up backing store volume '%s' as key\n", cmd->def->name, snapshotStrVol); - snapVol = virStorageVolLookupByKey(ctl->conn, snapshotStrVol); + snapVol = virStorageVolLookupByKey(conn, snapshotStrVol); if (snapVol) vshDebug(ctl, 5, "%s: Backing store volume found using '%s' as key\n", cmd->def->name, snapshotStrVol); @@ -7565,7 +7566,7 @@ cmdVolCreateAs(vshControl *ctl, const vshCmd *cmd) * backing-vol parameter as a path */ vshDebug(ctl, 5, "%s: Look up backing store volume '%s' as path\n", cmd->def->name, snapshotStrVol); - snapVol = virStorageVolLookupByPath(ctl->conn, snapshotStrVol); + snapVol = virStorageVolLookupByPath(conn, snapshotStrVol); if (snapVol) vshDebug(ctl, 5, "%s: Backing store volume found using '%s' as path\n", cmd->def->name, snapshotStrVol); @@ -7641,7 +7642,7 @@ cmdPoolUndefine(vshControl *ctl, const vshCmd *cmd) bool ret = true; const char *name; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(pool = vshCommandOptPool(ctl, cmd, "pool", &name))) @@ -7679,7 +7680,7 @@ cmdPoolUuid(vshControl *ctl, const vshCmd *cmd) virStoragePoolPtr pool; char uuid[VIR_UUID_STRING_BUFLEN]; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(pool = vshCommandOptPoolBy(ctl, cmd, "pool", NULL, @@ -7720,7 +7721,7 @@ cmdVolCreate(vshControl *ctl, const vshCmd *cmd) bool ret = true; char *buffer; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(pool = vshCommandOptPoolBy(ctl, cmd, "pool", NULL, @@ -7779,7 +7780,7 @@ cmdVolCreateFrom(vshControl *ctl, const vshCmd *cmd) bool ret = false; char *buffer = NULL; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) goto cleanup; if (!(pool = vshCommandOptPoolBy(ctl, cmd, "pool", NULL, VSH_BYNAME))) @@ -7877,7 +7878,7 @@ cmdVolClone(vshControl *ctl, const vshCmd *cmd) xmlChar *newxml = NULL; bool ret = false; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) goto cleanup; if (!(origvol = vshCommandOptVol(ctl, cmd, "vol", "pool", NULL))) @@ -7966,7 +7967,7 @@ cmdVolUpload (vshControl *ctl, const vshCmd *cmd) const char *name = NULL; unsigned long long offset = 0, length = 0; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) goto cleanup; if (vshCommandOptULongLong(cmd, "offset", &offset) < 0) { @@ -7993,7 +7994,7 @@ cmdVolUpload (vshControl *ctl, const vshCmd *cmd) goto cleanup; } - st = virStreamNew(ctl->conn, 0); + st = virStreamNew(conn, 0); if (virStorageVolUpload(vol, st, offset, length, 0) < 0) { vshError(ctl, _("cannot upload to volume %s"), name); goto cleanup; @@ -8058,7 +8059,7 @@ cmdVolDownload (vshControl *ctl, const vshCmd *cmd) unsigned long long offset = 0, length = 0; bool created = false; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (vshCommandOptULongLong(cmd, "offset", &offset) < 0) { @@ -8089,7 +8090,7 @@ cmdVolDownload (vshControl *ctl, const vshCmd *cmd) created = true; } - st = virStreamNew(ctl->conn, 0); + st = virStreamNew(conn, 0); if (virStorageVolDownload(vol, st, offset, length, 0) < 0) { vshError(ctl, _("cannot download from volume %s"), name); goto cleanup; @@ -8147,7 +8148,7 @@ cmdVolDelete(vshControl *ctl, const vshCmd *cmd) bool ret = true; const char *name; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(vol = vshCommandOptVol(ctl, cmd, "vol", "pool", &name))) { @@ -8188,7 +8189,7 @@ cmdVolWipe(vshControl *ctl, const vshCmd *cmd) bool ret = true; const char *name; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(vol = vshCommandOptVol(ctl, cmd, "vol", "pool", &name))) { @@ -8229,7 +8230,7 @@ cmdVolInfo(vshControl *ctl, const vshCmd *cmd) virStorageVolPtr vol; bool ret = true; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(vol = vshCommandOptVol(ctl, cmd, "vol", "pool", NULL))) @@ -8280,7 +8281,7 @@ cmdVolDumpXML(vshControl *ctl, const vshCmd *cmd) bool ret = true; char *dump; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(vol = vshCommandOptVol(ctl, cmd, "vol", "pool", NULL))) @@ -8340,7 +8341,7 @@ cmdVolList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) struct volInfoText *volInfoTexts = NULL; /* Check the connection to libvirtd daemon is still working */ - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; /* Look up the pool information given to us by the user */ @@ -8602,7 +8603,7 @@ cmdVolName(vshControl *ctl, const vshCmd *cmd) { virStorageVolPtr vol; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(vol = vshCommandOptVolBy(ctl, cmd, "vol", "pool", NULL, @@ -8638,7 +8639,7 @@ cmdVolPool(vshControl *ctl, const vshCmd *cmd) char uuid[VIR_UUID_STRING_BUFLEN]; /* Check the connection to libvirtd daemon is still working */ - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; /* Use the supplied string to locate the volume */ @@ -8692,7 +8693,7 @@ cmdVolKey(vshControl *ctl, const vshCmd *cmd) { virStorageVolPtr vol; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(vol = vshCommandOptVol(ctl, cmd, "vol", "pool", NULL))) @@ -8726,7 +8727,7 @@ cmdVolPath(vshControl *ctl, const vshCmd *cmd) virStorageVolPtr vol; const char *name = NULL; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(vol = vshCommandOptVol(ctl, cmd, "vol", "pool", &name))) { @@ -8761,7 +8762,7 @@ cmdSecretDefine(vshControl *ctl, const vshCmd *cmd) virSecretPtr res; char uuid[VIR_UUID_STRING_BUFLEN]; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (vshCommandOptString(cmd, "file", &from) <= 0) @@ -8770,7 +8771,7 @@ cmdSecretDefine(vshControl *ctl, const vshCmd *cmd) if (virFileReadAll(from, VIRSH_MAX_XML_FILE, &buffer) < 0) return false; - res = virSecretDefineXML(ctl->conn, buffer, 0); + res = virSecretDefineXML(conn, buffer, 0); VIR_FREE(buffer); if (res == NULL) { @@ -8808,7 +8809,7 @@ cmdSecretDumpXML(vshControl *ctl, const vshCmd *cmd) bool ret = false; char *xml; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; secret = vshCommandOptSecret(ctl, cmd, NULL); @@ -8852,7 +8853,7 @@ cmdSecretSetValue(vshControl *ctl, const vshCmd *cmd) int res; bool ret = false; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; secret = vshCommandOptSecret(ctl, cmd, NULL); @@ -8910,7 +8911,7 @@ cmdSecretGetValue(vshControl *ctl, const vshCmd *cmd) size_t value_size; bool ret = false; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; secret = vshCommandOptSecret(ctl, cmd, NULL); @@ -8960,7 +8961,7 @@ cmdSecretUndefine(vshControl *ctl, const vshCmd *cmd) bool ret = false; const char *uuid; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; secret = vshCommandOptSecret(ctl, cmd, &uuid); @@ -8994,17 +8995,17 @@ cmdSecretList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) int maxuuids = 0, i; char **uuids = NULL; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; - maxuuids = virConnectNumOfSecrets(ctl->conn); + maxuuids = virConnectNumOfSecrets(conn); if (maxuuids < 0) { vshError(ctl, "%s", _("Failed to list secrets")); return false; } uuids = vshMalloc(ctl, sizeof(*uuids) * maxuuids); - maxuuids = virConnectListSecrets(ctl->conn, uuids, maxuuids); + maxuuids = virConnectListSecrets(conn, uuids, maxuuids); if (maxuuids < 0) { vshError(ctl, "%s", _("Failed to list secrets")); VIR_FREE(uuids); @@ -9017,7 +9018,7 @@ cmdSecretList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) vshPrintExtra(ctl, "-----------------------------------------------------------\n"); for (i = 0; i < maxuuids; i++) { - virSecretPtr sec = virSecretLookupByUUIDString(ctl->conn, uuids[i]); + virSecretPtr sec = virSecretLookupByUUIDString(conn, uuids[i]); const char *usageType = NULL; if (!sec) { @@ -9075,10 +9076,10 @@ cmdVersion(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) unsigned int minor; unsigned int rel; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; - hvType = virConnectGetType(ctl->conn); + hvType = virConnectGetType(conn); if (hvType == NULL) { vshError(ctl, "%s", _("failed to get hypervisor type")); return false; @@ -9111,7 +9112,7 @@ cmdVersion(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) vshPrint(ctl, _("Using API: %s %d.%d.%d\n"), hvType, major, minor, rel); - ret = virConnectGetVersion(ctl->conn, &hvVersion); + ret = virConnectGetVersion(conn, &hvVersion); if (ret < 0) { vshError(ctl, "%s", _("failed to get the hypervisor version")); return false; @@ -9130,7 +9131,7 @@ cmdVersion(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) } if (vshCommandOptBool(cmd, "daemon")) { - ret = virConnectGetLibVersion(ctl->conn, &daemonVersion); + ret = virConnectGetLibVersion(conn, &daemonVersion); if (ret < 0) { vshError(ctl, "%s", _("failed to get the daemon version")); } else { @@ -9249,13 +9250,13 @@ cmdNodeListDevices (vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) int num_devices, i; int tree = vshCommandOptBool(cmd, "tree"); - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (vshCommandOptString(cmd, "cap", &cap) <= 0) cap = NULL; - num_devices = virNodeNumOfDevices(ctl->conn, cap, 0); + num_devices = virNodeNumOfDevices(conn, cap, 0); if (num_devices < 0) { vshError(ctl, "%s", _("Failed to count node devices")); return false; @@ -9265,7 +9266,7 @@ cmdNodeListDevices (vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) devices = vshMalloc(ctl, sizeof(char *) * num_devices); num_devices = - virNodeListDevices(ctl->conn, cap, devices, num_devices, 0); + virNodeListDevices(conn, cap, devices, num_devices, 0); if (num_devices < 0) { vshError(ctl, "%s", _("Failed to list node devices")); VIR_FREE(devices); @@ -9276,7 +9277,7 @@ cmdNodeListDevices (vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) char indentBuf[INDENT_BUFLEN]; char **parents = vshMalloc(ctl, sizeof(char *) * num_devices); for (i = 0; i < num_devices; i++) { - virNodeDevicePtr dev = virNodeDeviceLookupByName(ctl->conn, devices[i]); + virNodeDevicePtr dev = virNodeDeviceLookupByName(conn, devices[i]); if (dev && STRNEQ(devices[i], "computer")) { const char *parent = virNodeDeviceGetParent(dev); parents[i] = parent ? vshStrdup(ctl, parent) : NULL; @@ -9335,11 +9336,11 @@ cmdNodeDeviceDumpXML (vshControl *ctl, const vshCmd *cmd) virNodeDevicePtr device; char *xml; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (vshCommandOptString(cmd, "device", &name) <= 0) return false; - if (!(device = virNodeDeviceLookupByName(ctl->conn, name))) { + if (!(device = virNodeDeviceLookupByName(conn, name))) { vshError(ctl, "%s '%s'", _("Could not find matching device"), name); return false; } @@ -9378,11 +9379,11 @@ cmdNodeDeviceDettach (vshControl *ctl, const vshCmd *cmd) virNodeDevicePtr device; bool ret = true; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (vshCommandOptString(cmd, "device", &name) <= 0) return false; - if (!(device = virNodeDeviceLookupByName(ctl->conn, name))) { + if (!(device = virNodeDeviceLookupByName(conn, name))) { vshError(ctl, "%s '%s'", _("Could not find matching device"), name); return false; } @@ -9419,11 +9420,11 @@ cmdNodeDeviceReAttach (vshControl *ctl, const vshCmd *cmd) virNodeDevicePtr device; bool ret = true; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (vshCommandOptString(cmd, "device", &name) <= 0) return false; - if (!(device = virNodeDeviceLookupByName(ctl->conn, name))) { + if (!(device = virNodeDeviceLookupByName(conn, name))) { vshError(ctl, "%s '%s'", _("Could not find matching device"), name); return false; } @@ -9460,11 +9461,11 @@ cmdNodeDeviceReset (vshControl *ctl, const vshCmd *cmd) virNodeDevicePtr device; bool ret = true; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (vshCommandOptString(cmd, "device", &name) <= 0) return false; - if (!(device = virNodeDeviceLookupByName(ctl->conn, name))) { + if (!(device = virNodeDeviceLookupByName(conn, name))) { vshError(ctl, "%s '%s'", _("Could not find matching device"), name); return false; } @@ -9493,10 +9494,10 @@ cmdHostname (vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) { char *hostname; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; - hostname = virConnectGetHostname (ctl->conn); + hostname = virConnectGetHostname (conn); if (hostname == NULL) { vshError(ctl, "%s", _("failed to get hostname")); return false; @@ -9522,10 +9523,10 @@ cmdURI (vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) { char *uri; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; - uri = virConnectGetURI (ctl->conn); + uri = virConnectGetURI (conn); if (uri == NULL) { vshError(ctl, "%s", _("failed to get URI")); return false; @@ -9552,10 +9553,10 @@ cmdSysinfo (vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) { char *sysinfo; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; - sysinfo = virConnectGetSysinfo (ctl->conn, 0); + sysinfo = virConnectGetSysinfo (conn, 0); if (sysinfo == NULL) { vshError(ctl, "%s", _("failed to get sysinfo")); return false; @@ -9592,7 +9593,7 @@ cmdVNCDisplay(vshControl *ctl, const vshCmd *cmd) int port = 0; char *doc; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) @@ -9666,7 +9667,7 @@ cmdTTYConsole(vshControl *ctl, const vshCmd *cmd) bool ret = false; char *doc; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) @@ -9728,7 +9729,7 @@ cmdAttachDevice(vshControl *ctl, const vshCmd *cmd) int ret; unsigned int flags; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) @@ -9793,7 +9794,7 @@ cmdDetachDevice(vshControl *ctl, const vshCmd *cmd) int ret; unsigned int flags; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) @@ -9859,7 +9860,7 @@ cmdUpdateDevice(vshControl *ctl, const vshCmd *cmd) int ret; unsigned int flags; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) @@ -9937,7 +9938,7 @@ cmdAttachInterface(vshControl *ctl, const vshCmd *cmd) virBuffer buf = VIR_BUFFER_INITIALIZER; char *xml; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) goto cleanup; if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) @@ -10051,7 +10052,7 @@ cmdDetachInterface(vshControl *ctl, const vshCmd *cmd) int functionReturn = false; unsigned int flags; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) goto cleanup; if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) @@ -10196,7 +10197,7 @@ cmdAttachDisk(vshControl *ctl, const vshCmd *cmd) virBuffer buf = VIR_BUFFER_INITIALIZER; char *xml; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) goto cleanup; if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) @@ -10326,7 +10327,7 @@ cmdDetachDisk(vshControl *ctl, const vshCmd *cmd) bool functionReturn = false; unsigned int flags; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) goto cleanup; if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) @@ -10443,7 +10444,7 @@ cmdCPUCompare(vshControl *ctl, const vshCmd *cmd) char *buffer; int result; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (vshCommandOptString(cmd, "file", &from) <= 0) @@ -10452,7 +10453,7 @@ cmdCPUCompare(vshControl *ctl, const vshCmd *cmd) if (virFileReadAll(from, VIRSH_MAX_XML_FILE, &buffer) < 0) return false; - result = virConnectCompareCPU(ctl->conn, buffer, 0); + result = virConnectCompareCPU(conn, buffer, 0); VIR_FREE(buffer); switch (result) { @@ -10514,7 +10515,7 @@ cmdCPUBaseline(vshControl *ctl, const vshCmd *cmd) xmlXPathObjectPtr obj = NULL; int res, i; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) return false; if (vshCommandOptString(cmd, "file", &from) <= 0) @@ -10572,7 +10573,7 @@ cmdCPUBaseline(vshControl *ctl, const vshCmd *cmd) goto cleanup; } - result = virConnectBaselineCPU(ctl->conn, list, count, 0); + result = virConnectBaselineCPU(conn, list, count, 0); if (result) vshPrint(ctl, "%s", result); @@ -10885,7 +10886,7 @@ cmdEdit (vshControl *ctl, const vshCmd *cmd) char *doc_reread = NULL; int flags = VIR_DOMAIN_XML_SECURE | VIR_DOMAIN_XML_INACTIVE; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) goto cleanup; dom = vshCommandOptDomain (ctl, cmd, NULL); @@ -10932,7 +10933,7 @@ cmdEdit (vshControl *ctl, const vshCmd *cmd) /* Everything checks out, so redefine the domain. */ virDomainFree (dom); - dom = virDomainDefineXML (ctl->conn, doc_edited); + dom = virDomainDefineXML (conn, doc_edited); if (!dom) goto cleanup; @@ -11036,7 +11037,7 @@ cmdSnapshotCreate(vshControl *ctl, const vshCmd *cmd) char *doc = NULL; char *name = NULL; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) goto cleanup; dom = vshCommandOptDomain(ctl, cmd, NULL); @@ -11138,7 +11139,7 @@ cmdSnapshotCreateAs(vshControl *ctl, const vshCmd *cmd) char *parsed_name = NULL; virBuffer buf = VIR_BUFFER_INITIALIZER; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) goto cleanup; dom = vshCommandOptDomain(ctl, cmd, NULL); @@ -11235,7 +11236,7 @@ cmdSnapshotCurrent(vshControl *ctl, const vshCmd *cmd) int current; virDomainSnapshotPtr snapshot = NULL; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) goto cleanup; dom = vshCommandOptDomain(ctl, cmd, NULL); @@ -11303,7 +11304,7 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd) char timestr[100]; struct tm time_info; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) goto cleanup; dom = vshCommandOptDomain(ctl, cmd, NULL); @@ -11417,7 +11418,7 @@ cmdSnapshotDumpXML(vshControl *ctl, const vshCmd *cmd) virDomainSnapshotPtr snapshot = NULL; char *xml = NULL; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) goto cleanup; dom = vshCommandOptDomain(ctl, cmd, NULL); @@ -11472,7 +11473,7 @@ cmdDomainSnapshotRevert(vshControl *ctl, const vshCmd *cmd) const char *name = NULL; virDomainSnapshotPtr snapshot = NULL; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) goto cleanup; dom = vshCommandOptDomain(ctl, cmd, NULL); @@ -11525,7 +11526,7 @@ cmdSnapshotDelete(vshControl *ctl, const vshCmd *cmd) virDomainSnapshotPtr snapshot = NULL; unsigned int flags = 0; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) goto cleanup; dom = vshCommandOptDomain(ctl, cmd, NULL); @@ -11581,7 +11582,7 @@ cmdQemuMonitorCommand(vshControl *ctl, const vshCmd *cmd) char *result = NULL; unsigned int flags = 0; - if (!vshConnectionUsability(ctl, ctl->conn)) + if (!vshConnectionUsability(ctl)) goto cleanup; dom = vshCommandOptDomain(ctl, cmd, NULL); @@ -12463,20 +12464,20 @@ vshCommandOptDomainBy(vshControl *ctl, const vshCmd *cmd, if (virStrToLong_i(n, NULL, 10, &id) == 0 && id >= 0) { vshDebug(ctl, 5, "%s: <%s> seems like domain ID\n", cmd->def->name, optname); - dom = virDomainLookupByID(ctl->conn, id); + dom = virDomainLookupByID(conn, id); } } /* try it by UUID */ if (dom==NULL && (flag & VSH_BYUUID) && strlen(n)==VIR_UUID_STRING_BUFLEN-1) { vshDebug(ctl, 5, "%s: <%s> trying as domain UUID\n", cmd->def->name, optname); - dom = virDomainLookupByUUIDString(ctl->conn, n); + dom = virDomainLookupByUUIDString(conn, n); } /* try it by NAME */ if (dom==NULL && (flag & VSH_BYNAME)) { vshDebug(ctl, 5, "%s: <%s> trying as domain NAME\n", cmd->def->name, optname); - dom = virDomainLookupByName(ctl->conn, n); + dom = virDomainLookupByName(conn, n); } if (!dom) @@ -12508,13 +12509,13 @@ vshCommandOptNetworkBy(vshControl *ctl, const vshCmd *cmd, if ((flag & VSH_BYUUID) && (strlen(n) == VIR_UUID_STRING_BUFLEN-1)) { vshDebug(ctl, 5, "%s: <%s> trying as network UUID\n", cmd->def->name, optname); - network = virNetworkLookupByUUIDString(ctl->conn, n); + network = virNetworkLookupByUUIDString(conn, n); } /* try it by NAME */ if (network==NULL && (flag & VSH_BYNAME)) { vshDebug(ctl, 5, "%s: <%s> trying as network NAME\n", cmd->def->name, optname); - network = virNetworkLookupByName(ctl->conn, n); + network = virNetworkLookupByName(conn, n); } if (!network) @@ -12547,13 +12548,13 @@ vshCommandOptNWFilterBy(vshControl *ctl, const vshCmd *cmd, if ((flag & VSH_BYUUID) && (strlen(n) == VIR_UUID_STRING_BUFLEN-1)) { vshDebug(ctl, 5, "%s: <%s> trying as nwfilter UUID\n", cmd->def->name, optname); - nwfilter = virNWFilterLookupByUUIDString(ctl->conn, n); + nwfilter = virNWFilterLookupByUUIDString(conn, n); } /* try it by NAME */ if (nwfilter == NULL && (flag & VSH_BYNAME)) { vshDebug(ctl, 5, "%s: <%s> trying as nwfilter NAME\n", cmd->def->name, optname); - nwfilter = virNWFilterLookupByName(ctl->conn, n); + nwfilter = virNWFilterLookupByName(conn, n); } if (!nwfilter) @@ -12585,13 +12586,13 @@ vshCommandOptInterfaceBy(vshControl *ctl, const vshCmd *cmd, if ((flag & VSH_BYNAME)) { vshDebug(ctl, 5, "%s: <%s> trying as interface NAME\n", cmd->def->name, optname); - iface = virInterfaceLookupByName(ctl->conn, n); + iface = virInterfaceLookupByName(conn, n); } /* try it by MAC */ if ((iface == NULL) && (flag & VSH_BYMAC)) { vshDebug(ctl, 5, "%s: <%s> trying as interface MAC\n", cmd->def->name, optname); - iface = virInterfaceLookupByMACString(ctl->conn, n); + iface = virInterfaceLookupByMACString(conn, n); } if (!iface) @@ -12620,13 +12621,13 @@ vshCommandOptPoolBy(vshControl *ctl, const vshCmd *cmd, const char *optname, if ((flag & VSH_BYUUID) && (strlen(n) == VIR_UUID_STRING_BUFLEN-1)) { vshDebug(ctl, 5, "%s: <%s> trying as pool UUID\n", cmd->def->name, optname); - pool = virStoragePoolLookupByUUIDString(ctl->conn, n); + pool = virStoragePoolLookupByUUIDString(conn, n); } /* try it by NAME */ if (pool == NULL && (flag & VSH_BYNAME)) { vshDebug(ctl, 5, "%s: <%s> trying as pool NAME\n", cmd->def->name, optname); - pool = virStoragePoolLookupByName(ctl->conn, n); + pool = virStoragePoolLookupByName(conn, n); } if (!pool) @@ -12672,13 +12673,13 @@ vshCommandOptVolBy(vshControl *ctl, const vshCmd *cmd, if (vol == NULL && (flag & VSH_BYUUID)) { vshDebug(ctl, 5, "%s: <%s> trying as vol key\n", cmd->def->name, optname); - vol = virStorageVolLookupByKey(ctl->conn, n); + vol = virStorageVolLookupByKey(conn, n); } /* try it by path */ if (vol == NULL && (flag & VSH_BYUUID)) { vshDebug(ctl, 5, "%s: <%s> trying as vol path\n", cmd->def->name, optname); - vol = virStorageVolLookupByPath(ctl->conn, n); + vol = virStorageVolLookupByPath(conn, n); } if (!vol) @@ -12708,7 +12709,7 @@ vshCommandOptSecret(vshControl *ctl, const vshCmd *cmd, const char **name) if (name != NULL) *name = n; - secret = virSecretLookupByUUIDString(ctl->conn, n); + secret = virSecretLookupByUUIDString(conn, n); if (secret == NULL) vshError(ctl, _("failed to get secret '%s'"), n); @@ -12728,7 +12729,7 @@ vshCommandRun(vshControl *ctl, const vshCmd *cmd) struct timeval before, after; bool enable_timing = ctl->timing; - if ((ctl->conn == NULL || disconnected) && + if ((conn == NULL || disconnected) && !(cmd->def->flags & VSH_CMD_FLAG_NOCONNECT)) vshReconnect(ctl); @@ -13252,7 +13253,7 @@ vshDomainVcpuStateToString(int state) } static bool -vshConnectionUsability(vshControl *ctl, virConnectPtr conn) +vshConnectionUsability(vshControl *ctl) { /* TODO: use something like virConnectionState() to * check usability of the connection @@ -13342,7 +13343,7 @@ vshInit(vshControl *ctl) { char *debugEnv; - if (ctl->conn) + if (conn) return false; if (ctl->debug == -1) { @@ -13378,9 +13379,9 @@ vshInit(vshControl *ctl) return false; if (ctl->name) { - ctl->conn = virConnectOpenAuth(ctl->name, - virConnectAuthPtrDefault, - ctl->readonly ? VIR_CONNECT_RO : 0); + conn = virConnectOpenAuth(ctl->name, + virConnectAuthPtrDefault, + ctl->readonly ? VIR_CONNECT_RO : 0); /* Connecting to a named connection must succeed, but we delay * connecting to the default connection until we need it @@ -13388,7 +13389,7 @@ vshInit(vshControl *ctl) * non-default connection, or might be 'help' which needs no * connection). */ - if (!ctl->conn) { + if (!conn) { virshReportError(ctl); vshError(ctl, "%s", _("failed to connect to the hypervisor")); return false; @@ -13768,9 +13769,9 @@ vshDeinit(vshControl *ctl) vshReadlineDeinit(ctl); vshCloseLogFile(ctl); VIR_FREE(ctl->name); - if (ctl->conn) { + if (conn) { int ret; - if ((ret = virConnectClose(ctl->conn)) != 0) { + if ((ret = virConnectClose(conn)) != 0) { vshError(ctl, _("Failed to disconnect from the hypervisor, %d leaked reference(s)"), ret); } } -- 1.7.5.rc3

On 07/04/2011 02:41 AM, Michal Privoznik wrote:
Since virsh is not multi-threaded,
Technically, virsh _is_ multi-threaded, in that it uses multiple threads in order to process Ctrl-C to abort a migration; however, in this instance, the main thread waits for the worker thread to complete, and there is no input processing that changes 'conn' during that time.
it is safe to have it as global variable.
At any rate, I still think this part of the claim is true; and if it ever changes, we can make conn a thread-local variable instead. However, if we do that, we will want to use an accessor method to get at the thread-local conn via portable code, rather than relying on gcc __thread extensions. So I would recommend a v2 of this patch:
This is going to be needed in some special cases where we can't change function prototype but want to have connection object accessible. --- tools/virsh.c | 555 +++++++++++++++++++++++++++++---------------------------- 1 files changed, 278 insertions(+), 277 deletions(-) @@ -242,6 +241,8 @@ typedef struct vshCmdGrp { const vshCmdDef *commands; } vshCmdGrp;
+virConnectPtr conn; /* connection to hypervisor (MAY BE NULL) */
Make this static. Just because it is global to the file doesn't mean that it has to be exported beyond the file. Then add: static virConnectPtr vshConn(void) { return conn; } and instead of doing s/ctl->conn/conn/, you instead do s/ctl->conn/vshConn()/. That way, if we ever need to make conn thread-local, only vshConn needs to change, rather than changing 200+ lines of callers to yet another convention. The bulk of this patch is mechanical, but I did spot a problem given my above preference for future-proofing our maintenance efforts: When updating the 'doMigrate' function, I would recommend modifying the struct __vshCtrlData to add a virConnectPtr member, and pass vshConn() through that struct rather than having doMigrate rely on the global conn (seeing as how if we ever change conn to be thread-safe, the doMigrate execution would be in a different thread than the primary thread that initialized conn). And that means that this change:
-static bool vshConnectionUsability(vshControl *ctl, virConnectPtr conn); +static bool vshConnectionUsability(vshControl *ctl);
is ill-advised. vshConnectionUsability is one of the functions called inside doMigrate, so it needs to operate on the virConnectPtr passed in as an argument rather than assuming that the current global 'conn' is correct. -- Eric Blake eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org

This commit introduces command-based completer. Any command can now have a completer, which will generate additional command arguments. Completer is called repeatedly until it returns NULL. On the first call, @state is non-zero. --- tools/virsh.c | 364 ++++++++++++++++++++++++++++++--------------------------- 1 files changed, 193 insertions(+), 171 deletions(-) diff --git a/tools/virsh.c b/tools/virsh.c index eeacec3..3dabb10 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -202,6 +202,7 @@ typedef struct { const vshCmdOptDef *opts; /* definition of command options */ const vshCmdInfo *info; /* details about command */ int flags; /* bitwise OR of VSH_CMD_FLAG */ + char * (*completer) (const char *, int); /* command completer */ } vshCmdDef; /* @@ -11614,272 +11615,285 @@ cleanup: static const vshCmdDef domManagementCmds[] = { {"attach-device", cmdAttachDevice, opts_attach_device, - info_attach_device, 0}, + info_attach_device, 0, NULL}, {"attach-disk", cmdAttachDisk, opts_attach_disk, - info_attach_disk, 0}, + info_attach_disk, 0, NULL}, {"attach-interface", cmdAttachInterface, opts_attach_interface, - info_attach_interface, 0}, - {"autostart", cmdAutostart, opts_autostart, info_autostart, 0}, - {"blkiotune", cmdBlkiotune, opts_blkiotune, info_blkiotune, 0}, + info_attach_interface, 0, NULL}, + {"autostart", cmdAutostart, opts_autostart, info_autostart, 0, NULL}, + {"blkiotune", cmdBlkiotune, opts_blkiotune, info_blkiotune, 0, NULL}, #ifndef WIN32 - {"console", cmdConsole, opts_console, info_console, 0}, + {"console", cmdConsole, opts_console, info_console, 0, NULL}, #endif - {"cpu-baseline", cmdCPUBaseline, opts_cpu_baseline, info_cpu_baseline, 0}, - {"cpu-compare", cmdCPUCompare, opts_cpu_compare, info_cpu_compare, 0}, - {"create", cmdCreate, opts_create, info_create, 0}, - {"define", cmdDefine, opts_define, info_define, 0}, - {"destroy", cmdDestroy, opts_destroy, info_destroy, 0}, + {"cpu-baseline", cmdCPUBaseline, opts_cpu_baseline, + info_cpu_baseline, 0, NULL}, + {"cpu-compare", cmdCPUCompare, opts_cpu_compare, info_cpu_compare, 0, NULL}, + {"create", cmdCreate, opts_create, info_create, 0, NULL}, + {"define", cmdDefine, opts_define, info_define, 0, NULL}, + {"destroy", cmdDestroy, opts_destroy, info_destroy, 0, NULL}, {"detach-device", cmdDetachDevice, opts_detach_device, - info_detach_device, 0}, - {"detach-disk", cmdDetachDisk, opts_detach_disk, info_detach_disk, 0}, + info_detach_device, 0, NULL}, + {"detach-disk", cmdDetachDisk, opts_detach_disk, info_detach_disk, 0, NULL}, {"detach-interface", cmdDetachInterface, opts_detach_interface, - info_detach_interface, 0}, - {"domid", cmdDomid, opts_domid, info_domid, 0}, - {"domjobabort", cmdDomjobabort, opts_domjobabort, info_domjobabort, 0}, - {"domjobinfo", cmdDomjobinfo, opts_domjobinfo, info_domjobinfo, 0}, - {"domname", cmdDomname, opts_domname, info_domname, 0}, - {"domuuid", cmdDomuuid, opts_domuuid, info_domuuid, 0}, + info_detach_interface, 0, NULL}, + {"domid", cmdDomid, opts_domid, info_domid, 0, NULL}, + {"domjobabort", cmdDomjobabort, opts_domjobabort, + info_domjobabort, 0, NULL}, + {"domjobinfo", cmdDomjobinfo, opts_domjobinfo, info_domjobinfo, 0, NULL}, + {"domname", cmdDomname, opts_domname, info_domname, 0, NULL}, + {"domuuid", cmdDomuuid, opts_domuuid, info_domuuid, 0, NULL}, {"domxml-from-native", cmdDomXMLFromNative, opts_domxmlfromnative, - info_domxmlfromnative, 0}, + info_domxmlfromnative, 0, NULL}, {"domxml-to-native", cmdDomXMLToNative, opts_domxmltonative, - info_domxmltonative, 0}, - {"dump", cmdDump, opts_dump, info_dump, 0}, - {"dumpxml", cmdDumpXML, opts_dumpxml, info_dumpxml, 0}, - {"edit", cmdEdit, opts_edit, info_edit, 0}, - {"inject-nmi", cmdInjectNMI, opts_inject_nmi, info_inject_nmi, 0}, - {"managedsave", cmdManagedSave, opts_managedsave, info_managedsave, 0}, + info_domxmltonative, 0, NULL}, + {"dump", cmdDump, opts_dump, info_dump, 0, NULL}, + {"dumpxml", cmdDumpXML, opts_dumpxml, info_dumpxml, 0, NULL}, + {"edit", cmdEdit, opts_edit, info_edit, 0, NULL}, + {"inject-nmi", cmdInjectNMI, opts_inject_nmi, info_inject_nmi, 0, NULL}, + {"managedsave", cmdManagedSave, opts_managedsave, + info_managedsave, 0, NULL}, {"managedsave-remove", cmdManagedSaveRemove, opts_managedsaveremove, - info_managedsaveremove, 0}, - {"maxvcpus", cmdMaxvcpus, opts_maxvcpus, info_maxvcpus, 0}, - {"memtune", cmdMemtune, opts_memtune, info_memtune, 0}, - {"migrate", cmdMigrate, opts_migrate, info_migrate, 0}, + info_managedsaveremove, 0, NULL}, + {"maxvcpus", cmdMaxvcpus, opts_maxvcpus, info_maxvcpus, 0, NULL}, + {"memtune", cmdMemtune, opts_memtune, info_memtune, 0, NULL}, + {"migrate", cmdMigrate, opts_migrate, info_migrate, 0, NULL}, {"migrate-setmaxdowntime", cmdMigrateSetMaxDowntime, - opts_migrate_setmaxdowntime, info_migrate_setmaxdowntime, 0}, + opts_migrate_setmaxdowntime, info_migrate_setmaxdowntime, 0, NULL}, {"migrate-setspeed", cmdMigrateSetMaxSpeed, - opts_migrate_setspeed, info_migrate_setspeed, 0}, - {"reboot", cmdReboot, opts_reboot, info_reboot, 0}, - {"restore", cmdRestore, opts_restore, info_restore, 0}, - {"resume", cmdResume, opts_resume, info_resume, 0}, - {"save", cmdSave, opts_save, info_save, 0}, - {"schedinfo", cmdSchedinfo, opts_schedinfo, info_schedinfo, 0}, - {"screenshot", cmdScreenshot, opts_screenshot, info_screenshot, 0}, - {"setmaxmem", cmdSetmaxmem, opts_setmaxmem, info_setmaxmem, 0}, - {"setmem", cmdSetmem, opts_setmem, info_setmem, 0}, - {"setvcpus", cmdSetvcpus, opts_setvcpus, info_setvcpus, 0}, - {"shutdown", cmdShutdown, opts_shutdown, info_shutdown, 0}, - {"start", cmdStart, opts_start, info_start, 0}, - {"suspend", cmdSuspend, opts_suspend, info_suspend, 0}, - {"ttyconsole", cmdTTYConsole, opts_ttyconsole, info_ttyconsole, 0}, - {"undefine", cmdUndefine, opts_undefine, info_undefine, 0}, + opts_migrate_setspeed, info_migrate_setspeed, 0, NULL}, + {"reboot", cmdReboot, opts_reboot, info_reboot, 0, NULL}, + {"restore", cmdRestore, opts_restore, info_restore, 0, NULL}, + {"resume", cmdResume, opts_resume, info_resume, 0, NULL}, + {"save", cmdSave, opts_save, info_save, 0, NULL}, + {"schedinfo", cmdSchedinfo, opts_schedinfo, info_schedinfo, 0, NULL}, + {"screenshot", cmdScreenshot, opts_screenshot, info_screenshot, 0, NULL}, + {"setmaxmem", cmdSetmaxmem, opts_setmaxmem, info_setmaxmem, 0, NULL}, + {"setmem", cmdSetmem, opts_setmem, info_setmem, 0, NULL}, + {"setvcpus", cmdSetvcpus, opts_setvcpus, info_setvcpus, 0, NULL}, + {"shutdown", cmdShutdown, opts_shutdown, info_shutdown, 0, NULL}, + {"start", cmdStart, opts_start, info_start, 0, NULL}, + {"suspend", cmdSuspend, opts_suspend, info_suspend, 0, NULL}, + {"ttyconsole", cmdTTYConsole, opts_ttyconsole, info_ttyconsole, 0, NULL}, + {"undefine", cmdUndefine, opts_undefine, info_undefine, 0, NULL}, {"update-device", cmdUpdateDevice, opts_update_device, - info_update_device, 0}, - {"vcpucount", cmdVcpucount, opts_vcpucount, info_vcpucount, 0}, - {"vcpuinfo", cmdVcpuinfo, opts_vcpuinfo, info_vcpuinfo, 0}, - {"vcpupin", cmdVcpuPin, opts_vcpupin, info_vcpupin, 0}, - {"version", cmdVersion, opts_version, info_version, 0}, - {"vncdisplay", cmdVNCDisplay, opts_vncdisplay, info_vncdisplay, 0}, - {NULL, NULL, NULL, NULL, 0} + info_update_device, 0, NULL}, + {"vcpucount", cmdVcpucount, opts_vcpucount, info_vcpucount, 0, NULL}, + {"vcpuinfo", cmdVcpuinfo, opts_vcpuinfo, info_vcpuinfo, 0, NULL}, + {"vcpupin", cmdVcpuPin, opts_vcpupin, info_vcpupin, 0, NULL}, + {"version", cmdVersion, opts_version, info_version, 0, NULL}, + {"vncdisplay", cmdVNCDisplay, opts_vncdisplay, info_vncdisplay, 0, NULL}, + {NULL, NULL, NULL, NULL, 0, NULL} }; static const vshCmdDef domMonitoringCmds[] = { - {"domblkinfo", cmdDomblkinfo, opts_domblkinfo, info_domblkinfo, 0}, - {"domblkstat", cmdDomblkstat, opts_domblkstat, info_domblkstat, 0}, - {"domcontrol", cmdDomControl, opts_domcontrol, info_domcontrol, 0}, - {"domifstat", cmdDomIfstat, opts_domifstat, info_domifstat, 0}, - {"dominfo", cmdDominfo, opts_dominfo, info_dominfo, 0}, - {"dommemstat", cmdDomMemStat, opts_dommemstat, info_dommemstat, 0}, - {"domstate", cmdDomstate, opts_domstate, info_domstate, 0}, - {"list", cmdList, opts_list, info_list, 0}, - {NULL, NULL, NULL, NULL, 0} + {"domblkinfo", cmdDomblkinfo, opts_domblkinfo, info_domblkinfo, 0, NULL}, + {"domblkstat", cmdDomblkstat, opts_domblkstat, info_domblkstat, 0, NULL}, + {"domcontrol", cmdDomControl, opts_domcontrol, info_domcontrol, 0, NULL}, + {"domifstat", cmdDomIfstat, opts_domifstat, info_domifstat, 0, NULL}, + {"dominfo", cmdDominfo, opts_dominfo, info_dominfo, 0, NULL}, + {"dommemstat", cmdDomMemStat, opts_dommemstat, info_dommemstat, 0, NULL}, + {"domstate", cmdDomstate, opts_domstate, info_domstate, 0, NULL}, + {"list", cmdList, opts_list, info_list, 0, NULL}, + {NULL, NULL, NULL, NULL, 0, NULL} }; static const vshCmdDef storagePoolCmds[] = { {"find-storage-pool-sources-as", cmdPoolDiscoverSourcesAs, - opts_find_storage_pool_sources_as, info_find_storage_pool_sources_as, 0}, + opts_find_storage_pool_sources_as, + info_find_storage_pool_sources_as, 0, NULL}, {"find-storage-pool-sources", cmdPoolDiscoverSources, - opts_find_storage_pool_sources, info_find_storage_pool_sources, 0}, + opts_find_storage_pool_sources, info_find_storage_pool_sources, 0, NULL}, {"pool-autostart", cmdPoolAutostart, opts_pool_autostart, - info_pool_autostart, 0}, - {"pool-build", cmdPoolBuild, opts_pool_build, info_pool_build, 0}, - {"pool-create-as", cmdPoolCreateAs, opts_pool_X_as, info_pool_create_as, 0}, - {"pool-create", cmdPoolCreate, opts_pool_create, info_pool_create, 0}, - {"pool-define-as", cmdPoolDefineAs, opts_pool_X_as, info_pool_define_as, 0}, - {"pool-define", cmdPoolDefine, opts_pool_define, info_pool_define, 0}, - {"pool-delete", cmdPoolDelete, opts_pool_delete, info_pool_delete, 0}, - {"pool-destroy", cmdPoolDestroy, opts_pool_destroy, info_pool_destroy, 0}, - {"pool-dumpxml", cmdPoolDumpXML, opts_pool_dumpxml, info_pool_dumpxml, 0}, - {"pool-edit", cmdPoolEdit, opts_pool_edit, info_pool_edit, 0}, - {"pool-info", cmdPoolInfo, opts_pool_info, info_pool_info, 0}, - {"pool-list", cmdPoolList, opts_pool_list, info_pool_list, 0}, - {"pool-name", cmdPoolName, opts_pool_name, info_pool_name, 0}, - {"pool-refresh", cmdPoolRefresh, opts_pool_refresh, info_pool_refresh, 0}, - {"pool-start", cmdPoolStart, opts_pool_start, info_pool_start, 0}, + info_pool_autostart, 0, NULL}, + {"pool-build", cmdPoolBuild, opts_pool_build, info_pool_build, 0, NULL}, + {"pool-create-as", cmdPoolCreateAs, opts_pool_X_as, + info_pool_create_as, 0, NULL}, + {"pool-create", cmdPoolCreate, opts_pool_create, info_pool_create, 0, NULL}, + {"pool-define-as", cmdPoolDefineAs, opts_pool_X_as, + info_pool_define_as, 0, NULL}, + {"pool-define", cmdPoolDefine, opts_pool_define, info_pool_define, 0, NULL}, + {"pool-delete", cmdPoolDelete, opts_pool_delete, info_pool_delete, 0, NULL}, + {"pool-destroy", cmdPoolDestroy, opts_pool_destroy, + info_pool_destroy, 0, NULL}, + {"pool-dumpxml", cmdPoolDumpXML, opts_pool_dumpxml, + info_pool_dumpxml, 0, NULL}, + {"pool-edit", cmdPoolEdit, opts_pool_edit, info_pool_edit, 0, NULL}, + {"pool-info", cmdPoolInfo, opts_pool_info, info_pool_info, 0, NULL}, + {"pool-list", cmdPoolList, opts_pool_list, info_pool_list, 0, NULL}, + {"pool-name", cmdPoolName, opts_pool_name, info_pool_name, 0, NULL}, + {"pool-refresh", cmdPoolRefresh, opts_pool_refresh, + info_pool_refresh, 0, NULL}, + {"pool-start", cmdPoolStart, opts_pool_start, info_pool_start, 0, NULL}, {"pool-undefine", cmdPoolUndefine, opts_pool_undefine, - info_pool_undefine, 0}, - {"pool-uuid", cmdPoolUuid, opts_pool_uuid, info_pool_uuid, 0}, - {NULL, NULL, NULL, NULL, 0} + info_pool_undefine, 0, NULL}, + {"pool-uuid", cmdPoolUuid, opts_pool_uuid, info_pool_uuid, 0, NULL}, + {NULL, NULL, NULL, NULL, 0, NULL} }; static const vshCmdDef storageVolCmds[] = { - {"vol-clone", cmdVolClone, opts_vol_clone, info_vol_clone, 0}, + {"vol-clone", cmdVolClone, opts_vol_clone, info_vol_clone, 0, NULL}, {"vol-create-as", cmdVolCreateAs, opts_vol_create_as, - info_vol_create_as, 0}, - {"vol-create", cmdVolCreate, opts_vol_create, info_vol_create, 0}, + info_vol_create_as, 0, NULL}, + {"vol-create", cmdVolCreate, opts_vol_create, info_vol_create, 0, NULL}, {"vol-create-from", cmdVolCreateFrom, opts_vol_create_from, - info_vol_create_from, 0}, - {"vol-delete", cmdVolDelete, opts_vol_delete, info_vol_delete, 0}, - {"vol-download", cmdVolDownload, opts_vol_download, info_vol_download, 0}, - {"vol-dumpxml", cmdVolDumpXML, opts_vol_dumpxml, info_vol_dumpxml, 0}, - {"vol-info", cmdVolInfo, opts_vol_info, info_vol_info, 0}, - {"vol-key", cmdVolKey, opts_vol_key, info_vol_key, 0}, - {"vol-list", cmdVolList, opts_vol_list, info_vol_list, 0}, - {"vol-name", cmdVolName, opts_vol_name, info_vol_name, 0}, - {"vol-path", cmdVolPath, opts_vol_path, info_vol_path, 0}, - {"vol-pool", cmdVolPool, opts_vol_pool, info_vol_pool, 0}, - {"vol-upload", cmdVolUpload, opts_vol_upload, info_vol_upload, 0}, - {"vol-wipe", cmdVolWipe, opts_vol_wipe, info_vol_wipe, 0}, - {NULL, NULL, NULL, NULL, 0} + info_vol_create_from, 0, NULL}, + {"vol-delete", cmdVolDelete, opts_vol_delete, info_vol_delete, 0, NULL}, + {"vol-download", cmdVolDownload, opts_vol_download, + info_vol_download, 0, NULL}, + {"vol-dumpxml", cmdVolDumpXML, opts_vol_dumpxml, info_vol_dumpxml, 0, NULL}, + {"vol-info", cmdVolInfo, opts_vol_info, info_vol_info, 0, NULL}, + {"vol-key", cmdVolKey, opts_vol_key, info_vol_key, 0, NULL}, + {"vol-list", cmdVolList, opts_vol_list, info_vol_list, 0, NULL}, + {"vol-name", cmdVolName, opts_vol_name, info_vol_name, 0, NULL}, + {"vol-path", cmdVolPath, opts_vol_path, info_vol_path, 0, NULL}, + {"vol-pool", cmdVolPool, opts_vol_pool, info_vol_pool, 0, NULL}, + {"vol-upload", cmdVolUpload, opts_vol_upload, info_vol_upload, 0, NULL}, + {"vol-wipe", cmdVolWipe, opts_vol_wipe, info_vol_wipe, 0, NULL}, + {NULL, NULL, NULL, NULL, 0, NULL} }; static const vshCmdDef networkCmds[] = { {"net-autostart", cmdNetworkAutostart, opts_network_autostart, - info_network_autostart, 0}, + info_network_autostart, 0, NULL}, {"net-create", cmdNetworkCreate, opts_network_create, - info_network_create, 0}, + info_network_create, 0, NULL}, {"net-define", cmdNetworkDefine, opts_network_define, - info_network_define, 0}, + info_network_define, 0, NULL}, {"net-destroy", cmdNetworkDestroy, opts_network_destroy, - info_network_destroy, 0}, + info_network_destroy, 0, NULL}, {"net-dumpxml", cmdNetworkDumpXML, opts_network_dumpxml, - info_network_dumpxml, 0}, - {"net-edit", cmdNetworkEdit, opts_network_edit, info_network_edit, 0}, - {"net-info", cmdNetworkInfo, opts_network_info, info_network_info, 0}, - {"net-list", cmdNetworkList, opts_network_list, info_network_list, 0}, - {"net-name", cmdNetworkName, opts_network_name, info_network_name, 0}, - {"net-start", cmdNetworkStart, opts_network_start, info_network_start, 0}, + info_network_dumpxml, 0, NULL}, + {"net-edit", cmdNetworkEdit, opts_network_edit, info_network_edit, 0, NULL}, + {"net-info", cmdNetworkInfo, opts_network_info, info_network_info, 0, NULL}, + {"net-list", cmdNetworkList, opts_network_list, info_network_list, 0, NULL}, + {"net-name", cmdNetworkName, opts_network_name, info_network_name, 0, NULL}, + {"net-start", cmdNetworkStart, opts_network_start, + info_network_start, 0, NULL}, {"net-undefine", cmdNetworkUndefine, opts_network_undefine, - info_network_undefine, 0}, - {"net-uuid", cmdNetworkUuid, opts_network_uuid, info_network_uuid, 0}, - {NULL, NULL, NULL, NULL, 0} + info_network_undefine, 0, NULL}, + {"net-uuid", cmdNetworkUuid, opts_network_uuid, info_network_uuid, 0, NULL}, + {NULL, NULL, NULL, NULL, 0, NULL} }; static const vshCmdDef nodedevCmds[] = { {"nodedev-create", cmdNodeDeviceCreate, opts_node_device_create, - info_node_device_create, 0}, + info_node_device_create, 0, NULL}, {"nodedev-destroy", cmdNodeDeviceDestroy, opts_node_device_destroy, - info_node_device_destroy, 0}, + info_node_device_destroy, 0, NULL}, {"nodedev-dettach", cmdNodeDeviceDettach, opts_node_device_dettach, - info_node_device_dettach, 0}, + info_node_device_dettach, 0, NULL}, {"nodedev-dumpxml", cmdNodeDeviceDumpXML, opts_node_device_dumpxml, - info_node_device_dumpxml, 0}, + info_node_device_dumpxml, 0, NULL}, {"nodedev-list", cmdNodeListDevices, opts_node_list_devices, - info_node_list_devices, 0}, + info_node_list_devices, 0, NULL}, {"nodedev-reattach", cmdNodeDeviceReAttach, opts_node_device_reattach, - info_node_device_reattach, 0}, + info_node_device_reattach, 0, NULL}, {"nodedev-reset", cmdNodeDeviceReset, opts_node_device_reset, - info_node_device_reset, 0}, - {NULL, NULL, NULL, NULL, 0} + info_node_device_reset, 0, NULL}, + {NULL, NULL, NULL, NULL, 0, NULL} }; static const vshCmdDef ifaceCmds[] = { {"iface-begin", cmdInterfaceBegin, opts_interface_begin, - info_interface_begin, 0}, + info_interface_begin, 0, NULL}, {"iface-commit", cmdInterfaceCommit, opts_interface_commit, - info_interface_commit, 0}, + info_interface_commit, 0, NULL}, {"iface-define", cmdInterfaceDefine, opts_interface_define, - info_interface_define, 0}, + info_interface_define, 0, NULL}, {"iface-destroy", cmdInterfaceDestroy, opts_interface_destroy, - info_interface_destroy, 0}, + info_interface_destroy, 0, NULL}, {"iface-dumpxml", cmdInterfaceDumpXML, opts_interface_dumpxml, - info_interface_dumpxml, 0}, + info_interface_dumpxml, 0, NULL}, {"iface-edit", cmdInterfaceEdit, opts_interface_edit, - info_interface_edit, 0}, + info_interface_edit, 0, NULL}, {"iface-list", cmdInterfaceList, opts_interface_list, - info_interface_list, 0}, + info_interface_list, 0, NULL}, {"iface-mac", cmdInterfaceMAC, opts_interface_mac, - info_interface_mac, 0}, + info_interface_mac, 0, NULL}, {"iface-name", cmdInterfaceName, opts_interface_name, - info_interface_name, 0}, + info_interface_name, 0, NULL}, {"iface-rollback", cmdInterfaceRollback, opts_interface_rollback, - info_interface_rollback, 0}, + info_interface_rollback, 0, NULL}, {"iface-start", cmdInterfaceStart, opts_interface_start, - info_interface_start, 0}, + info_interface_start, 0, NULL}, {"iface-undefine", cmdInterfaceUndefine, opts_interface_undefine, - info_interface_undefine, 0}, - {NULL, NULL, NULL, NULL, 0} + info_interface_undefine, 0, NULL}, + {NULL, NULL, NULL, NULL, 0, NULL} }; static const vshCmdDef nwfilterCmds[] = { {"nwfilter-define", cmdNWFilterDefine, opts_nwfilter_define, - info_nwfilter_define, 0}, + info_nwfilter_define, 0, NULL}, {"nwfilter-dumpxml", cmdNWFilterDumpXML, opts_nwfilter_dumpxml, - info_nwfilter_dumpxml, 0}, + info_nwfilter_dumpxml, 0, NULL}, {"nwfilter-edit", cmdNWFilterEdit, opts_nwfilter_edit, - info_nwfilter_edit, 0}, + info_nwfilter_edit, 0, NULL}, {"nwfilter-list", cmdNWFilterList, opts_nwfilter_list, - info_nwfilter_list, 0}, + info_nwfilter_list, 0, NULL}, {"nwfilter-undefine", cmdNWFilterUndefine, opts_nwfilter_undefine, - info_nwfilter_undefine, 0}, - {NULL, NULL, NULL, NULL, 0} + info_nwfilter_undefine, 0, NULL}, + {NULL, NULL, NULL, NULL, 0, NULL} }; static const vshCmdDef secretCmds[] = { {"secret-define", cmdSecretDefine, opts_secret_define, - info_secret_define, 0}, + info_secret_define, 0, NULL}, {"secret-dumpxml", cmdSecretDumpXML, opts_secret_dumpxml, - info_secret_dumpxml, 0}, + info_secret_dumpxml, 0, NULL}, {"secret-get-value", cmdSecretGetValue, opts_secret_get_value, - info_secret_get_value, 0}, - {"secret-list", cmdSecretList, NULL, info_secret_list, 0}, + info_secret_get_value, 0, NULL}, + {"secret-list", cmdSecretList, NULL, info_secret_list, 0, NULL}, {"secret-set-value", cmdSecretSetValue, opts_secret_set_value, - info_secret_set_value, 0}, + info_secret_set_value, 0, NULL}, {"secret-undefine", cmdSecretUndefine, opts_secret_undefine, - info_secret_undefine, 0}, - {NULL, NULL, NULL, NULL, 0} + info_secret_undefine, 0, NULL}, + {NULL, NULL, NULL, NULL, 0, NULL} }; static const vshCmdDef virshCmds[] = { - {"cd", cmdCd, opts_cd, info_cd, VSH_CMD_FLAG_NOCONNECT}, - {"echo", cmdEcho, opts_echo, info_echo, VSH_CMD_FLAG_NOCONNECT}, - {"exit", cmdQuit, NULL, info_quit, VSH_CMD_FLAG_NOCONNECT}, - {"help", cmdHelp, opts_help, info_help, VSH_CMD_FLAG_NOCONNECT}, - {"pwd", cmdPwd, NULL, info_pwd, VSH_CMD_FLAG_NOCONNECT}, - {"quit", cmdQuit, NULL, info_quit, VSH_CMD_FLAG_NOCONNECT}, - {NULL, NULL, NULL, NULL, 0} + {"cd", cmdCd, opts_cd, info_cd, VSH_CMD_FLAG_NOCONNECT, NULL}, + {"echo", cmdEcho, opts_echo, info_echo, VSH_CMD_FLAG_NOCONNECT, NULL}, + {"exit", cmdQuit, NULL, info_quit, VSH_CMD_FLAG_NOCONNECT, NULL}, + {"help", cmdHelp, opts_help, info_help, VSH_CMD_FLAG_NOCONNECT, NULL}, + {"pwd", cmdPwd, NULL, info_pwd, VSH_CMD_FLAG_NOCONNECT, NULL}, + {"quit", cmdQuit, NULL, info_quit, VSH_CMD_FLAG_NOCONNECT, NULL}, + {NULL, NULL, NULL, NULL, 0, NULL} }; static const vshCmdDef snapshotCmds[] = { {"snapshot-create", cmdSnapshotCreate, opts_snapshot_create, - info_snapshot_create, 0}, + info_snapshot_create, 0, NULL}, {"snapshot-create-as", cmdSnapshotCreateAs, opts_snapshot_create_as, - info_snapshot_create_as, 0}, + info_snapshot_create_as, 0, NULL}, {"snapshot-current", cmdSnapshotCurrent, opts_snapshot_current, - info_snapshot_current, 0}, + info_snapshot_current, 0, NULL}, {"snapshot-delete", cmdSnapshotDelete, opts_snapshot_delete, - info_snapshot_delete, 0}, + info_snapshot_delete, 0, NULL}, {"snapshot-dumpxml", cmdSnapshotDumpXML, opts_snapshot_dumpxml, - info_snapshot_dumpxml, 0}, + info_snapshot_dumpxml, 0, NULL}, {"snapshot-list", cmdSnapshotList, opts_snapshot_list, - info_snapshot_list, 0}, + info_snapshot_list, 0, NULL}, {"snapshot-revert", cmdDomainSnapshotRevert, opts_snapshot_revert, - info_snapshot_revert, 0}, - {NULL, NULL, NULL, NULL, 0} + info_snapshot_revert, 0, NULL}, + {NULL, NULL, NULL, NULL, 0, NULL} }; static const vshCmdDef hostAndHypervisorCmds[] = { - {"capabilities", cmdCapabilities, NULL, info_capabilities, 0}, + {"capabilities", cmdCapabilities, NULL, info_capabilities, 0, NULL}, {"connect", cmdConnect, opts_connect, info_connect, - VSH_CMD_FLAG_NOCONNECT}, - {"freecell", cmdFreecell, opts_freecell, info_freecell, 0}, - {"hostname", cmdHostname, NULL, info_hostname, 0}, - {"nodecpustats", cmdNodeCpuStats, opts_node_cpustats, info_nodecpustats, 0}, - {"nodeinfo", cmdNodeinfo, NULL, info_nodeinfo, 0}, - {"nodememstats", cmdNodeMemStats, opts_node_memstats, info_nodememstats, 0}, + VSH_CMD_FLAG_NOCONNECT, NULL}, + {"freecell", cmdFreecell, opts_freecell, info_freecell, 0, NULL}, + {"hostname", cmdHostname, NULL, info_hostname, 0, NULL}, + {"nodecpustats", cmdNodeCpuStats, opts_node_cpustats, + info_nodecpustats, 0, NULL}, + {"nodeinfo", cmdNodeinfo, NULL, info_nodeinfo, 0, NULL}, + {"nodememstats", cmdNodeMemStats, opts_node_memstats, + info_nodememstats, 0, NULL}, {"qemu-monitor-command", cmdQemuMonitorCommand, opts_qemu_monitor_command, - info_qemu_monitor_command, 0}, - {"sysinfo", cmdSysinfo, NULL, info_sysinfo, 0}, - {"uri", cmdURI, NULL, info_uri, 0}, - {NULL, NULL, NULL, NULL, 0} + info_qemu_monitor_command, 0, NULL}, + {"sysinfo", cmdSysinfo, NULL, info_sysinfo, 0, NULL}, + {"uri", cmdURI, NULL, info_uri, 0, NULL}, + {NULL, NULL, NULL, NULL, 0, NULL} }; static const vshCmdGrp cmdGroups[] = { @@ -13598,6 +13612,7 @@ vshReadlineOptionsGenerator(const char *text, int state) static int list_index, len; static const vshCmdDef *cmd = NULL; const char *name; + static char *completer_ret = NULL; if (!state) { /* determine command name */ @@ -13614,11 +13629,18 @@ vshReadlineOptionsGenerator(const char *text, int state) list_index = 0; len = strlen(text); VIR_FREE(cmdname); + if (cmd && cmd->completer && + ((completer_ret = cmd->completer(text, state)) != NULL)) + return completer_ret; } if (!cmd) return NULL; + if (cmd->completer && completer_ret && + ((completer_ret = cmd->completer(text, state)) != NULL)) + return completer_ret; + if (!cmd->opts) return NULL; -- 1.7.5.rc3

On 07/04/2011 02:41 AM, Michal Privoznik wrote:
This commit introduces command-based completer. Any command can now have a completer, which will generate additional command arguments. Completer is called repeatedly until it returns NULL. On the first call, @state is non-zero.
Don't you mean that on the first call, state is 0, and on subsequent calls, it is 1?
--- tools/virsh.c | 364 ++++++++++++++++++++++++++++++--------------------------- 1 files changed, 193 insertions(+), 171 deletions(-)
diff --git a/tools/virsh.c b/tools/virsh.c index eeacec3..3dabb10 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -202,6 +202,7 @@ typedef struct { const vshCmdOptDef *opts; /* definition of command options */ const vshCmdInfo *info; /* details about command */ int flags; /* bitwise OR of VSH_CMD_FLAG */ + char * (*completer) (const char *, int); /* command completer */ } vshCmdDef;
I'm still not convinced that this is the best approach. Let's look at patch 3/4, where one of the commands you changed was virsh attach-device, to use the listAllDomains completer:
{"attach-device", cmdAttachDevice, opts_attach_device, - info_attach_device, 0, NULL}, + info_attach_device, 0, complt_listAllDomains},
But attach-device has this synopsis: attach-device <domain> <file> [--persistent] That means, if I type: attach-device d<TAB> I get a list of all domains starting with d. But if I type: attach-device domain f<TAB> I would _still_ get a list of all domains starting with f, when what I _really_ want at that point is a list of a files in the current directory starting with f. Furthermore, if I type: attach-device -<TAB> I do _not_ get any indication that --domain, --file, or --persistent are also valid things to type at that point in the command, rather, it tries to give me a list of all domains starting with '-', even though to actually use such a domain, I would have to type an extra '--': attach-device -- -odd-domain Whereas if you go with my suggestion of having typed parameters, then attach-device does _not_ need a custom completer. Rather, it marks that the 'domain' option is a VSH_OT_DOMAIN_ALL, and the 'file' option is a VSH_OT_FILE. Then, attach-device d<TAB> says that since the argument does not start with '-', it must be the first data argument - and that data argument is typed VSH_OT_DOMAIN_ALL, so call complt_listDomainsFlags to get that list. Likewise, attach-device domain f<TAB> says that since we have already parsed an argument, the next argument must belong to the 'file' option, and we can use the normal readline file completion hook. Meanwhile, attach-device -<TAB> can see that the only valid thing here is an option name, and can thus cycle through the valid remaining options, to return the list '--domain', '--file', '--persistent'. And putting it all together, attach-device <TAB> can output the merged list of '--domain', '--file', '--persistent', as well as all domain names except for those that begin with '-'. At this point, I'm not seeing any utility in a per-function completer, when compared to a more generic utility in a per-option completer. -- Eric Blake eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org

This completer allows selection of active and/or inactive domains so only domains in valid state for a command are listed, e.g. only inactive for 'start' command, active for 'shutdown' and so on. --- tools/virsh.c | 250 +++++++++++++++++++++++++++++++++++++++++++++------------ 1 files changed, 199 insertions(+), 51 deletions(-) diff --git a/tools/virsh.c b/tools/virsh.c index 3dabb10..6a63363 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -600,6 +600,119 @@ vshReconnect(vshControl *ctl) } /* --------------- + * Completers + * --------------- + */ +#define ACTIVE (1<<0) +#define INACTIVE (1<<1) +static char * +complt_listDomainsFlags(const char *text ATTRIBUTE_UNUSED, int state, unsigned int flags) +{ + static int len = 0; + static int index_active = 0; + static int index_inactive = 0; + static int maxid = 0; + static int *ids = NULL; + static int maxname = 0; + static char **names = NULL; + char *ret; + + /* + * TODO: + * If we are not connected, should we connect here + * or simply return NULL and thus not complete 'live data'? + */ + if (!conn) + return NULL; + + if (!state) { + len = strlen(text); + maxid = 0; + maxname = 0; + + if (flags & ACTIVE) { + maxid = virConnectNumOfDomains(conn); + if (maxid < 0) + goto cleanup; + if (maxid) { + ids = vshMalloc(NULL, sizeof(int) * maxid); + if ((maxid = virConnectListDomains(conn, ids, maxid)) < 0) + goto cleanup; + + qsort(ids, maxid, sizeof(int), idsorter); + } + } + if (flags & INACTIVE) { + maxname = virConnectNumOfDefinedDomains(conn); + if (maxname < 0) + goto cleanup; + if (maxname) { + names = vshMalloc(NULL, sizeof(char *) * maxname); + if ((maxname = + virConnectListDefinedDomains(conn, names, maxname)) < 0) + goto cleanup; + + qsort(names, maxname, sizeof(char *), namesorter); + } + } + + index_active = 0; + index_inactive = 0; + } + + while (index_active < maxid) { + virDomainPtr dom = virDomainLookupByID(conn, ids[index_active]); + index_active++; + + if (!dom) + continue; + + ret = (char *) virDomainGetName(dom); + if (STRNEQLEN(ret, text, len)) { + virDomainFree(dom); + continue; + } + ret = vshStrdup(NULL, ret); + virDomainFree(dom); + + return ret; + } + + while (index_inactive < maxname) { + ret = names[index_inactive]; + index_inactive++; + + if (STREQLEN(ret, text, len)) + return ret; + + VIR_FREE(ret); + } + +cleanup: + VIR_FREE(ids); + VIR_FREE(names); + return NULL; +} + +static char * +complt_listActiveDomains(const char *text, int state) +{ + return complt_listDomainsFlags(text, state, ACTIVE); +} + +static char * +complt_listInactiveDomains(const char *text, int state) +{ + return complt_listDomainsFlags(text, state, INACTIVE); +} + +static char * +complt_listAllDomains(const char *text, int state) +{ + return complt_listDomainsFlags(text, state, ACTIVE | INACTIVE); +} + +/* --------------- * Commands * --------------- */ @@ -11615,84 +11728,119 @@ cleanup: static const vshCmdDef domManagementCmds[] = { {"attach-device", cmdAttachDevice, opts_attach_device, - info_attach_device, 0, NULL}, + info_attach_device, 0, complt_listAllDomains}, {"attach-disk", cmdAttachDisk, opts_attach_disk, - info_attach_disk, 0, NULL}, + info_attach_disk, 0, complt_listAllDomains}, {"attach-interface", cmdAttachInterface, opts_attach_interface, - info_attach_interface, 0, NULL}, - {"autostart", cmdAutostart, opts_autostart, info_autostart, 0, NULL}, - {"blkiotune", cmdBlkiotune, opts_blkiotune, info_blkiotune, 0, NULL}, + info_attach_interface, 0, complt_listAllDomains}, + {"autostart", cmdAutostart, opts_autostart, + info_autostart, 0, complt_listAllDomains}, + {"blkiotune", cmdBlkiotune, opts_blkiotune, + info_blkiotune, 0, complt_listAllDomains}, #ifndef WIN32 - {"console", cmdConsole, opts_console, info_console, 0, NULL}, + {"console", cmdConsole, opts_console, + info_console, 0, complt_listActiveDomains}, #endif {"cpu-baseline", cmdCPUBaseline, opts_cpu_baseline, info_cpu_baseline, 0, NULL}, {"cpu-compare", cmdCPUCompare, opts_cpu_compare, info_cpu_compare, 0, NULL}, {"create", cmdCreate, opts_create, info_create, 0, NULL}, {"define", cmdDefine, opts_define, info_define, 0, NULL}, - {"destroy", cmdDestroy, opts_destroy, info_destroy, 0, NULL}, + {"destroy", cmdDestroy, opts_destroy, + info_destroy, 0, complt_listActiveDomains}, {"detach-device", cmdDetachDevice, opts_detach_device, - info_detach_device, 0, NULL}, - {"detach-disk", cmdDetachDisk, opts_detach_disk, info_detach_disk, 0, NULL}, + info_detach_device, 0, complt_listAllDomains}, + {"detach-disk", cmdDetachDisk, opts_detach_disk, + info_detach_disk, 0, complt_listAllDomains}, {"detach-interface", cmdDetachInterface, opts_detach_interface, - info_detach_interface, 0, NULL}, - {"domid", cmdDomid, opts_domid, info_domid, 0, NULL}, + info_detach_interface, 0, complt_listAllDomains}, + {"domid", cmdDomid, opts_domid, info_domid, 0, complt_listActiveDomains}, {"domjobabort", cmdDomjobabort, opts_domjobabort, - info_domjobabort, 0, NULL}, - {"domjobinfo", cmdDomjobinfo, opts_domjobinfo, info_domjobinfo, 0, NULL}, - {"domname", cmdDomname, opts_domname, info_domname, 0, NULL}, - {"domuuid", cmdDomuuid, opts_domuuid, info_domuuid, 0, NULL}, + info_domjobabort, 0, complt_listActiveDomains}, + {"domjobinfo", cmdDomjobinfo, opts_domjobinfo, + info_domjobinfo, 0, complt_listActiveDomains}, + {"domname", cmdDomname, opts_domname, + info_domname, 0, complt_listAllDomains}, + {"domuuid", cmdDomuuid, opts_domuuid, + info_domuuid, 0, complt_listAllDomains}, {"domxml-from-native", cmdDomXMLFromNative, opts_domxmlfromnative, info_domxmlfromnative, 0, NULL}, {"domxml-to-native", cmdDomXMLToNative, opts_domxmltonative, info_domxmltonative, 0, NULL}, - {"dump", cmdDump, opts_dump, info_dump, 0, NULL}, - {"dumpxml", cmdDumpXML, opts_dumpxml, info_dumpxml, 0, NULL}, - {"edit", cmdEdit, opts_edit, info_edit, 0, NULL}, - {"inject-nmi", cmdInjectNMI, opts_inject_nmi, info_inject_nmi, 0, NULL}, + {"dump", cmdDump, opts_dump, info_dump, 0, complt_listActiveDomains}, + {"dumpxml", cmdDumpXML, opts_dumpxml, + info_dumpxml, 0, complt_listAllDomains}, + {"edit", cmdEdit, opts_edit, info_edit, 0, complt_listAllDomains}, + {"inject-nmi", cmdInjectNMI, opts_inject_nmi, + info_inject_nmi, 0, complt_listActiveDomains}, {"managedsave", cmdManagedSave, opts_managedsave, - info_managedsave, 0, NULL}, + info_managedsave, 0, complt_listActiveDomains}, {"managedsave-remove", cmdManagedSaveRemove, opts_managedsaveremove, - info_managedsaveremove, 0, NULL}, + info_managedsaveremove, 0, complt_listAllDomains}, {"maxvcpus", cmdMaxvcpus, opts_maxvcpus, info_maxvcpus, 0, NULL}, - {"memtune", cmdMemtune, opts_memtune, info_memtune, 0, NULL}, - {"migrate", cmdMigrate, opts_migrate, info_migrate, 0, NULL}, + {"memtune", cmdMemtune, opts_memtune, + info_memtune, 0, complt_listAllDomains}, + {"migrate", cmdMigrate, opts_migrate, + info_migrate, 0, complt_listAllDomains}, {"migrate-setmaxdowntime", cmdMigrateSetMaxDowntime, - opts_migrate_setmaxdowntime, info_migrate_setmaxdowntime, 0, NULL}, + opts_migrate_setmaxdowntime, info_migrate_setmaxdowntime, 0, + complt_listAllDomains}, {"migrate-setspeed", cmdMigrateSetMaxSpeed, - opts_migrate_setspeed, info_migrate_setspeed, 0, NULL}, - {"reboot", cmdReboot, opts_reboot, info_reboot, 0, NULL}, - {"restore", cmdRestore, opts_restore, info_restore, 0, NULL}, - {"resume", cmdResume, opts_resume, info_resume, 0, NULL}, - {"save", cmdSave, opts_save, info_save, 0, NULL}, - {"schedinfo", cmdSchedinfo, opts_schedinfo, info_schedinfo, 0, NULL}, - {"screenshot", cmdScreenshot, opts_screenshot, info_screenshot, 0, NULL}, - {"setmaxmem", cmdSetmaxmem, opts_setmaxmem, info_setmaxmem, 0, NULL}, - {"setmem", cmdSetmem, opts_setmem, info_setmem, 0, NULL}, - {"setvcpus", cmdSetvcpus, opts_setvcpus, info_setvcpus, 0, NULL}, - {"shutdown", cmdShutdown, opts_shutdown, info_shutdown, 0, NULL}, - {"start", cmdStart, opts_start, info_start, 0, NULL}, - {"suspend", cmdSuspend, opts_suspend, info_suspend, 0, NULL}, - {"ttyconsole", cmdTTYConsole, opts_ttyconsole, info_ttyconsole, 0, NULL}, - {"undefine", cmdUndefine, opts_undefine, info_undefine, 0, NULL}, + opts_migrate_setspeed, info_migrate_setspeed, 0, complt_listAllDomains}, + {"reboot", cmdReboot, opts_reboot, + info_reboot, 0, complt_listActiveDomains}, + {"restore", cmdRestore, opts_restore, + info_restore, 0, complt_listInactiveDomains}, + {"resume", cmdResume, opts_resume, + info_resume, 0, complt_listActiveDomains}, + {"save", cmdSave, opts_save, info_save, 0, complt_listActiveDomains}, + {"schedinfo", cmdSchedinfo, opts_schedinfo, + info_schedinfo, 0, complt_listAllDomains}, + {"screenshot", cmdScreenshot, opts_screenshot, + info_screenshot, 0, complt_listActiveDomains}, + {"setmaxmem", cmdSetmaxmem, opts_setmaxmem, + info_setmaxmem, 0, complt_listAllDomains}, + {"setmem", cmdSetmem, opts_setmem, info_setmem, 0, complt_listAllDomains}, + {"setvcpus", cmdSetvcpus, opts_setvcpus, + info_setvcpus, 0, complt_listAllDomains}, + {"shutdown", cmdShutdown, opts_shutdown, + info_shutdown, 0, complt_listActiveDomains}, + {"start", cmdStart, opts_start, info_start, 0, complt_listInactiveDomains}, + {"suspend", cmdSuspend, opts_suspend, + info_suspend, 0, complt_listActiveDomains}, + {"ttyconsole", cmdTTYConsole, opts_ttyconsole, + info_ttyconsole, 0, complt_listActiveDomains}, + {"undefine", cmdUndefine, opts_undefine, + info_undefine, 0, complt_listInactiveDomains}, {"update-device", cmdUpdateDevice, opts_update_device, - info_update_device, 0, NULL}, - {"vcpucount", cmdVcpucount, opts_vcpucount, info_vcpucount, 0, NULL}, - {"vcpuinfo", cmdVcpuinfo, opts_vcpuinfo, info_vcpuinfo, 0, NULL}, - {"vcpupin", cmdVcpuPin, opts_vcpupin, info_vcpupin, 0, NULL}, + info_update_device, 0, complt_listAllDomains}, + {"vcpucount", cmdVcpucount, opts_vcpucount, + info_vcpucount, 0, complt_listAllDomains}, + {"vcpuinfo", cmdVcpuinfo, opts_vcpuinfo, + info_vcpuinfo, 0, complt_listAllDomains}, + {"vcpupin", cmdVcpuPin, opts_vcpupin, + info_vcpupin, 0, complt_listAllDomains}, {"version", cmdVersion, opts_version, info_version, 0, NULL}, - {"vncdisplay", cmdVNCDisplay, opts_vncdisplay, info_vncdisplay, 0, NULL}, + {"vncdisplay", cmdVNCDisplay, opts_vncdisplay, + info_vncdisplay, 0, complt_listActiveDomains}, {NULL, NULL, NULL, NULL, 0, NULL} }; static const vshCmdDef domMonitoringCmds[] = { - {"domblkinfo", cmdDomblkinfo, opts_domblkinfo, info_domblkinfo, 0, NULL}, - {"domblkstat", cmdDomblkstat, opts_domblkstat, info_domblkstat, 0, NULL}, - {"domcontrol", cmdDomControl, opts_domcontrol, info_domcontrol, 0, NULL}, - {"domifstat", cmdDomIfstat, opts_domifstat, info_domifstat, 0, NULL}, - {"dominfo", cmdDominfo, opts_dominfo, info_dominfo, 0, NULL}, - {"dommemstat", cmdDomMemStat, opts_dommemstat, info_dommemstat, 0, NULL}, - {"domstate", cmdDomstate, opts_domstate, info_domstate, 0, NULL}, + {"domblkinfo", cmdDomblkinfo, opts_domblkinfo, + info_domblkinfo, 0, complt_listActiveDomains}, + {"domblkstat", cmdDomblkstat, opts_domblkstat, + info_domblkstat, 0, complt_listActiveDomains}, + {"domcontrol", cmdDomControl, opts_domcontrol, + info_domcontrol, 0, complt_listActiveDomains}, + {"domifstat", cmdDomIfstat, opts_domifstat, + info_domifstat, 0, complt_listActiveDomains}, + {"dominfo", cmdDominfo, opts_dominfo, + info_dominfo, 0, complt_listAllDomains}, + {"dommemstat", cmdDomMemStat, opts_dommemstat, + info_dommemstat, 0, complt_listActiveDomains}, + {"domstate", cmdDomstate, opts_domstate, + info_domstate, 0, complt_listAllDomains}, {"list", cmdList, opts_list, info_list, 0, NULL}, {NULL, NULL, NULL, NULL, 0, NULL} }; -- 1.7.5.rc3

On 07/04/2011 02:41 AM, Michal Privoznik wrote:
This completer allows selection of active and/or inactive domains so only domains in valid state for a command are listed, e.g. only inactive for 'start' command, active for 'shutdown' and so on. --- tools/virsh.c | 250 +++++++++++++++++++++++++++++++++++++++++++++------------ 1 files changed, 199 insertions(+), 51 deletions(-)
diff --git a/tools/virsh.c b/tools/virsh.c index 3dabb10..6a63363 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -600,6 +600,119 @@ vshReconnect(vshControl *ctl) }
/* --------------- + * Completers + * --------------- + */ +#define ACTIVE (1<<0) +#define INACTIVE (1<<1) +static char * +complt_listDomainsFlags(const char *text ATTRIBUTE_UNUSED, int state, unsigned int flags) +{
This function might still be useful, even if you change to having per-option completers instead of per-command completers. You _need_ to pay attention to 'text' - if I type: start d<TAB> then I want _only_ the domains whose names start with d, which you can only know if you read 'text' to see that input left off with a starting 'd'. Also, if 'text' starts off at the beginning of a word, you want a flag that says whether to include or filter out domain names that happen to start with '-' (if I type start --domain -<TAB> then list only domains starting with dash, whereas if I type start <TAB> then listing a domain name starting with dash would be wrong because it would be in a position that would be interpreted as an option rather than a domain name).
+ static int len = 0; + static int index_active = 0; + static int index_inactive = 0; + static int maxid = 0; + static int *ids = NULL; + static int maxname = 0; + static char **names = NULL; + char *ret;
That's a lot of static variables. If we ever need to go thread-local, it would be easier to create a single struct, and malloc a thread-local instance of that struct. But for now this is probably okay; it's not as severe as the patch 1/4 where going thread-local would affect all callers.
+ + /* + * TODO: + * If we are not connected, should we connect here + * or simply return NULL and thus not complete 'live data'? + */ + if (!conn) + return NULL;
Hmm. In most cases, we can then reuse the connection. Besides, when I type: start d<TAB> I don't want the behavior to depend on whether I have run a previous command that opened a connection. But in reality, maybe the thing to do is to return NULL here if conn is not already established, and instead teach the generic completion that it should autoconnect if attempting completion on a command that itself is marked auto-connect. That is, virsh help <TAB> should _not_ open a connection, since cmdHelp is marked VSH_CMD_FLAG_NOCONNECT, but: virsh start <TAB> is fine opening the connection, since cmdStart would have also opened the connection, and will happily reuse an already-open connection. Furthermore, this integrates well into the fact that we (eventually) need to add a completion command: virsh start d<TAB> would be hooked to a bash completion function that calls: virsh complete 'start d' where the new cmdComplete is marked VSH_CMD_FLAG_NOCONNECT (that is, it does not connect on its own), but which will auto-connect if it detects that it is being used to generate the completion of some other command that would normally autoconnect.
+ + if (!state) { + len = strlen(text); + maxid = 0; + maxname = 0; + + if (flags & ACTIVE) { + maxid = virConnectNumOfDomains(conn); + if (maxid < 0) + goto cleanup; + if (maxid) { + ids = vshMalloc(NULL, sizeof(int) * maxid); + if ((maxid = virConnectListDomains(conn, ids, maxid)) < 0) + goto cleanup; + + qsort(ids, maxid, sizeof(int), idsorter); + } + } + if (flags & INACTIVE) { + maxname = virConnectNumOfDefinedDomains(conn); + if (maxname < 0) + goto cleanup; + if (maxname) { + names = vshMalloc(NULL, sizeof(char *) * maxname); + if ((maxname = + virConnectListDefinedDomains(conn, names, maxname)) < 0) + goto cleanup; + + qsort(names, maxname, sizeof(char *), namesorter);
Why are we sorting here? Either readline sorts as well (and this is redundant), or if we are generating per-option completions, then we might be merging this return list into a larger list of other possible completions, at which point we would want that overall list sorted by the generic completion handler rather than just here.
+ } + } + + index_active = 0; + index_inactive = 0; + } + + while (index_active < maxid) { + virDomainPtr dom = virDomainLookupByID(conn, ids[index_active]); + index_active++; + + if (!dom) + continue; + + ret = (char *) virDomainGetName(dom); + if (STRNEQLEN(ret, text, len)) {
What happens if the domain disappears between the time that you gathered the list and now that you call virDomainGetName()? STRNEQLEN is not very forgiving of a NULL (ret) parameter. In that case, the best thing to do would be just skipping that index, and going on to the next one. It seems odd to me to be reusing 'ret' here with a cast to (char*), for what is really 'const char *' data, especially since...
+ virDomainFree(dom); + continue; + } + ret = vshStrdup(NULL, ret);
here, you have to malloc ret into a real 'char *' data to meet the rl_completion generator contract. It seems like using a secondary declaration const char *name = virDomainGetName(dom) might be wiser.
@@ -11615,84 +11728,119 @@ cleanup:
static const vshCmdDef domManagementCmds[] = { {"attach-device", cmdAttachDevice, opts_attach_device, - info_attach_device, 0, NULL}, + info_attach_device, 0, complt_listAllDomains},
See my comments on 2/4 why I think this is the wrong place to be using the new completion function. -- Eric Blake eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org

This completer returns command names and group keywords as well. --- tools/virsh.c | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 42 insertions(+), 1 deletions(-) diff --git a/tools/virsh.c b/tools/virsh.c index 6a63363..f30d51c 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -712,6 +712,46 @@ complt_listAllDomains(const char *text, int state) return complt_listDomainsFlags(text, state, ACTIVE | INACTIVE); } +static char * +complt_listCmdsAndGroups(const char *text, int state) +{ + static int len = 0; + static int grp_index = 0; + static const char *ret = NULL; + static const vshCmdGrp *g = NULL; + static const vshCmdDef *c = NULL; + + if (!state) { + len = strlen(text); + grp_index = 0; + g = cmdGroups; + c = g->commands; + } + + while ((ret = cmdGroups[grp_index].keyword)) { + grp_index++; + + if (STRNEQLEN(ret, text, len)) + continue; + + return vshStrdup(NULL, ret); + } + + while(g->name) { + while ((ret = c->name)) { + c++; + if (STRNEQLEN(ret, text, len)) + continue; + + return vshStrdup(NULL, ret); + } + g++; + c = g->commands; + } + + return NULL; +} + /* --------------- * Commands * --------------- @@ -12002,7 +12042,8 @@ static const vshCmdDef virshCmds[] = { {"cd", cmdCd, opts_cd, info_cd, VSH_CMD_FLAG_NOCONNECT, NULL}, {"echo", cmdEcho, opts_echo, info_echo, VSH_CMD_FLAG_NOCONNECT, NULL}, {"exit", cmdQuit, NULL, info_quit, VSH_CMD_FLAG_NOCONNECT, NULL}, - {"help", cmdHelp, opts_help, info_help, VSH_CMD_FLAG_NOCONNECT, NULL}, + {"help", cmdHelp, opts_help, info_help, + VSH_CMD_FLAG_NOCONNECT, complt_listCmdsAndGroups}, {"pwd", cmdPwd, NULL, info_pwd, VSH_CMD_FLAG_NOCONNECT, NULL}, {"quit", cmdQuit, NULL, info_quit, VSH_CMD_FLAG_NOCONNECT, NULL}, {NULL, NULL, NULL, NULL, 0, NULL} -- 1.7.5.rc3

On 07/04/2011 02:41 AM, Michal Privoznik wrote:
This completer returns command names and group keywords as well. --- tools/virsh.c | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 42 insertions(+), 1 deletions(-)
diff --git a/tools/virsh.c b/tools/virsh.c index 6a63363..f30d51c 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -712,6 +712,46 @@ complt_listAllDomains(const char *text, int state) return complt_listDomainsFlags(text, state, ACTIVE | INACTIVE); }
+static char * +complt_listCmdsAndGroups(const char *text, int state)
This function is nice,
@@ -12002,7 +12042,8 @@ static const vshCmdDef virshCmds[] = { {"cd", cmdCd, opts_cd, info_cd, VSH_CMD_FLAG_NOCONNECT, NULL}, {"echo", cmdEcho, opts_echo, info_echo, VSH_CMD_FLAG_NOCONNECT, NULL}, {"exit", cmdQuit, NULL, info_quit, VSH_CMD_FLAG_NOCONNECT, NULL}, - {"help", cmdHelp, opts_help, info_help, VSH_CMD_FLAG_NOCONNECT, NULL}, + {"help", cmdHelp, opts_help, info_help, + VSH_CMD_FLAG_NOCONNECT, complt_listCmdsAndGroups},
but rather than tying it to cmdHelp, I think it makes more sense to tie it to a VSH_OT_COMMAND option type. -- Eric Blake eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org
participants (2)
-
Eric Blake
-
Michal Privoznik