libprocstat: add helper to query knotes for specific kqueue

(cherry picked from commit bf46aec4b29a72bcaaa9f1b2fc446ee299f5a6fd)
This commit is contained in:
Konstantin Belousov 2025-02-25 01:44:10 +02:00
parent 1795bfc315
commit 3cb2a80f6b
3 changed files with 72 additions and 0 deletions

View file

@ -50,6 +50,8 @@ FBSD_1.7 {
};
FBSD_1.8 {
procstat_get_kqueue_info;
procstat_getrlimitusage;
procstat_freekqinfo;
procstat_freerlimitusage;
};

View file

@ -2838,3 +2838,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);
}

View file

@ -110,6 +110,7 @@
struct kinfo_kstack;
struct kinfo_proc;
struct kinfo_vmentry;
struct kinfo_knote;
struct procstat;
struct ptrace_lwpinfo;
struct rlimit;
@ -205,6 +206,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);
@ -220,6 +222,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,