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
This commit is contained in:
Konstantin Belousov 2025-03-14 00:31:25 +02:00
parent fa8fdd80df
commit 5e7c43ff02
4 changed files with 101 additions and 0 deletions

View file

@ -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,

View file

@ -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)
{

View file

@ -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. */

View file

@ -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);