LCOV - code coverage report
Current view: top level - libpkg - backup.c (source / functions) Hit Total Coverage
Test: rapport Lines: 0 78 0.0 %
Date: 2021-12-10 16:22:55 Functions: 0 4 0.0 %
Branches: 0 28 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*-
       2                 :            :  * Copyright (c) 2011-2020 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 <fcntl.h>
      30                 :            : #include <libgen.h>
      31                 :            : #include <string.h>
      32                 :            : #include <errno.h>
      33                 :            : 
      34                 :            : #include "pkg.h"
      35                 :            : #include "private/event.h"
      36                 :            : #include "private/pkg.h"
      37                 :            : #include "private/pkgdb.h"
      38                 :            : 
      39                 :            : #include <bsd_compat.h>
      40                 :            : 
      41                 :            : /* Number of pages to copy per call to sqlite3_backup_step()
      42                 :            :    Default page size is 1024 bytes on Unix */
      43                 :            : #define NPAGES  4
      44                 :            : 
      45                 :            : static int
      46                 :          0 : ps_cb(void *ps, int ncols, char **coltext, __unused char **colnames)
      47                 :            : {
      48                 :            :         /* We should have exactly one row and one column of output */
      49         [ #  # ]:          0 :         if (ncols != 1)
      50                 :          0 :                 return (-1);    /* ABORT! */
      51                 :            : 
      52                 :          0 :         *(off_t *)ps = strtoll(coltext[0], NULL, 10);
      53                 :            : 
      54                 :          0 :         return (0);
      55                 :          0 : }
      56                 :            : 
      57                 :            : static int
      58                 :          0 : copy_database(sqlite3 *src, sqlite3 *dst)
      59                 :            : {
      60                 :            :         sqlite3_backup  *b;
      61                 :            :         char            *errmsg;
      62                 :            :         off_t            total;
      63                 :            :         off_t            done;
      64                 :            :         off_t            page_size;
      65                 :            :         int              ret;
      66                 :            : 
      67         [ #  # ]:          0 :         assert(src != NULL);
      68         [ #  # ]:          0 :         assert(dst != NULL);
      69                 :            : 
      70                 :          0 :         ret = sqlite3_exec(dst, "PRAGMA main.locking_mode=EXCLUSIVE;"
      71                 :            :                            "BEGIN IMMEDIATE;COMMIT;", NULL, NULL, &errmsg);
      72         [ #  # ]:          0 :         if (ret != SQLITE_OK) {
      73                 :          0 :                 pkg_emit_error("sqlite error -- %s", errmsg);
      74                 :          0 :                 sqlite3_free(errmsg);
      75                 :          0 :                 return (EPKG_FATAL);
      76                 :            :         }
      77                 :            : 
      78                 :          0 :         ret = sqlite3_exec(dst, "PRAGMA page_size", ps_cb, &page_size, &errmsg);
      79         [ #  # ]:          0 :         if (ret != SQLITE_OK) {
      80                 :          0 :                 pkg_emit_error("sqlite error -- %s", errmsg);
      81                 :          0 :                 sqlite3_free(errmsg);
      82                 :          0 :                 return (EPKG_FATAL);
      83                 :            :         }
      84                 :            : 
      85                 :          0 :         b = sqlite3_backup_init(dst, "main", src, "main");
      86                 :            : 
      87                 :          0 :         pkg_emit_progress_start(NULL);
      88                 :          0 :         do {
      89                 :          0 :                 ret = sqlite3_backup_step(b, NPAGES);
      90                 :          0 :                 total = sqlite3_backup_pagecount(b);
      91                 :          0 :                 done = total - sqlite3_backup_remaining(b);
      92                 :          0 :                 pkg_emit_progress_tick(done, total);
      93                 :            : 
      94   [ #  #  #  # ]:          0 :                 if (ret != SQLITE_OK && ret != SQLITE_DONE ) {
      95         [ #  # ]:          0 :                         if (ret == SQLITE_BUSY) {
      96                 :          0 :                                 sqlite3_sleep(250);
      97                 :          0 :                         } else {
      98                 :          0 :                                 ERROR_SQLITE(dst, "backup step");
      99                 :          0 :                                 break;
     100                 :            :                         }
     101                 :          0 :                 }
     102         [ #  # ]:          0 :         } while(done < total);
     103                 :            : 
     104                 :          0 :         ret = sqlite3_backup_finish(b);
     105                 :          0 :         pkg_emit_progress_tick(total, total);
     106                 :            : 
     107                 :          0 :         sqlite3_exec(dst, "PRAGMA main.locking_mode=NORMAL;"
     108                 :            :                            "BEGIN IMMEDIATE;COMMIT;", NULL, NULL, &errmsg);
     109                 :            : 
     110         [ #  # ]:          0 :         if (ret != SQLITE_OK) {
     111                 :          0 :                 pkg_emit_error("sqlite error -- %s", errmsg);
     112                 :          0 :                 sqlite3_free(errmsg);
     113                 :          0 :                 return (EPKG_FATAL);
     114                 :            :         }
     115                 :            : 
     116                 :          0 :         return ret;
     117                 :          0 : }
     118                 :            : 
     119                 :            : int
     120                 :          0 : pkgdb_dump(struct pkgdb *db, const char *dest)
     121                 :            : {
     122                 :            :         sqlite3 *backup;
     123                 :            :         int      ret;
     124                 :            :         int destdbfd;
     125                 :            :         int savedfd;
     126                 :            :         char *d;
     127                 :            : 
     128                 :          0 :         d = xstrdup(dest);
     129                 :          0 :         d = get_dirname(d);
     130                 :          0 :         destdbfd = open(d, O_DIRECTORY|O_CLOEXEC);
     131         [ #  # ]:          0 :         if (destdbfd == -1)
     132                 :          0 :                 pkg_fatal_errno("Unable to access '%s'", d);
     133                 :            : 
     134                 :          0 :         savedfd = pkg_get_dbdirfd();
     135                 :          0 :         ctx.pkg_dbdirfd = destdbfd;
     136                 :          0 :         ret = sqlite3_open(dest, &backup);
     137                 :          0 :         free(d);
     138                 :            : 
     139         [ #  # ]:          0 :         if (ret != SQLITE_OK) {
     140                 :          0 :                 ERROR_SQLITE(backup, "sqlite3_open");
     141                 :          0 :                 sqlite3_close(backup);
     142                 :          0 :                 return (EPKG_FATAL);
     143                 :            :         }
     144                 :            : 
     145                 :          0 :         pkg_emit_backup();
     146                 :          0 :         ret = copy_database(db->sqlite, backup);
     147                 :            : 
     148                 :          0 :         sqlite3_close(backup);
     149                 :          0 :         ctx.pkg_dbdirfd = savedfd;
     150                 :          0 :         close(savedfd);
     151                 :            : 
     152                 :          0 :         return (ret == SQLITE_OK? EPKG_OK : EPKG_FATAL);
     153                 :          0 : }
     154                 :            : 
     155                 :            : int
     156                 :          0 : pkgdb_load(struct pkgdb *db, const char *src)
     157                 :            : {
     158                 :            :         sqlite3 *restore;
     159                 :            :         int      ret;
     160                 :            : 
     161         [ #  # ]:          0 :         if (eaccess(src, R_OK)) {
     162                 :          0 :                 pkg_fatal_errno("Unable to access '%s'", src);
     163                 :          0 :         }
     164                 :            : 
     165                 :          0 :         ret = sqlite3_open(src, &restore);
     166                 :            : 
     167         [ #  # ]:          0 :         if (ret != SQLITE_OK) {
     168                 :          0 :                 ERROR_SQLITE(restore, "sqlite3_open");
     169                 :          0 :                 sqlite3_close(restore);
     170                 :          0 :                 return (EPKG_FATAL);
     171                 :            :         }
     172                 :            : 
     173                 :          0 :         pkg_emit_restore();
     174                 :          0 :         ret = copy_database(restore, db->sqlite);
     175                 :            : 
     176                 :          0 :         sqlite3_close(restore);
     177                 :            : 
     178                 :          0 :         return (ret == SQLITE_OK? EPKG_OK : EPKG_FATAL);
     179                 :          0 : }

Generated by: LCOV version 1.15