From patchwork Wed Sep 9 18:40:21 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 1360935 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=GnwYiCAS; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4BmrSn3SkNz9sTH for ; Thu, 10 Sep 2020 04:41:13 +1000 (AEST) Received: from localhost ([::1]:43860 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kG51r-0005LH-C5 for incoming@patchwork.ozlabs.org; Wed, 09 Sep 2020 14:41:11 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56434) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kG51W-0005IQ-Lk for qemu-devel@nongnu.org; Wed, 09 Sep 2020 14:40:50 -0400 Received: from us-smtp-1.mimecast.com ([205.139.110.61]:33571 helo=us-smtp-delivery-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1kG51U-0007D6-Ue for qemu-devel@nongnu.org; Wed, 09 Sep 2020 14:40:50 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1599676847; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=3hIuRlOch12nW25o6+lj0a/Akr3yOI37PrVQ6WMUZPo=; b=GnwYiCASqF+Fq/bN95AyMGOl/Ek0/6nsIdu5Vjt7gQ1J3iZD1bJmnnPVbdJIi/uKEycvQD cr9ML8sfk1HAi9r/ZGYvuOczWo6sshNjTqLer+Z/M+mk/+dEIJS7sjLH/HNQcoBz/tqYTB 53PgCYvR/FIVVNNKG+skyCGOb5N4bSs= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-386-zIz3GvgLPNW1qIpSQrAHbQ-1; Wed, 09 Sep 2020 14:40:45 -0400 X-MC-Unique: zIz3GvgLPNW1qIpSQrAHbQ-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 3AC211084C82 for ; Wed, 9 Sep 2020 18:40:44 +0000 (UTC) Received: from localhost (ovpn-113-94.ams2.redhat.com [10.36.113.94]) by smtp.corp.redhat.com (Postfix) with ESMTPS id DCD6E7E8E3; Wed, 9 Sep 2020 18:40:37 +0000 (UTC) From: Max Reitz To: qemu-devel@nongnu.org Subject: [PATCH 1/8] linux/fuse.h: Pull in from Linux Date: Wed, 9 Sep 2020 20:40:21 +0200 Message-Id: <20200909184028.262297-2-mreitz@redhat.com> In-Reply-To: <20200909184028.262297-1-mreitz@redhat.com> References: <20200909184028.262297-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=mreitz@redhat.com X-Mimecast-Spam-Score: 0.001 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=205.139.110.61; envelope-from=mreitz@redhat.com; helo=us-smtp-delivery-1.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/09/09 14:15:10 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: virtio-fs@redhat.com, Miklos Szeredi , "Dr . David Alan Gilbert" , Stefan Hajnoczi , Max Reitz Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Update the linux/fuse.h standard header from the kernel development tree that implements FUSE submounts. This adds the fuse_attr.flags field, the FUSE_ATTR_FLAGS INIT flag, and the FUSE_ATTR_SUBMOUNT flag for fuse_attr.flags. Signed-off-by: Max Reitz --- include/standard-headers/linux/fuse.h | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/include/standard-headers/linux/fuse.h b/include/standard-headers/linux/fuse.h index f4df0a40f6..7dd7a3b992 100644 --- a/include/standard-headers/linux/fuse.h +++ b/include/standard-headers/linux/fuse.h @@ -227,7 +227,7 @@ struct fuse_attr { uint32_t gid; uint32_t rdev; uint32_t blksize; - uint32_t padding; + uint32_t flags; }; struct fuse_kstatfs { @@ -310,6 +310,7 @@ struct fuse_file_lock { * FUSE_NO_OPENDIR_SUPPORT: kernel supports zero-message opendir * FUSE_EXPLICIT_INVAL_DATA: only invalidate cached pages on explicit request * FUSE_MAP_ALIGNMENT: map_alignment field is valid + * FUSE_ATTR_FLAGS: fuse_attr.flags is present and valid */ #define FUSE_ASYNC_READ (1 << 0) #define FUSE_POSIX_LOCKS (1 << 1) @@ -338,6 +339,7 @@ struct fuse_file_lock { #define FUSE_NO_OPENDIR_SUPPORT (1 << 24) #define FUSE_EXPLICIT_INVAL_DATA (1 << 25) #define FUSE_MAP_ALIGNMENT (1 << 26) +#define FUSE_ATTR_FLAGS (1 << 27) /** * CUSE INIT request/reply flags @@ -413,6 +415,13 @@ struct fuse_file_lock { */ #define FUSE_FSYNC_FDATASYNC (1 << 0) +/** + * fuse_attr flags + * + * FUSE_ATTR_SUBMOUNT: File/directory is a submount point + */ +#define FUSE_ATTR_SUBMOUNT (1 << 0) + enum fuse_opcode { FUSE_LOOKUP = 1, FUSE_FORGET = 2, /* no reply */ From patchwork Wed Sep 9 18:40:22 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 1360937 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=X1YBOiQD; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4BmrVm06Spz9sTH for ; Thu, 10 Sep 2020 04:42:55 +1000 (AEST) Received: from localhost ([::1]:50000 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kG53V-0007pE-NT for incoming@patchwork.ozlabs.org; Wed, 09 Sep 2020 14:42:53 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56486) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kG51c-0005TE-Sh for qemu-devel@nongnu.org; Wed, 09 Sep 2020 14:40:56 -0400 Received: from us-smtp-delivery-1.mimecast.com ([205.139.110.120]:46580 helo=us-smtp-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1kG51b-0007Lx-4b for qemu-devel@nongnu.org; Wed, 09 Sep 2020 14:40:56 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1599676854; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=iD3nU3q29aS+NTmVIJFCCkIEfzkuLj2dF9Y2ZbLAPos=; b=X1YBOiQD6eLxyQS3brne9RcitLtHe3jyHvBz/KNFQVKMZCbXVP0/uGFQEI0ZIYIOV8uTBi tTYZlrmaHj3I0XD4L3FremjprtcWI42m8pciVpX5xxLw2caAKgPz1n3aj6Dvp/A1WnNZ9q k5Kwkh6amJx3Zxt2YbkGGUxg4VHY0+0= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-512-RRXArTR_OmylrN2gsfeP4A-1; Wed, 09 Sep 2020 14:40:52 -0400 X-MC-Unique: RRXArTR_OmylrN2gsfeP4A-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 1024B80EF8C for ; Wed, 9 Sep 2020 18:40:52 +0000 (UTC) Received: from localhost (ovpn-113-94.ams2.redhat.com [10.36.113.94]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 3079719C78; Wed, 9 Sep 2020 18:40:46 +0000 (UTC) From: Max Reitz To: qemu-devel@nongnu.org Subject: [PATCH 2/8] virtiofsd: Announce FUSE_ATTR_FLAGS Date: Wed, 9 Sep 2020 20:40:22 +0200 Message-Id: <20200909184028.262297-3-mreitz@redhat.com> In-Reply-To: <20200909184028.262297-1-mreitz@redhat.com> References: <20200909184028.262297-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=mreitz@redhat.com X-Mimecast-Spam-Score: 0.001 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=205.139.110.120; envelope-from=mreitz@redhat.com; helo=us-smtp-1.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/09/09 03:13:17 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: virtio-fs@redhat.com, Miklos Szeredi , "Dr . David Alan Gilbert" , Stefan Hajnoczi , Max Reitz Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" The fuse_attr.flags field is currently just initialized to 0, which is valid. Thus, there is no reason not to always announce FUSE_ATTR_FLAGS (when the kernel supports it). Signed-off-by: Max Reitz --- tools/virtiofsd/fuse_common.h | 8 ++++++++ tools/virtiofsd/fuse_lowlevel.c | 7 +++++++ 2 files changed, 15 insertions(+) diff --git a/tools/virtiofsd/fuse_common.h b/tools/virtiofsd/fuse_common.h index 686c42c0a5..870544fe13 100644 --- a/tools/virtiofsd/fuse_common.h +++ b/tools/virtiofsd/fuse_common.h @@ -352,6 +352,14 @@ struct fuse_file_info { */ #define FUSE_CAP_NO_OPENDIR_SUPPORT (1 << 24) +/** + * Indicates that the client will provide fuse_attr.flags, and the kernel will + * interpret it. + * + * This feature is enabled by default when supported by the kernel. + */ +#define FUSE_CAP_ATTR_FLAGS (1 << 27) + /** * Ioctl flags * diff --git a/tools/virtiofsd/fuse_lowlevel.c b/tools/virtiofsd/fuse_lowlevel.c index 2dd36ec03b..e9e2652d33 100644 --- a/tools/virtiofsd/fuse_lowlevel.c +++ b/tools/virtiofsd/fuse_lowlevel.c @@ -1988,6 +1988,9 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, bufsize = max_bufsize; } } + if (arg->flags & FUSE_ATTR_FLAGS) { + se->conn.capable |= FUSE_CAP_ATTR_FLAGS; + } #ifdef HAVE_SPLICE #ifdef HAVE_VMSPLICE se->conn.capable |= FUSE_CAP_SPLICE_WRITE | FUSE_CAP_SPLICE_MOVE; @@ -2014,6 +2017,7 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, LL_SET_DEFAULT(1, FUSE_CAP_ASYNC_DIO); LL_SET_DEFAULT(1, FUSE_CAP_IOCTL_DIR); LL_SET_DEFAULT(1, FUSE_CAP_ATOMIC_O_TRUNC); + LL_SET_DEFAULT(1, FUSE_CAP_ATTR_FLAGS); LL_SET_DEFAULT(se->op.write_buf, FUSE_CAP_SPLICE_READ); LL_SET_DEFAULT(se->op.getlk && se->op.setlk, FUSE_CAP_POSIX_LOCKS); LL_SET_DEFAULT(se->op.flock, FUSE_CAP_FLOCK_LOCKS); @@ -2103,6 +2107,9 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, if (se->conn.want & FUSE_CAP_POSIX_ACL) { outarg.flags |= FUSE_POSIX_ACL; } + if (se->conn.want & FUSE_CAP_ATTR_FLAGS) { + outarg.flags |= FUSE_ATTR_FLAGS; + } outarg.max_readahead = se->conn.max_readahead; outarg.max_write = se->conn.max_write; if (se->conn.max_background >= (1 << 16)) { From patchwork Wed Sep 9 18:40:23 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 1360941 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=UxFAyqFD; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4BmrY76tmNz9sTH for ; Thu, 10 Sep 2020 04:44:59 +1000 (AEST) Received: from localhost ([::1]:57454 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kG55V-0002PX-TM for incoming@patchwork.ozlabs.org; Wed, 09 Sep 2020 14:44:57 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56510) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kG51f-0005ap-SY for qemu-devel@nongnu.org; Wed, 09 Sep 2020 14:40:59 -0400 Received: from us-smtp-2.mimecast.com ([205.139.110.61]:20763 helo=us-smtp-delivery-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1kG51e-0007Nx-6M for qemu-devel@nongnu.org; Wed, 09 Sep 2020 14:40:59 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1599676856; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Arn6B0SmeqikafxO9N/VhdjhmeW74avnuzI4jKm4YPA=; b=UxFAyqFDdNlMGk+h7hQu9+MnsNpojWiKJLZmqzcejtgx+k/EiidLKVynTz2WMa71IHi9z2 W+fLzl2uEvDuvC79k1w2RDZ+8unQJ+m+3Sk6AOAsbwDNJ6RSD4HCtU1C6N7zMlYMOoIxfa E/b6mokhAUD4SweZaIjrSV8kaFgYpmI= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-208-5DCMU4eNMWC9lm-RQR-qJA-1; Wed, 09 Sep 2020 14:40:55 -0400 X-MC-Unique: 5DCMU4eNMWC9lm-RQR-qJA-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 8ED081DDFD for ; Wed, 9 Sep 2020 18:40:54 +0000 (UTC) Received: from localhost (ovpn-113-94.ams2.redhat.com [10.36.113.94]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 260517E8E0; Wed, 9 Sep 2020 18:40:53 +0000 (UTC) From: Max Reitz To: qemu-devel@nongnu.org Subject: [PATCH 3/8] virtiofsd: Add attr_flags to fuse_entry_param Date: Wed, 9 Sep 2020 20:40:23 +0200 Message-Id: <20200909184028.262297-4-mreitz@redhat.com> In-Reply-To: <20200909184028.262297-1-mreitz@redhat.com> References: <20200909184028.262297-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=mreitz@redhat.com X-Mimecast-Spam-Score: 0.001 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=205.139.110.61; envelope-from=mreitz@redhat.com; helo=us-smtp-delivery-1.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/09/09 14:15:10 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: virtio-fs@redhat.com, Miklos Szeredi , "Dr . David Alan Gilbert" , Stefan Hajnoczi , Max Reitz Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" fuse_entry_param is converted to fuse_attr on the line (by fill_entry()), so it should have a member that mirrors fuse_attr.flags. fill_entry() should then copy this fuse_entry_param.attr_flags to fuse_attr.flags. Signed-off-by: Max Reitz --- tools/virtiofsd/fuse_lowlevel.h | 5 +++++ tools/virtiofsd/fuse_lowlevel.c | 13 +++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/tools/virtiofsd/fuse_lowlevel.h b/tools/virtiofsd/fuse_lowlevel.h index 562fd5241e..9c06240f9e 100644 --- a/tools/virtiofsd/fuse_lowlevel.h +++ b/tools/virtiofsd/fuse_lowlevel.h @@ -102,6 +102,11 @@ struct fuse_entry_param { * large value. */ double entry_timeout; + + /** + * Flags for fuse_attr.flags that do not fit into attr. + */ + uint32_t attr_flags; }; /** diff --git a/tools/virtiofsd/fuse_lowlevel.c b/tools/virtiofsd/fuse_lowlevel.c index e9e2652d33..3ca49456c3 100644 --- a/tools/virtiofsd/fuse_lowlevel.c +++ b/tools/virtiofsd/fuse_lowlevel.c @@ -329,7 +329,8 @@ static unsigned int calc_timeout_nsec(double t) } } -static void fill_entry(struct fuse_entry_out *arg, +static void fill_entry(struct fuse_session *se, + struct fuse_entry_out *arg, const struct fuse_entry_param *e) { *arg = (struct fuse_entry_out){ @@ -341,6 +342,10 @@ static void fill_entry(struct fuse_entry_out *arg, .attr_valid_nsec = calc_timeout_nsec(e->attr_timeout), }; convert_stat(&e->attr, &arg->attr); + + if (se->conn.capable & FUSE_CAP_ATTR_FLAGS) { + arg->attr.flags = e->attr_flags; + } } /* @@ -365,7 +370,7 @@ size_t fuse_add_direntry_plus(fuse_req_t req, char *buf, size_t bufsize, struct fuse_direntplus *dp = (struct fuse_direntplus *)buf; memset(&dp->entry_out, 0, sizeof(dp->entry_out)); - fill_entry(&dp->entry_out, e); + fill_entry(req->se, &dp->entry_out, e); struct fuse_dirent *dirent = &dp->dirent; *dirent = (struct fuse_dirent){ @@ -403,7 +408,7 @@ int fuse_reply_entry(fuse_req_t req, const struct fuse_entry_param *e) size_t size = sizeof(arg); memset(&arg, 0, sizeof(arg)); - fill_entry(&arg, e); + fill_entry(req->se, &arg, e); return send_reply_ok(req, &arg, size); } @@ -416,7 +421,7 @@ int fuse_reply_create(fuse_req_t req, const struct fuse_entry_param *e, struct fuse_open_out *oarg = (struct fuse_open_out *)(buf + entrysize); memset(buf, 0, sizeof(buf)); - fill_entry(earg, e); + fill_entry(req->se, earg, e); fill_open(oarg, f); return send_reply_ok(req, buf, entrysize + sizeof(struct fuse_open_out)); } From patchwork Wed Sep 9 18:40:24 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 1360943 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=Jiz3Rspk; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4BmrbC1Ydhz9sTM for ; Thu, 10 Sep 2020 04:46:47 +1000 (AEST) Received: from localhost ([::1]:35262 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kG57F-0004uh-7J for incoming@patchwork.ozlabs.org; Wed, 09 Sep 2020 14:46:45 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56552) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kG51j-0005jC-KU for qemu-devel@nongnu.org; Wed, 09 Sep 2020 14:41:03 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:23267) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1kG51h-0007Op-Qf for qemu-devel@nongnu.org; Wed, 09 Sep 2020 14:41:03 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1599676860; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=cH7xZq5UQALYLOlvnCkkgvSjeRQrwsY6OiBeqlB2TJc=; b=Jiz3RspkEPMV54ED6z1HpAS8gpgq8VoTSQWwExaZOTmBvQqPcxL3HHwKIm+K7rkFxjr3ek 23ffFj1e9Xbp6FiL+9k97YLNdj01AXzv0MCnPGxfZdqwDhZaBffnR+8vPleWmxPxBNDNa7 GQ/OxeKCs+Aw2P7cQYQ2RVg6JCfVLVc= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-195-cdIuODWMPkSFLEI5TPMPGg-1; Wed, 09 Sep 2020 14:40:57 -0400 X-MC-Unique: cdIuODWMPkSFLEI5TPMPGg-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id E843780EF8C for ; Wed, 9 Sep 2020 18:40:56 +0000 (UTC) Received: from localhost (ovpn-113-94.ams2.redhat.com [10.36.113.94]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 7A14219C78; Wed, 9 Sep 2020 18:40:56 +0000 (UTC) From: Max Reitz To: qemu-devel@nongnu.org Subject: [PATCH 4/8] virtiofsd: Add fuse_reply_attr_with_flags() Date: Wed, 9 Sep 2020 20:40:24 +0200 Message-Id: <20200909184028.262297-5-mreitz@redhat.com> In-Reply-To: <20200909184028.262297-1-mreitz@redhat.com> References: <20200909184028.262297-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=mreitz@redhat.com X-Mimecast-Spam-Score: 0.001 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=216.205.24.124; envelope-from=mreitz@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/09/09 07:20:24 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: virtio-fs@redhat.com, Miklos Szeredi , "Dr . David Alan Gilbert" , Stefan Hajnoczi , Max Reitz Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" The plain fuse_reply_attr() function does not allow setting fuse_attr.flags, so add this new function that does. Make fuse_reply_attr() a wrapper around it. Signed-off-by: Max Reitz --- tools/virtiofsd/fuse_lowlevel.h | 15 +++++++++++++++ tools/virtiofsd/fuse_lowlevel.c | 14 ++++++++++++-- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/tools/virtiofsd/fuse_lowlevel.h b/tools/virtiofsd/fuse_lowlevel.h index 9c06240f9e..1ff6ba1e4f 100644 --- a/tools/virtiofsd/fuse_lowlevel.h +++ b/tools/virtiofsd/fuse_lowlevel.h @@ -1313,6 +1313,21 @@ int fuse_reply_create(fuse_req_t req, const struct fuse_entry_param *e, int fuse_reply_attr(fuse_req_t req, const struct stat *attr, double attr_timeout); +/** + * Reply with attributes and set fuse_attr.flags + * + * Possible requests: + * getattr, setattr + * + * @param req request handle + * @param attr the attributes + * @param attr_timeout validity timeout (in seconds) for the attributes + * @param attr_flags flags to put into fuse_attr.flags + * @return zero for success, -errno for failure to send reply + */ +int fuse_reply_attr_with_flags(fuse_req_t req, const struct stat *attr, + double attr_timeout, uint32_t attr_flags); + /** * Reply with the contents of a symbolic link * diff --git a/tools/virtiofsd/fuse_lowlevel.c b/tools/virtiofsd/fuse_lowlevel.c index 3ca49456c3..70efd3feaf 100644 --- a/tools/virtiofsd/fuse_lowlevel.c +++ b/tools/virtiofsd/fuse_lowlevel.c @@ -426,8 +426,8 @@ int fuse_reply_create(fuse_req_t req, const struct fuse_entry_param *e, return send_reply_ok(req, buf, entrysize + sizeof(struct fuse_open_out)); } -int fuse_reply_attr(fuse_req_t req, const struct stat *attr, - double attr_timeout) +int fuse_reply_attr_with_flags(fuse_req_t req, const struct stat *attr, + double attr_timeout, uint32_t attr_flags) { struct fuse_attr_out arg; size_t size = sizeof(arg); @@ -437,9 +437,19 @@ int fuse_reply_attr(fuse_req_t req, const struct stat *attr, arg.attr_valid_nsec = calc_timeout_nsec(attr_timeout); convert_stat(attr, &arg.attr); + if (req->se->conn.capable & FUSE_CAP_ATTR_FLAGS) { + arg.attr.flags = attr_flags; + } + return send_reply_ok(req, &arg, size); } +int fuse_reply_attr(fuse_req_t req, const struct stat *attr, + double attr_timeout) +{ + return fuse_reply_attr_with_flags(req, attr, attr_timeout, 0); +} + int fuse_reply_readlink(fuse_req_t req, const char *linkname) { return send_reply_ok(req, linkname, strlen(linkname)); From patchwork Wed Sep 9 18:40:25 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 1360938 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=bVJxIGa/; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4BmrWX2Xrlz9sTH for ; Thu, 10 Sep 2020 04:43:36 +1000 (AEST) Received: from localhost ([::1]:51504 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kG546-0008Po-1M for incoming@patchwork.ozlabs.org; Wed, 09 Sep 2020 14:43:34 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56590) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kG51r-0005yw-0n for qemu-devel@nongnu.org; Wed, 09 Sep 2020 14:41:11 -0400 Received: from us-smtp-1.mimecast.com ([207.211.31.81]:38813 helo=us-smtp-delivery-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1kG51p-0007SL-F5 for qemu-devel@nongnu.org; Wed, 09 Sep 2020 14:41:10 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1599676868; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=nh0FPSe4hR16BIoT/N4xYTXt5vkDFlUFUIGOhNvTSeI=; b=bVJxIGa/7KsWqzYC62toP4Fsw+3JH84DMbhflW/KbTRsOKiHQ4oS6V2GT+twXeAoODDFcV iZgbzAr3GIvPop8H5/FGXrdsXVSXrOQ4z4Vfa6yW1Utu0s7OW7qJNDBjXHRca7m5suCU/H M2DnnuOZTiE26hUaWS0YpEzImtMZkjE= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-125-cn6qZ8zrMl6JqWeBZOb9_Q-1; Wed, 09 Sep 2020 14:41:06 -0400 X-MC-Unique: cn6qZ8zrMl6JqWeBZOb9_Q-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id E94FC80EF8A for ; Wed, 9 Sep 2020 18:41:05 +0000 (UTC) Received: from localhost (ovpn-113-94.ams2.redhat.com [10.36.113.94]) by smtp.corp.redhat.com (Postfix) with ESMTPS id CC2A860BEC; Wed, 9 Sep 2020 18:40:59 +0000 (UTC) From: Max Reitz To: qemu-devel@nongnu.org Subject: [PATCH 5/8] virtiofsd: Store every lo_inode's parent_dev Date: Wed, 9 Sep 2020 20:40:25 +0200 Message-Id: <20200909184028.262297-6-mreitz@redhat.com> In-Reply-To: <20200909184028.262297-1-mreitz@redhat.com> References: <20200909184028.262297-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=mreitz@redhat.com X-Mimecast-Spam-Score: 0.002 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=207.211.31.81; envelope-from=mreitz@redhat.com; helo=us-smtp-delivery-1.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/09/09 02:43:02 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: virtio-fs@redhat.com, Miklos Szeredi , "Dr . David Alan Gilbert" , Stefan Hajnoczi , Max Reitz Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" We want to detect mount points in the shared tree. We report them to the guest by setting the FUSE_ATTR_SUBMOUNT flag in fuse_attr.flags, but because the FUSE client will create a submount for every directory that has this flag set, we must do this only for the actual mount points. We can detect mount points by comparing a directory's st_dev with its parent's st_dev. To be able to do so, we need to store the parent's st_dev in the lo_inode object. Note that mount points need not necessarily be directories; a single file can be a mount point as well. However, for the sake of simplicity let us ignore any non-directory mount points for now. Signed-off-by: Max Reitz --- tools/virtiofsd/passthrough_ll.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tools/virtiofsd/passthrough_ll.c b/tools/virtiofsd/passthrough_ll.c index 784330e0e4..2c48c03b4c 100644 --- a/tools/virtiofsd/passthrough_ll.c +++ b/tools/virtiofsd/passthrough_ll.c @@ -124,6 +124,14 @@ struct lo_inode { GHashTable *posix_locks; /* protected by lo_inode->plock_mutex */ mode_t filetype; + + /* + * So we can detect crossmount roots + * (As such, this only needs to be valid for directories. Note + * that files can have multiple parents due to hard links, and so + * their parent_dev may fluctuate.) + */ + dev_t parent_dev; }; struct lo_cred { @@ -821,6 +829,7 @@ static int lo_do_lookup(fuse_req_t req, fuse_ino_t parent, const char *name, g_hash_table_insert(lo->inodes, &inode->key, inode); pthread_mutex_unlock(&lo->mutex); } + inode->parent_dev = dir->key.dev; e->ino = inode->fuse_ino; lo_inode_put(lo, &inode); lo_inode_put(lo, &dir); @@ -1047,6 +1056,14 @@ static void lo_link(fuse_req_t req, fuse_ino_t ino, fuse_ino_t parent, fuse_log(FUSE_LOG_DEBUG, " %lli/%s -> %lli\n", (unsigned long long)parent, name, (unsigned long long)e.ino); + /* + * No need to update inode->parent_dev, because + * (1) We cannot, the inode now has more than one parent, + * (2) Directories cannot have more than one parent, so link() + * does not work for them; but parent_dev only needs to be + * valid for directories. + */ + fuse_reply_entry(req, &e); lo_inode_put(lo, &parent_inode); lo_inode_put(lo, &inode); From patchwork Wed Sep 9 18:40:26 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 1360944 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=SvMZqLe0; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4BmrdQ6PWwz9sTH for ; Thu, 10 Sep 2020 04:48:42 +1000 (AEST) Received: from localhost ([::1]:39114 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kG596-0006VL-R8 for incoming@patchwork.ozlabs.org; Wed, 09 Sep 2020 14:48:40 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56764) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kG52H-0006bo-Ho for qemu-devel@nongnu.org; Wed, 09 Sep 2020 14:41:37 -0400 Received: from us-smtp-1.mimecast.com ([207.211.31.81]:22595 helo=us-smtp-delivery-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1kG528-0007Wm-2L for qemu-devel@nongnu.org; Wed, 09 Sep 2020 14:41:37 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1599676887; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=h/3RU9i9f4uhYugdG9EKMoXD/+j4KkTslSj3LvNgL4w=; b=SvMZqLe0EFQknq2Mcr7JXHcfMrMC8aJAKVDbXZ8xJVXg5ZmgAg8+EO1Yyi89a5wzqII0c9 wGu89sqgj7GNw7Ajd0MRFyAaDBZwygVuy7EuuCL6fXRTUYifjCUx7DvkrY/XR06ys5muG4 /L87TF8bIffuewNcFD3OfMaEG6iDsI4= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-455-KwrEkrVBOT2iMOWUM526Ng-1; Wed, 09 Sep 2020 14:41:15 -0400 X-MC-Unique: KwrEkrVBOT2iMOWUM526Ng-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 4EAFE1882FA1 for ; Wed, 9 Sep 2020 18:41:14 +0000 (UTC) Received: from localhost (ovpn-113-94.ams2.redhat.com [10.36.113.94]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 102AE5C221; Wed, 9 Sep 2020 18:41:07 +0000 (UTC) From: Max Reitz To: qemu-devel@nongnu.org Subject: [PATCH 6/8] virtiofsd: Announce sub-mount points Date: Wed, 9 Sep 2020 20:40:26 +0200 Message-Id: <20200909184028.262297-7-mreitz@redhat.com> In-Reply-To: <20200909184028.262297-1-mreitz@redhat.com> References: <20200909184028.262297-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=mreitz@redhat.com X-Mimecast-Spam-Score: 0.001 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=207.211.31.81; envelope-from=mreitz@redhat.com; helo=us-smtp-delivery-1.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/09/09 02:43:02 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: virtio-fs@redhat.com, Miklos Szeredi , "Dr . David Alan Gilbert" , Stefan Hajnoczi , Max Reitz Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Whenever we encounter a directory with an st_dev that differs from that of its parent, we set the FUSE_ATTR_SUBMOUNT flag so the guest can create a submount for it. Make this behavior optional, so submounts are only announced to the guest with the announce_submounts option. Some users may prefer the current behavior, so that the guest learns nothing about the host mount structure. Signed-off-by: Max Reitz --- tools/virtiofsd/helper.c | 1 + tools/virtiofsd/passthrough_ll.c | 67 ++++++++++++++++++++++++++++---- 2 files changed, 60 insertions(+), 8 deletions(-) diff --git a/tools/virtiofsd/helper.c b/tools/virtiofsd/helper.c index 7bc5d7dc5a..8c5b923604 100644 --- a/tools/virtiofsd/helper.c +++ b/tools/virtiofsd/helper.c @@ -178,6 +178,7 @@ void fuse_cmdline_help(void) " (0 leaves rlimit unchanged)\n" " default: min(1000000, fs.file-max - 16384)\n" " if the current rlimit is lower\n" + " -o announce_submounts Announce sub-mount points to the guest\n" ); } diff --git a/tools/virtiofsd/passthrough_ll.c b/tools/virtiofsd/passthrough_ll.c index 2c48c03b4c..fe7b9fbbb6 100644 --- a/tools/virtiofsd/passthrough_ll.c +++ b/tools/virtiofsd/passthrough_ll.c @@ -40,6 +40,7 @@ #include "fuse_virtio.h" #include "fuse_log.h" #include "fuse_lowlevel.h" +#include "standard-headers/linux/fuse.h" #include #include #include @@ -159,6 +160,7 @@ struct lo_data { int timeout_set; int readdirplus_set; int readdirplus_clear; + int announce_submounts; struct lo_inode root; GHashTable *inodes; /* protected by lo->mutex */ struct lo_map ino_map; /* protected by lo->mutex */ @@ -187,6 +189,7 @@ static const struct fuse_opt lo_opts[] = { { "cache=always", offsetof(struct lo_data, cache), CACHE_ALWAYS }, { "readdirplus", offsetof(struct lo_data, readdirplus_set), 1 }, { "no_readdirplus", offsetof(struct lo_data, readdirplus_clear), 1 }, + { "announce_submounts", offsetof(struct lo_data, announce_submounts), 1 }, FUSE_OPT_END }; static bool use_syslog = false; @@ -582,22 +585,52 @@ static void lo_init(void *userdata, struct fuse_conn_info *conn) } } +/** + * Call fstatat() and set st_rdev whenever a directory's st_dev + * differs from the rparent's st_dev (@parent_dev). This will + * announce submounts to the FUSE client (unless @announce_submounts + * is false). + */ +static int do_fstatat(int dirfd, const char *pathname, struct stat *statbuf, + int flags, dev_t parent_dev, uint32_t *fuse_attr_flags) +{ + int res = fstatat(dirfd, pathname, statbuf, flags); + if (res == -1) { + return res; + } + + if (statbuf->st_dev != parent_dev && S_ISDIR(statbuf->st_mode) && + fuse_attr_flags) + { + *fuse_attr_flags |= FUSE_ATTR_SUBMOUNT; + } + + return 0; +} + static void lo_getattr(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi) { int res; struct stat buf; struct lo_data *lo = lo_data(req); + struct lo_inode *inode = lo_inode(req, ino); + uint32_t fuse_attr_flags = 0; (void)fi; - res = - fstatat(lo_fd(req, ino), "", &buf, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW); + res = do_fstatat(inode->fd, "", &buf, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW, + inode->parent_dev, &fuse_attr_flags); + lo_inode_put(lo, &inode); if (res == -1) { return (void)fuse_reply_err(req, errno); } - fuse_reply_attr(req, &buf, lo->timeout); + if (!lo->announce_submounts) { + fuse_attr_flags &= ~FUSE_ATTR_SUBMOUNT; + } + + fuse_reply_attr_with_flags(req, &buf, lo->timeout, fuse_attr_flags); } static int lo_fi_fd(fuse_req_t req, struct fuse_file_info *fi) @@ -793,11 +826,16 @@ static int lo_do_lookup(fuse_req_t req, fuse_ino_t parent, const char *name, goto out_err; } - res = fstatat(newfd, "", &e->attr, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW); + res = do_fstatat(newfd, "", &e->attr, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW, + dir->key.dev, &e->attr_flags); if (res == -1) { goto out_err; } + if (!lo->announce_submounts) { + e->attr_flags &= ~FUSE_ATTR_SUBMOUNT; + } + inode = lo_find(lo, &e->attr); if (inode) { close(newfd); @@ -1043,11 +1081,17 @@ static void lo_link(fuse_req_t req, fuse_ino_t ino, fuse_ino_t parent, goto out_err; } - res = fstatat(inode->fd, "", &e.attr, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW); + res = do_fstatat(inode->fd, "", &e.attr, + AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW, + parent_inode->key.dev, &e.attr_flags); if (res == -1) { goto out_err; } + if (!lo->announce_submounts) { + e.attr_flags &= ~FUSE_ATTR_SUBMOUNT; + } + pthread_mutex_lock(&lo->mutex); inode->nlookup++; pthread_mutex_unlock(&lo->mutex); @@ -1082,14 +1126,21 @@ static struct lo_inode *lookup_name(fuse_req_t req, fuse_ino_t parent, { int res; struct stat attr; + struct lo_data *lo = lo_data(req); + struct lo_inode *dir = lo_inode(req, parent); + + if (!dir) { + return NULL; + } - res = fstatat(lo_fd(req, parent), name, &attr, - AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW); + res = do_fstatat(dir->fd, name, &attr, + AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW, dir->key.dev, NULL); + lo_inode_put(lo, &dir); if (res == -1) { return NULL; } - return lo_find(lo_data(req), &attr); + return lo_find(lo, &attr); } static void lo_rmdir(fuse_req_t req, fuse_ino_t parent, const char *name) From patchwork Wed Sep 9 18:40:27 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 1360942 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=hebgFlKI; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4BmrYY16p1z9sTH for ; Thu, 10 Sep 2020 04:45:21 +1000 (AEST) Received: from localhost ([::1]:59396 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kG55r-0003BP-2u for incoming@patchwork.ozlabs.org; Wed, 09 Sep 2020 14:45:19 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56762) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kG52H-0006bl-Ey for qemu-devel@nongnu.org; Wed, 09 Sep 2020 14:41:37 -0400 Received: from us-smtp-1.mimecast.com ([207.211.31.81]:21107 helo=us-smtp-delivery-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1kG52D-0007XS-6G for qemu-devel@nongnu.org; Wed, 09 Sep 2020 14:41:35 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1599676892; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=pO3E3kGGsZzsX9286qE2Jx8AVImitKbxOpDZsw3/Mz8=; b=hebgFlKIcHlAM+3CImimsHGMXKSIN5tIjmphUciMX/S37sdBK/YC+NOtP2nZjkAxXZE6q8 bI5bloxFXzGMON0PWARh2jFhiC7ZqZ7YhHNRxmyns1cKkaDHB9+VIZKZ8cEcT6G1aQfBkN 9XJB5qVLTY3R/pgwmO4eFTydyMb4ZkE= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-433-KqsffzZLOO-bodsYqT5XBg-1; Wed, 09 Sep 2020 14:41:23 -0400 X-MC-Unique: KqsffzZLOO-bodsYqT5XBg-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 3E1C410051D4 for ; Wed, 9 Sep 2020 18:41:22 +0000 (UTC) Received: from localhost (ovpn-113-94.ams2.redhat.com [10.36.113.94]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 393445D9E8; Wed, 9 Sep 2020 18:41:16 +0000 (UTC) From: Max Reitz To: qemu-devel@nongnu.org Subject: [PATCH 7/8] tests/acceptance/boot_linux: Accept SSH pubkey Date: Wed, 9 Sep 2020 20:40:27 +0200 Message-Id: <20200909184028.262297-8-mreitz@redhat.com> In-Reply-To: <20200909184028.262297-1-mreitz@redhat.com> References: <20200909184028.262297-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=mreitz@redhat.com X-Mimecast-Spam-Score: 0.001 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=207.211.31.81; envelope-from=mreitz@redhat.com; helo=us-smtp-delivery-1.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/09/09 02:43:02 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_FILL_THIS_FORM_SHORT=0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: virtio-fs@redhat.com, Miklos Szeredi , "Dr . David Alan Gilbert" , Stefan Hajnoczi , Max Reitz Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Let download_cloudinit() take an optional pubkey, which subclasses of BootLinux can pass through setUp(). Signed-off-by: Max Reitz Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: WIllian Rampazzo --- tests/acceptance/boot_linux.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/tests/acceptance/boot_linux.py b/tests/acceptance/boot_linux.py index 0055dc7cee..ad997c3f2e 100644 --- a/tests/acceptance/boot_linux.py +++ b/tests/acceptance/boot_linux.py @@ -57,7 +57,7 @@ class BootLinuxBase(Test): self.cancel('Failed to download/prepare boot image') return boot.path - def download_cloudinit(self): + def download_cloudinit(self, ssh_pubkey=None): self.log.info('Preparing cloudinit image') try: cloudinit_iso = os.path.join(self.workdir, 'cloudinit.iso') @@ -67,7 +67,8 @@ class BootLinuxBase(Test): password='password', # QEMU's hard coded usermode router address phone_home_host='10.0.2.2', - phone_home_port=self.phone_home_port) + phone_home_port=self.phone_home_port, + authorized_key=ssh_pubkey) except Exception: self.cancel('Failed to prepared cloudinit image') return cloudinit_iso @@ -80,19 +81,19 @@ class BootLinux(BootLinuxBase): timeout = 900 chksum = None - def setUp(self): + def setUp(self, ssh_pubkey=None): super(BootLinux, self).setUp() self.vm.add_args('-smp', '2') self.vm.add_args('-m', '1024') self.prepare_boot() - self.prepare_cloudinit() + self.prepare_cloudinit(ssh_pubkey) def prepare_boot(self): path = self.download_boot() self.vm.add_args('-drive', 'file=%s' % path) - def prepare_cloudinit(self): - cloudinit_iso = self.download_cloudinit() + def prepare_cloudinit(self, ssh_pubkey=None): + cloudinit_iso = self.download_cloudinit(ssh_pubkey) self.vm.add_args('-drive', 'file=%s,format=raw' % cloudinit_iso) def launch_and_wait(self): From patchwork Wed Sep 9 18:40:28 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 1360945 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=SeXIk4TF; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4Bmrg71vRLz9sTH for ; Thu, 10 Sep 2020 04:50:11 +1000 (AEST) Received: from localhost ([::1]:43336 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kG5AX-0008AV-71 for incoming@patchwork.ozlabs.org; Wed, 09 Sep 2020 14:50:09 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56850) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kG52g-00075c-RU for qemu-devel@nongnu.org; Wed, 09 Sep 2020 14:42:03 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:32721) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1kG52c-0007dB-If for qemu-devel@nongnu.org; Wed, 09 Sep 2020 14:42:01 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1599676917; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=5WiFObBQtvbXFHdECwFxPJ/NDMLyc4hMQ1slDh18Gfc=; b=SeXIk4TFyVp5Z22IicPt0qV6/j5mwibt3RwIxM4OUdOlajVUoyXbI+UHg2CTTNhN1K6n5b o+yprynOmHPsysoP4pm6hRHg/beKNSvu0ZcnN2O4kUbUwnE36QEMo9XivsNdThH/z1hwD2 dPCjk9CW9JyeBtsH44T/i84ny7tzdtE= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-499-28yMh-OSONON8-Mkh6xTVA-1; Wed, 09 Sep 2020 14:41:32 -0400 X-MC-Unique: 28yMh-OSONON8-Mkh6xTVA-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 3A4F91DDFD for ; Wed, 9 Sep 2020 18:41:31 +0000 (UTC) Received: from localhost (ovpn-113-94.ams2.redhat.com [10.36.113.94]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 448B41002388; Wed, 9 Sep 2020 18:41:24 +0000 (UTC) From: Max Reitz To: qemu-devel@nongnu.org Subject: [PATCH 8/8] tests/acceptance: Add virtiofs_submounts.py Date: Wed, 9 Sep 2020 20:40:28 +0200 Message-Id: <20200909184028.262297-9-mreitz@redhat.com> In-Reply-To: <20200909184028.262297-1-mreitz@redhat.com> References: <20200909184028.262297-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=mreitz@redhat.com X-Mimecast-Spam-Score: 0.002 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=216.205.24.124; envelope-from=mreitz@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/09/09 07:20:24 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: virtio-fs@redhat.com, Miklos Szeredi , "Dr . David Alan Gilbert" , Stefan Hajnoczi , Max Reitz Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This test invokes several shell scripts to create a random directory tree full of submounts, and then check in the VM whether every submount has its own ID and the structure looks as expected. (Note that the test scripts must be non-executable, so Avocado will not try to execute them as if they were tests on their own, too.) Because at this commit's date it is unlikely that the Linux kernel on the image provided by boot_linux.py supports submounts in virtio-fs, the test will be cancelled if no custom Linux binary is provided through the vmlinuz parameter. (The on-image kernel can be used by providing an empty string via vmlinuz=.) So, invoking the test can be done as follows: $ avocado run \ tests/acceptance/virtiofs_submounts.py \ -p vmlinuz=/path/to/linux/build/arch/x86/boot/bzImage This test requires root privileges (through passwordless sudo -n), because at this point, virtiofsd requires them. (If you have a timestamp_timeout period for sudoers (e.g. the default of 5 min), you can provide this by executing something like "sudo true" before invoking Avocado.) Signed-off-by: Max Reitz --- tests/acceptance/virtiofs_submounts.py | 289 ++++++++++++++++++ .../virtiofs_submounts.py.data/cleanup.sh | 46 +++ .../guest-cleanup.sh | 30 ++ .../virtiofs_submounts.py.data/guest.sh | 138 +++++++++ .../virtiofs_submounts.py.data/host.sh | 127 ++++++++ 5 files changed, 630 insertions(+) create mode 100644 tests/acceptance/virtiofs_submounts.py create mode 100644 tests/acceptance/virtiofs_submounts.py.data/cleanup.sh create mode 100644 tests/acceptance/virtiofs_submounts.py.data/guest-cleanup.sh create mode 100644 tests/acceptance/virtiofs_submounts.py.data/guest.sh create mode 100644 tests/acceptance/virtiofs_submounts.py.data/host.sh diff --git a/tests/acceptance/virtiofs_submounts.py b/tests/acceptance/virtiofs_submounts.py new file mode 100644 index 0000000000..8b207b3e57 --- /dev/null +++ b/tests/acceptance/virtiofs_submounts.py @@ -0,0 +1,289 @@ +import logging +import re +import os +import subprocess +import time + +from avocado import skipUnless +from avocado_qemu import Test, BUILD_DIR +from avocado_qemu import wait_for_console_pattern +from avocado.utils import ssh + +from qemu.accel import kvm_available + +from boot_linux import BootLinux + + +def run_cmd(args): + subp = subprocess.Popen(args, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + universal_newlines=True) + stdout, stderr = subp.communicate() + ret = subp.returncode + + return (stdout, stderr, ret) + +def has_passwordless_sudo(): + """ + This function is for use in a @avocado.skipUnless decorator, e.g.: + + @skipUnless(*has_passwordless_sudo()) + def test_something_that_needs_sudo(self): + ... + """ + + _, stderr, exitcode = run_cmd(('sudo', '-n', 'true')) + if exitcode != 0: + return (False, f'Failed to use sudo -n: {stderr.strip()}') + else: + return (True, '') + + +class VirtiofsSubmountsTest(BootLinux): + """ + :avocado: tags=arch:x86_64 + """ + + def get_portfwd(self): + port = None + + res = self.vm.command('human-monitor-command', + command_line='info usernet') + for line in res.split('\r\n'): + match = \ + re.search(r'TCP.HOST_FORWARD.*127\.0\.0\.1\s*(\d+)\s+10\.', + line) + if match is not None: + port = match[1] + break + + self.assertIsNotNone(port) + self.log.debug('sshd listening on port: ' + port) + return port + + def ssh_connect(self, username, keyfile): + self.ssh_logger = logging.getLogger('ssh') + port = self.get_portfwd() + self.ssh_session = ssh.Session('127.0.0.1', port=int(port), + user=username, key=keyfile) + for i in range(10): + try: + self.ssh_session.connect() + return + except: + time.sleep(4) + pass + self.fail('sshd timeout') + + def ssh_command(self, command): + self.ssh_logger.info(command) + result = self.ssh_session.cmd(command) + stdout_lines = [line.rstrip() for line + in result.stdout_text.splitlines()] + for line in stdout_lines: + self.ssh_logger.info(line) + stderr_lines = [line.rstrip() for line + in result.stderr_text.splitlines()] + for line in stderr_lines: + self.ssh_logger.warning(line) + + self.assertEqual(result.exit_status, 0, + f'Guest command failed: {command}') + return stdout_lines, stderr_lines + + def run(self, args, ignore_error=False): + stdout, stderr, ret = run_cmd(args) + + if ret != 0: + cmdline = ' '.join(args) + if not ignore_error: + self.fail(f'{cmdline}: Returned {ret}: {stderr}') + else: + self.log.warn(f'{cmdline}: Returned {ret}: {stderr}') + + return (stdout, stderr, ret) + + def set_up_shared_dir(self): + atwd = os.getenv('AVOCADO_TEST_WORKDIR') + self.shared_dir = os.path.join(atwd, 'virtiofs-shared') + + os.mkdir(self.shared_dir) + + self.run(('cp', self.get_data('guest.sh'), + os.path.join(self.shared_dir, 'check.sh'))) + + self.run(('cp', self.get_data('guest-cleanup.sh'), + os.path.join(self.shared_dir, 'cleanup.sh'))) + + def set_up_virtiofs(self): + attmp = os.getenv('AVOCADO_TESTS_COMMON_TMPDIR') + self.vfsdsock = os.path.join(attmp, 'vfsdsock') + + self.run(('sudo', '-n', 'rm', '-f', self.vfsdsock), ignore_error=True) + + self.virtiofsd = \ + subprocess.Popen(('sudo', '-n', + 'tools/virtiofsd/virtiofsd', + f'--socket-path={self.vfsdsock}', + '-o', f'source={self.shared_dir}', + '-o', 'cache=always', + '-o', 'xattr', + '-o', 'announce_submounts', + '-f'), + stdout=subprocess.DEVNULL, + stderr=subprocess.PIPE, + universal_newlines=True) + + while not os.path.exists(self.vfsdsock): + if self.virtiofsd.poll() is not None: + self.fail('virtiofsd exited prematurely: ' + + self.virtiofsd.communicate()[1]) + time.sleep(0.1) + + self.run(('sudo', '-n', 'chmod', 'go+rw', self.vfsdsock)) + + self.vm.add_args('-chardev', + f'socket,id=vfsdsock,path={self.vfsdsock}', + '-device', + 'vhost-user-fs-pci,queue-size=1024,chardev=vfsdsock' \ + ',tag=host', + '-object', + 'memory-backend-file,id=mem,size=1G,' \ + 'mem-path=/dev/shm,share=on', + '-numa', + 'node,memdev=mem') + + def launch_vm(self): + self.launch_and_wait() + self.ssh_connect('root', self.ssh_key) + + def set_up_nested_mounts(self): + scratch_dir = os.path.join(self.shared_dir, 'scratch') + try: + os.mkdir(scratch_dir) + except FileExistsError: + pass + + args = ['bash', self.get_data('host.sh'), scratch_dir] + if self.seed: + args += [self.seed] + + out, _, _ = self.run(args) + seed = re.search(r'^Seed: \d+', out) + self.log.info(seed[0]) + + def mount_in_guest(self): + self.ssh_command('mkdir -p /mnt/host') + self.ssh_command('mount -t virtiofs host /mnt/host') + + def check_in_guest(self): + self.ssh_command('bash /mnt/host/check.sh /mnt/host/scratch/share') + + def live_cleanup(self): + self.ssh_command('bash /mnt/host/cleanup.sh /mnt/host/scratch') + + # It would be nice if the above was sufficient to make virtiofsd clear + # all references to the mounted directories (so they can be unmounted + # on the host), but unfortunately it is not. To do so, we have to + # resort to a remount. + self.ssh_command('mount -o remount /mnt/host') + + scratch_dir = os.path.join(self.shared_dir, 'scratch') + self.run(('bash', self.get_data('cleanup.sh'), scratch_dir)) + + @skipUnless(*has_passwordless_sudo()) + def setUp(self): + vmlinuz = self.params.get('vmlinuz') + if vmlinuz is None: + self.cancel('vmlinuz parameter not set; you must point it to a ' + 'Linux kernel binary to test (to run this test with ' \ + 'the on-image kernel, set it to an empty string)') + + self.seed = self.params.get('seed') + + atwd = os.getenv('AVOCADO_TEST_WORKDIR') + self.ssh_key = os.path.join(atwd, 'id_ed25519') + + self.run(('ssh-keygen', '-t', 'ed25519', '-f', self.ssh_key)) + + pubkey = open(self.ssh_key + '.pub').read() + + super(VirtiofsSubmountsTest, self).setUp(pubkey) + + if len(vmlinuz) > 0: + self.vm.add_args('-kernel', vmlinuz, + '-append', 'console=ttyS0 root=/dev/sda1') + + # Allow us to connect to SSH + self.vm.add_args('-netdev', 'user,id=vnet,hostfwd=:127.0.0.1:0-:22', + '-device', 'e1000,netdev=vnet') + + if not kvm_available(self.arch, self.qemu_bin): + self.cancel(KVM_NOT_AVAILABLE) + self.vm.add_args('-accel', 'kvm') + + def tearDown(self): + try: + self.vm.shutdown() + except: + pass + + scratch_dir = os.path.join(self.shared_dir, 'scratch') + self.run(('bash', self.get_data('cleanup.sh'), scratch_dir), + ignore_error=True) + + def test_pre_virtiofsd_set_up(self): + self.set_up_shared_dir() + + self.set_up_nested_mounts() + + self.set_up_virtiofs() + self.launch_vm() + self.mount_in_guest() + self.check_in_guest() + + def test_pre_launch_set_up(self): + self.set_up_shared_dir() + self.set_up_virtiofs() + + self.set_up_nested_mounts() + + self.launch_vm() + self.mount_in_guest() + self.check_in_guest() + + def test_post_launch_set_up(self): + self.set_up_shared_dir() + self.set_up_virtiofs() + self.launch_vm() + + self.set_up_nested_mounts() + + self.mount_in_guest() + self.check_in_guest() + + def test_post_mount_set_up(self): + self.set_up_shared_dir() + self.set_up_virtiofs() + self.launch_vm() + self.mount_in_guest() + + self.set_up_nested_mounts() + + self.check_in_guest() + + def test_two_runs(self): + self.set_up_shared_dir() + + self.set_up_nested_mounts() + + self.set_up_virtiofs() + self.launch_vm() + self.mount_in_guest() + self.check_in_guest() + + self.live_cleanup() + self.set_up_nested_mounts() + + self.check_in_guest() diff --git a/tests/acceptance/virtiofs_submounts.py.data/cleanup.sh b/tests/acceptance/virtiofs_submounts.py.data/cleanup.sh new file mode 100644 index 0000000000..2a6579a0fe --- /dev/null +++ b/tests/acceptance/virtiofs_submounts.py.data/cleanup.sh @@ -0,0 +1,46 @@ +#!/bin/bash + +function print_usage() +{ + if [ -n "$2" ]; then + echo "Error: $2" + echo + fi + echo "Usage: $1 " +} + +scratch_dir=$1 +if [ -z "$scratch_dir" ]; then + print_usage "$0" 'Scratch dir not given' >&2 + exit 1 +fi + +cd "$scratch_dir/share" || exit 1 +mps=(mnt*) +mp_i=0 +for mp in "${mps[@]}"; do + mp_i=$((mp_i + 1)) + printf "Unmounting %i/%i...\r" "$mp_i" "${#mps[@]}" + + sudo umount -R "$mp" + rm -rf "$mp" +done +echo + +rm some-file +cd .. +rmdir share + +imgs=(fs*.img) +img_i=0 +for img in "${imgs[@]}"; do + img_i=$((img_i + 1)) + printf "Detaching and deleting %i/%i...\r" "$img_i" "${#imgs[@]}" + + dev=$(losetup -j "$img" | sed -e 's/:.*//') + sudo losetup -d "$dev" + rm -f "$img" +done +echo + +echo 'Done.' diff --git a/tests/acceptance/virtiofs_submounts.py.data/guest-cleanup.sh b/tests/acceptance/virtiofs_submounts.py.data/guest-cleanup.sh new file mode 100644 index 0000000000..729cb2d1a5 --- /dev/null +++ b/tests/acceptance/virtiofs_submounts.py.data/guest-cleanup.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +function print_usage() +{ + if [ -n "$2" ]; then + echo "Error: $2" + echo + fi + echo "Usage: $1 " +} + +scratch_dir=$1 +if [ -z "$scratch_dir" ]; then + print_usage "$0" 'Scratch dir not given' >&2 + exit 1 +fi + +cd "$scratch_dir/share" || exit 1 + +mps=(mnt*) +mp_i=0 +for mp in "${mps[@]}"; do + mp_i=$((mp_i + 1)) + printf "Unmounting %i/%i...\r" "$mp_i" "${#mps[@]}" + + sudo umount -R "$mp" +done +echo + +echo 'Done.' diff --git a/tests/acceptance/virtiofs_submounts.py.data/guest.sh b/tests/acceptance/virtiofs_submounts.py.data/guest.sh new file mode 100644 index 0000000000..59ba40fde1 --- /dev/null +++ b/tests/acceptance/virtiofs_submounts.py.data/guest.sh @@ -0,0 +1,138 @@ +#!/bin/bash + +function print_usage() +{ + if [ -n "$2" ]; then + echo "Error: $2" + echo + fi + echo "Usage: $1 " + echo '(The shared directory is the "share" directory in the scratch' \ + 'directory)' +} + +shared_dir=$1 +if [ -z "$shared_dir" ]; then + print_usage "$0" 'Shared dir not given' >&2 + exit 1 +fi + +cd "$shared_dir" + +# FIXME: This should not be necessary, but it is. In order for all +# submounts to be proper mount points, we need to visit them. +# (Before we visit them, they will not be auto-mounted, and so just +# appear as normal directories, with the catch that their st_ino will +# be the st_ino of the filesystem they host, while the st_dev will +# still be the st_dev of the parent.) +# `find` does not work, because it will refuse to touch the mount +# points as long as they are not mounted; their st_dev being shared +# with the parent and st_ino just being the root node's inode ID +# will practically ensure that this node exists elsewhere on the +# filesystem, and `find` is required to recognize loops and not to +# follow them. +# Thus, we have to manually visit all nodes first. + +mnt_i=0 + +function recursively_visit() +{ + pushd "$1" >/dev/null + for entry in *; do + if [[ "$entry" == mnt* ]]; then + mnt_i=$((mnt_i + 1)) + printf "Triggering auto-mount $mnt_i...\r" + fi + + if [ -d "$entry" ]; then + recursively_visit "$entry" + fi + done + popd >/dev/null +} + +recursively_visit . +echo + + +if [ -n "$(find -name not-mounted)" ]; then + echo "Error: not-mounted files visible on mount points:" >&2 + find -name not-mounted >&2 + exit 1 +fi + +if [ ! -f some-file -o "$(cat some-file)" != 'root' ]; then + echo "Error: Bad file in the share root" >&2 + exit 1 +fi + +shopt -s nullglob + +function check_submounts() +{ + local base_path=$1 + + for mp in mnt*; do + printf "Checking submount %i...\r" "$((${#devs[@]} + 1))" + + mp_i=$(echo "$mp" | sed -e 's/mnt//') + dev=$(stat -c '%D' "$mp") + + if [ -n "${devs[mp_i]}" ]; then + echo "Error: $mp encountered twice" >&2 + exit 1 + fi + devs[mp_i]=$dev + + pushd "$mp" >/dev/null + path="$base_path$mp" + while true; do + expected_content="$(printf '%s\n%s\n' "$mp_i" "$path")" + if [ ! -f some-file ]; then + echo "Error: $PWD/some-file does not exist" >&2 + exit 1 + fi + + if [ "$(cat some-file)" != "$expected_content" ]; then + echo "Error: Bad content in $PWD/some-file:" >&2 + echo '--- found ---' + cat some-file + echo '--- expected ---' + echo "$expected_content" + exit 1 + fi + if [ "$(stat -c '%D' some-file)" != "$dev" ]; then + echo "Error: $PWD/some-file has the wrong device ID" >&2 + exit 1 + fi + + if [ -d sub ]; then + if [ "$(stat -c '%D' sub)" != "$dev" ]; then + echo "Error: $PWD/some-file has the wrong device ID" >&2 + exit 1 + fi + cd sub + path="$path/sub" + else + if [ -n "$(echo mnt*)" ]; then + check_submounts "$path/" + fi + break + fi + done + popd >/dev/null + done +} + +root_dev=$(stat -c '%D' some-file) +devs=() +check_submounts '' +echo + +reused_devs=$(echo "$root_dev ${devs[@]}" | tr ' ' '\n' | sort | uniq -d) +if [ -n "$reused_devs" ]; then + echo "Error: Reused device IDs: $reused_devs" >&2 + exit 1 +fi + +echo "Test passed for ${#devs[@]} submounts." diff --git a/tests/acceptance/virtiofs_submounts.py.data/host.sh b/tests/acceptance/virtiofs_submounts.py.data/host.sh new file mode 100644 index 0000000000..d8a9afebdb --- /dev/null +++ b/tests/acceptance/virtiofs_submounts.py.data/host.sh @@ -0,0 +1,127 @@ +#!/bin/bash + +mount_count=128 + +function print_usage() +{ + if [ -n "$2" ]; then + echo "Error: $2" + echo + fi + echo "Usage: $1 [seed]" + echo "(If no seed is given, it will be randomly generated.)" +} + +scratch_dir=$1 +if [ -z "$scratch_dir" ]; then + print_usage "$0" 'No scratch dir given' >&2 + exit 1 +fi + +if [ ! -d "$scratch_dir" ]; then + print_usage "$0" "$scratch_dir is not a directory" >&2 + exit 1 +fi + +seed=$2 +if [ -z "$seed" ]; then + seed=$RANDOM +fi +RANDOM=$seed + +echo "Seed: $seed" + +set -e +shopt -s nullglob + +cd "$scratch_dir" +if [ -d share ]; then + echo 'Error: This directory seems to be in use already' >&2 + exit 1 +fi + +for ((i = 0; i < $mount_count; i++)); do + printf "Setting up fs %i/%i...\r" "$((i + 1))" "$mount_count" + + rm -f fs$i.img + truncate -s 512M fs$i.img + mkfs.xfs -q fs$i.img + devs[i]=$(sudo losetup -f --show fs$i.img) +done +echo + +top_level_mounts=$((RANDOM % mount_count + 1)) + +mkdir -p share +echo 'root' > share/some-file + +for ((i = 0; i < $top_level_mounts; i++)); do + printf "Mounting fs %i/%i...\r" "$((i + 1))" "$mount_count" + + mkdir -p share/mnt$i + touch share/mnt$i/not-mounted + sudo mount "${devs[i]}" share/mnt$i + sudo chown "$(id -u):$(id -g)" share/mnt$i + + pushd share/mnt$i >/dev/null + path=mnt$i + nesting=$((RANDOM % 4)) + for ((j = 0; j < $nesting; j++)); do + cat > some-file < some-file </dev/null +done + +for ((; i < $mount_count; i++)); do + printf "Mounting fs %i/%i...\r" "$((i + 1))" "$mount_count" + + mp_i=$((i % top_level_mounts)) + + pushd share/mnt$mp_i >/dev/null + path=mnt$mp_i + while true; do + sub_mp="$(echo mnt*)" + if cd sub 2>/dev/null; then + path="$path/sub" + elif [ -n "$sub_mp" ] && cd "$sub_mp" 2>/dev/null; then + path="$path/$sub_mp" + else + break + fi + done + mkdir mnt$i + touch mnt$i/not-mounted + sudo mount "${devs[i]}" mnt$i + sudo chown "$(id -u):$(id -g)" mnt$i + + cd mnt$i + path="$path/mnt$i" + nesting=$((RANDOM % 4)) + for ((j = 0; j < $nesting; j++)); do + cat > some-file < some-file </dev/null +done +echo + +echo 'Done.'