[lxc-devel] [PATCH] do not allocate lxc_snapshot array if NULL is passed into snapshot_list as a ret_snaps parameter.

S.Çağlar Onur caglar at 10ur.org
Tue Oct 15 04:32:38 UTC 2013


All the other (similar) API calls behaves this way, aka passing NULL returns the count.
This patch both provides consistency to calling conventions and
also may make binding's life little easier cause we need to call those function two times.
First to get the length and then get the data itself. This is required because we cannot
pass our native data types directly to C world, at least Go can't for now.

Right now a function that returns size only has to do something like that to free returned array;

    int i;
    struct lxc_snapshot *s;

    int n = c->snapshot_list(c, &s);
    if (n < 1)
        return 0;

    for (i = 0; i < n; i++) {
        s[i].free(&s[i]);
    }
    free(s);
    return n;

whereas following should be enough.

    return c->snapshot_list(c, NULL);
---
 src/lxc/lxccontainer.c | 37 ++++++++++++++++++++-----------------
 src/lxc/lxccontainer.h |  4 ++--
 2 files changed, 22 insertions(+), 19 deletions(-)

diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index 6f97879..391e4cd 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -2516,23 +2516,25 @@ static int lxcapi_snapshot_list(struct lxc_container *c, struct lxc_snapshot **r
 		}
 		if (!file_exists(path2))
 			continue;
-		nsnaps = realloc(snaps, (count + 1)*sizeof(*snaps));
-		if (!nsnaps) {
-			SYSERROR("Out of memory");
-			goto out_free;
-		}
-		snaps = nsnaps;
-		snaps[count].free = lxcsnap_free;
-		snaps[count].name = strdup(direntp->d_name);
-		if (!snaps[count].name)
-			goto out_free;
-		snaps[count].lxcpath = strdup(snappath);
-		if (!snaps[count].lxcpath) {
-			free(snaps[count].name);
-			goto out_free;
+		if(ret_snaps != NULL) {
+			nsnaps = realloc(snaps, (count + 1)*sizeof(*snaps));
+			if (!nsnaps) {
+				SYSERROR("Out of memory");
+				goto out_free;
+			}
+			snaps = nsnaps;
+			snaps[count].free = lxcsnap_free;
+			snaps[count].name = strdup(direntp->d_name);
+			if (!snaps[count].name)
+				goto out_free;
+			snaps[count].lxcpath = strdup(snappath);
+			if (!snaps[count].lxcpath) {
+				free(snaps[count].name);
+				goto out_free;
+			}
+			snaps[count].comment_pathname = get_snapcomment_path(snappath, direntp->d_name);
+			snaps[count].timestamp = get_timestamp(snappath, direntp->d_name);
 		}
-		snaps[count].comment_pathname = get_snapcomment_path(snappath, direntp->d_name);
-		snaps[count].timestamp = get_timestamp(snappath, direntp->d_name);
 		count++;
 	}
 
@@ -2541,7 +2543,8 @@ static int lxcapi_snapshot_list(struct lxc_container *c, struct lxc_snapshot **r
 		WARN("failed to close directory");
 	process_unlock();
 
-	*ret_snaps = snaps;
+	if (ret_snaps != NULL)
+		*ret_snaps = snaps;
 	return count;
 
 out_free:
diff --git a/src/lxc/lxccontainer.h b/src/lxc/lxccontainer.h
index 5901066..bb77126 100644
--- a/src/lxc/lxccontainer.h
+++ b/src/lxc/lxccontainer.h
@@ -197,12 +197,12 @@ struct lxc_container {
 
 	/*
 	 * snapshot_list() will return a description of all snapshots of c in
-	 * a simple array.  See src/tests/snapshot.c for the proper way to
+	 * a simple array, if ret_snaps is not null.  See src/tests/snapshot.c for the proper way to
 	 * free the allocated results.
 	 *
 	 * Returns the number of snapshots.
 	 */
-	int (*snapshot_list)(struct lxc_container *, struct lxc_snapshot **);
+	int (*snapshot_list)(struct lxc_container *c, struct lxc_snapshot **ret_snaps);
 
 	/*
 	 * snapshot_restore() will create a new container based on a snapshot.
-- 
1.8.1.2





More information about the lxc-devel mailing list