Page MenuHomeFreeBSD

D30948.id.diff
No OneTemporary

D30948.id.diff

Index: lib/libpfctl/libpfctl.c
===================================================================
--- lib/libpfctl/libpfctl.c
+++ lib/libpfctl/libpfctl.c
@@ -743,8 +743,10 @@
{
struct pfioc_nv nv;
struct pfctl_states_stats stats;
- nvlist_t *nvl = NULL;
+ nvlist_t *nvl = NULL, *nvl_req = NULL;
+ void *nvlpacked;
const nvlist_t * const *slist;
+ uint64_t token = 0;
size_t found_count;
size_t size_estimate;
int error = 0;
@@ -757,10 +759,26 @@
TAILQ_INIT(&states->states);
size_estimate = 64 + (stats.states * stats.state_size_hint);
+ /* Never more than 100MB at a time. */
+ size_estimate = MIN(size_estimate, 100 * 1024 * 1024);
+
+ nv.len = 0;
nv.data = malloc(size_estimate);
- nv.len = nv.size = size_estimate;
+ nv.size = size_estimate;
for (;;) {
+ if (token != 0) {
+ /* Tell the kernel where to resume from. */
+ nvl_req = nvlist_create(0);
+ nvlist_add_number(nvl_req, "token", token);
+
+ nvlpacked = nvlist_pack(nvl_req, &nv.len);
+ assert(nv.len <= nv.size);
+ memcpy(nv.data, nvlpacked, nv.len);
+ nvlist_destroy(nvl_req);
+ free(nvlpacked);
+ }
+
if (ioctl(dev, DIOCGETSTATESNV, &nv)) {
error = errno;
goto out;
@@ -773,33 +791,22 @@
goto out;
}
- states->count = nvlist_get_number(nvl, "count");
-
- /* Are there any states? */
- if (states->count == 0)
- break;
-
if (nvlist_exists_nvlist_array(nvl, "states"))
slist = nvlist_get_nvlist_array(nvl, "states", &found_count);
- else
+ else {
found_count = 0;
- if (found_count < states->count) {
- size_t new_size = nv.size +
- (nv.size * states->count / (found_count + 1) * 2);
-
- /* Our buffer is too small. Estimate what we need based
- * on how many states fit in the previous allocation
- * and how many states there are. Doubled for margin.
- * */
- nv.data = realloc(nv.data, new_size);
- nv.size = new_size;
-
- if (nv.data == NULL) {
- error = ENOMEM;
- goto out;
+ /* If we've made no progress and have no states our
+ * allocation is just too small. */
+ if (token == nvlist_get_number(nvl, "token")) {
+ nv.size *= 2;
+ nv.data = realloc(nv.data, nv.size);
+ if (nv.data == NULL) {
+ error = ENOMEM;
+ goto out;
+ }
+ continue;
}
- continue;
}
for (size_t i = 0; i < found_count; i++) {
@@ -812,8 +819,13 @@
pf_nvstate_to_state(slist[i], s);
TAILQ_INSERT_TAIL(&states->states, s, entry);
+ states->count++;
}
- break;
+
+ if (nvlist_get_bool(nvl, "done"))
+ break;
+
+ token = nvlist_get_number(nvl, "token");
}
out:

File Metadata

Mime Type
text/plain
Expires
Mon, Aug 31, 12:17 AM (14 h, 3 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37636160
Default Alt Text
D30948.id.diff (2 KB)

Event Timeline