git: 5e7c43ff02dc - main - Add NT_PROCSTAT_KQUEUES core note
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 24 Mar 2025 02:24:51 UTC
The branch main has been updated by kib:
URL: https://cgit.FreeBSD.org/src/commit/?id=5e7c43ff02dc0ec246582af24d3f4d03d5d55bf4
commit 5e7c43ff02dc0ec246582af24d3f4d03d5d55bf4
Author: Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2025-03-13 22:31:25 +0000
Commit: Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2025-03-24 02:24:14 +0000
Add NT_PROCSTAT_KQUEUES core note
Suggested by: jhb
Reviewed by: markj
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D49372
---
sys/kern/imgact_elf.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
sys/kern/kern_event.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
sys/sys/elf_common.h | 1 +
sys/sys/user.h | 2 ++
4 files changed, 101 insertions(+)
diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c
index fc074ad74e6b..1a2c0e2ef93d 100644
--- a/sys/kern/imgact_elf.c
+++ b/sys/kern/imgact_elf.c
@@ -1574,6 +1574,7 @@ static void __elfN(note_threadmd)(void *, struct sbuf *, size_t *);
static void __elfN(note_procstat_auxv)(void *, struct sbuf *, size_t *);
static void __elfN(note_procstat_proc)(void *, struct sbuf *, size_t *);
static void __elfN(note_procstat_psstrings)(void *, struct sbuf *, size_t *);
+static void __elfN(note_procstat_kqueues)(void *, struct sbuf *, size_t *);
static void note_procstat_files(void *, struct sbuf *, size_t *);
static void note_procstat_groups(void *, struct sbuf *, size_t *);
static void note_procstat_osrel(void *, struct sbuf *, size_t *);
@@ -1899,6 +1900,8 @@ __elfN(prepare_notes)(struct thread *td, struct note_info_list *list,
__elfN(note_procstat_psstrings), p);
size += __elfN(register_note)(td, list, NT_PROCSTAT_AUXV,
__elfN(note_procstat_auxv), p);
+ size += __elfN(register_note)(td, list, NT_PROCSTAT_KQUEUES,
+ __elfN(note_procstat_kqueues), p);
*sizep = size;
}
@@ -2719,6 +2722,54 @@ __elfN(note_procstat_auxv)(void *arg, struct sbuf *sb, size_t *sizep)
}
}
+static void
+__elfN(note_procstat_kqueues)(void *arg, struct sbuf *sb, size_t *sizep)
+{
+ struct proc *p;
+ size_t size, sect_sz, i;
+ ssize_t start_len, sect_len;
+ int structsize;
+ bool compat32;
+
+#if defined(COMPAT_FREEBSD32) && __ELF_WORD_SIZE == 32
+ compat32 = true;
+ structsize = sizeof(struct kinfo_knote32);
+#else
+ compat32 = false;
+ structsize = sizeof(struct kinfo_knote);
+#endif
+ p = arg;
+ if (sb == NULL) {
+ size = 0;
+ sb = sbuf_new(NULL, NULL, 128, SBUF_FIXEDLEN);
+ sbuf_set_drain(sb, sbuf_count_drain, &size);
+ sbuf_bcat(sb, &structsize, sizeof(structsize));
+ kern_proc_kqueues_out(p, sb, -1, compat32);
+ sbuf_finish(sb);
+ sbuf_delete(sb);
+ *sizep = size;
+ } else {
+ sbuf_start_section(sb, &start_len);
+
+ sbuf_bcat(sb, &structsize, sizeof(structsize));
+ kern_proc_kqueues_out(p, sb, *sizep - sizeof(structsize),
+ compat32);
+
+ sect_len = sbuf_end_section(sb, start_len, 0, 0);
+ if (sect_len < 0)
+ return;
+ sect_sz = sect_len;
+
+ KASSERT(sect_sz <= *sizep,
+ ("kern_proc_kqueue_out did not respect maxlen; "
+ "requested %zu, got %zu", *sizep - sizeof(structsize),
+ sect_sz - sizeof(structsize)));
+
+ for (i = 0; i < *sizep - sect_sz && sb->s_error == 0; i++)
+ sbuf_putc(sb, 0);
+ }
+}
+
#define MAX_NOTES_LOOP 4096
bool
__elfN(parse_notes)(const struct image_params *imgp, const Elf_Note *checknote,
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c
index c7260f6bb267..8188323bdbc9 100644
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -2940,6 +2940,53 @@ out:
return (error);
}
+struct kern_proc_kqueues_out1_cb_args {
+ struct sbuf *s;
+ bool compat32;
+};
+
+static int
+kern_proc_kqueues_out1_cb(struct proc *p, int fd, struct file *fp, void *arg)
+{
+ struct kqueue *kq;
+ struct kern_proc_kqueues_out1_cb_args *a;
+
+ if (fp->f_type != DTYPE_KQUEUE)
+ return (0);
+ a = arg;
+ kq = fp->f_data;
+ return (kern_proc_kqueue_report(a->s, p, fd, kq, a->compat32));
+}
+
+static int
+kern_proc_kqueues_out1(struct thread *td, struct proc *p, struct sbuf *s,
+ bool compat32)
+{
+ struct kern_proc_kqueues_out1_cb_args a;
+
+ MPASS(p == curproc);
+
+ a.s = s;
+ a.compat32 = compat32;
+ return (fget_remote_foreach(td, p, kern_proc_kqueues_out1_cb, &a));
+}
+
+int
+kern_proc_kqueues_out(struct proc *p, struct sbuf *sb, size_t maxlen,
+ bool compat32)
+{
+ struct sbuf *s, sm;
+ int error;
+
+ s = sbuf_new(&sm, NULL, maxlen, SBUF_FIXEDLEN);
+ error = kern_proc_kqueues_out1(curthread, p, s, compat32);
+ sbuf_finish(s);
+ if (error == 0)
+ sbuf_bcat(sb, sbuf_data(s), MIN(sbuf_len(s), maxlen));
+ sbuf_delete(s);
+ return (error);
+}
+
static int
sysctl_kern_proc_kqueue(SYSCTL_HANDLER_ARGS)
{
diff --git a/sys/sys/elf_common.h b/sys/sys/elf_common.h
index 766ff6ede51b..488aaaf25ab1 100644
--- a/sys/sys/elf_common.h
+++ b/sys/sys/elf_common.h
@@ -840,6 +840,7 @@ typedef struct {
#define NT_PROCSTAT_PSSTRINGS 15 /* Procstat ps_strings data. */
#define NT_PROCSTAT_AUXV 16 /* Procstat auxv data. */
#define NT_PTLWPINFO 17 /* Thread ptrace miscellaneous info. */
+#define NT_PROCSTAT_KQUEUES 18 /* Procstat kqueues events. */
#define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */
#define NT_PPC_VSX 0x102 /* PowerPC VSX registers */
#define NT_X86_SEGBASES 0x200 /* x86 FS/GS base addresses. */
diff --git a/sys/sys/user.h b/sys/sys/user.h
index c053441c9e6a..8396f827e9ed 100644
--- a/sys/sys/user.h
+++ b/sys/sys/user.h
@@ -721,6 +721,8 @@ int kern_proc_cwd_out(struct proc *p, struct sbuf *sb, ssize_t maxlen);
int kern_proc_out(struct proc *p, struct sbuf *sb, int flags);
int kern_proc_vmmap_out(struct proc *p, struct sbuf *sb, ssize_t maxlen,
int flags);
+int kern_proc_kqueues_out(struct proc *p, struct sbuf *s, size_t maxlen,
+ bool compat32);
int vntype_to_kinfo(int vtype);
void pack_kinfo(struct kinfo_file *kif);