gpart: append partition name to the underlying provider's physical path

If the underlying provider's physical path is null, then the gpart device's
physical path will be, too. Otherwise, it will append the partition name,
such as "/p1" or "/s1/a". This will make gpart work better with zfsd(8).

PR:		224965
MFC after:	3 weeks
Differential Revision:	https://reviews.freebsd.org/D14010
This commit is contained in:
Alan Somers 2018-02-14 20:26:09 +00:00
parent abc4f7e735
commit 834063202a
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=329275
4 changed files with 233 additions and 3 deletions

View file

@ -275,6 +275,35 @@ g_part_geometry(struct g_part_table *table, struct g_consumer *cp,
}
}
static void
g_part_get_physpath_done(struct bio *bp)
{
struct g_geom *gp;
struct g_part_entry *entry;
struct g_part_table *table;
struct g_provider *pp;
struct bio *pbp;
pbp = bp->bio_parent;
pp = pbp->bio_to;
gp = pp->geom;
table = gp->softc;
entry = pp->private;
if (bp->bio_error == 0) {
char *end;
size_t len, remainder;
len = strlcat(bp->bio_data, "/", bp->bio_length);
if (len < bp->bio_length) {
end = bp->bio_data + len;
remainder = bp->bio_length - len;
G_PART_NAME(table, entry, end, remainder);
}
}
g_std_done(bp);
}
#define DPRINTF(...) if (bootverbose) { \
printf("GEOM_PART: " __VA_ARGS__); \
}
@ -2189,6 +2218,7 @@ g_part_start(struct bio *bp)
struct g_part_table *table;
struct g_kerneldump *gkd;
struct g_provider *pp;
void (*done_func)(struct bio *) = g_std_done;
char buf[64];
biotrack(bp, __func__);
@ -2243,6 +2273,10 @@ g_part_start(struct bio *bp)
if (g_handleattr_str(bp, "PART::type",
G_PART_TYPE(table, entry, buf, sizeof(buf))))
return;
if (!strcmp("GEOM::physpath", bp->bio_attribute)) {
done_func = g_part_get_physpath_done;
break;
}
if (!strcmp("GEOM::kerneldump", bp->bio_attribute)) {
/*
* Check that the partition is suitable for kernel
@ -2279,7 +2313,7 @@ g_part_start(struct bio *bp)
g_io_deliver(bp, ENOMEM);
return;
}
bp2->bio_done = g_std_done;
bp2->bio_done = done_func;
g_io_request(bp2, cp);
}

View file

@ -7,10 +7,9 @@ TESTSDIR= ${TESTSBASE}/sys/geom/class
TESTS_SUBDIRS+= concat
TESTS_SUBDIRS+= eli
TESTS_SUBDIRS+= gate
# XXX: might not work due to geom(4) changes; more investigation's needed
#TESTS_SUBDIRS+= gpt
TESTS_SUBDIRS+= mirror
TESTS_SUBDIRS+= nop
TESTS_SUBDIRS+= part
TESTS_SUBDIRS+= raid3
TESTS_SUBDIRS+= shsec
TESTS_SUBDIRS+= stripe

View file

@ -0,0 +1,10 @@
# $FreeBSD$
PACKAGE= tests
TESTSDIR= ${TESTSBASE}/sys/geom/class/${.CURDIR:T}
# TODO: port the perl tests in tools/regression/geom_gpt
ATF_TESTS_SH+= misc
.include <bsd.test.mk>

View file

@ -0,0 +1,187 @@
# Copyright (c) 2018 Alan Somers
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# $FreeBSD$
MD_DEVS="md.devs"
atf_test_case blank_physpath cleanup
blank_physpath_head()
{
atf_set "descr" "gpart shouldn't add physical paths to underlying providers that have none"
atf_set "require.user" "root"
}
blank_physpath_body()
{
load_gnop
load_gpart
md=$(alloc_md)
atf_check -o empty -e ignore diskinfo -p ${md}
atf_check -s exit:0 -o ignore gpart create -s bsd ${md}
atf_check -s exit:0 -o ignore gpart add -t freebsd-ufs ${md}
atf_check -o empty -e ignore diskinfo -p ${md}a
}
blank_physpath_cleanup()
{
common_cleanup
}
atf_test_case bsd_physpath cleanup
bsd_physpath_head()
{
atf_set "descr" "BSD partitions should append /X to the underlying device's physical path"
atf_set "require.user" "root"
}
bsd_physpath_body()
{
load_gnop
load_gpart
md=$(alloc_md)
physpath="some/physical/path"
atf_check gnop create -z $physpath /dev/${md}
atf_check -s exit:0 -o ignore gpart create -s bsd ${md}.nop
atf_check -s exit:0 -o ignore gpart add -t freebsd-ufs ${md}.nop
gpart_physpath=$(diskinfo -p ${md}.nopa)
atf_check_equal "${physpath}/a" "$gpart_physpath"
}
bsd_physpath_cleanup()
{
common_cleanup
}
atf_test_case gpt_physpath cleanup
gpt_physpath_head()
{
atf_set "descr" "GPT partitions should append /pX to the underlying device's physical path"
atf_set "require.user" "root"
}
gpt_physpath_body()
{
load_gnop
load_gpart
md=$(alloc_md)
physpath="some/physical/path"
atf_check gnop create -z $physpath /dev/${md}
atf_check -s exit:0 -o ignore gpart create -s gpt ${md}.nop
atf_check -s exit:0 -o ignore gpart add -t efi ${md}.nop
gpart_physpath=$(diskinfo -p ${md}.nopp1)
atf_check_equal "${physpath}/p1" "$gpart_physpath"
}
gpt_physpath_cleanup()
{
common_cleanup
}
atf_test_case mbr_physpath cleanup
mbr_physpath_head()
{
atf_set "descr" "MBR partitions should append /sX to the underlying device's physical path"
atf_set "require.user" "root"
}
mbr_physpath_body()
{
load_gnop
load_gpart
md=$(alloc_md)
physpath="some/physical/path"
atf_check gnop create -z $physpath /dev/${md}
atf_check -s exit:0 -o ignore gpart create -s mbr ${md}.nop
atf_check -s exit:0 -o ignore gpart add -t freebsd ${md}.nop
gpart_physpath=$(diskinfo -p ${md}.nops1)
atf_check_equal "${physpath}/s1" "$gpart_physpath"
}
mbr_physpath_cleanup()
{
common_cleanup
}
atf_test_case mbr_bsd_physpath cleanup
mbr_bsd_physpath_head()
{
atf_set "descr" "BSD partitions nested within MBR partitions should append /sX/Y to the underlying device's physical path"
atf_set "require.user" "root"
}
mbr_bsd_physpath_body()
{
load_gnop
load_gpart
md=$(alloc_md)
physpath="some/physical/path"
atf_check gnop create -z $physpath /dev/${md}
atf_check -s exit:0 -o ignore gpart create -s mbr ${md}.nop
atf_check -s exit:0 -o ignore gpart add -t freebsd ${md}.nop
atf_check -s exit:0 -o ignore gpart create -s bsd ${md}.nops1
atf_check -s exit:0 -o ignore gpart add -t freebsd-ufs ${md}.nops1
gpart_physpath=$(diskinfo -p ${md}.nops1a)
atf_check_equal "${physpath}/s1/a" "$gpart_physpath"
}
mbr_bsd_physpath_cleanup()
{
common_cleanup
}
atf_init_test_cases()
{
atf_add_test_case blank_physpath
atf_add_test_case bsd_physpath
atf_add_test_case gpt_physpath
atf_add_test_case mbr_physpath
atf_add_test_case mbr_bsd_physpath
}
alloc_md()
{
local md
md=$(mdconfig -a -t swap -s 1M) || atf_fail "mdconfig -a failed"
echo ${md} >> $MD_DEVS
echo ${md}
}
common_cleanup()
{
if [ -f "$MD_DEVS" ]; then
while read test_md; do
gnop destroy -f ${test_md}.nop 2>/dev/null
mdconfig -d -u $test_md 2>/dev/null
done < $MD_DEVS
rm $MD_DEVS
fi
true
}
load_gpart()
{
if ! kldstat -q -m g_part; then
geom part load || atf_skip "could not load module for geom part"
fi
}
load_gnop()
{
if ! kldstat -q -m g_nop; then
geom nop load || atf_skip "could not load module for geom nop"
fi
}