summaryrefslogtreecommitdiffstats
path: root/sys/geom/eli/g_eli_ctl.c
diff options
context:
space:
mode:
authorpjd <pjd@FreeBSD.org>2006-08-09 18:11:14 +0000
committerpjd <pjd@FreeBSD.org>2006-08-09 18:11:14 +0000
commitb2ae936be5770cb95ef230182dc30da91308565b (patch)
treec2ce4f09e3fa2e0c6279cf9dcb57fa4bc280e161 /sys/geom/eli/g_eli_ctl.c
parent41a38f71c97dbc8a0216c1f1456203720aff5868 (diff)
downloadFreeBSD-src-b2ae936be5770cb95ef230182dc30da91308565b.zip
FreeBSD-src-b2ae936be5770cb95ef230182dc30da91308565b.tar.gz
Allow geli to operate on read-only providers.
Initial patch from: vd MFC after: 2 weeks
Diffstat (limited to 'sys/geom/eli/g_eli_ctl.c')
-rw-r--r--sys/geom/eli/g_eli_ctl.c65
1 files changed, 47 insertions, 18 deletions
diff --git a/sys/geom/eli/g_eli_ctl.c b/sys/geom/eli/g_eli_ctl.c
index a6db6c2..702f854 100644
--- a/sys/geom/eli/g_eli_ctl.c
+++ b/sys/geom/eli/g_eli_ctl.c
@@ -57,7 +57,7 @@ g_eli_ctl_attach(struct gctl_req *req, struct g_class *mp)
struct g_provider *pp;
const char *name;
u_char *key, mkey[G_ELI_DATAIVKEYLEN];
- int *nargs, *detach;
+ int *nargs, *detach, *readonly;
int keysize, error;
u_int nkey;
@@ -79,6 +79,12 @@ g_eli_ctl_attach(struct gctl_req *req, struct g_class *mp)
return;
}
+ readonly = gctl_get_paraml(req, "readonly", sizeof(*readonly));
+ if (readonly == NULL) {
+ gctl_error(req, "No '%s' argument.", "readonly");
+ return;
+ }
+
name = gctl_get_asciiparam(req, "arg0");
if (name == NULL) {
gctl_error(req, "No 'arg%u' argument.", 0);
@@ -124,8 +130,16 @@ g_eli_ctl_attach(struct gctl_req *req, struct g_class *mp)
}
G_ELI_DEBUG(1, "Using Master Key %u for %s.", nkey, pp->name);
+ if (*detach && *readonly) {
+ bzero(&md, sizeof(md));
+ gctl_error(req, "Options -d and -r are mutually exclusive.",
+ pp->name, error);
+ return;
+ }
if (*detach)
md.md_flags |= G_ELI_FLAG_WO_DETACH;
+ if (*readonly)
+ md.md_flags |= G_ELI_FLAG_RO;
g_eli_create(req, mp, pp, &md, mkey, nkey);
bzero(mkey, sizeof(mkey));
bzero(&md, sizeof(md));
@@ -374,6 +388,10 @@ g_eli_ctl_setkey(struct gctl_req *req, struct g_class *mp)
gctl_error(req, "Provider %s is invalid.", name);
return;
}
+ if (sc->sc_flags & G_ELI_FLAG_RO) {
+ gctl_error(req, "Cannot change keys for read-only provider.");
+ return;
+ }
cp = LIST_FIRST(&sc->sc_geom->consumer);
pp = cp->provider;
@@ -483,6 +501,10 @@ g_eli_ctl_delkey(struct gctl_req *req, struct g_class *mp)
gctl_error(req, "Provider %s is invalid.", name);
return;
}
+ if (sc->sc_flags & G_ELI_FLAG_RO) {
+ gctl_error(req, "Cannot delete keys for read-only provider.");
+ return;
+ }
cp = LIST_FIRST(&sc->sc_geom->consumer);
pp = cp->provider;
@@ -565,9 +587,7 @@ g_eli_kill_one(struct g_eli_softc *sc)
{
struct g_provider *pp;
struct g_consumer *cp;
- u_char *sector;
- int err, error = 0;
- u_int i;
+ int error = 0;
g_topology_assert();
@@ -580,22 +600,31 @@ g_eli_kill_one(struct g_eli_softc *sc)
cp = LIST_FIRST(&sc->sc_geom->consumer);
pp = cp->provider;
- sector = malloc(pp->sectorsize, M_ELI, M_WAITOK);
- for (i = 0; i <= g_eli_overwrites; i++) {
- if (i == g_eli_overwrites)
- bzero(sector, pp->sectorsize);
- else
- arc4rand(sector, pp->sectorsize, 0);
- err = g_write_data(cp, pp->mediasize - pp->sectorsize, sector,
- pp->sectorsize);
- if (err != 0) {
- G_ELI_DEBUG(0, "Cannot erase metadata on %s "
- "(error=%d).", pp->name, err);
- if (error == 0)
- error = err;
+ if (sc->sc_flags & G_ELI_FLAG_RO) {
+ G_ELI_DEBUG(0, "WARNING: Metadata won't be erased on read-only "
+ "provider: %s.", pp->name);
+ } else {
+ u_char *sector;
+ u_int i;
+ int err;
+
+ sector = malloc(pp->sectorsize, M_ELI, M_WAITOK);
+ for (i = 0; i <= g_eli_overwrites; i++) {
+ if (i == g_eli_overwrites)
+ bzero(sector, pp->sectorsize);
+ else
+ arc4rand(sector, pp->sectorsize, 0);
+ err = g_write_data(cp, pp->mediasize - pp->sectorsize,
+ sector, pp->sectorsize);
+ if (err != 0) {
+ G_ELI_DEBUG(0, "Cannot erase metadata on %s "
+ "(error=%d).", pp->name, err);
+ if (error == 0)
+ error = err;
+ }
}
+ free(sector, M_ELI);
}
- free(sector, M_ELI);
if (error == 0)
G_ELI_DEBUG(0, "%s has been killed.", pp->name);
g_eli_destroy(sc, 1);
OpenPOWER on IntegriCloud