From owner-svn-src-all@freebsd.org Fri Jun 5 16:12:22 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 6BC2F33061D; Fri, 5 Jun 2020 16:12:22 +0000 (UTC) (envelope-from cem@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 49dnjL1Dt9z4CG3; Fri, 5 Jun 2020 16:12:22 +0000 (UTC) (envelope-from cem@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 1AD3813772; Fri, 5 Jun 2020 16:12:22 +0000 (UTC) (envelope-from cem@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 055GCLvv009494; Fri, 5 Jun 2020 16:12:21 GMT (envelope-from cem@FreeBSD.org) Received: (from cem@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 055GCL11009491; Fri, 5 Jun 2020 16:12:21 GMT (envelope-from cem@FreeBSD.org) Message-Id: <202006051612.055GCL11009491@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: cem set sender to cem@FreeBSD.org using -f From: Conrad Meyer Date: Fri, 5 Jun 2020 16:12:21 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r361838 - in head/sys/geom: . label X-SVN-Group: head X-SVN-Commit-Author: cem X-SVN-Commit-Paths: in head/sys/geom: . label X-SVN-Commit-Revision: 361838 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 16:12:22 -0000 Author: cem Date: Fri Jun 5 16:12:21 2020 New Revision: 361838 URL: https://svnweb.freebsd.org/changeset/base/361838 Log: geom_label: Use provider aliasing to alias upstream geoms For synthetic aliases (just pseudonyms inferred from metadata like GPT or UFS labels, GPT UUIDs, etc), use the GEOM provider aliasing system to create a symlink to the real device instead of creating an independent device. This makes it more clear which labels and devices correspond, and we can safely have multiple labels to a single device accessed at once. The confusingly named geom_label on-disk construct continues to behave identically to how it did before. This requires teaching GEOM's provider aliasing about the possibility that aliases might be added later in time, and GEOM's devfs interaction layer not to worry about existing aliases during retaste. Discussed with: imp Relnotes: sure, if we don't end up reverting it Differential Revision: https://reviews.freebsd.org/D24968 Modified: head/sys/geom/geom_dev.c head/sys/geom/label/g_label.c Modified: head/sys/geom/geom_dev.c ============================================================================== --- head/sys/geom/geom_dev.c Fri Jun 5 16:05:09 2020 (r361837) +++ head/sys/geom/geom_dev.c Fri Jun 5 16:12:21 2020 (r361838) @@ -336,9 +336,20 @@ g_dev_taste(struct g_class *mp, struct g_provider *pp, struct cdev *dev, *adev; char buf[SPECNAMELEN + 6]; struct make_dev_args args; + bool retaste; g_trace(G_T_TOPOLOGY, "dev_taste(%s,%s)", mp->name, pp->name); g_topology_assert(); + /* Only one geom_dev per provider. */ + LIST_FOREACH(cp, &pp->consumers, consumers) { + if (cp->geom->class != mp || (cp->flags & G_CF_SPOILED)) + continue; + gp = cp->geom; + sc = cp->private; + dev = sc->sc_dev; + retaste = true; + goto aliases; + } gp = g_new_geomf(mp, "%s", pp->name); sc = g_malloc(sizeof(*sc), M_WAITOK | M_ZERO); mtx_init(&sc->sc_mtx, "g_dev", NULL, MTX_DEF); @@ -380,6 +391,8 @@ g_dev_taste(struct g_class *mp, struct g_provider *pp, g_dev_attrchanged(cp, "GEOM::physpath"); snprintf(buf, sizeof(buf), "cdev=%s", gp->name); devctl_notify_f("GEOM", "DEV", "CREATE", buf, M_WAITOK); + retaste = false; +aliases: /* * Now add all the aliases for this drive */ @@ -387,8 +400,16 @@ g_dev_taste(struct g_class *mp, struct g_provider *pp, error = make_dev_alias_p(MAKEDEV_CHECKNAME | MAKEDEV_WAITOK, &adev, dev, "%s", gap->ga_alias); if (error) { - printf("%s: make_dev_alias_p() failed (name=%s, error=%d)\n", - __func__, gap->ga_alias, error); + /* + * With aliases added after initial taste, we don't + * know which aliases are new in this retaste, so we + * try to create all of them. EEXIST is expected and + * silently ignored or else this becomes really spammy. + */ + if (error != EEXIST || !retaste) + printf("%s: make_dev_alias_p() failed (name=%s," + " error=%d)\n", __func__, gap->ga_alias, + error); continue; } snprintf(buf, sizeof(buf), "cdev=%s", gap->ga_alias); Modified: head/sys/geom/label/g_label.c ============================================================================== --- head/sys/geom/label/g_label.c Fri Jun 5 16:05:09 2020 (r361837) +++ head/sys/geom/label/g_label.c Fri Jun 5 16:12:21 2020 (r361838) @@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -344,18 +345,16 @@ g_label_taste(struct g_class *mp, struct g_provider *p { struct g_label_metadata md; struct g_consumer *cp; + struct g_class *clsp; struct g_geom *gp; int i; + bool changed; g_trace(G_T_TOPOLOGY, "%s(%s, %s)", __func__, mp->name, pp->name); g_topology_assert(); G_LABEL_DEBUG(2, "Tasting %s.", pp->name); - /* Skip providers that are already open for writing. */ - if (pp->acw > 0) - return (NULL); - if (strcmp(pp->geom->class->name, mp->name) == 0) return (NULL); @@ -391,9 +390,16 @@ g_label_taste(struct g_class *mp, struct g_provider *p if (md.md_provsize != pp->mediasize) break; + /* Skip providers that are already open for writing. */ + if (pp->acw > 0) { + g_access(cp, -1, 0, 0); + goto end; + } + g_label_create(NULL, mp, pp, md.md_label, G_LABEL_DIR, pp->mediasize - pp->sectorsize); } while (0); + changed = false; for (i = 0; g_labels[i] != NULL; i++) { char label[128]; @@ -405,8 +411,28 @@ g_label_taste(struct g_class *mp, struct g_provider *p g_topology_lock(); if (label[0] == '\0') continue; - g_label_create(NULL, mp, pp, label, g_labels[i]->ld_dir, - pp->mediasize); + if (!g_label_is_name_ok(label)) { + G_LABEL_DEBUG(0, + "%s contains suspicious label, skipping.", + pp->name); + G_LABEL_DEBUG(1, "%s suspicious label is: %s", + pp->name, label); + continue; + } + g_provider_add_alias(pp, "%s/%s", g_labels[i]->ld_dir, label); + changed = true; + } + /* + * Force devfs interface to retaste the provider, to catch the new + * alias(es). + */ + if (changed) { + LIST_FOREACH(clsp, &g_classes, class) { + if (strcmp(clsp->name, "DEV") != 0) + continue; + clsp->taste(clsp, pp, 0); + break; + } } g_access(cp, -1, 0, 0); end: