Add "-a alignment" option to gpart(8). When it specified gpart(8)
tries to align partition start offset and size to be multiple of alignment value. MFC after: 2 weeks
This commit is contained in:
parent
a7ad07bff3
commit
d9711c28ef
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=221363
@ -93,6 +93,7 @@ static void gpart_restore(struct gctl_req *, unsigned int);
|
|||||||
|
|
||||||
struct g_command PUBSYM(class_commands)[] = {
|
struct g_command PUBSYM(class_commands)[] = {
|
||||||
{ "add", 0, gpart_issue, {
|
{ "add", 0, gpart_issue, {
|
||||||
|
{ 'a', "alignment", GPART_AUTOFILL, G_TYPE_STRING },
|
||||||
{ 'b', "start", GPART_AUTOFILL, G_TYPE_STRING },
|
{ 'b', "start", GPART_AUTOFILL, G_TYPE_STRING },
|
||||||
{ 's', "size", GPART_AUTOFILL, G_TYPE_STRING },
|
{ 's', "size", GPART_AUTOFILL, G_TYPE_STRING },
|
||||||
{ 't', "type", NULL, G_TYPE_STRING },
|
{ 't', "type", NULL, G_TYPE_STRING },
|
||||||
@ -100,7 +101,8 @@ struct g_command PUBSYM(class_commands)[] = {
|
|||||||
{ 'l', "label", G_VAL_OPTIONAL, G_TYPE_STRING },
|
{ 'l', "label", G_VAL_OPTIONAL, G_TYPE_STRING },
|
||||||
{ 'f', "flags", GPART_FLAGS, G_TYPE_STRING },
|
{ 'f', "flags", GPART_FLAGS, G_TYPE_STRING },
|
||||||
G_OPT_SENTINEL },
|
G_OPT_SENTINEL },
|
||||||
"[-b start] [-s size] -t type [-i index] [-l label] [-f flags] geom"
|
"[-a alignment] [-b start] [-s size] -t type [-i index] "
|
||||||
|
"[-l label] [-f flags] geom"
|
||||||
},
|
},
|
||||||
{ "backup", 0, gpart_backup, G_NULL_OPTS,
|
{ "backup", 0, gpart_backup, G_NULL_OPTS,
|
||||||
"geom"
|
"geom"
|
||||||
@ -168,11 +170,12 @@ struct g_command PUBSYM(class_commands)[] = {
|
|||||||
"-a attrib -i index [-f flags] geom"
|
"-a attrib -i index [-f flags] geom"
|
||||||
},
|
},
|
||||||
{ "resize", 0, gpart_issue, {
|
{ "resize", 0, gpart_issue, {
|
||||||
|
{ 'a', "alignment", GPART_AUTOFILL, G_TYPE_STRING },
|
||||||
{ 's', "size", GPART_AUTOFILL, G_TYPE_STRING },
|
{ 's', "size", GPART_AUTOFILL, G_TYPE_STRING },
|
||||||
{ 'i', GPART_PARAM_INDEX, NULL, G_TYPE_NUMBER },
|
{ 'i', GPART_PARAM_INDEX, NULL, G_TYPE_NUMBER },
|
||||||
{ 'f', "flags", GPART_FLAGS, G_TYPE_STRING },
|
{ 'f', "flags", GPART_FLAGS, G_TYPE_STRING },
|
||||||
G_OPT_SENTINEL },
|
G_OPT_SENTINEL },
|
||||||
"[-s size] -i index [-f flags] geom"
|
"[-a alignment] [-s size] -i index [-f flags] geom"
|
||||||
},
|
},
|
||||||
{ "restore", 0, gpart_restore, {
|
{ "restore", 0, gpart_restore, {
|
||||||
{ 'F', "force", NULL, G_TYPE_BOOL },
|
{ 'F', "force", NULL, G_TYPE_BOOL },
|
||||||
@ -298,6 +301,9 @@ fmtattrib(struct gprovider *pp)
|
|||||||
return (buf);
|
return (buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define ALIGNDOWN(d, a) (-(a) & (d))
|
||||||
|
#define ALIGNUP(d, a) (-(-(a) & -(d)))
|
||||||
|
|
||||||
static int
|
static int
|
||||||
gpart_autofill_resize(struct gctl_req *req)
|
gpart_autofill_resize(struct gctl_req *req)
|
||||||
{
|
{
|
||||||
@ -306,7 +312,7 @@ gpart_autofill_resize(struct gctl_req *req)
|
|||||||
struct ggeom *gp;
|
struct ggeom *gp;
|
||||||
struct gprovider *pp;
|
struct gprovider *pp;
|
||||||
off_t last, size, start, new_size;
|
off_t last, size, start, new_size;
|
||||||
off_t lba, new_lba;
|
off_t lba, new_lba, alignment;
|
||||||
const char *s;
|
const char *s;
|
||||||
int error, idx;
|
int error, idx;
|
||||||
|
|
||||||
@ -333,6 +339,19 @@ gpart_autofill_resize(struct gctl_req *req)
|
|||||||
if (pp == NULL)
|
if (pp == NULL)
|
||||||
errx(EXIT_FAILURE, "Provider for geom %s not found.", s);
|
errx(EXIT_FAILURE, "Provider for geom %s not found.", s);
|
||||||
|
|
||||||
|
s = gctl_get_ascii(req, "alignment");
|
||||||
|
alignment = 1;
|
||||||
|
if (*s != '*') {
|
||||||
|
error = g_parse_lba(s, pp->lg_sectorsize, &alignment);
|
||||||
|
if (error)
|
||||||
|
errc(EXIT_FAILURE, error, "Invalid alignment param");
|
||||||
|
if (alignment == 0)
|
||||||
|
errx(EXIT_FAILURE, "Invalid alignment param");
|
||||||
|
}
|
||||||
|
error = gctl_delete_param(req, "alignment");
|
||||||
|
if (error)
|
||||||
|
errc(EXIT_FAILURE, error, "internal error");
|
||||||
|
|
||||||
s = gctl_get_ascii(req, "size");
|
s = gctl_get_ascii(req, "size");
|
||||||
if (*s == '*')
|
if (*s == '*')
|
||||||
new_size = 0;
|
new_size = 0;
|
||||||
@ -341,10 +360,14 @@ gpart_autofill_resize(struct gctl_req *req)
|
|||||||
if (error)
|
if (error)
|
||||||
errc(EXIT_FAILURE, error, "Invalid size param");
|
errc(EXIT_FAILURE, error, "Invalid size param");
|
||||||
/* no autofill necessary. */
|
/* no autofill necessary. */
|
||||||
goto done;
|
if (alignment == 1)
|
||||||
|
goto done;
|
||||||
|
if (new_size > alignment)
|
||||||
|
new_size = ALIGNDOWN(new_size, alignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
last = (off_t)strtoimax(find_geomcfg(gp, "last"), NULL, 0);
|
last = (off_t)strtoimax(find_geomcfg(gp, "last"), NULL, 0);
|
||||||
|
last = ALIGNDOWN(last, alignment);
|
||||||
LIST_FOREACH(pp, &gp->lg_provider, lg_provider) {
|
LIST_FOREACH(pp, &gp->lg_provider, lg_provider) {
|
||||||
s = find_provcfg(pp, "index");
|
s = find_provcfg(pp, "index");
|
||||||
if (s == NULL)
|
if (s == NULL)
|
||||||
@ -376,7 +399,7 @@ gpart_autofill_resize(struct gctl_req *req)
|
|||||||
size = lba - start;
|
size = lba - start;
|
||||||
pp = find_provider(gp, lba);
|
pp = find_provider(gp, lba);
|
||||||
if (pp == NULL)
|
if (pp == NULL)
|
||||||
new_size = last - start + 1;
|
new_size = ALIGNDOWN(last - start + 1, alignment);
|
||||||
else {
|
else {
|
||||||
s = find_provcfg(pp, "start");
|
s = find_provcfg(pp, "start");
|
||||||
if (s == NULL) {
|
if (s == NULL) {
|
||||||
@ -389,6 +412,7 @@ gpart_autofill_resize(struct gctl_req *req)
|
|||||||
* Is there any free space between current and
|
* Is there any free space between current and
|
||||||
* next providers?
|
* next providers?
|
||||||
*/
|
*/
|
||||||
|
new_lba = ALIGNUP(new_lba, alignment);
|
||||||
if (new_lba > lba)
|
if (new_lba > lba)
|
||||||
new_size = new_lba - start;
|
new_size = new_lba - start;
|
||||||
else {
|
else {
|
||||||
@ -410,12 +434,12 @@ gpart_autofill(struct gctl_req *req)
|
|||||||
struct gclass *cp;
|
struct gclass *cp;
|
||||||
struct ggeom *gp;
|
struct ggeom *gp;
|
||||||
struct gprovider *pp;
|
struct gprovider *pp;
|
||||||
off_t first, last;
|
off_t first, last, a_first;
|
||||||
off_t size, start;
|
off_t size, start, a_lba;
|
||||||
off_t lba, len;
|
off_t lba, len, alignment;
|
||||||
uintmax_t grade;
|
uintmax_t grade;
|
||||||
const char *s;
|
const char *s;
|
||||||
int error, has_size, has_start;
|
int error, has_size, has_start, has_alignment;
|
||||||
|
|
||||||
s = gctl_get_ascii(req, "verb");
|
s = gctl_get_ascii(req, "verb");
|
||||||
if (strcmp(s, "resize") == 0)
|
if (strcmp(s, "resize") == 0)
|
||||||
@ -442,6 +466,20 @@ gpart_autofill(struct gctl_req *req)
|
|||||||
if (pp == NULL)
|
if (pp == NULL)
|
||||||
errx(EXIT_FAILURE, "Provider for geom %s not found.", s);
|
errx(EXIT_FAILURE, "Provider for geom %s not found.", s);
|
||||||
|
|
||||||
|
s = gctl_get_ascii(req, "alignment");
|
||||||
|
has_alignment = (*s == '*') ? 0 : 1;
|
||||||
|
alignment = 1;
|
||||||
|
if (has_alignment) {
|
||||||
|
error = g_parse_lba(s, pp->lg_sectorsize, &alignment);
|
||||||
|
if (error)
|
||||||
|
errc(EXIT_FAILURE, error, "Invalid alignment param");
|
||||||
|
if (alignment == 0)
|
||||||
|
errx(EXIT_FAILURE, "Invalid alignment param");
|
||||||
|
}
|
||||||
|
error = gctl_delete_param(req, "alignment");
|
||||||
|
if (error)
|
||||||
|
errc(EXIT_FAILURE, error, "internal error");
|
||||||
|
|
||||||
s = gctl_get_ascii(req, "size");
|
s = gctl_get_ascii(req, "size");
|
||||||
has_size = (*s == '*') ? 0 : 1;
|
has_size = (*s == '*') ? 0 : 1;
|
||||||
size = 0;
|
size = 0;
|
||||||
@ -449,6 +487,8 @@ gpart_autofill(struct gctl_req *req)
|
|||||||
error = g_parse_lba(s, pp->lg_sectorsize, &size);
|
error = g_parse_lba(s, pp->lg_sectorsize, &size);
|
||||||
if (error)
|
if (error)
|
||||||
errc(EXIT_FAILURE, error, "Invalid size param");
|
errc(EXIT_FAILURE, error, "Invalid size param");
|
||||||
|
if (size > alignment)
|
||||||
|
size = ALIGNDOWN(size, alignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
s = gctl_get_ascii(req, "start");
|
s = gctl_get_ascii(req, "start");
|
||||||
@ -458,15 +498,18 @@ gpart_autofill(struct gctl_req *req)
|
|||||||
error = g_parse_lba(s, pp->lg_sectorsize, &start);
|
error = g_parse_lba(s, pp->lg_sectorsize, &start);
|
||||||
if (error)
|
if (error)
|
||||||
errc(EXIT_FAILURE, error, "Invalid start param");
|
errc(EXIT_FAILURE, error, "Invalid start param");
|
||||||
|
start = ALIGNUP(start, alignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* No autofill necessary. */
|
/* No autofill necessary. */
|
||||||
if (has_size && has_start)
|
if (has_size && has_start && !has_alignment)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
first = (off_t)strtoimax(find_geomcfg(gp, "first"), NULL, 0);
|
first = (off_t)strtoimax(find_geomcfg(gp, "first"), NULL, 0);
|
||||||
last = (off_t)strtoimax(find_geomcfg(gp, "last"), NULL, 0);
|
last = (off_t)strtoimax(find_geomcfg(gp, "last"), NULL, 0);
|
||||||
grade = ~0ULL;
|
grade = ~0ULL;
|
||||||
|
a_first = ALIGNUP(first, alignment);
|
||||||
|
last = ALIGNDOWN(last, alignment);
|
||||||
while ((pp = find_provider(gp, first)) != NULL) {
|
while ((pp = find_provider(gp, first)) != NULL) {
|
||||||
s = find_provcfg(pp, "start");
|
s = find_provcfg(pp, "start");
|
||||||
if (s == NULL) {
|
if (s == NULL) {
|
||||||
@ -475,23 +518,24 @@ gpart_autofill(struct gctl_req *req)
|
|||||||
} else
|
} else
|
||||||
lba = (off_t)strtoimax(s, NULL, 0);
|
lba = (off_t)strtoimax(s, NULL, 0);
|
||||||
|
|
||||||
if (first < lba) {
|
a_lba = ALIGNDOWN(lba, alignment);
|
||||||
|
if (first < a_lba && a_first < a_lba) {
|
||||||
/* Free space [first, lba> */
|
/* Free space [first, lba> */
|
||||||
len = lba - first;
|
len = a_lba - a_first;
|
||||||
if (has_size) {
|
if (has_size) {
|
||||||
if (len >= size &&
|
if (len >= size &&
|
||||||
(uintmax_t)(len - size) < grade) {
|
(uintmax_t)(len - size) < grade) {
|
||||||
start = first;
|
start = a_first;
|
||||||
grade = len - size;
|
grade = len - size;
|
||||||
}
|
}
|
||||||
} else if (has_start) {
|
} else if (has_start) {
|
||||||
if (start >= first && start < lba) {
|
if (start >= a_first && start < a_lba) {
|
||||||
size = lba - start;
|
size = a_lba - start;
|
||||||
grade = start - first;
|
grade = start - a_first;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (grade == ~0ULL || len > size) {
|
if (grade == ~0ULL || len > size) {
|
||||||
start = first;
|
start = a_first;
|
||||||
size = len;
|
size = len;
|
||||||
grade = 0;
|
grade = 0;
|
||||||
}
|
}
|
||||||
@ -505,24 +549,25 @@ gpart_autofill(struct gctl_req *req)
|
|||||||
(off_t)strtoimax(s, NULL, 0) / pp->lg_sectorsize;
|
(off_t)strtoimax(s, NULL, 0) / pp->lg_sectorsize;
|
||||||
} else
|
} else
|
||||||
first = (off_t)strtoimax(s, NULL, 0) + 1;
|
first = (off_t)strtoimax(s, NULL, 0) + 1;
|
||||||
|
a_first = ALIGNUP(first, alignment);
|
||||||
}
|
}
|
||||||
if (first <= last) {
|
if (a_first <= last) {
|
||||||
/* Free space [first-last] */
|
/* Free space [first-last] */
|
||||||
len = last - first + 1;
|
len = ALIGNDOWN(last - a_first + 1, alignment);
|
||||||
if (has_size) {
|
if (has_size) {
|
||||||
if (len >= size &&
|
if (len >= size &&
|
||||||
(uintmax_t)(len - size) < grade) {
|
(uintmax_t)(len - size) < grade) {
|
||||||
start = first;
|
start = a_first;
|
||||||
grade = len - size;
|
grade = len - size;
|
||||||
}
|
}
|
||||||
} else if (has_start) {
|
} else if (has_start) {
|
||||||
if (start >= first && start <= last) {
|
if (start >= a_first && start <= last) {
|
||||||
size = last - start + 1;
|
size = ALIGNDOWN(last - start + 1, alignment);
|
||||||
grade = start - first;
|
grade = start - a_first;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (grade == ~0ULL || len > size) {
|
if (grade == ~0ULL || len > size) {
|
||||||
start = first;
|
start = a_first;
|
||||||
size = len;
|
size = len;
|
||||||
grade = 0;
|
grade = 0;
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd March 12, 2011
|
.Dd May 03, 2011
|
||||||
.Dt GPART 8
|
.Dt GPART 8
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -91,6 +91,7 @@ utility:
|
|||||||
.Nm
|
.Nm
|
||||||
.Cm add
|
.Cm add
|
||||||
.Fl t Ar type
|
.Fl t Ar type
|
||||||
|
.Op Fl a Ar alignment
|
||||||
.Op Fl b Ar start
|
.Op Fl b Ar start
|
||||||
.Op Fl s Ar size
|
.Op Fl s Ar size
|
||||||
.Op Fl i Ar index
|
.Op Fl i Ar index
|
||||||
@ -148,6 +149,7 @@ utility:
|
|||||||
.Nm
|
.Nm
|
||||||
.Cm resize
|
.Cm resize
|
||||||
.Fl i Ar index
|
.Fl i Ar index
|
||||||
|
.Op Fl a Ar alignment
|
||||||
.Op Fl s Ar size
|
.Op Fl s Ar size
|
||||||
.Op Fl f Ar flags
|
.Op Fl f Ar flags
|
||||||
.Ar geom
|
.Ar geom
|
||||||
@ -209,7 +211,17 @@ Partition types are discussed below in the section entitled
|
|||||||
.Sx "PARTITION TYPES" .
|
.Sx "PARTITION TYPES" .
|
||||||
.Pp
|
.Pp
|
||||||
Additional options include:
|
Additional options include:
|
||||||
.Bl -tag -width 10n
|
.Bl -tag -width 12n
|
||||||
|
.It Fl a Ar alignment
|
||||||
|
If specified, then
|
||||||
|
.Nm
|
||||||
|
utility tries to align
|
||||||
|
.Ar start
|
||||||
|
offset and partition
|
||||||
|
.Ar size
|
||||||
|
to be multiple of
|
||||||
|
.Ar alignment
|
||||||
|
value.
|
||||||
.It Fl i Ar index
|
.It Fl i Ar index
|
||||||
The index in the partition table at which the new partition is to be
|
The index in the partition table at which the new partition is to be
|
||||||
placed.
|
placed.
|
||||||
@ -416,7 +428,15 @@ to maximum available from given geom
|
|||||||
.Ar geom .
|
.Ar geom .
|
||||||
.Pp
|
.Pp
|
||||||
Additional options include:
|
Additional options include:
|
||||||
.Bl -tag -width 10n
|
.Bl -tag -width 12n
|
||||||
|
.It Fl a Ar alignment
|
||||||
|
If specified, then
|
||||||
|
.Nm
|
||||||
|
utility tries to align partition
|
||||||
|
.Ar size
|
||||||
|
to be multiple of
|
||||||
|
.Ar alignment
|
||||||
|
value.
|
||||||
.It Fl f Ar flags
|
.It Fl f Ar flags
|
||||||
Additional operational flags.
|
Additional operational flags.
|
||||||
See the section entitled
|
See the section entitled
|
||||||
@ -834,6 +854,13 @@ partition that would contain UFS where the system boots from.
|
|||||||
/sbin/gpart add -s 512M -t freebsd-ufs da0
|
/sbin/gpart add -s 512M -t freebsd-ufs da0
|
||||||
.Ed
|
.Ed
|
||||||
.Pp
|
.Pp
|
||||||
|
Create a 15GB-sized
|
||||||
|
.Cm freebsd-ufs
|
||||||
|
partition that would contain UFS and aligned on 4KB boundaries:
|
||||||
|
.Bd -literal -offset indent
|
||||||
|
/sbin/gpart add -s 15G -t freebsd-ufs -a 4k da0
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
After having created all required partitions, embed bootstrap code into them.
|
After having created all required partitions, embed bootstrap code into them.
|
||||||
.Bd -literal -offset indent
|
.Bd -literal -offset indent
|
||||||
/sbin/gpart bootcode -p /boot/boot1 da0
|
/sbin/gpart bootcode -p /boot/boot1 da0
|
||||||
|
Loading…
Reference in New Issue
Block a user