Author: pjd Date: Thu Sep 23 11:18:02 2010 New Revision: 213060 URL: http://svn.freebsd.org/changeset/base/213060
Log: - When trashing metadata, repeat overwrite kern.geom.eli.overwrites times. - Flush write cache after each write. MFC after: 1 week Modified: head/sbin/geom/class/eli/geom_eli.c Modified: head/sbin/geom/class/eli/geom_eli.c ============================================================================== --- head/sbin/geom/class/eli/geom_eli.c Thu Sep 23 11:04:50 2010 (r213059) +++ head/sbin/geom/class/eli/geom_eli.c Thu Sep 23 11:18:02 2010 (r213060) @@ -27,6 +27,9 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); +#include <sys/types.h> +#include <sys/sysctl.h> + #include <stdio.h> #include <stdint.h> #include <stdlib.h> @@ -1015,11 +1018,54 @@ eli_delkey(struct gctl_req *req) eli_delkey_detached(req, prov); } +static int +eli_trash_metadata(struct gctl_req *req, const char *prov, int fd, off_t offset) +{ + unsigned int overwrites; + unsigned char *sector; + ssize_t size; + int error; + + size = sizeof(overwrites); + if (sysctlbyname("kern.geom.eli.overwrites", &overwrites, &size, + NULL, 0) == -1 || overwrites == 0) { + overwrites = G_ELI_OVERWRITES; + } + + size = g_sectorsize(fd); + if (size <= 0) { + gctl_error(req, "Cannot obtain provider sector size %s: %s.", + prov, strerror(errno)); + return (-1); + } + sector = malloc(size); + if (sector == NULL) { + gctl_error(req, "Cannot allocate %zd bytes of memory.", size); + return (-1); + } + + error = 0; + do { + arc4rand(sector, size); + if (pwrite(fd, sector, size, offset) != size) { + if (error == 0) + error = errno; + } + (void)g_flush(fd); + } while (--overwrites > 0); + if (error != 0) { + gctl_error(req, "Cannot trash metadata on provider %s: %s.", + prov, strerror(error)); + return (-1); + } + return (0); +} + static void eli_kill_detached(struct gctl_req *req, const char *prov) { - struct g_eli_metadata md; - int error; + off_t offset; + int fd; /* * NOTE: Maybe we should verify if this is geli provider first, @@ -1036,12 +1082,22 @@ eli_kill_detached(struct gctl_req *req, } #endif - arc4rand((unsigned char *)&md, sizeof(md)); - error = g_metadata_store(prov, (unsigned char *)&md, sizeof(md)); - if (error != 0) { - gctl_error(req, "Cannot write metadata to %s: %s.", prov, - strerror(error)); + fd = g_open(prov, 1); + if (fd == -1) { + gctl_error(req, "Cannot open provider %s: %s.", prov, + strerror(errno)); + return; } + offset = g_mediasize(fd) - g_sectorsize(fd); + if (offset <= 0) { + gctl_error(req, + "Cannot obtain media size or sector size for provider %s: %s.", + prov, strerror(errno)); + (void)g_close(fd); + return; + } + (void)eli_trash_metadata(req, prov, fd, offset); + (void)g_close(fd); } static void @@ -1336,12 +1392,8 @@ eli_resize(struct gctl_req *req) (void)g_flush(provfd); /* Now trash the old metadata. */ - arc4rand(sector, secsize); - if (pwrite(provfd, sector, secsize, oldsize - secsize) != secsize) { - gctl_error(req, "Failed to clobber old metadata: %s.", - strerror(errno)); + if (eli_trash_metadata(req, prov, provfd, oldsize - secsize) == -1) goto out; - } out: if (provfd >= 0) (void)g_close(provfd); _______________________________________________ svn-src-head@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"