Implement the resize command for resizing partitions. Without new
size, the partition in question is resized to fill all available space. Quality work by Andrey! Submitted by: "Andrey V. Elsukov" <bu7cher@yandex.ru>
This commit is contained in:
parent
3f71c319f4
commit
783310e6d9
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=207095
@ -133,6 +133,13 @@ struct g_command PUBSYM(class_commands)[] = {
|
||||
G_OPT_SENTINEL },
|
||||
"geom", NULL
|
||||
},
|
||||
{ "resize", 0, gpart_issue, {
|
||||
{ 's', "size", autofill, G_TYPE_ASCLBA },
|
||||
{ 'i', index_param, NULL, G_TYPE_ASCNUM },
|
||||
{ 'f', "flags", flags, G_TYPE_STRING },
|
||||
G_OPT_SENTINEL },
|
||||
"geom", NULL
|
||||
},
|
||||
G_CMD_SENTINEL
|
||||
};
|
||||
|
||||
@ -242,6 +249,99 @@ fmtattrib(struct gprovider *pp)
|
||||
return (buf);
|
||||
}
|
||||
|
||||
static int
|
||||
gpart_autofill_resize(struct gctl_req *req)
|
||||
{
|
||||
struct gmesh mesh;
|
||||
struct gclass *cp;
|
||||
struct ggeom *gp;
|
||||
struct gprovider *pp;
|
||||
unsigned long long last, size, start, new_size;
|
||||
unsigned long long lba, new_lba;
|
||||
const char *s;
|
||||
char *val;
|
||||
int error, idx;
|
||||
|
||||
s = gctl_get_ascii(req, "size");
|
||||
if (*s == '*')
|
||||
new_size = (unsigned long long)atoll(s);
|
||||
else
|
||||
return (0);
|
||||
|
||||
s = gctl_get_ascii(req, index_param);
|
||||
idx = strtol(s, &val, 10);
|
||||
if (idx < 1 || *s == '\0' || *val != '\0')
|
||||
errx(EXIT_FAILURE, "invalid partition index");
|
||||
|
||||
error = geom_gettree(&mesh);
|
||||
if (error)
|
||||
return (error);
|
||||
s = gctl_get_ascii(req, "class");
|
||||
if (s == NULL)
|
||||
abort();
|
||||
cp = find_class(&mesh, s);
|
||||
if (cp == NULL)
|
||||
errx(EXIT_FAILURE, "Class %s not found.", s);
|
||||
s = gctl_get_ascii(req, "geom");
|
||||
if (s == NULL)
|
||||
abort();
|
||||
gp = find_geom(cp, s);
|
||||
if (gp == NULL)
|
||||
errx(EXIT_FAILURE, "No such geom: %s.", s);
|
||||
last = atoll(find_geomcfg(gp, "last"));
|
||||
|
||||
LIST_FOREACH(pp, &gp->lg_provider, lg_provider) {
|
||||
s = find_provcfg(pp, "index");
|
||||
if (s == NULL)
|
||||
continue;
|
||||
if (atoi(s) == idx)
|
||||
break;
|
||||
}
|
||||
if (pp == NULL)
|
||||
errx(EXIT_FAILURE, "invalid partition index");
|
||||
|
||||
s = find_provcfg(pp, "start");
|
||||
if (s == NULL) {
|
||||
s = find_provcfg(pp, "offset");
|
||||
start = atoll(s) / pp->lg_sectorsize;
|
||||
} else
|
||||
start = atoll(s);
|
||||
s = find_provcfg(pp, "end");
|
||||
if (s == NULL) {
|
||||
s = find_provcfg(pp, "length");
|
||||
lba = start + atoll(s) / pp->lg_sectorsize;
|
||||
} else
|
||||
lba = atoll(s) + 1;
|
||||
|
||||
if (lba > last)
|
||||
return (ENOSPC);
|
||||
size = lba - start;
|
||||
pp = find_provider(gp, lba);
|
||||
if (pp == NULL)
|
||||
new_size = last - start + 1;
|
||||
else {
|
||||
s = find_provcfg(pp, "start");
|
||||
if (s == NULL) {
|
||||
s = find_provcfg(pp, "offset");
|
||||
new_lba = atoll(s) / pp->lg_sectorsize;
|
||||
} else
|
||||
new_lba = atoll(s);
|
||||
/* Is there any free space between current and
|
||||
* next providers?
|
||||
*/
|
||||
if (new_lba > lba)
|
||||
new_size = new_lba - start;
|
||||
else
|
||||
return (ENOSPC);
|
||||
}
|
||||
asprintf(&val, "%llu", new_size);
|
||||
if (val == NULL)
|
||||
return (ENOMEM);
|
||||
gctl_change_param(req, "size", -1, val);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
gpart_autofill(struct gctl_req *req)
|
||||
{
|
||||
@ -257,6 +357,8 @@ gpart_autofill(struct gctl_req *req)
|
||||
int error, has_size, has_start;
|
||||
|
||||
s = gctl_get_ascii(req, "verb");
|
||||
if (strcmp(s, "resize") == 0)
|
||||
return gpart_autofill_resize(req);
|
||||
if (strcmp(s, "add") != 0)
|
||||
return (0);
|
||||
|
||||
|
@ -24,7 +24,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd November 18, 2008
|
||||
.Dd April 22, 2010
|
||||
.Dt GPART 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -120,6 +120,13 @@ utility:
|
||||
.Op Fl t Ar type
|
||||
.Op Fl f Ar flags
|
||||
.Ar geom
|
||||
.\" ==== RESIZE ====
|
||||
.Nm
|
||||
.Cm resize
|
||||
.Fl i Ar index
|
||||
.Op Fl s Ar size
|
||||
.Op Fl f Ar flags
|
||||
.Ar geom
|
||||
.\" ==== SET ====
|
||||
.Nm
|
||||
.Cm set
|
||||
@ -325,6 +332,30 @@ See the section entitled
|
||||
below for a discussion
|
||||
about its use.
|
||||
.El
|
||||
.\" ==== RESIZE ====
|
||||
.It Cm resize
|
||||
Resize a partition from geom
|
||||
.Ar geom
|
||||
and further identified by the
|
||||
.Fl i Ar index
|
||||
option. New partition size is expressed in logical block
|
||||
numbers and can be given by the
|
||||
.Fl s Ar size
|
||||
option. If
|
||||
.Fl s
|
||||
option is ommited then new size is automatically calculated
|
||||
to maximum available from given geom
|
||||
.Ar geom .
|
||||
.Pp
|
||||
Additional options include:
|
||||
.Bl -tag -width 10n
|
||||
.It Fl f Ar flags
|
||||
Additional operational flags.
|
||||
See the section entitled
|
||||
.Sx "OPERATIONAL FLAGS"
|
||||
below for a discussion
|
||||
about its use.
|
||||
.El
|
||||
.\" ==== SET ====
|
||||
.It Cm set
|
||||
Set the named attribute on the partition entry.
|
||||
|
Loading…
Reference in New Issue
Block a user