aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/geom/part/gpart.813
-rw-r--r--sys/geom/part/g_part.c12
-rw-r--r--sys/geom/part/g_part_gpt.c16
3 files changed, 34 insertions, 7 deletions
diff --git a/lib/geom/part/gpart.8 b/lib/geom/part/gpart.8
index 80ea0a317d3a..a19f06dd67be 100644
--- a/lib/geom/part/gpart.8
+++ b/lib/geom/part/gpart.8
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd June 17, 2018
+.Dd September 3, 2019
.Dt GPART 8
.Os
.Sh NAME
@@ -1207,7 +1207,13 @@ variables can be used to control the behavior of the
GEOM class.
The default value is shown next to each variable.
.Bl -tag -width indent
-.It Va kern.geom.part.auto_resize: No 1
+.It Va kern.geom.part.allow_nesting : No 0
+By default, some schemes (currently BSD, BSD64 and VTOC8) do not permit
+further nested partitioning.
+This variable overrides this restriction and allows arbitrary nesting (except
+within partitions created at offset 0).
+Some schemes have their own separate checks, for which see below.
+.It Va kern.geom.part.auto_resize : No 1
This variable controls automatic resize behavior of
.Nm
GEOM class.
@@ -1228,6 +1234,9 @@ disk metadata.
If some inconsistency is detected, the partition table will be
rejected with a diagnostic message:
.Sy "GEOM_PART: Integrity check failed (provider, scheme)" .
+.It Va kern.geom.part.gpt.allow_nesting : No 0
+By default the GPT scheme is allowed only at the outermost nesting level.
+This variable allows this restriction to be removed.
.It Va kern.geom.part.ldm.debug : No 0
Debug level of the Logical Disk Manager (LDM) module.
This can be set to a number between 0 and 2 inclusive.
diff --git a/sys/geom/part/g_part.c b/sys/geom/part/g_part.c
index 3b8fe3916aec..583fa190f9f8 100644
--- a/sys/geom/part/g_part.c
+++ b/sys/geom/part/g_part.c
@@ -143,6 +143,10 @@ static u_int auto_resize = 1;
SYSCTL_UINT(_kern_geom_part, OID_AUTO, auto_resize,
CTLFLAG_RWTUN, &auto_resize, 1,
"Enable auto resize");
+static u_int allow_nesting = 0;
+SYSCTL_UINT(_kern_geom_part, OID_AUTO, allow_nesting,
+ CTLFLAG_RWTUN, &allow_nesting, 0,
+ "Allow additional levels of nesting");
/*
* The GEOM partitioning class.
@@ -2271,7 +2275,13 @@ g_part_start(struct bio *bp)
return;
if (g_handleattr_int(bp, "GEOM::fwsectors", table->gpt_sectors))
return;
- if (g_handleattr_int(bp, "PART::isleaf", table->gpt_isleaf))
+ /*
+ * allow_nesting overrides "isleaf" to false _unless_ the
+ * provider offset is zero, since otherwise we would recurse.
+ */
+ if (g_handleattr_int(bp, "PART::isleaf",
+ table->gpt_isleaf &&
+ (allow_nesting == 0 || entry->gpe_offset == 0)))
return;
if (g_handleattr_int(bp, "PART::depth", table->gpt_depth))
return;
diff --git a/sys/geom/part/g_part_gpt.c b/sys/geom/part/g_part_gpt.c
index f69cd84efab4..5eb2c03fe552 100644
--- a/sys/geom/part/g_part_gpt.c
+++ b/sys/geom/part/g_part_gpt.c
@@ -54,6 +54,14 @@ __FBSDID("$FreeBSD$");
FEATURE(geom_part_gpt, "GEOM partitioning class for GPT partitions support");
+SYSCTL_DECL(_kern_geom_part);
+static SYSCTL_NODE(_kern_geom_part, OID_AUTO, gpt, CTLFLAG_RW, 0,
+ "GEOM_PART_GPT GUID Partition Table");
+
+static u_int allow_nesting = 0;
+SYSCTL_UINT(_kern_geom_part_gpt, OID_AUTO, allow_nesting,
+ CTLFLAG_RWTUN, &allow_nesting, 0, "Allow GPT to be nested inside other schemes");
+
CTASSERT(offsetof(struct gpt_hdr, padding) == 92);
CTASSERT(sizeof(struct gpt_ent) == 128);
@@ -652,8 +660,8 @@ g_part_gpt_create(struct g_part_table *basetable, struct g_part_parms *gpp)
struct g_part_gpt_table *table;
size_t tblsz;
- /* We don't nest, which means that our depth should be 0. */
- if (basetable->gpt_depth != 0)
+ /* Our depth should be 0 unless nesting was explicitly enabled. */
+ if (!allow_nesting && basetable->gpt_depth != 0)
return (ENXIO);
table = (struct g_part_gpt_table *)basetable;
@@ -815,8 +823,8 @@ g_part_gpt_probe(struct g_part_table *table, struct g_consumer *cp)
u_char *buf;
int error, index, pri, res;
- /* We don't nest, which means that our depth should be 0. */
- if (table->gpt_depth != 0)
+ /* Our depth should be 0 unless nesting was explicitly enabled. */
+ if (!allow_nesting && table->gpt_depth != 0)
return (ENXIO);
pp = cp->provider;