The branch main has been updated by kib:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=bf46aec4b29a72bcaaa9f1b2fc446ee299f5a6fd

commit bf46aec4b29a72bcaaa9f1b2fc446ee299f5a6fd
Author:     Konstantin Belousov <k...@freebsd.org>
AuthorDate: 2025-02-24 23:44:10 +0000
Commit:     Konstantin Belousov <k...@freebsd.org>
CommitDate: 2025-03-13 16:09:35 +0000

    libprocstat: add helper to query knotes for specific kqueue
    
    Reviewed by:    markj
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
    Differential revision:  https://reviews.freebsd.org/D49163
---
 lib/libprocstat/Symbol.map    |  2 ++
 lib/libprocstat/libprocstat.c | 66 +++++++++++++++++++++++++++++++++++++++++++
 lib/libprocstat/libprocstat.h |  4 +++
 3 files changed, 72 insertions(+)

diff --git a/lib/libprocstat/Symbol.map b/lib/libprocstat/Symbol.map
index c2ea7e95312c..3d71c3eaae4a 100644
--- a/lib/libprocstat/Symbol.map
+++ b/lib/libprocstat/Symbol.map
@@ -50,6 +50,8 @@ FBSD_1.7 {
 };
 
 FBSD_1.8 {
+        procstat_get_kqueue_info;
         procstat_getrlimitusage;
+        procstat_freekqinfo;
         procstat_freerlimitusage;
 };
\ No newline at end of file
diff --git a/lib/libprocstat/libprocstat.c b/lib/libprocstat/libprocstat.c
index 90e4879ca05b..3c70c939ff7e 100644
--- a/lib/libprocstat/libprocstat.c
+++ b/lib/libprocstat/libprocstat.c
@@ -2817,3 +2817,69 @@ procstat_freerlimitusage(struct procstat *procstat 
__unused, rlim_t *resusage)
 {
        free(resusage);
 }
+
+static struct kinfo_knote *
+procstat_get_kqueue_info_sysctl(pid_t pid, int kqfd, unsigned int *cntp,
+    char *errbuf)
+{
+       int error, name[5];
+       struct kinfo_knote *val;
+       size_t len;
+
+       name[0] = CTL_KERN;
+       name[1] = KERN_PROC;
+       name[2] = KERN_PROC_KQUEUE;
+       name[3] = pid;
+       name[4] = kqfd;
+
+       len = 0;
+       error = sysctl(name, nitems(name), NULL, &len, NULL, 0);
+       if (error == -1) {
+               snprintf(errbuf, _POSIX2_LINE_MAX,
+                   "KERN_PROC_KQUEUE.pid<%d>.kq<%d> (size q) failed: %s",
+                   pid, kqfd, strerror(errno));
+               return (NULL);
+       }
+       val = malloc(len);
+       if (val == NULL) {
+               snprintf(errbuf, _POSIX2_LINE_MAX, "no memory");
+               return (NULL);
+       }
+
+       error = sysctl(name, nitems(name), val, &len, NULL, 0);
+       if (error == -1) {
+               snprintf(errbuf, _POSIX2_LINE_MAX,
+                   "KERN_PROC_KQUEUE.pid<%d>.kq<%d> failed: %s",
+                   pid, kqfd, strerror(errno));
+               free(val);
+               return (NULL);
+       }
+       *cntp = len / sizeof(*val);
+       return (val);
+}
+
+struct kinfo_knote *
+procstat_get_kqueue_info(struct procstat *procstat,
+    struct kinfo_proc *kp, int kqfd, unsigned int *count, char *errbuf)
+{
+       switch (procstat->type) {
+       case PROCSTAT_KVM:
+               warnx("kvm method is not supported");
+               return (NULL);
+       case PROCSTAT_SYSCTL:
+               return (procstat_get_kqueue_info_sysctl(kp->ki_pid, kqfd,
+                   count, errbuf));
+       case PROCSTAT_CORE:
+               warnx("core method is not supported");
+               return (NULL);
+       default:
+               warnx("unknown access method: %d", procstat->type);
+               return (NULL);
+       }
+}
+
+void
+procstat_freekqinfo(struct procstat *procstat __unused, struct kinfo_knote *v)
+{
+       free(v);
+}
diff --git a/lib/libprocstat/libprocstat.h b/lib/libprocstat/libprocstat.h
index 81a3ac05393d..0e9a4214414c 100644
--- a/lib/libprocstat/libprocstat.h
+++ b/lib/libprocstat/libprocstat.h
@@ -110,6 +110,7 @@
 struct kinfo_kstack;
 struct kinfo_proc;
 struct kinfo_vmentry;
+struct kinfo_knote;
 struct procstat;
 struct ptrace_lwpinfo;
 struct rlimit;
@@ -204,6 +205,7 @@ void        procstat_freeauxv(struct procstat *procstat, 
Elf_Auxinfo *auxv);
 #endif
 void   procstat_freeenvv(struct procstat *procstat);
 void   procstat_freegroups(struct procstat *procstat, gid_t *groups);
+void   procstat_freekqinfo(struct procstat *procstat, struct kinfo_knote *kni);
 void   procstat_freekstack(struct procstat *procstat,
     struct kinfo_kstack *kkstp);
 void   procstat_freeprocs(struct procstat *procstat, struct kinfo_proc *p);
@@ -219,6 +221,8 @@ struct filestat_list        *procstat_getfiles(struct 
procstat *procstat,
     struct kinfo_proc *kp, int mmapped);
 struct kinfo_proc      *procstat_getprocs(struct procstat *procstat,
     int what, int arg, unsigned int *count);
+struct kinfo_knote     *procstat_get_kqueue_info(struct procstat *procstat,
+    struct kinfo_proc *kp, int kqfd, unsigned int *count, char *errbuf);
 int    procstat_get_pipe_info(struct procstat *procstat, struct filestat *fst,
     struct pipestat *pipe, char *errbuf);
 int    procstat_get_pts_info(struct procstat *procstat, struct filestat *fst,

Reply via email to