diff options
author | luigi <luigi@FreeBSD.org> | 2010-03-04 16:56:36 +0000 |
---|---|---|
committer | luigi <luigi@FreeBSD.org> | 2010-03-04 16:56:36 +0000 |
commit | 7053937fa6b7489260f32ab5250e908f6b721c6c (patch) | |
tree | d80e9fcfcaa025df57ed1c13a72ae2f0017a0177 /sbin | |
parent | b486493f31704510ea9ba1a97eb1f59f7b828fd1 (diff) | |
download | FreeBSD-src-7053937fa6b7489260f32ab5250e908f6b721c6c.zip FreeBSD-src-7053937fa6b7489260f32ab5250e908f6b721c6c.tar.gz |
make the listing of queues/pipes/schedulers handle the case of
data size increasing while we fetch the info.
Diffstat (limited to 'sbin')
-rw-r--r-- | sbin/ipfw/dummynet.c | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/sbin/ipfw/dummynet.c b/sbin/ipfw/dummynet.c index dbbf011..1cc6832 100644 --- a/sbin/ipfw/dummynet.c +++ b/sbin/ipfw/dummynet.c @@ -1241,8 +1241,8 @@ dummynet_flush(void) void dummynet_list(int ac, char *av[], int show_counters) { - struct dn_id oid, *x; - int ret, l = sizeof(oid); + struct dn_id oid, *x = NULL; + int ret, i, l = sizeof(oid); oid_fill(&oid, l, DN_CMD_GET, DN_API_VERSION); switch (co.do_pipe) { @@ -1256,14 +1256,29 @@ dummynet_list(int ac, char *av[], int show_counters) oid.subtype = DN_SCH; /* list sched */ break; } + + /* Request the buffer size (in oid.id)*/ ret = do_cmd(-IP_DUMMYNET3, &oid, (uintptr_t)&l); // printf("%s returns %d need %d\n", __FUNCTION__, ret, oid.id); if (ret != 0 || oid.id <= sizeof(oid)) return; - l = oid.id; - x = safe_calloc(1, l); + + /* Try max 10 times + * Buffer is correct if l != 0. + * If l == 0 no buffer is sent, maybe because kernel requires + * a greater buffer, so try with the new size in x->id. + */ + for (i = 0, l = oid.id; i < 10; i++, l = x->id) { + x = safe_realloc(x, l); *x = oid; ret = do_cmd(-IP_DUMMYNET3, x, (uintptr_t)&l); + + if (ret != 0 || x->id <= sizeof(oid)) + return; + + if (l != 0) + break; /* ok */ + } // printf("%s returns %d need %d\n", __FUNCTION__, ret, oid.id); // XXX filter on ac, av list_pipes(x, O_NEXT(x, l)); |