From nobody Mon Apr 7 01:28:57 2025 X-Original-To: dev-commits-src-all@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 4ZWBST6rn0z5sN96; Mon, 07 Apr 2025 01:28:57 +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 4ZWBST6Kqtz3wY8; Mon, 07 Apr 2025 01:28:57 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1743989337; 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=8MyKzqdYwboY+4ZeHPdaWVSyu52vbzgSUGiGQYvJ7GI=; b=aqnsAiCqDdD7ry/F6d0usbK+efjxS+D3mbPzLSaY7aRsAVJEjykByDZstaahF5rqUKnpMQ T2bHRhpMQ68G2kpffuQbx7O5qy54jF5vJ6ebnf9SREL6+9Nld0KpDhvSF5xiDc8C0YnurC ez0NZ5+X2jrDrkzQw4t+8Z3Z2ZZ0PAg+bByQdYzWb6l0U1b1lYjmnlstfuy4OMmSi2VsW2 8WnDI8UaMqVCEOYTCXiOVHuk0TpwCbV7G394JD1hdWJWSW+6nT0pT8d54hBL9jJqy73Xv7 sOmxTnzuzBevj5+qvEYstrDDXc145j1Gkrv7S3Ndzy+DDrQ7P5PxrI+v7qUMDw== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1743989337; a=rsa-sha256; cv=none; b=HMysYZDt6UBjso7f/nbJLXXokvTEdrx401nh7a6gWAOxP+kW6KfW0b4AuhwWysrSKPNuyC pzG9bMBCXjrs9LkaucdB4yDweZg0OStMl1M1IRQBGsXOIVXzPDCjoDHPe367B7xKrrbqx6 BU03Lo7fmi+jKwjhrBwQ7ueCNi/GhdjbJP8BZjQFWLP9lOX8+V9jaFy/du8ILgKfb7YGat uo3WRGbHfLx29EfuzrKsacEqPLeMEHk8l2WvnPwKtJsJNYAA5eEacBcE7k9BLcM9zHtcqN LlDW0kQveMu8Mc82faHLyHh9QAYWQJLJP2vlFfkVGxWN80PGWXUTv7wJ9UD67Q== 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=1743989337; 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=8MyKzqdYwboY+4ZeHPdaWVSyu52vbzgSUGiGQYvJ7GI=; b=BxEDu9ImQvJ1Uy5OcwOpg56xVnlJpWNlmwfq/9Q8gJ+UoiiE7gZ/uqRs+a4hdoys6Kgb0J 5B519JLVdk5PSHyCD5xm1P2C0Mc35NXS6BXbRql9mk0aZoBeAum00wwu9Rc5i3M7asEr6E LVHv2CYw89yVVVkDxtAtjBet4SmskWpDzWw1VTbW7eLDww73ECzWh7aznUTNZRLHTJBvIo E0ftnB6KkP6jYOUdpOCx+0EeNE7f9mwmQANkWTBgqE0W6woxGYYL5jKK6UELHNiHHpxb18 TTP9Z4l6lYrCC4TZfvle3R1wLKZgDMUVSK7k0ktK3r/ma3OIrYpqbPYdJYMp1Q== 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 4ZWBST5n98z9V2; Mon, 07 Apr 2025 01:28:57 +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 5371Svng062826; Mon, 7 Apr 2025 01:28:57 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 5371SvW3062823; Mon, 7 Apr 2025 01:28:57 GMT (envelope-from git) Date: Mon, 7 Apr 2025 01:28:57 GMT Message-Id: <202504070128.5371SvW3062823@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Konstantin Belousov Subject: git: e2af76d47017 - stable/14 - Add sysctl kern.proc.kqueue List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@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/stable/14 X-Git-Reftype: branch X-Git-Commit: e2af76d4701719a485f8972cef05bb8d0fbc50c3 Auto-Submitted: auto-generated The branch stable/14 has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=e2af76d4701719a485f8972cef05bb8d0fbc50c3 commit e2af76d4701719a485f8972cef05bb8d0fbc50c3 Author: Konstantin Belousov AuthorDate: 2025-02-23 20:25:25 +0000 Commit: Konstantin Belousov CommitDate: 2025-04-07 01:28:20 +0000 Add sysctl kern.proc.kqueue (cherry picked from commit e60f608eb9cf3b38099948545934d699de9bbcea) --- 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 f2f1a42adf2b..651f7312a37f 100644 --- a/sys/kern/sys_pipe.c +++ b/sys/kern/sys_pipe.c @@ -176,21 +176,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, }; /* @@ -1901,3 +1906,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 6c116448a59a..bf1ed1b51109 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -81,6 +81,7 @@ #include #include #include +#include #include #include #include @@ -6416,7 +6417,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 @@ -6494,20 +6495,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 @@ -6656,6 +6663,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 a446d6701cfa..5955b704b7f9 100644 --- a/sys/sys/sysctl.h +++ b/sys/sys/sysctl.h @@ -1043,6 +1043,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 7e4ab5bd914f..aa8c38d13288 100644 --- a/sys/sys/user.h +++ b/sys/sys/user.h @@ -40,6 +40,7 @@ #ifndef _KERNEL /* stuff that *used* to be included by user.h, or is now needed */ #include +#include #include #include #include @@ -667,6 +668,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