Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F168757828
D30948.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
2 KB
Referenced Files
None
Subscribers
None
D30948.id.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D30948: libpfctl: read states in multiple calls
Attached
Detach File
Event Timeline
Log In to Comment