LCOV - code coverage report
Current view: top level - libpkg - backup.c (source / functions) Hit Total Coverage
Test: cov.info Lines: 0 71 0.0 %
Date: 2015-08-15 Functions: 0 4 0.0 %

          Line data    Source code
       1             : /*-
       2             :  * Copyright (c) 2011-2014 Baptiste Daroussin <bapt@FreeBSD.org>
       3             :  * Copyright (c) 2012 Matthew Seaman <matthew@FreeBSD.org>
       4             :  * All rights reserved.
       5             :  * 
       6             :  * Redistribution and use in source and binary forms, with or without
       7             :  * modification, are permitted provided that the following conditions
       8             :  * are met:
       9             :  * 1. Redistributions of source code must retain the above copyright
      10             :  *    notice, this list of conditions and the following disclaimer
      11             :  *    in this position and unchanged.
      12             :  * 2. Redistributions in binary form must reproduce the above copyright
      13             :  *    notice, this list of conditions and the following disclaimer in the
      14             :  *    documentation and/or other materials provided with the distribution.
      15             :  * 
      16             :  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
      17             :  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
      18             :  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
      19             :  * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
      20             :  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
      21             :  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      22             :  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      23             :  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      24             :  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
      25             :  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      26             :  */
      27             : 
      28             : #include <assert.h>
      29             : #include <libgen.h>
      30             : #include <string.h>
      31             : #include <errno.h>
      32             : 
      33             : #include "pkg.h"
      34             : #include "private/event.h"
      35             : #include "private/pkg.h"
      36             : #include "private/pkgdb.h"
      37             : 
      38             : #include <bsd_compat.h>
      39             : 
      40             : /* Number of pages to copy per call to sqlite3_backup_step()
      41             :    Default page size is 1024 bytes on Unix */
      42             : #define NPAGES  4
      43             : 
      44             : static int
      45           0 : ps_cb(void *ps, int ncols, char **coltext, __unused char **colnames)
      46             : {
      47             :         /* We should have exactly one row and one column of output */
      48           0 :         if (ncols != 1)
      49           0 :                 return (-1);    /* ABORT! */
      50             : 
      51           0 :         *(off_t *)ps = strtoll(coltext[0], NULL, 10);
      52             : 
      53           0 :         return (0);
      54             : }
      55             : 
      56             : static int
      57           0 : copy_database(sqlite3 *src, sqlite3 *dst)
      58             : {
      59             :         sqlite3_backup  *b;
      60             :         char            *errmsg;
      61             :         off_t            total;
      62             :         off_t            done;
      63             :         off_t            page_size;
      64             :         int              ret;
      65             : 
      66           0 :         assert(src != NULL);
      67           0 :         assert(dst != NULL);
      68             : 
      69           0 :         ret = sqlite3_exec(dst, "PRAGMA main.locking_mode=EXCLUSIVE;"
      70             :                            "BEGIN IMMEDIATE;COMMIT;", NULL, NULL, &errmsg);
      71           0 :         if (ret != SQLITE_OK) {
      72           0 :                 pkg_emit_error("sqlite error -- %s", errmsg);
      73           0 :                 sqlite3_free(errmsg);
      74           0 :                 return (EPKG_FATAL);
      75             :         }
      76             : 
      77           0 :         ret = sqlite3_exec(dst, "PRAGMA page_size", ps_cb, &page_size, &errmsg);
      78           0 :         if (ret != SQLITE_OK) {
      79           0 :                 pkg_emit_error("sqlite error -- %s", errmsg);
      80           0 :                 sqlite3_free(errmsg);
      81           0 :                 return (EPKG_FATAL);
      82             :         }
      83             : 
      84           0 :         b = sqlite3_backup_init(dst, "main", src, "main");
      85             : 
      86           0 :         total = 0;
      87             : 
      88           0 :         pkg_emit_progress_start(NULL);
      89             :         do {
      90           0 :                 ret = sqlite3_backup_step(b, NPAGES);
      91           0 :                 total = sqlite3_backup_pagecount(b);
      92           0 :                 done = total - sqlite3_backup_remaining(b);
      93           0 :                 pkg_emit_progress_tick(done, total);
      94             : 
      95           0 :                 if (ret != SQLITE_OK && ret != SQLITE_DONE ) {
      96           0 :                         if (ret == SQLITE_BUSY) {
      97           0 :                                 sqlite3_sleep(250);
      98             :                         } else {
      99           0 :                                 ERROR_SQLITE(dst, "backup step");
     100           0 :                                 break;
     101             :                         }
     102             :                 }
     103           0 :         } while(done < total);
     104             : 
     105           0 :         ret = sqlite3_backup_finish(b);
     106           0 :         pkg_emit_progress_tick(total, total);
     107             : 
     108           0 :         sqlite3_exec(dst, "PRAGMA main.locking_mode=NORMAL;"
     109             :                            "BEGIN IMMEDIATE;COMMIT;", NULL, NULL, &errmsg);
     110             : 
     111           0 :         if (ret != SQLITE_OK) {
     112           0 :                 pkg_emit_error("sqlite error -- %s", errmsg);
     113           0 :                 sqlite3_free(errmsg);
     114           0 :                 return (EPKG_FATAL);
     115             :         }
     116             : 
     117           0 :         return ret;
     118             : }
     119             : 
     120             : int
     121           0 : pkgdb_dump(struct pkgdb *db, const char *dest)
     122             : {
     123             :         sqlite3 *backup;
     124             :         int      ret;
     125             : 
     126           0 :         if (eaccess(dest, W_OK)) {
     127           0 :                 if (errno != ENOENT) {
     128           0 :                         pkg_emit_error("eaccess(%s) -- %s", dest,
     129           0 :                             strerror(errno));
     130           0 :                         return (EPKG_FATAL);
     131             :                 }
     132             : 
     133             :                 /* Could we create the Sqlite DB file? */
     134           0 :                 if (eaccess(bsd_dirname(dest), W_OK)) {
     135           0 :                         pkg_emit_error("eaccess(%s) -- %s", bsd_dirname(dest),
     136           0 :                             strerror(errno));
     137           0 :                         return (EPKG_FATAL);
     138             :                 }
     139             :         }
     140             : 
     141           0 :         ret = sqlite3_open(dest, &backup);
     142             : 
     143           0 :         if (ret != SQLITE_OK) {
     144           0 :                 ERROR_SQLITE(backup, "sqlite3_open");
     145           0 :                 sqlite3_close(backup);
     146           0 :                 return (EPKG_FATAL);
     147             :         }
     148             : 
     149           0 :         pkg_emit_backup();
     150           0 :         ret = copy_database(db->sqlite, backup);
     151             : 
     152           0 :         sqlite3_close(backup);
     153             : 
     154           0 :         return (ret == SQLITE_OK? EPKG_OK : EPKG_FATAL);
     155             : }
     156             : 
     157             : int
     158           0 : pkgdb_load(struct pkgdb *db, const char *src)
     159             : {
     160             :         sqlite3 *restore;
     161             :         int      ret;
     162             : 
     163           0 :         if (eaccess(src, R_OK)) {
     164           0 :                 pkg_emit_error("eaccess(%s) -- %s", src, strerror(errno));
     165           0 :                 return (EPKG_FATAL);
     166             :         }
     167             : 
     168           0 :         ret = sqlite3_open(src, &restore);
     169             : 
     170           0 :         if (ret != SQLITE_OK) {
     171           0 :                 ERROR_SQLITE(restore, "sqlite3_open");
     172           0 :                 sqlite3_close(restore);
     173           0 :                 return (EPKG_FATAL);
     174             :         }
     175             : 
     176           0 :         pkg_emit_restore();
     177           0 :         ret = copy_database(restore, db->sqlite);
     178             : 
     179           0 :         sqlite3_close(restore);
     180             : 
     181           0 :         return (ret == SQLITE_OK? EPKG_OK : EPKG_FATAL);
     182             : }

Generated by: LCOV version 1.10