From nobody Tue Mar 14 14:19:37 2023 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 4PbbJB2rMkz3yKZ9; Tue, 14 Mar 2023 14:19:38 +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 "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4PbbJB24zZz45mT; Tue, 14 Mar 2023 14:19:38 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1678803578; 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=LPILlxu61jliviLEQ0Cq/AKdEEi1hKJme7kK06oBM6g=; b=oZCZViX9yKzXh6DvM/hDs85HEvvlABZzjFPjor3yDKIVRHocQtmQB3RbXn2WC1M3KvKxGv vCC49p3D8WB3YRX37cGllFDdKa8sx+vS5bv5j6YCgLHadC6UORce8RREObBOJeWiqyur60 jht9bdZZL5Su9EUbdSzBA2ywRwjRCxmzcbJpqXZaK4PnVOql2hH7D3iuNTMs40wIPFBz76 Ny/ZsrTrQZP1/p1kJamD+vycAv8D4lrK0dR3eUNS9fniSL1keHErJgwRhprnYAuFpO7Je3 T70sqzV94qJMTpYZX/fdeh5iVxz5SgpCXw0OE3+y3CrgsN649CNJcDMM1c2eLw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1678803578; 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=LPILlxu61jliviLEQ0Cq/AKdEEi1hKJme7kK06oBM6g=; b=bh+Yrx6T9hlwdnyEUtqdfI/FYspLsZ18TDcgEAb8+swmEH6iOXUgw7Uo45sHwpbadWJAzX PXNHfZL98jzw1CUAl077ZOIrMCqNUtZPpxU7xVHNBEs7iv2oJNUEX5Y73YXDJJZdiBVjO/ GaNxQfkPUk1I4kdeH7W1fmCpLuIn8VvAqIKO+akn02SLm63ZaERXuOwV4YhGhCzlhsGn7f Y/vLT3HuBiBdBNfAwuhA43L+tdelpPDXuxWxZIcNr0Te8l5aENh7mYEeJclQQRMB1FKSgV utWd/fZPPe8MMMezgxE8+jE8FD/xqTLcGdTeJaVTcLU7CdE9CGG0PXuKN7Op8w== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1678803578; a=rsa-sha256; cv=none; b=TEmRYjo3GFqAEn01clDEPMJeKlSbCfi9YNKIfSRrv/HvCDWiE0CPwhu9LEMhoEjXawdSxh F4n59OovUCWEes6yp56uwNcSQcWsh4awOLh/JJ0nsFXbB26ccIVRdiEVLN4iLSiEkgwPtJ krqE425ncNnfj4kOk/yQ98AmluJpVcsKpzPs/yXNqHubqNZTLEzunJOGFHZDYdmZxwgEqv qQI9TmcUn4MAUugffuydGrupUN1QPULCqp7nkSsRDaTHa8LpbY7qLB5t621A2Xq+HawrYP Rgt+T1DVV5ycPa1yua0Qe6AHYHAFgTrLWcEoMFP2HwmG2h98d9H5X1zahkILMw== 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 4PbbJB0wTfzds2; Tue, 14 Mar 2023 14:19:38 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 32EEJb7p044490; Tue, 14 Mar 2023 14:19:37 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 32EEJbtH044489; Tue, 14 Mar 2023 14:19:37 GMT (envelope-from git) Date: Tue, 14 Mar 2023 14:19:37 GMT Message-Id: <202303141419.32EEJbtH044489@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Allan Jude Subject: git: a849842f510a - main - loader: Add support for booting from a ZFS snapshot 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: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: allanjude X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: a849842f510af48717e35ff709623e0dd1b80b20 Auto-Submitted: auto-generated X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by allanjude: URL: https://cgit.FreeBSD.org/src/commit/?id=a849842f510af48717e35ff709623e0dd1b80b20 commit a849842f510af48717e35ff709623e0dd1b80b20 Author: Allan Jude AuthorDate: 2022-11-26 18:11:13 +0000 Commit: Allan Jude CommitDate: 2023-03-14 14:18:29 +0000 loader: Add support for booting from a ZFS snapshot When booting from a snapshot we need to follow a different code path to turn the objset ID into the name, and for forward lookups we need to walk the parent's snapnames_zap. With this, it is possible to set the pools BOOTFS property to a snapshot and boot with a read-only filesystem of that snapshot. Reviewed by: tsoome, rew, imp Sponsored By: Beckhoff Automation GmbH & Co. KG Sponsored By: Klara, Inc. Differential Revision: https://reviews.freebsd.org/D38600 --- stand/libsa/zfs/zfsimpl.c | 56 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 2 deletions(-) diff --git a/stand/libsa/zfs/zfsimpl.c b/stand/libsa/zfs/zfsimpl.c index 36c90613e827..76063e76225f 100644 --- a/stand/libsa/zfs/zfsimpl.c +++ b/stand/libsa/zfs/zfsimpl.c @@ -3068,11 +3068,12 @@ zfs_rlookup(const spa_t *spa, uint64_t objnum, char *result) char name[256]; char component[256]; uint64_t dir_obj, parent_obj, child_dir_zapobj; - dnode_phys_t child_dir_zap, dataset, dir, parent; + dnode_phys_t child_dir_zap, snapnames_zap, dataset, dir, parent; dsl_dir_phys_t *dd; dsl_dataset_phys_t *ds; char *p; int len; + boolean_t issnap = B_FALSE; p = &name[sizeof(name) - 1]; *p = '\0'; @@ -3083,6 +3084,8 @@ zfs_rlookup(const spa_t *spa, uint64_t objnum, char *result) } ds = (dsl_dataset_phys_t *)&dataset.dn_bonus; dir_obj = ds->ds_dir_obj; + if (ds->ds_snapnames_zapobj == 0) + issnap = B_TRUE; for (;;) { if (objset_get_dnode(spa, spa->spa_mos, dir_obj, &dir) != 0) @@ -3098,6 +3101,34 @@ zfs_rlookup(const spa_t *spa, uint64_t objnum, char *result) &parent) != 0) return (EIO); dd = (dsl_dir_phys_t *)&parent.dn_bonus; + if (issnap == B_TRUE) { + /* + * The dataset we are looking up is a snapshot + * the dir_obj is the parent already, we don't want + * the grandparent just yet. Reset to the parent. + */ + dd = (dsl_dir_phys_t *)&dir.dn_bonus; + /* Lookup the dataset to get the snapname ZAP */ + if (objset_get_dnode(spa, spa->spa_mos, + dd->dd_head_dataset_obj, &dataset)) + return (EIO); + ds = (dsl_dataset_phys_t *)&dataset.dn_bonus; + if (objset_get_dnode(spa, spa->spa_mos, + ds->ds_snapnames_zapobj, &snapnames_zap) != 0) + return (EIO); + /* Get the name of the snapshot */ + if (zap_rlookup(spa, &snapnames_zap, component, + objnum) != 0) + return (EIO); + len = strlen(component); + p -= len; + memcpy(p, component, len); + --p; + *p = '@'; + issnap = B_FALSE; + continue; + } + child_dir_zapobj = dd->dd_child_dir_zapobj; if (objset_get_dnode(spa, spa->spa_mos, child_dir_zapobj, &child_dir_zap) != 0) @@ -3127,9 +3158,11 @@ zfs_lookup_dataset(const spa_t *spa, const char *name, uint64_t *objnum) { char element[256]; uint64_t dir_obj, child_dir_zapobj; - dnode_phys_t child_dir_zap, dir; + dnode_phys_t child_dir_zap, snapnames_zap, dir, dataset; dsl_dir_phys_t *dd; + dsl_dataset_phys_t *ds; const char *p, *q; + boolean_t issnap = B_FALSE; if (objset_get_dnode(spa, spa->spa_mos, DMU_POOL_DIRECTORY_OBJECT, &dir)) @@ -3160,6 +3193,25 @@ zfs_lookup_dataset(const spa_t *spa, const char *name, uint64_t *objnum) p += strlen(p); } + if (issnap == B_TRUE) { + if (objset_get_dnode(spa, spa->spa_mos, + dd->dd_head_dataset_obj, &dataset)) + return (EIO); + ds = (dsl_dataset_phys_t *)&dataset.dn_bonus; + if (objset_get_dnode(spa, spa->spa_mos, + ds->ds_snapnames_zapobj, &snapnames_zap) != 0) + return (EIO); + /* Actual loop condition #2. */ + if (zap_lookup(spa, &snapnames_zap, element, + sizeof (dir_obj), 1, &dir_obj) != 0) + return (ENOENT); + *objnum = dir_obj; + return (0); + } else if ((q = strchr(element, '@')) != NULL) { + issnap = B_TRUE; + element[q - element] = '\0'; + p = q + 1; + } child_dir_zapobj = dd->dd_child_dir_zapobj; if (objset_get_dnode(spa, spa->spa_mos, child_dir_zapobj, &child_dir_zap) != 0)