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 },
|
G_OPT_SENTINEL },
|
||||||
"geom", NULL
|
"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
|
G_CMD_SENTINEL
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -242,6 +249,99 @@ fmtattrib(struct gprovider *pp)
|
|||||||
return (buf);
|
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
|
static int
|
||||||
gpart_autofill(struct gctl_req *req)
|
gpart_autofill(struct gctl_req *req)
|
||||||
{
|
{
|
||||||
@ -257,6 +357,8 @@ gpart_autofill(struct gctl_req *req)
|
|||||||
int error, has_size, has_start;
|
int error, has_size, has_start;
|
||||||
|
|
||||||
s = gctl_get_ascii(req, "verb");
|
s = gctl_get_ascii(req, "verb");
|
||||||
|
if (strcmp(s, "resize") == 0)
|
||||||
|
return gpart_autofill_resize(req);
|
||||||
if (strcmp(s, "add") != 0)
|
if (strcmp(s, "add") != 0)
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd November 18, 2008
|
.Dd April 22, 2010
|
||||||
.Dt GPART 8
|
.Dt GPART 8
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -120,6 +120,13 @@ utility:
|
|||||||
.Op Fl t Ar type
|
.Op Fl t Ar type
|
||||||
.Op Fl f Ar flags
|
.Op Fl f Ar flags
|
||||||
.Ar geom
|
.Ar geom
|
||||||
|
.\" ==== RESIZE ====
|
||||||
|
.Nm
|
||||||
|
.Cm resize
|
||||||
|
.Fl i Ar index
|
||||||
|
.Op Fl s Ar size
|
||||||
|
.Op Fl f Ar flags
|
||||||
|
.Ar geom
|
||||||
.\" ==== SET ====
|
.\" ==== SET ====
|
||||||
.Nm
|
.Nm
|
||||||
.Cm set
|
.Cm set
|
||||||
@ -325,6 +332,30 @@ See the section entitled
|
|||||||
below for a discussion
|
below for a discussion
|
||||||
about its use.
|
about its use.
|
||||||
.El
|
.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 ====
|
.\" ==== SET ====
|
||||||
.It Cm set
|
.It Cm set
|
||||||
Set the named attribute on the partition entry.
|
Set the named attribute on the partition entry.
|
||||||
|
Loading…
Reference in New Issue
Block a user