+
+ /* Get the number of active networks */
+ if (!MATCH(VIR_CONNECT_LIST_NETWORKS_FILTERS_ACTIVE) ||
+ MATCH(VIR_CONNECT_LIST_NETWORKS_ACTIVE)) {
+ if ((nActiveNets = virConnectNumOfNetworks(ctl->conn))< 0) {
+ vshError(ctl, "%s", _("Failed to get the number of active networks"));
+ goto cleanup;
+ }
+ }
+
+ /* Get the number of inactive networks */
+ if (!MATCH(VIR_CONNECT_LIST_NETWORKS_FILTERS_ACTIVE) ||
+ MATCH(VIR_CONNECT_LIST_NETWORKS_INACTIVE)) {
+ if ((nInactiveNets = virConnectNumOfDefinedNetworks(ctl->conn))< 0) {
+ vshError(ctl, "%s", _("Failed to get the number of inactive networks"));
+ goto cleanup;
+ }
+ }
+
+ nAllNets = nActiveNets + nInactiveNets;
+
+ if (nAllNets == 0)
+ return list;
+
+ names = vshMalloc(ctl, sizeof(char *) * nAllNets);
+
+ /* Retrieve a list of active network names */
+ if (!MATCH(VIR_CONNECT_LIST_NETWORKS_FILTERS_ACTIVE) ||
+ MATCH(VIR_CONNECT_LIST_NETWORKS_ACTIVE)) {
+ if (virConnectListNetworks(ctl->conn,
+ names, nActiveNets)< 0) {
+ vshError(ctl, "%s", _("Failed to list active networks"));
+ goto cleanup;
+ }
+ }
+
+ /* Add the inactive networks to the end of the name list */
+ if (!MATCH(VIR_CONNECT_LIST_NETWORKS_FILTERS_ACTIVE) ||
+ MATCH(VIR_CONNECT_LIST_NETWORKS_ACTIVE)) {
+ if (virConnectListDefinedNetworks(ctl->conn,
+&names[nActiveNets],
+ nInactiveNets)< 0) {
+ vshError(ctl, "%s", _("Failed to list inactive networks"));
+ goto cleanup;
+ }
+ }
+
+ list->nets = vshMalloc(ctl, sizeof(virNetworkPtr) * (nAllNets));
+ list->nnets = 0;
+
+ /* get active networks */
+ for (i = 0; i< nActiveNets; i++) {
+ if (!(net = virNetworkLookupByName(ctl->conn, names[i])))
+ continue;
+ list->nets[list->nnets++] = net;
+ }
+
+ /* get inactive networks */
+ for (i = 0; i< nInactiveNets; i++) {
+ if (!(net = virNetworkLookupByName(ctl->conn, names[i])))
+ continue;
+ list->nets[list->nnets++] = net;
+ }
+
+ /* truncate networks that weren't found */
+ deleted = nAllNets - list->nnets;
+
+filter:
+ /* filter list the list if the list was acquired by fallback means */
+ for (i = 0; i< list->nnets; i++) {
+ net = list->nets[i];
+
+ /* persistence filter */
+ if (MATCH(VIR_CONNECT_LIST_NETWORKS_FILTERS_PERSISTENT)) {
+ if ((persistent = virNetworkIsPersistent(net))< 0) {
+ vshError(ctl, "%s", _("Failed to get network persistence info"));
+ goto cleanup;
+ }
+
+ if (!((MATCH(VIR_CONNECT_LIST_NETWORKS_PERSISTENT)&& persistent) ||
+ (MATCH(VIR_CONNECT_LIST_NETWORKS_TRANSIENT)&& !persistent)))
+ goto remove_entry;
+ }
+
+ /* autostart filter */
+ if (MATCH(VIR_CONNECT_LIST_NETWORKS_FILTERS_AUTOSTART)) {
+ if (virNetworkGetAutostart(net,&autostart)< 0) {
+ vshError(ctl, "%s", _("Failed to get network autostart state"));
+ goto cleanup;
+ }
+
+ if (!((MATCH(VIR_CONNECT_LIST_NETWORKS_AUTOSTART)&& autostart) ||
+ (MATCH(VIR_CONNECT_LIST_NETWORKS_NO_AUTOSTART)&& !autostart)))
+ goto remove_entry;
+ }
+ /* the pool matched all filters, it may stay */
+ continue;
+
+remove_entry:
+ /* the pool has to be removed as it failed one of the filters */
+ virNetworkFree(list->nets[i]);
+ list->nets[i] = NULL;
+ deleted++;
+ }
+
+finished:
+ /* sort the list */
+ if (list->nets&& list->nnets)
+ qsort(list->nets, list->nnets,
+ sizeof(*list->nets), vshNetworkSorter);
+
+ /* truncate the list if filter simulation deleted entries */
+ if (deleted)
+ VIR_SHRINK_N(list->nets, list->nnets, deleted);
+
+ success = true;
+
+cleanup:
+ for (i = 0; i< nAllNets; i++)
+ VIR_FREE(names[i]);
+ VIR_FREE(names);
+
+ if (!success) {
+ vshNetworkListFree(list);
+ list = NULL;
+ }
+
+ return list;
+}
+
/*
* "net-list" command
*/
@@ -354,114 +574,70 @@ static const vshCmdInfo info_network_list[] = {
static const vshCmdOptDef opts_network_list[] = {
{"inactive", VSH_OT_BOOL, 0, N_("list inactive networks")},
{"all", VSH_OT_BOOL, 0, N_("list inactive& active networks")},
+ {"persistent", VSH_OT_BOOL, 0, N_("list persistent networks")},
+ {"transient", VSH_OT_BOOL, 0, N_("list transient networks")},
+ {"autostart", VSH_OT_BOOL, 0, N_("list networks with autostart enabled")},
+ {"no-autostart", VSH_OT_BOOL, 0, N_("list networks with autostart disabled")},
{NULL, 0, 0, NULL}
};
static bool
cmdNetworkList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
{
+ vshNetworkListPtr list = NULL;
+ int i;
bool inactive = vshCommandOptBool(cmd, "inactive");
bool all = vshCommandOptBool(cmd, "all");
- bool active = !inactive || all;
- int maxactive = 0, maxinactive = 0, i;
- char **activeNames = NULL, **inactiveNames = NULL;
- inactive |= all;
-
- if (active) {
- maxactive = virConnectNumOfNetworks(ctl->conn);
- if (maxactive< 0) {
- vshError(ctl, "%s", _("Failed to list active networks"));
- return false;
- }
- if (maxactive) {
- activeNames = vshMalloc(ctl, sizeof(char *) * maxactive);
-
- if ((maxactive = virConnectListNetworks(ctl->conn, activeNames,
- maxactive))< 0) {
- vshError(ctl, "%s", _("Failed to list active networks"));
- VIR_FREE(activeNames);
- return false;
- }
+ bool persistent = vshCommandOptBool(cmd, "persistent");
+ bool transient = vshCommandOptBool(cmd, "transient");
+ bool autostart = vshCommandOptBool(cmd, "autostart");
+ bool no_autostart = vshCommandOptBool(cmd, "no-autostart");
+ unsigned int flags = VIR_CONNECT_LIST_NETWORKS_ACTIVE;
- qsort(&activeNames[0], maxactive, sizeof(char *), vshNameSorter);
- }
- }
- if (inactive) {
- maxinactive = virConnectNumOfDefinedNetworks(ctl->conn);
- if (maxinactive< 0) {
- vshError(ctl, "%s", _("Failed to list inactive networks"));
- VIR_FREE(activeNames);
- return false;
- }
- if (maxinactive) {
- inactiveNames = vshMalloc(ctl, sizeof(char *) * maxinactive);
-
- if ((maxinactive =
- virConnectListDefinedNetworks(ctl->conn, inactiveNames,
- maxinactive))< 0) {
- vshError(ctl, "%s", _("Failed to list inactive networks"));
- VIR_FREE(activeNames);
- VIR_FREE(inactiveNames);
- return false;
- }
+ if (inactive)
+ flags = VIR_CONNECT_LIST_NETWORKS_INACTIVE;
- qsort(&inactiveNames[0], maxinactive, sizeof(char*), vshNameSorter);
- }
- }
- vshPrintExtra(ctl, "%-20s %-10s %s\n", _("Name"), _("State"),
- _("Autostart"));
- vshPrintExtra(ctl, "-----------------------------------------\n");
+ if (all)
+ flags = VIR_CONNECT_LIST_NETWORKS_ACTIVE |
+ VIR_CONNECT_LIST_NETWORKS_INACTIVE;
- for (i = 0; i< maxactive; i++) {
- virNetworkPtr network =
- virNetworkLookupByName(ctl->conn, activeNames[i]);
- const char *autostartStr;
- int autostart = 0;
+ if (persistent)
+ flags |= VIR_CONNECT_LIST_NETWORKS_PERSISTENT;
- /* this kind of work with networks is not atomic operation */
- if (!network) {
- VIR_FREE(activeNames[i]);
- continue;
- }
+ if (transient)
+ flags |= VIR_CONNECT_LIST_NETWORKS_TRANSIENT;
- if (virNetworkGetAutostart(network,&autostart)< 0)
- autostartStr = _("no autostart");
- else
- autostartStr = autostart ? _("yes") : _("no");
+ if (autostart)
+ flags |= VIR_CONNECT_LIST_NETWORKS_AUTOSTART;
- vshPrint(ctl, "%-20s %-10s %-10s\n",
- virNetworkGetName(network),
- _("active"),
- autostartStr);
- virNetworkFree(network);
- VIR_FREE(activeNames[i]);
- }
- for (i = 0; i< maxinactive; i++) {
- virNetworkPtr network = virNetworkLookupByName(ctl->conn, inactiveNames[i]);
- const char *autostartStr;
- int autostart = 0;
+ if (no_autostart)
+ flags |= VIR_CONNECT_LIST_NETWORKS_NO_AUTOSTART;
- /* this kind of work with networks is not atomic operation */
- if (!network) {
- VIR_FREE(inactiveNames[i]);
- continue;
- }
+ if (!(list = vshNetworkListCollect(ctl, flags)))
+ return false;
+
+ vshPrintExtra(ctl, "%-20s %-10s %-13s %s\n", _("Name"), _("State"),
+ _("Autostart"), _("Persistent"));
+ vshPrintExtra(ctl, "--------------------------------------------------\n");