On 09/05/12 08:02, Osier Yang wrote:
tools/virsh-nwfilter.c:
* vshNWFilterSorter to sort network filters by name
* vshNWFilterListFree to free the network filter objects list.
* vshNWFilterListCollect to collect the network filter objects, trying
to use new API first, fall back to older APIs if it's not supported.
---
tools/virsh-nwfilter.c | 163 +++++++++++++++++++++++++++++++++++++++---------
1 files changed, 134 insertions(+), 29 deletions(-)
diff --git a/tools/virsh-nwfilter.c b/tools/virsh-nwfilter.c
index 5169d38..57cf2b7 100644
--- a/tools/virsh-nwfilter.c
+++ b/tools/virsh-nwfilter.c
@@ -190,6 +190,134 @@ cmdNWFilterDumpXML(vshControl *ctl, const vshCmd *cmd)
return ret;
}
+static int
+vshNWFilterSorter(const void *a, const void *b)
+{
+ virNWFilterPtr *fa = (virNWFilterPtr *) a;
+ virNWFilterPtr *fb = (virNWFilterPtr *) b;
+
+ if (*fa && !*fb)
+ return -1;
+
+ if (!*fa)
+ return *fb != NULL;
+
+ return vshStrcasecmp(virNWFilterGetName(*fa),
+ virNWFilterGetName(*fb));
Bad indentation.
+}
+
+struct vshNWFilterList {
+ virNWFilterPtr *filters;
+ size_t nfilters;
+};
+typedef struct vshNWFilterList *vshNWFilterListPtr;
+
+static void
+vshNWFilterListFree(vshNWFilterListPtr list)
+{
+ int i;
+
+ if (list && list->nfilters) {
+ for (i = 0; i < list->nfilters; i++) {
+ if (list->filters[i])
+ virNWFilterFree(list->filters[i]);
+ }
+ VIR_FREE(list->filters);
+ }
+ VIR_FREE(list);
+}
+
+static vshNWFilterListPtr
+vshNWFilterListCollect(vshControl *ctl,
+ unsigned int flags)
+{
+ vshNWFilterListPtr list = vshMalloc(ctl, sizeof(*list));
+ int i;
+ int ret;
+ virNWFilterPtr filter;
+ bool success = false;
+ size_t deleted = 0;
+ int nfilters = 0;
+ char **names = NULL;
+
+ /* try the list with flags support (0.10.2 and later) */
+ if ((ret = virConnectListAllNWFilters(ctl->conn,
+ &list->filters,
+ flags)) >= 0) {
+ list->nfilters = ret;
+ goto finished;
+ }
+
+ /* check if the command is actually supported */
+ if (last_error && last_error->code == VIR_ERR_NO_SUPPORT) {
+ vshResetLibvirtError();
+ goto fallback;
+ }
+
+ /* there was an error during the call */
+ vshError(ctl, "%s", _("Failed to list node filters"));
+ goto cleanup;
+
+
+fallback:
+ /* fall back to old method (0.9.13 and older) */
+ vshResetLibvirtError();
+
+ nfilters = virConnectNumOfNWFilters(ctl->conn);
+ if (nfilters < 0) {
+ vshError(ctl, "%s", _("Failed to count network filters"));
+ goto cleanup;
+ }
+
+ if (nfilters == 0)
+ return list;
+
+ names = vshMalloc(ctl, sizeof(char *) * nfilters);
+
+ nfilters = virConnectListNWFilters(ctl->conn, names, nfilters);
+ if (nfilters < 0) {
+ vshError(ctl, "%s", _("Failed to list network filters"));
+ goto cleanup;
+ }
+
+ list->filters = vshMalloc(ctl, sizeof(virNWFilterPtr) * (nfilters));
Brackets are not necessary around nfilters.
+ list->nfilters = 0;
+
+ /* get the network filters */
+ for (i = 0; i < nfilters ; i++) {
+ if (!(filter = virNWFilterLookupByName(ctl->conn, names[i])))
+ continue;
+ list->filters[list->nfilters++] = filter;
+ }
+
+ /* truncate network filters that weren't found */
+ deleted = nfilters - list->nfilters;
+
+finished:
+ /* sort the list */
+ if (list->filters && list->nfilters)
+ qsort(list->filters, list->nfilters,
+ sizeof(*list->filters), vshNWFilterSorter);
+
+ /* truncate the list for not found filter objects */
+ if (deleted)
+ VIR_SHRINK_N(list->filters, list->nfilters, deleted);
+
+ success = true;
+
+cleanup:
+ for (i = 0; i < nfilters; i++)
+ VIR_FREE(names[i]);
+ VIR_FREE(names);
+
+ if (!success) {
+ vshNWFilterListFree(list);
+ list = NULL;
+ }
+
+ return list;
+}
+
/*
* "nwfilter-list" command
*/
Otherwise looks OK.
Peter