aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKyle Evans <kevans@FreeBSD.org>2019-09-03 20:57:20 +0000
committerKyle Evans <kevans@FreeBSD.org>2019-09-03 20:57:20 +0000
commitef03f57dd201827cc74615571c410273e49a5964 (patch)
tree817841551cbdd7b5ab38853f4cd816fb400f6830
parentdca52ab480bfe71c3dc1d86822e551a7d1c9ec72 (diff)
downloadsrc-ef03f57dd201827cc74615571c410273e49a5964.tar.gz
src-ef03f57dd201827cc74615571c410273e49a5964.zip
Allow more nesting of GEOM partitioning schemes
GEOM is supposed to be topology-agnostic, but the GPT and BSD partition code has arbitrary restrictions on nesting that are annoying in cases such as running VMs on raw partitions (since the VM's partitioning scheme is not visible to the host). This patch adds sysctls to disable the restrictions except in the case of BSD label (and similar) partitions with offset 0 (where we need to avoid recursively recognizing the label). Submitted by: Andrew Gierth MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D21350
Notes
Notes: svn path=/head/; revision=351797
-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;