From owner-svn-src-all@freebsd.org Fri Jun 5 06:34:07 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 A505F341C66; Fri, 5 Jun 2020 06:34:07 +0000 (UTC) (envelope-from avg@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 49dXt610ctz4CvF; Fri, 5 Jun 2020 06:34:05 +0000 (UTC) (envelope-from avg@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 942B8CC86; Fri, 5 Jun 2020 06:34:05 +0000 (UTC) (envelope-from avg@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 0556Y5eT048676; Fri, 5 Jun 2020 06:34:05 GMT (envelope-from avg@FreeBSD.org) Received: (from avg@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 0556Y4ch048671; Fri, 5 Jun 2020 06:34:04 GMT (envelope-from avg@FreeBSD.org) Message-Id: <202006050634.0556Y4ch048671@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: avg set sender to avg@FreeBSD.org using -f From: Andriy Gapon Date: Fri, 5 Jun 2020 06:34:04 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org Subject: svn commit: r361823 - in stable/12/lib/libprocstat: . zfs X-SVN-Group: stable-12 X-SVN-Commit-Author: avg X-SVN-Commit-Paths: in stable/12/lib/libprocstat: . zfs X-SVN-Commit-Revision: 361823 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: Fri, 05 Jun 2020 06:34:07 -0000 Author: avg Date: Fri Jun 5 06:34:04 2020 New Revision: 361823 URL: https://svnweb.freebsd.org/changeset/base/361823 Log: MFC r361363,r361434: libprocstat: fix ZFS support First of all, znode_phys_t hasn't been used for storing file attributes for a long time now. Modern ZFS versions use a System Attribute table with a flexible layout. But more importantly all the required information is available in znode_t itself. It's not easy to include zfs_znode.h in userland without breaking code because the most interesting parts of the header are kernel-only. And hardcoding field offsets is too fragile. So, I created a new compilation unit that includes zfs_znode.h using some mild kludges to get it and its dependencies to compile in userland. The compilation unit exports interesting field offsets and does not have any other code. PR: 194117 Sponsored by: Panzura Added: stable/12/lib/libprocstat/zfs_defs.c - copied, changed from r361363, head/lib/libprocstat/zfs_defs.c stable/12/lib/libprocstat/zfs_defs.h - copied unchanged from r361363, head/lib/libprocstat/zfs_defs.h Modified: stable/12/lib/libprocstat/Makefile stable/12/lib/libprocstat/zfs.c stable/12/lib/libprocstat/zfs/Makefile Directory Properties: stable/12/ (props changed) Modified: stable/12/lib/libprocstat/Makefile ============================================================================== --- stable/12/lib/libprocstat/Makefile Fri Jun 5 06:21:23 2020 (r361822) +++ stable/12/lib/libprocstat/Makefile Fri Jun 5 06:34:04 2020 (r361823) @@ -61,16 +61,17 @@ MLINKS+=libprocstat.3 procstat_close.3 \ # XXX This is a hack. .if ${MK_CDDL} != "no" CFLAGS+= -DLIBPROCSTAT_ZFS -OBJS+= zfs/zfs.o -SOBJS+= zfs/zfs.pico -POBJS+= zfs/zfs.po +SRCS+= zfs.c +OBJS+= zfs/zfs_defs.o +SOBJS+= zfs/zfs_defs.pico +POBJS+= zfs/zfs_defs.po SUBDIR= zfs -zfs/zfs.o: .PHONY - @cd ${.CURDIR}/zfs && ${MAKE} zfs.o -zfs/zfs.pico: .PHONY - @cd ${.CURDIR}/zfs && ${MAKE} zfs.pico -zfs/zfs.po: .PHONY - @cd ${.CURDIR}/zfs && ${MAKE} zfs.po +zfs/zfs_defs.o: .PHONY + @cd ${.CURDIR}/zfs && ${MAKE} zfs_defs.o +zfs/zfs_defs.pico: .PHONY + @cd ${.CURDIR}/zfs && ${MAKE} zfs_defs.pico +zfs/zfs_defs.po: .PHONY + @cd ${.CURDIR}/zfs && ${MAKE} zfs_defs.po .endif .include Modified: stable/12/lib/libprocstat/zfs.c ============================================================================== --- stable/12/lib/libprocstat/zfs.c Fri Jun 5 06:21:23 2020 (r361822) +++ stable/12/lib/libprocstat/zfs.c Fri Jun 5 06:34:04 2020 (r361823) @@ -31,22 +31,13 @@ #include #define _KERNEL #include -#include #undef _KERNEL +#include +#include #include +#include +#include -#undef lbolt -#undef lbolt64 -#undef gethrestime_sec -#include -#include -#include -#include -#include -#include -#include -#include - #include #include @@ -57,24 +48,15 @@ #define ZFS #include "libprocstat.h" #include "common_kvm.h" +#include "zfs_defs.h" -/* - * Offset calculations that are used to get data from znode without having the - * definition. - */ -#define LOCATION_ZID (2 * sizeof(void *)) -#define LOCATION_ZPHYS(zsize) ((zsize) - (2 * sizeof(void *) + sizeof(struct task))) - int zfs_filestat(kvm_t *kd, struct vnode *vp, struct vnstat *vn) { - znode_phys_t zphys; struct mount mount, *mountptr; - uint64_t *zid; - void *znodeptr, *vnodeptr; + void *znodeptr; char *dataptr; - void *zphys_addr; size_t len; int size; @@ -83,33 +65,27 @@ zfs_filestat(kvm_t *kd, struct vnode *vp, struct vnsta warnx("error getting sysctl"); return (1); } - znodeptr = malloc(size); - if (znodeptr == NULL) { + dataptr = malloc(size); + if (dataptr == NULL) { warnx("error allocating memory for znode storage"); return (1); } - /* Since we have problems including vnode.h, we'll use the wrappers. */ - vnodeptr = getvnodedata(vp); - if (!kvm_read_all(kd, (unsigned long)vnodeptr, znodeptr, - (size_t)size)) { - warnx("can't read znode at %p", (void *)vnodeptr); + + if ((size_t)size < offsetof_z_id + sizeof(uint64_t) || + (size_t)size < offsetof_z_mode + sizeof(mode_t) || + (size_t)size < offsetof_z_size + sizeof(uint64_t)) { + warnx("znode_t size is too small"); goto bad; } - /* - * z_id field is stored in the third pointer. We therefore skip the two - * first bytes. - * - * Pointer to the z_phys structure is the next last pointer. Therefore - * go back two bytes from the end. - */ - dataptr = znodeptr; - zid = (uint64_t *)(dataptr + LOCATION_ZID); - zphys_addr = *(void **)(dataptr + LOCATION_ZPHYS(size)); + if ((size_t)size != sizeof_znode_t) + warnx("znode_t size mismatch, data could be wrong"); - if (!kvm_read_all(kd, (unsigned long)zphys_addr, &zphys, - sizeof(zphys))) { - warnx("can't read znode_phys at %p", zphys_addr); + /* Since we have problems including vnode.h, we'll use the wrappers. */ + znodeptr = getvnodedata(vp); + if (!kvm_read_all(kd, (unsigned long)znodeptr, dataptr, + (size_t)size)) { + warnx("can't read znode at %p", (void *)znodeptr); goto bad; } @@ -119,18 +95,18 @@ zfs_filestat(kvm_t *kd, struct vnode *vp, struct vnsta warnx("can't read mount at %p", (void *)mountptr); goto bad; } - vn->vn_fsid = mount.mnt_stat.f_fsid.val[0]; - vn->vn_fileid = *zid; + /* - * XXX: Shows up wrong in output, but UFS has this error too. Could - * be that we're casting mode-variables from 64-bit to 8-bit or simply - * error in the mode-to-string function. + * XXX Assume that this is a znode, but it can be a special node + * under .zfs/. */ - vn->vn_mode = (mode_t)zphys.zp_mode; - vn->vn_size = (u_long)zphys.zp_size; - free(znodeptr); + vn->vn_fsid = mount.mnt_stat.f_fsid.val[0]; + vn->vn_fileid = *(uint64_t *)(void *)(dataptr + offsetof_z_id); + vn->vn_mode = *(mode_t *)(void *)(dataptr + offsetof_z_mode); + vn->vn_size = *(uint64_t *)(void *)(dataptr + offsetof_z_size); + free(dataptr); return (0); bad: - free(znodeptr); + free(dataptr); return (1); } Modified: stable/12/lib/libprocstat/zfs/Makefile ============================================================================== --- stable/12/lib/libprocstat/zfs/Makefile Fri Jun 5 06:21:23 2020 (r361822) +++ stable/12/lib/libprocstat/zfs/Makefile Fri Jun 5 06:34:04 2020 (r361823) @@ -2,20 +2,20 @@ .PATH: ${.CURDIR:H} -SRCS= zfs.c -OBJS= zfs.o +SRCS= zfs_defs.c +OBJS= zfs_defs.o WARNS?= 1 CFLAGS+= -I${SRCTOP}/sys/cddl/compat/opensolaris CFLAGS+= -I${SRCTOP}/cddl/compat/opensolaris/include CFLAGS+= -I${SRCTOP}/cddl/compat/opensolaris/lib/libumem -CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libzpool/common CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/common/zfs CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common/fs/zfs CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/head CFLAGS+= -I${.CURDIR:H} CFLAGS+= -DNEED_SOLARIS_BOOLEAN +CFLAGS+= -fno-builtin -nostdlib all: ${OBJS} CLEANFILES= ${OBJS} Copied and modified: stable/12/lib/libprocstat/zfs_defs.c (from r361363, head/lib/libprocstat/zfs_defs.c) ============================================================================== --- head/lib/libprocstat/zfs_defs.c Fri May 22 11:20:23 2020 (r361363, copy source) +++ stable/12/lib/libprocstat/zfs_defs.c Fri Jun 5 06:34:04 2020 (r361823) @@ -57,3 +57,7 @@ size_t sizeof_znode_t = sizeof(znode_t); size_t offsetof_z_id = offsetof(znode_t, z_id); size_t offsetof_z_size = offsetof(znode_t, z_size); size_t offsetof_z_mode = offsetof(znode_t, z_mode); + +/* Keep pcpu.h satisfied. */ +uintptr_t *__start_set_pcpu; +uintptr_t *__stop_set_pcpu; Copied: stable/12/lib/libprocstat/zfs_defs.h (from r361363, head/lib/libprocstat/zfs_defs.h) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ stable/12/lib/libprocstat/zfs_defs.h Fri Jun 5 06:34:04 2020 (r361823, copy of r361363, head/lib/libprocstat/zfs_defs.h) @@ -0,0 +1,38 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2020 Andriy Gapon + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _LIBPROCSTAT_ZFS_DEFS_H +#define _LIBPROCSTAT_ZFS_DEFS_H + +extern size_t sizeof_znode_t; +extern size_t offsetof_z_id; +extern size_t offsetof_z_size; +extern size_t offsetof_z_mode; + +#endif /* _LIBPROCSTAT_ZFS_DEFS_H */