Author: pjd
Date: Tue Oct 25 07:31:13 2011
New Revision: 226716
URL: http://svn.freebsd.org/changeset/base/226716

Log:
  Simplify eli_backup_create() and eli_backup_restore() functions.
  As a side-effect it is now possible to backup unsupported (newer)
  GELI metadata versions.
  
  MFC after:    3 days

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 Tue Oct 25 07:24:51 2011        
(r226715)
+++ head/sbin/geom/class/eli/geom_eli.c Tue Oct 25 07:31:13 2011        
(r226716)
@@ -1295,66 +1295,53 @@ eli_kill(struct gctl_req *req)
 static int
 eli_backup_create(struct gctl_req *req, const char *prov, const char *file)
 {
-       struct g_eli_metadata md;
        unsigned char *sector;
        ssize_t secsize;
-       off_t mediasize;
-       int filefd, provfd, ret;
+       int error, filefd, ret;
 
        ret = -1;
-       provfd = filefd = -1;
+       filefd = -1;
        sector = NULL;
        secsize = 0;
 
-       provfd = g_open(prov, 0);
-       if (provfd == -1) {
-               gctl_error(req, "Cannot open %s: %s.", prov, strerror(errno));
-               goto out;
-       }
-       filefd = open(file, O_WRONLY | O_TRUNC | O_CREAT, 0600);
-       if (filefd == -1) {
-               gctl_error(req, "Cannot open %s: %s.", file, strerror(errno));
-               goto out;
-       }
-
-       mediasize = g_mediasize(provfd);
-       secsize = g_sectorsize(provfd);
-       if (mediasize == -1 || secsize == -1) {
+       secsize = g_get_sectorsize(prov);
+       if (secsize == 0) {
                gctl_error(req, "Cannot get informations about %s: %s.", prov,
                    strerror(errno));
                goto out;
        }
-
        sector = malloc(secsize);
        if (sector == NULL) {
                gctl_error(req, "Cannot allocate memory.");
                goto out;
        }
-
        /* Read metadata from the provider. */
-       if (pread(provfd, sector, secsize, mediasize - secsize) != secsize) {
-               gctl_error(req, "Cannot read metadata: %s.", strerror(errno));
+       error = g_metadata_read(prov, sector, secsize, G_ELI_MAGIC);
+       if (error != 0) {
+               gctl_error(req, "Unable to read metadata from %s: %s.", prov,
+                   strerror(error));
                goto out;
        }
-       /* Check if this is geli provider. */
-       if (eli_metadata_decode(sector, &md) != 0) {
-               gctl_error(req, "MD5 hash mismatch: not a geli provider?");
+
+       filefd = open(file, O_WRONLY | O_TRUNC | O_CREAT, 0600);
+       if (filefd == -1) {
+               gctl_error(req, "Unable to open %s: %s.", file,
+                   strerror(errno));
                goto out;
        }
        /* Write metadata to the destination file. */
        if (write(filefd, sector, secsize) != secsize) {
-               gctl_error(req, "Cannot write to %s: %s.", file,
+               gctl_error(req, "Unable to write to %s: %s.", file,
                    strerror(errno));
+               (void)close(filefd);
+               (void)unlink(file);
                goto out;
        }
        (void)fsync(filefd);
+       (void)close(filefd);
        /* Success. */
        ret = 0;
 out:
-       if (provfd >= 0)
-               (void)g_close(provfd);
-       if (filefd >= 0)
-               (void)close(filefd);
        if (sector != NULL) {
                bzero(sector, secsize);
                free(sector);
@@ -1384,10 +1371,8 @@ eli_restore(struct gctl_req *req)
 {
        struct g_eli_metadata md;
        const char *file, *prov;
-       unsigned char *sector;
-       ssize_t secsize;
        off_t mediasize;
-       int nargs, filefd, provfd;
+       int nargs;
 
        nargs = gctl_get_int(req, "nargs");
        if (nargs != 2) {
@@ -1397,72 +1382,28 @@ eli_restore(struct gctl_req *req)
        file = gctl_get_ascii(req, "arg0");
        prov = gctl_get_ascii(req, "arg1");
 
-       provfd = filefd = -1;
-       sector = NULL;
-       secsize = 0;
-
-       filefd = open(file, O_RDONLY);
-       if (filefd == -1) {
-               gctl_error(req, "Cannot open %s: %s.", file, strerror(errno));
-               goto out;
-       }
-       provfd = g_open(prov, 1);
-       if (provfd == -1) {
-               gctl_error(req, "Cannot open %s: %s.", prov, strerror(errno));
-               goto out;
-       }
-
-       mediasize = g_mediasize(provfd);
-       secsize = g_sectorsize(provfd);
-       if (mediasize == -1 || secsize == -1) {
-               gctl_error(req, "Cannot get informations about %s: %s.", prov,
-                   strerror(errno));
-               goto out;
-       }
-
-       sector = malloc(secsize);
-       if (sector == NULL) {
-               gctl_error(req, "Cannot allocate memory.");
-               goto out;
-       }
-
        /* Read metadata from the backup file. */
-       if (read(filefd, sector, secsize) != secsize) {
-               gctl_error(req, "Cannot read from %s: %s.", file,
+       if (eli_metadata_read(req, file, &md) == -1)
+               return;
+       /* Obtain provider's mediasize. */
+       mediasize = g_get_mediasize(prov);
+       if (mediasize == 0) {
+               gctl_error(req, "Cannot get informations about %s: %s.", prov,
                    strerror(errno));
-               goto out;
-       }
-       /* Check if this file contains geli metadata. */
-       if (eli_metadata_decode(sector, &md) != 0) {
-               gctl_error(req, "MD5 hash mismatch: not a geli backup file?");
-               goto out;
+               return;
        }
        /* Check if the provider size has changed since we did the backup. */
        if (md.md_provsize != (uint64_t)mediasize) {
                if (gctl_get_int(req, "force")) {
                        md.md_provsize = mediasize;
-                       eli_metadata_encode(&md, sector);
                } else {
                        gctl_error(req, "Provider size mismatch: "
                            "wrong backup file?");
-                       goto out;
+                       return;
                }
        }
-       /* Write metadata from the provider. */
-       if (pwrite(provfd, sector, secsize, mediasize - secsize) != secsize) {
-               gctl_error(req, "Cannot write metadata: %s.", strerror(errno));
-               goto out;
-       }
-       (void)g_flush(provfd);
-out:
-       if (provfd >= 0)
-               (void)g_close(provfd);
-       if (filefd >= 0)
-               (void)close(filefd);
-       if (sector != NULL) {
-               bzero(sector, secsize);
-               free(sector);
-       }
+       /* Write metadata to the provider. */
+       (void)eli_metadata_store(req, prov, &md);
 }
 
 static void
_______________________________________________
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"

Reply via email to