From owner-svn-src-all@freebsd.org Wed Aug 19 17:10:06 2020 Return-Path: Delivered-To: svn-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 2C4073C4C3F; Wed, 19 Aug 2020 17:10:06 +0000 (UTC) (envelope-from imp@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 "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4BWvRK3zN0z4HsS; Wed, 19 Aug 2020 17:10:05 +0000 (UTC) (envelope-from imp@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 5CB8425E74; Wed, 19 Aug 2020 17:10:05 +0000 (UTC) (envelope-from imp@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 07JHA5Iv008765; Wed, 19 Aug 2020 17:10:05 GMT (envelope-from imp@FreeBSD.org) Received: (from imp@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 07JHA5Rk008764; Wed, 19 Aug 2020 17:10:05 GMT (envelope-from imp@FreeBSD.org) Message-Id: <202008191710.07JHA5Rk008764@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: imp set sender to imp@FreeBSD.org using -f From: Warner Losh Date: Wed, 19 Aug 2020 17:10:05 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r364402 - head/sys/kern X-SVN-Group: head X-SVN-Commit-Author: imp X-SVN-Commit-Paths: head/sys/kern X-SVN-Commit-Revision: 364402 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.33 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 19 Aug 2020 17:10:06 -0000 Author: imp Date: Wed Aug 19 17:10:04 2020 New Revision: 364402 URL: https://svnweb.freebsd.org/changeset/base/364402 Log: Add VFS FS events for mount and unmount to devctl/devd Report when a filesystem is mounted, remounted or unmounted via devd, along with details about the mount point and mount options. Discussed with: kib@ Reviewed by: kirk@ (prior version) Sponsored by: Netflix Diffential Revision: https://reviews.freebsd.org/D25969 Modified: head/sys/kern/vfs_mount.c Modified: head/sys/kern/vfs_mount.c ============================================================================== --- head/sys/kern/vfs_mount.c Wed Aug 19 17:09:58 2020 (r364401) +++ head/sys/kern/vfs_mount.c Wed Aug 19 17:10:04 2020 (r364402) @@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -101,6 +102,8 @@ MTX_SYSINIT(mountlist, &mountlist_mtx, "mountlist", MT EVENTHANDLER_LIST_DEFINE(vfs_mounted); EVENTHANDLER_LIST_DEFINE(vfs_unmounted); +static void dev_vfs_event(const char *type, struct mount *mp, bool donew); + /* * Global opts, taken by all filesystems */ @@ -1020,6 +1023,7 @@ vfs_domount_first( VOP_UNLOCK(vp); EVENTHANDLER_DIRECT_INVOKE(vfs_mounted, mp, newdp, td); VOP_UNLOCK(newdp); + dev_vfs_event("MOUNT", mp, false); mountcheckdirs(vp, newdp); vn_seqc_write_end(vp); vn_seqc_write_end(newdp); @@ -1221,6 +1225,7 @@ vfs_domount_update( if (error != 0) goto end; + dev_vfs_event("REMOUNT", mp, true); if (mp->mnt_opt != NULL) vfs_freeopts(mp->mnt_opt); mp->mnt_opt = mp->mnt_optnew; @@ -1839,6 +1844,7 @@ dounmount(struct mount *mp, int flags, struct thread * TAILQ_REMOVE(&mountlist, mp, mnt_list); mtx_unlock(&mountlist_mtx); EVENTHANDLER_DIRECT_INVOKE(vfs_unmounted, mp, td); + dev_vfs_event("UNMOUNT", mp, false); if (coveredvp != NULL) { coveredvp->v_mountedhere = NULL; vn_seqc_write_end(coveredvp); @@ -2425,4 +2431,72 @@ kernel_vmount(int flags, ...) error = kernel_mount(ma, flags); return (error); +} + +/* Map from mount options to printable formats. */ +static struct mntoptnames optnames[] = { + MNTOPT_NAMES +}; + +static void +dev_vfs_event_mntopt(struct sbuf *sb, const char *what, struct vfsoptlist *opts) +{ + struct vfsopt *opt; + + if (opts == NULL || TAILQ_EMPTY(opts)) + return; + sbuf_printf(sb, " %s=\"", what); + TAILQ_FOREACH(opt, opts, link) { + if (opt->name[0] == '\0' || (opt->len > 0 && *(char *)opt->value == '\0')) + continue; + devctl_safe_quote_sb(sb, opt->name); + if (opt->len > 0) { + sbuf_putc(sb, '='); + devctl_safe_quote_sb(sb, opt->value); + } + sbuf_putc(sb, ';'); + } + sbuf_putc(sb, '"'); +} + +#define DEVCTL_LEN 1024 +static void +dev_vfs_event(const char *type, struct mount *mp, bool donew) +{ + const uint8_t *cp; + struct mntoptnames *fp; + struct sbuf sb; + struct statfs *sfp = &mp->mnt_stat; + char *buf; + + buf = malloc(DEVCTL_LEN, M_MOUNT, M_WAITOK); + if (buf == NULL) + return; + sbuf_new(&sb, buf, DEVCTL_LEN, SBUF_FIXEDLEN); + sbuf_cpy(&sb, "mount-point=\""); + devctl_safe_quote_sb(&sb, sfp->f_mntonname); + sbuf_cat(&sb, "\" mount-dev=\""); + devctl_safe_quote_sb(&sb, sfp->f_mntfromname); + sbuf_cat(&sb, "\" mount-type=\""); + devctl_safe_quote_sb(&sb, sfp->f_fstypename); + sbuf_cat(&sb, "\" fsid=0x"); + cp = (const uint8_t *)&sfp->f_fsid.val[0]; + for (int i = 0; i < sizeof(sfp->f_fsid); i++) + sbuf_printf(&sb, "%02x", cp[i]); + sbuf_printf(&sb, " owner=%u flags=\"", sfp->f_owner); + for (fp = optnames; fp->o_opt != 0; fp++) { + if ((mp->mnt_flag & fp->o_opt) != 0) { + sbuf_cat(&sb, fp->o_name); + sbuf_putc(&sb, ';'); + } + } + sbuf_putc(&sb, '"'); + dev_vfs_event_mntopt(&sb, "opt", mp->mnt_opt); + if (donew) + dev_vfs_event_mntopt(&sb, "optnew", mp->mnt_optnew); + sbuf_finish(&sb); + + devctl_notify("VFS", "FS", type, sbuf_data(&sb)); + sbuf_delete(&sb); + free(buf, M_MOUNT); }