Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F109639450
D31042.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
D31042.diff
View Options
Index: lib/libpfctl/libpfctl.h
===================================================================
--- lib/libpfctl/libpfctl.h
+++ lib/libpfctl/libpfctl.h
@@ -238,6 +238,11 @@
uint32_t sync_flags;
};
+struct pfctl_states_stats {
+ uint64_t states;
+ size_t state_size_hint;
+};
+
TAILQ_HEAD(pfctl_statelist, pfctl_state);
struct pfctl_states {
struct pfctl_statelist states;
@@ -254,6 +259,7 @@
const char *anchor, const char *anchor_call, u_int32_t ticket,
u_int32_t pool_ticket);
int pfctl_set_keepcounters(int dev, bool keep);
+int pfctl_get_states_stats(int dev, struct pfctl_states_stats *stats);
int pfctl_get_states(int dev, struct pfctl_states *states);
void pfctl_free_states(struct pfctl_states *states);
int pfctl_clear_states(int dev, const struct pfctl_kill *kill,
Index: lib/libpfctl/libpfctl.c
===================================================================
--- lib/libpfctl/libpfctl.c
+++ lib/libpfctl/libpfctl.c
@@ -705,21 +705,65 @@
s->sync_flags = nvlist_get_number(nvl, "sync_flags");
}
+int
+pfctl_get_states_stats(int dev, struct pfctl_states_stats *stats)
+{
+ struct pfioc_nv nv;
+ nvlist_t *nvl = NULL;
+ int error = 0;
+
+ bzero(stats, sizeof(*stats));
+
+ nv.data = malloc(128);
+ nv.len = nv.size = 128;
+
+ if (ioctl(dev, DIOCGETSTATESSTATSNV, &nv)) {
+ error = errno;
+ goto out;
+ }
+
+ nvl = nvlist_unpack(nv.data, nv.len, 0);
+ if (nvl == NULL) {
+ error = EIO;
+ goto out;
+ }
+
+ stats->states = nvlist_get_number(nvl, "states");
+ stats->state_size_hint = nvlist_get_number(nvl, "state_size_hint");
+
+out:
+ nvlist_destroy(nvl);
+ free(nv.data);
+
+ return (error);
+}
+
int
pfctl_get_states(int dev, struct pfctl_states *states)
{
- struct pfioc_nv nv;
- nvlist_t *nvl = NULL;
- const nvlist_t * const *slist;
- size_t found_count;
- int error = 0;
+ struct pfioc_nv nv;
+ struct pfctl_states_stats stats;
+ nvlist_t *nvl = NULL;
+ const nvlist_t * const *slist;
+ size_t found_count;
+ size_t size_estimate;
+ int error = 0;
+
+ error = pfctl_get_states_stats(dev, &stats);
+ if (error)
+ return (error);
bzero(states, sizeof(*states));
TAILQ_INIT(&states->states);
- /* Just enough to get a number, and we'll grow from there. */
- nv.data = malloc(64);
- nv.len = nv.size = 64;
+ /* 20% extra, in case more states are added between the stats call and
+ * the actual read. */
+ size_estimate = 64 + (stats.states * stats.state_size_hint * 12 / 10);
+ /* Never more than 100MB at a time. */
+ size_estimate = MIN(size_estimate, 100 * 1024 * 1024);
+
+ nv.data = malloc(size_estimate);
+ nv.len = nv.size = size_estimate;
for (;;) {
if (ioctl(dev, DIOCGETSTATESNV, &nv)) {
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Feb 8, 8:32 PM (18 h, 9 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16531788
Default Alt Text
D31042.diff (2 KB)
Attached To
Mode
D31042: libpfctl: Implement pfctl_get_states_stats()
Attached
Detach File
Event Timeline
Log In to Comment