git: 1c3d6532ca29 - main - libprocstat: add knowledge about NT_PROCSTAT_KQUEUES core file section

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Mon, 24 Mar 2025 02:24:56 UTC
The branch main has been updated by kib:

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

commit 1c3d6532ca29c7aa7d26edd4074bc91671ac1bc2
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2025-03-13 23:06:05 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2025-03-24 02:24:14 +0000

    libprocstat: add knowledge about NT_PROCSTAT_KQUEUES core file section
    
    Reviewed by:    markj
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
    Differential revision:  https://reviews.freebsd.org/D49372
---
 lib/libprocstat/core.c        |  4 ++++
 lib/libprocstat/core.h        |  1 +
 lib/libprocstat/libprocstat.c | 33 +++++++++++++++++++++++++++++++--
 3 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/lib/libprocstat/core.c b/lib/libprocstat/core.c
index 37ea9b7bb912..b27b35de3bab 100644
--- a/lib/libprocstat/core.c
+++ b/lib/libprocstat/core.c
@@ -109,6 +109,10 @@ static const struct psc_type_info {
 		.n_type = NT_PTLWPINFO,
 		.structsize = sizeof(struct ptrace_lwpinfo)
 	},
+	[PSC_TYPE_KQUEUES] = {
+		.n_type = NT_PROCSTAT_KQUEUES,
+		.structsize = sizeof(struct kinfo_knote)
+	},
 };
 
 static bool	core_offset(struct procstat_core *core, off_t offset);
diff --git a/lib/libprocstat/core.h b/lib/libprocstat/core.h
index 8f6aa40192da..f4276fbdf09e 100644
--- a/lib/libprocstat/core.h
+++ b/lib/libprocstat/core.h
@@ -43,6 +43,7 @@ enum psc_type {
 	PSC_TYPE_ENVV,
 	PSC_TYPE_AUXV,
 	PSC_TYPE_PTLWPINFO,
+	PSC_TYPE_KQUEUES,
 	PSC_TYPE_MAX
 };
 
diff --git a/lib/libprocstat/libprocstat.c b/lib/libprocstat/libprocstat.c
index 3c70c939ff7e..29f464ef6414 100644
--- a/lib/libprocstat/libprocstat.c
+++ b/lib/libprocstat/libprocstat.c
@@ -2862,6 +2862,9 @@ struct kinfo_knote *
 procstat_get_kqueue_info(struct procstat *procstat,
     struct kinfo_proc *kp, int kqfd, unsigned int *count, char *errbuf)
 {
+	struct kinfo_knote *kn, *k, *res, *rn;
+	size_t len, kqn;
+
 	switch (procstat->type) {
 	case PROCSTAT_KVM:
 		warnx("kvm method is not supported");
@@ -2870,8 +2873,34 @@ procstat_get_kqueue_info(struct procstat *procstat,
 		return (procstat_get_kqueue_info_sysctl(kp->ki_pid, kqfd,
 		    count, errbuf));
 	case PROCSTAT_CORE:
-		warnx("core method is not supported");
-		return (NULL);
+		k = procstat_core_get(procstat->core, PSC_TYPE_KQUEUES,
+		    NULL, &len);
+		if (k == NULL) {
+			snprintf(errbuf, _POSIX2_LINE_MAX,
+			    "getting NT_PROCSTAT_KQUEUES note failed");
+			*count = 0;
+			return (NULL);
+		}
+		for (kqn = 0, kn = k; kn < k + len / sizeof(*kn); kn++) {
+			if (kn->knt_kq_fd == kqfd)
+				kqn++;
+		}
+		res = calloc(kqn, sizeof(*res));
+		if (res == NULL) {
+			free(k);
+			snprintf(errbuf, _POSIX2_LINE_MAX,
+			    "no memory");
+			return (NULL);
+		}
+		for (kn = k, rn = res; kn < k + len / sizeof(*kn); kn++) {
+			if (kn->knt_kq_fd != kqfd)
+				continue;
+			*rn = *kn;
+			rn++;
+		}
+		*count = kqn;
+		free(k);
+		return (res);
 	default:
 		warnx("unknown access method: %d", procstat->type);
 		return (NULL);