Changeset View
Standalone View
sys/geom/label/g_label.c
Show All 40 Lines | |||||
#include <sys/ctype.h> | #include <sys/ctype.h> | ||||
#include <sys/malloc.h> | #include <sys/malloc.h> | ||||
#include <sys/libkern.h> | #include <sys/libkern.h> | ||||
#include <sys/sbuf.h> | #include <sys/sbuf.h> | ||||
#include <sys/stddef.h> | #include <sys/stddef.h> | ||||
#include <sys/sysctl.h> | #include <sys/sysctl.h> | ||||
#include <geom/geom.h> | #include <geom/geom.h> | ||||
#include <geom/geom_dbg.h> | #include <geom/geom_dbg.h> | ||||
#include <geom/geom_int.h> | |||||
#include <geom/geom_slice.h> | #include <geom/geom_slice.h> | ||||
#include <geom/label/g_label.h> | #include <geom/label/g_label.h> | ||||
FEATURE(geom_label, "GEOM labeling support"); | FEATURE(geom_label, "GEOM labeling support"); | ||||
SYSCTL_DECL(_kern_geom); | SYSCTL_DECL(_kern_geom); | ||||
SYSCTL_NODE(_kern_geom, OID_AUTO, label, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, | SYSCTL_NODE(_kern_geom, OID_AUTO, label, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, | ||||
"GEOM_LABEL stuff"); | "GEOM_LABEL stuff"); | ||||
▲ Show 20 Lines • Show All 282 Lines • ▼ Show 20 Lines | g_label_access_taste(struct g_provider *pp __unused, int dr __unused, | ||||
return (EOPNOTSUPP); | return (EOPNOTSUPP); | ||||
} | } | ||||
static struct g_geom * | static struct g_geom * | ||||
g_label_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) | g_label_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) | ||||
{ | { | ||||
struct g_label_metadata md; | struct g_label_metadata md; | ||||
struct g_consumer *cp; | struct g_consumer *cp; | ||||
struct g_class *clsp; | |||||
struct g_geom *gp; | struct g_geom *gp; | ||||
int i; | int i; | ||||
bool changed; | |||||
g_trace(G_T_TOPOLOGY, "%s(%s, %s)", __func__, mp->name, pp->name); | g_trace(G_T_TOPOLOGY, "%s(%s, %s)", __func__, mp->name, pp->name); | ||||
g_topology_assert(); | g_topology_assert(); | ||||
G_LABEL_DEBUG(2, "Tasting %s.", pp->name); | 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) | if (strcmp(pp->geom->class->name, mp->name) == 0) | ||||
return (NULL); | return (NULL); | ||||
gp = g_new_geomf(mp, "label:taste"); | gp = g_new_geomf(mp, "label:taste"); | ||||
gp->start = g_label_start_taste; | gp->start = g_label_start_taste; | ||||
gp->access = g_label_access_taste; | gp->access = g_label_access_taste; | ||||
gp->orphan = g_label_orphan_taste; | gp->orphan = g_label_orphan_taste; | ||||
cp = g_new_consumer(gp); | cp = g_new_consumer(gp); | ||||
Show All 19 Lines | do { | ||||
* metadata. | * metadata. | ||||
*/ | */ | ||||
if (md.md_version < 2) | if (md.md_version < 2) | ||||
md.md_provsize = pp->mediasize; | md.md_provsize = pp->mediasize; | ||||
if (md.md_provsize != pp->mediasize) | if (md.md_provsize != pp->mediasize) | ||||
break; | break; | ||||
/* Skip providers that are already open for writing. */ | |||||
imp: Does this mean the symlinks disappear? | |||||
cemAuthorUnsubmitted Done Inline ActionsThis is moving lines formerly at 355-358 inside the condition where we found a real on-disk geom_label. They are not new in the revision. The idea is that for labels that are not a real geom_label, we can keep the symlinks even with a consumer with write access -- they all point at the same unique cdev. In the case where a geom has both an on-disk geom_label and other labels ... yeah, it might not create the symlinks. Possibly this should insead be: if (pp->acw == 0) g_label_create(...); I've never used the geom_label on-disk object and I'm not sure why one would anymore. UFS or GPT labels seem like a better fit today. So I mostly tried to leave the on-disk label objects alone. cem: This is moving lines formerly at 355-358 inside the condition where we found a real on-disk… | |||||
if (pp->acw > 0) { | |||||
g_access(cp, -1, 0, 0); | |||||
goto end; | |||||
} | |||||
g_label_create(NULL, mp, pp, md.md_label, G_LABEL_DIR, | g_label_create(NULL, mp, pp, md.md_label, G_LABEL_DIR, | ||||
pp->mediasize - pp->sectorsize); | pp->mediasize - pp->sectorsize); | ||||
} while (0); | } while (0); | ||||
changed = false; | |||||
for (i = 0; g_labels[i] != NULL; i++) { | for (i = 0; g_labels[i] != NULL; i++) { | ||||
char label[128]; | char label[128]; | ||||
if (g_labels[i]->ld_enabled == 0) | if (g_labels[i]->ld_enabled == 0) | ||||
continue; | continue; | ||||
g_topology_unlock(); | g_topology_unlock(); | ||||
g_labels[i]->ld_taste(cp, label, sizeof(label)); | g_labels[i]->ld_taste(cp, label, sizeof(label)); | ||||
g_label_mangle_name(label, sizeof(label)); | g_label_mangle_name(label, sizeof(label)); | ||||
g_topology_lock(); | g_topology_lock(); | ||||
if (label[0] == '\0') | if (label[0] == '\0') | ||||
continue; | continue; | ||||
g_label_create(NULL, mp, pp, label, g_labels[i]->ld_dir, | if (!g_label_is_name_ok(label)) { | ||||
impUnsubmitted Not Done Inline Actionsthis is a new check? I don't see it moved from elsewhere... Not that that's bad, just wondering imp: this is a new check? I don't see it moved from elsewhere... Not that that's bad, just… | |||||
cemAuthorUnsubmitted Done Inline ActionsIt's the same check as in g_label_create(), but the other code is substantially different. It could be subroutined out of both. cem: It's the same check as in `g_label_create()`, but the other code is substantially different. | |||||
pp->mediasize); | 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). | |||||
impUnsubmitted Not Done Inline Actionswhy? imp: why? | |||||
cemAuthorUnsubmitted Done Inline ActionsOtherwise it never gets tasted, and never creates the devfs alias. If you have / on an alias label, boot times out during mountroot. (g_provider_add_alias just throws the new string on a linked list; it doesn't create any first-class geom objects or cause geom_dev to retaste the provider.) cem: Otherwise it never gets tasted, and never creates the devfs alias. If you have `/` on an alias… | |||||
*/ | |||||
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); | g_access(cp, -1, 0, 0); | ||||
end: | end: | ||||
g_detach(cp); | g_detach(cp); | ||||
g_destroy_consumer(cp); | g_destroy_consumer(cp); | ||||
g_destroy_geom(gp); | g_destroy_geom(gp); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 161 Lines • Show Last 20 Lines |
Does this mean the symlinks disappear?