From nobody Thu Mar 13 16:10:06 2025 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4ZDCBl2ftWz5qsKr; Thu, 13 Mar 2025 16:10:07 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R10" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4ZDCBl0T6Vz3Wm2; Thu, 13 Mar 2025 16:10:07 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1741882207; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=/fEKZa/omCXtFLKh023l8xVvgzmHwCmslw6IpbmMDVo=; b=a6JzAQQ6o+xZxaVTwnNi4nENZVbq65iH+Z2M6q8CLFBieKbuGd0NDhPzy8C+oriCyQek9G 5cOf3z0C3ofkbdvjMwker0NMEcNwnEjqk3vXzv5pz9oS/JVl69oO1y9LdB8Mcg+MOn/M1D Sd9NjmtvTH+mBxZQjHvhK0ok2wS1E1ojU/eBxio7S6NG2BfuMXR5K+IEgQNackQr0ISUQX FEtVGhgjGC8/d38USGc3EQPnWfGHZIpPLHp+JuOKHsuvKWHGkuHtmSpOvTpczjySCdO3Ho Wf1vClgWBIqnvUfulgLfuzwepZBfZHf0REnPw8ouRiMVpHygf95XaX64PdS1nA== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1741882207; a=rsa-sha256; cv=none; b=ADI2PxSvO1gj0nsYnQZx0EIEzmCXMd2wA9FDRVr/WjXNwUGlu8T7KEFY8WufmfKmkUpXMH Dl+pclZIACPf9m4zQdQcCEm3znx8BsGRyuf15NlDMyXsjgPVp0TjSXVmSktq47fmdI3yYP I33XzqUXitcAFiCbJgvHy40xdW6MN7UFNFK2GPzOTm1GqkGYByWUuptkeS8WJdaMcowq+H 4T1WVaROtgZvA6c+O2Vr3FinnxLR9O6NN/54b/t+EnSg/eMgaXYInPlzPcU3ySBT/UlXXq 2/05R0EHVYet2+Q4QyAvktKTPNIJDvMOeTIT2z6pTERZ3D18N4I0f3QIlLIXRQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1741882207; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=/fEKZa/omCXtFLKh023l8xVvgzmHwCmslw6IpbmMDVo=; b=yIgrBNlho+v43p4FSV46mkcjQxuWbDeiahuQagR1Hah1yG8nX40TKjYd9Utagu/j8XCkZH WdqE12onRLp+At0YzEiYVAArmkl6oKzVdL+jm1G0xdDsTnBJFWQaaxFCT1a7GNl6jOCdko aky7x5zXkjtn39FsWvmXistRIo5q7aG7e2drP5pr8Fz4S/MC37dmWgE04Q/Ygn5u1158yS 4G5u0IHaJqDCyct7/LyKAmquMz58uboCuGpQaJlb6WOG0C9kGDLXthiIyPVeE1DMFr/Hy7 A545qH/rIcQUSJirxPND5KBWzU1yKWx/pJlwzjtpAKlh76OI/AVnpxE4hGAb3w== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4ZDCBk6kv5z14j7; Thu, 13 Mar 2025 16:10:06 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 52DGA6HM054272; Thu, 13 Mar 2025 16:10:06 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 52DGA6fw054267; Thu, 13 Mar 2025 16:10:06 GMT (envelope-from git) Date: Thu, 13 Mar 2025 16:10:06 GMT Message-Id: <202503131610.52DGA6fw054267@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Konstantin Belousov Subject: git: e60f608eb9cf - main - Add sysctl kern.proc.kqueue List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kib X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: e60f608eb9cf3b38099948545934d699de9bbcea Auto-Submitted: auto-generated The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=e60f608eb9cf3b38099948545934d699de9bbcea commit e60f608eb9cf3b38099948545934d699de9bbcea Author: Konstantin Belousov AuthorDate: 2025-02-23 20:25:25 +0000 Commit: Konstantin Belousov CommitDate: 2025-03-13 16:09:35 +0000 Add sysctl kern.proc.kqueue reporting registered events in the specified kqueue. Reviewed by: markj Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D49163 --- sys/kern/kern_event.c | 141 +++++++++++++++++++++++++++++++++++++++++++++++++- sys/kern/sys_pipe.c | 20 ++++++- sys/kern/vfs_subr.c | 50 ++++++++++++++++-- sys/sys/event.h | 5 ++ sys/sys/sysctl.h | 1 + sys/sys/user.h | 28 ++++++++++ sys/vm/sg_pager.c | 1 + 7 files changed, 238 insertions(+), 8 deletions(-) diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c index dcb2c10ee1f5..14aa3abd1901 100644 --- a/sys/kern/kern_event.c +++ b/sys/kern/kern_event.c @@ -64,6 +64,7 @@ #include #include #include +#include #include #include #include @@ -2730,8 +2731,15 @@ knote_drop_detached(struct knote *kn, struct thread *td) KQ_NOTOWNED(kq); KQ_LOCK(kq); - KASSERT(kn->kn_influx == 1, - ("knote_drop called on %p with influx %d", kn, kn->kn_influx)); + for (;;) { + KASSERT(kn->kn_influx >= 1, + ("knote_drop called on %p with influx %d", + kn, kn->kn_influx)); + if (kn->kn_influx == 1) + break; + kq->kq_state |= KQ_FLUXWAIT; + msleep(kq, &kq->kq_lock, PSOCK, "kqflxwt", 0); + } if (kn->kn_fop->f_isfd) list = &kq->kq_knlist[kn->kn_id]; @@ -2829,3 +2837,132 @@ noacquire: fdrop(fp, td); return (error); } + +struct knote_status_export_bit { + int kn_status_bit; + int knt_status_bit; +}; + +#define ST(name) \ + { .kn_status_bit = KN_##name, .knt_status_bit = KNOTE_STATUS_##name } +static const struct knote_status_export_bit knote_status_export_bits[] = { + ST(ACTIVE), + ST(QUEUED), + ST(DISABLED), + ST(DETACHED), + ST(KQUEUE), +}; +#undef ST + +static int +knote_status_export(int kn_status) +{ + const struct knote_status_export_bit *b; + unsigned i; + int res; + + res = 0; + for (i = 0; i < nitems(knote_status_export_bits); i++) { + b = &knote_status_export_bits[i]; + if ((kn_status & b->kn_status_bit) != 0) + res |= b->knt_status_bit; + } + return (res); +} + +static int +sysctl_kern_proc_kqueue_report_one(struct proc *p, struct sysctl_req *req, + struct kqueue *kq, struct knote *kn) +{ + struct kinfo_knote kin; + int error; + + if (kn->kn_status == KN_MARKER) + return (0); + + memset(&kin, 0, sizeof(kin)); + memcpy(&kin.knt_event, &kn->kn_kevent, sizeof(struct kevent)); + kin.knt_status = knote_status_export(kn->kn_status); + kn_enter_flux(kn); + KQ_UNLOCK_FLUX(kq); + if (kn->kn_fop->f_userdump != NULL) + (void)kn->kn_fop->f_userdump(p, kn, &kin); + error = SYSCTL_OUT(req, &kin, sizeof(kin)); + maybe_yield(); + KQ_LOCK(kq); + kn_leave_flux(kn); + return (error); +} + +static int +sysctl_kern_proc_kqueue(SYSCTL_HANDLER_ARGS) +{ + struct thread *td; + struct proc *p; + struct file *fp; + struct kqueue *kq; + struct knote *kn; + int error, i, *name; + + name = (int *)arg1; + if ((u_int)arg2 != 2) + return (EINVAL); + + error = pget((pid_t)name[0], PGET_HOLD | PGET_CANDEBUG, &p); + if (error != 0) + return (error); +#ifdef COMPAT_FREEBSD32 + if (SV_CURPROC_FLAG(SV_ILP32)) { + /* XXXKIB */ + error = EOPNOTSUPP; + goto out1; + } +#endif + + td = curthread; + error = fget_remote(td, p, name[1] /* kqfd */, &fp); + if (error != 0) + goto out1; + if (fp->f_type != DTYPE_KQUEUE) { + error = EINVAL; + goto out2; + } + + kq = fp->f_data; + if (req->oldptr == NULL) { + error = SYSCTL_OUT(req, NULL, sizeof(struct kinfo_knote) * + kq->kq_knlistsize * 11 / 10); + goto out2; + } + + KQ_LOCK(kq); + for (i = 0; i < kq->kq_knlistsize; i++) { + SLIST_FOREACH(kn, &kq->kq_knlist[i], kn_link) { + error = sysctl_kern_proc_kqueue_report_one(p, req, + kq, kn); + if (error != 0) + goto out3; + } + } + if (kq->kq_knhashmask == 0) + goto out3; + for (i = 0; i <= kq->kq_knhashmask; i++) { + SLIST_FOREACH(kn, &kq->kq_knhash[i], kn_link) { + error = sysctl_kern_proc_kqueue_report_one(p, req, + kq, kn); + if (error != 0) + goto out3; + } + } +out3: + KQ_UNLOCK_FLUX(kq); +out2: + fdrop(fp, td); +out1: + PRELE(p); + return (error); +} + +static SYSCTL_NODE(_kern_proc, KERN_PROC_KQUEUE, kq, + CTLFLAG_RD | CTLFLAG_MPSAFE, + sysctl_kern_proc_kqueue, "KQueue events"); diff --git a/sys/kern/sys_pipe.c b/sys/kern/sys_pipe.c index b842db44e7f1..9340779918a2 100644 --- a/sys/kern/sys_pipe.c +++ b/sys/kern/sys_pipe.c @@ -175,21 +175,26 @@ static void filt_pipedetach_notsup(struct knote *kn); static int filt_pipenotsup(struct knote *kn, long hint); static int filt_piperead(struct knote *kn, long hint); static int filt_pipewrite(struct knote *kn, long hint); +static int filt_pipedump(struct proc *p, struct knote *kn, + struct kinfo_knote *kin); static const struct filterops pipe_nfiltops = { .f_isfd = 1, .f_detach = filt_pipedetach_notsup, .f_event = filt_pipenotsup + /* no userdump */ }; static const struct filterops pipe_rfiltops = { .f_isfd = 1, .f_detach = filt_pipedetach, - .f_event = filt_piperead + .f_event = filt_piperead, + .f_userdump = filt_pipedump, }; static const struct filterops pipe_wfiltops = { .f_isfd = 1, .f_detach = filt_pipedetach, - .f_event = filt_pipewrite + .f_event = filt_pipewrite, + .f_userdump = filt_pipedump, }; /* @@ -1900,3 +1905,14 @@ filt_pipenotsup(struct knote *kn, long hint) return (0); } + +static int +filt_pipedump(struct proc *p, struct knote *kn, + struct kinfo_knote *kin) +{ + struct pipe *pipe = kn->kn_hook; + + kin->knt_extdata = KNOTE_EXTDATA_PIPE; + kin->knt_pipe.knt_pipe_ino = pipe->pipe_ino; + return (0); +} diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 9e9b56064ecf..95ed98d3217d 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -79,6 +79,7 @@ #include #include #include +#include #include #include #include @@ -6483,7 +6484,7 @@ const struct filterops fs_filtops = { .f_isfd = 0, .f_attach = filt_fsattach, .f_detach = filt_fsdetach, - .f_event = filt_fsevent + .f_event = filt_fsevent, }; static int @@ -6559,20 +6560,26 @@ static int filt_vfsread(struct knote *kn, long hint); static int filt_vfswrite(struct knote *kn, long hint); static int filt_vfsvnode(struct knote *kn, long hint); static void filt_vfsdetach(struct knote *kn); +static int filt_vfsdump(struct proc *p, struct knote *kn, + struct kinfo_knote *kin); + static const struct filterops vfsread_filtops = { .f_isfd = 1, .f_detach = filt_vfsdetach, - .f_event = filt_vfsread + .f_event = filt_vfsread, + .f_userdump = filt_vfsdump, }; static const struct filterops vfswrite_filtops = { .f_isfd = 1, .f_detach = filt_vfsdetach, - .f_event = filt_vfswrite + .f_event = filt_vfswrite, + .f_userdump = filt_vfsdump, }; static const struct filterops vfsvnode_filtops = { .f_isfd = 1, .f_detach = filt_vfsdetach, - .f_event = filt_vfsvnode + .f_event = filt_vfsvnode, + .f_userdump = filt_vfsdump, }; static void @@ -6721,6 +6728,41 @@ filt_vfsvnode(struct knote *kn, long hint) return (res); } +static int +filt_vfsdump(struct proc *p, struct knote *kn, struct kinfo_knote *kin) +{ + struct vattr va; + struct vnode *vp; + char *fullpath, *freepath; + int error; + + kin->knt_extdata = KNOTE_EXTDATA_VNODE; + + vp = kn->kn_fp->f_vnode; + kin->knt_vnode.knt_vnode_type = vntype_to_kinfo(vp->v_type); + + va.va_fsid = VNOVAL; + vn_lock(vp, LK_SHARED | LK_RETRY); + error = VOP_GETATTR(vp, &va, curthread->td_ucred); + VOP_UNLOCK(vp); + if (error != 0) + return (error); + kin->knt_vnode.knt_vnode_fsid = va.va_fsid; + kin->knt_vnode.knt_vnode_fileid = va.va_fileid; + + freepath = NULL; + fullpath = "-"; + error = vn_fullpath(vp, &fullpath, &freepath); + if (error == 0) { + strlcpy(kin->knt_vnode.knt_vnode_fullpath, fullpath, + sizeof(kin->knt_vnode.knt_vnode_fullpath)); + } + if (freepath != NULL) + free(freepath, M_TEMP); + + return (0); +} + int vfs_read_dirent(struct vop_readdir_args *ap, struct dirent *dp, off_t off) { diff --git a/sys/sys/event.h b/sys/sys/event.h index 1c640c86703d..dee3365ba7b6 100644 --- a/sys/sys/event.h +++ b/sys/sys/event.h @@ -262,12 +262,17 @@ struct knlist { #define EVENT_REGISTER 1 #define EVENT_PROCESS 2 +struct kinfo_knote; +struct proc; + struct filterops { int f_isfd; /* true if ident == filedescriptor */ int (*f_attach)(struct knote *kn); void (*f_detach)(struct knote *kn); int (*f_event)(struct knote *kn, long hint); void (*f_touch)(struct knote *kn, struct kevent *kev, u_long type); + int (*f_userdump)(struct proc *p, struct knote *kn, + struct kinfo_knote *kin); }; /* diff --git a/sys/sys/sysctl.h b/sys/sys/sysctl.h index f7abc27083aa..916c91da3d53 100644 --- a/sys/sys/sysctl.h +++ b/sys/sys/sysctl.h @@ -1041,6 +1041,7 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_entry); #define KERN_PROC_SIGFASTBLK 44 /* address of fastsigblk magic word */ #define KERN_PROC_VM_LAYOUT 45 /* virtual address space layout info */ #define KERN_PROC_RLIMIT_USAGE 46 /* array of rlim_t */ +#define KERN_PROC_KQUEUE 47 /* array of struct kinfo_knote */ /* * KERN_IPC identifiers diff --git a/sys/sys/user.h b/sys/sys/user.h index 02ca69968541..cf42412af66f 100644 --- a/sys/sys/user.h +++ b/sys/sys/user.h @@ -38,6 +38,7 @@ #ifndef _KERNEL /* stuff that *used* to be included by user.h, or is now needed */ #include +#include #include #include #include @@ -665,6 +666,33 @@ struct kinfo_vm_layout { uintptr_t kvm_spare[12]; }; +#define KNOTE_STATUS_ACTIVE 0x00000001 +#define KNOTE_STATUS_QUEUED 0x00000002 +#define KNOTE_STATUS_DISABLED 0x00000004 +#define KNOTE_STATUS_DETACHED 0x00000008 +#define KNOTE_STATUS_KQUEUE 0x00000010 + +#define KNOTE_EXTDATA_NONE 0 +#define KNOTE_EXTDATA_VNODE 1 +#define KNOTE_EXTDATA_PIPE 2 + +struct kinfo_knote { + struct kevent knt_event; + int knt_status; + int knt_extdata; + union { + struct { + int knt_vnode_type; + uint64_t knt_vnode_fsid; + uint64_t knt_vnode_fileid; + char knt_vnode_fullpath[PATH_MAX]; + } knt_vnode; + struct { + ino_t knt_pipe_ino; + } knt_pipe; + }; +}; + #ifdef _KERNEL /* Flags for kern_proc_out function. */ #define KERN_PROC_NOTHREADS 0x1 diff --git a/sys/vm/sg_pager.c b/sys/vm/sg_pager.c index f1f4a3763bb0..64f226dd9c58 100644 --- a/sys/vm/sg_pager.c +++ b/sys/vm/sg_pager.c @@ -34,6 +34,7 @@ */ #include +#include #include #include #include