LCOV - code coverage report
Current view: top level - src/server/protocol2 - bsparse.c (source / functions) Hit Total Coverage
Test: burp-coverage-clean.info Lines: 112 136 82.4 %
Date: 2021-06-01 21:59:08 Functions: 11 12 91.7 %

          Line data    Source code
       1             : #include "../../burp.h"
       2             : #include "../../attribs.h"
       3             : #include "../../base64.h"
       4             : #include "../../conffile.h"
       5             : #include "../../cstat.h"
       6             : #include "../../fsops.h"
       7             : #include "../../fzp.h"
       8             : #include "../../handy.h"
       9             : #include "../../hexmap.h"
      10             : #include "../../iobuf.h"
      11             : #include "../../lock.h"
      12             : #include "../../log.h"
      13             : #include "../../strlist.h"
      14             : #include "../../protocol2/blk.h"
      15             : #include "../bu_get.h"
      16             : #include "../protocol2/backup_phase4.h"
      17             : #include "../sdirs.h"
      18             : #include "bsigs.h"
      19             : #include "clist.h"
      20             : #include "champ_chooser/champ_chooser.h"
      21             : #include "sparse_min.h"
      22             : 
      23             : static struct lock *sparse_lock=NULL;
      24             : static struct cstat *clist=NULL;
      25             : 
      26           3 : static int usage(void)
      27             : {
      28           3 :         logfmt("\nUsage: %s [options] <path to dedup_group>\n", prog);
      29           3 :         logfmt("\n");
      30           3 :         logfmt(" Options:\n");
      31           3 :         logfmt("  -c <path>  Path to config file (default: %s).\n",
      32             :                 config_default_path());
      33           3 :         logfmt("\n");
      34           3 :         return 1;
      35             : }
      36             : 
      37           1 : static void release_locks(struct cstat *clist)
      38             : {
      39             :         struct cstat *c;
      40             :         struct sdirs *s;
      41           4 :         for(c=clist; c; c=c->next)
      42             :         {
      43           3 :                 s=(struct sdirs *)c->sdirs;
      44           3 :                 if(!s) continue;
      45           3 :                 lock_release(s->lock_storage_for_write);
      46           3 :                 logp("released: %s\n", c->name);
      47             :         }
      48           1 :         lock_release(sparse_lock);
      49           1 :         lock_free(&sparse_lock);
      50           1 :         logp("released: sparse index\n");
      51           1 : }
      52             : 
      53           0 : static void sighandler(__attribute__ ((unused)) int signum)
      54             : {
      55           0 :         release_locks(clist);
      56           0 :         exit(1);
      57             : }
      58             : 
      59           1 : static struct sdirs *get_sdirs(struct conf **conf)
      60             : {
      61           1 :         struct sdirs *sdirs=NULL;
      62           1 :         if(!(sdirs=sdirs_alloc())
      63           1 :           || sdirs_init_from_confs(sdirs, conf))
      64           0 :                 sdirs_free(&sdirs);
      65           1 :         return sdirs;
      66             : }
      67             : 
      68           1 : static int parse_directory(const char *arg,
      69             :         char **directory, char **dedup_group)
      70             : {
      71             :         char *cp;
      72           1 :         if(!(*directory=strdup_w(arg, __func__)))
      73             :                 goto error;
      74           1 :         strip_trailing_slashes(directory);
      75           1 :         if(!(cp=strrchr(*directory, '/')))
      76             :         {
      77           0 :                 logp("Could not parse directory '%s'\n", *directory);
      78           0 :                 goto error;
      79             :         }
      80           1 :         *cp='\0';
      81           1 :         if(!(*dedup_group=strdup_w(cp+1, __func__)))
      82             :                 goto error;
      83           1 :         if(!*directory || !*dedup_group)
      84             :                 goto error;
      85             :         return 0;
      86             : error:
      87           0 :         free_w(directory);
      88           0 :         free_w(dedup_group);
      89           0 :         return -1;
      90             : }
      91             : 
      92           1 : static struct conf **load_conf(const char *configfile,
      93             :         const char *directory, const char *dedup_group)
      94             : {
      95           1 :         struct conf **conf=NULL;
      96           1 :         if(!(conf=confs_alloc())
      97           1 :           || confs_init(conf)
      98           1 :           || conf_load_global_only(configfile, conf)
      99           1 :           || set_string(conf[OPT_CNAME], "fake")
     100           1 :           || set_string(conf[OPT_DIRECTORY], directory)
     101           1 :           || set_string(conf[OPT_DEDUP_GROUP], dedup_group)
     102           1 :           || set_protocol(conf, PROTO_2))
     103           0 :                 confs_free(&conf);
     104           1 :         return conf;
     105             : }
     106             : 
     107           1 : static void setup_sighandler(void)
     108             : {
     109           1 :         signal(SIGABRT, &sighandler);
     110           1 :         signal(SIGTERM, &sighandler);
     111           1 :         signal(SIGINT, &sighandler);
     112           1 : }
     113             : 
     114           1 : static int get_sparse_lock(const char *sparse)
     115             : {
     116           1 :         if(!(sparse_lock=try_to_get_sparse_lock(sparse)))
     117             :         {
     118           0 :                 logp("Could not get sparse lock\n");
     119           0 :                 return -1;
     120             :         }
     121             :         return 0;
     122             : }
     123             : 
     124           1 : static int get_client_locks(struct cstat *clist)
     125             : {
     126             :         struct cstat *c;
     127             :         struct sdirs *s;
     128           8 :         for(c=clist; c; c=c->next)
     129             :         {
     130           3 :                 s=(struct sdirs *)c->sdirs;
     131           3 :                 if(mkpath(&s->lock_storage_for_write->path, s->lockdir))
     132             :                 {
     133           0 :                         logp("problem with lock directory: %s\n", s->lockdir);
     134           0 :                         return -1;
     135             :                 }
     136             : 
     137           3 :                 lock_get(s->lock_storage_for_write);
     138           3 :                 switch(s->lock_storage_for_write->status)
     139             :                 {
     140             :                         case GET_LOCK_GOT:
     141           3 :                                 logp("locked: %s\n", c->name);
     142             :                                 break;
     143             :                         case GET_LOCK_NOT_GOT:
     144           0 :                                 logp("Unable to get lock for client %s\n",
     145             :                                         c->name);
     146           0 :                                 return -1;
     147             :                         case GET_LOCK_ERROR:
     148             :                         default:
     149           0 :                                 logp("Problem with lock file: %s\n",
     150             :                                         s->lock_storage_for_write->path);
     151           0 :                                 return -1;
     152             :                 }
     153             :         }
     154             :         return 0;
     155             : }
     156             : 
     157           3 : static int merge_in_client_sparse_indexes(struct cstat *c,
     158             :         const char *global_sparse)
     159             : {
     160           3 :         int ret=-1;
     161           3 :         char *sparse=NULL;
     162           3 :         struct bu *b=NULL;
     163           3 :         struct bu *bu_list=NULL;
     164           3 :         struct sdirs *s=(struct sdirs *)c->sdirs;
     165             : 
     166           3 :         if(bu_get_list(s, &bu_list))
     167             :                 goto end;
     168          12 :         for(b=bu_list; b; b=b->next)
     169             :         {
     170           9 :                 free_w(&sparse);
     171           9 :                 if(!(sparse=prepend_s(b->path, "manifest/sparse")))
     172             :                         goto end;
     173           9 :                 logp("merge: %s\n", sparse);
     174           9 :                 if(merge_into_global_sparse(sparse,
     175             :                         global_sparse, sparse_lock))
     176             :                                 goto end;
     177             :         }
     178             :         ret=0;
     179             : end:
     180           3 :         bu_list_free(&bu_list);
     181           3 :         free_w(&sparse);
     182           3 :         return ret;
     183             : }
     184             : 
     185           1 : static int merge_in_all_sparse_indexes(const char *global_sparse)
     186             : {
     187             :         struct cstat *c;
     188             : 
     189           1 :         if(!is_reg_lstat(global_sparse)
     190           0 :           && unlink(global_sparse))
     191             :         {
     192           0 :                 logp("Could not delete %s: %s\n",
     193           0 :                         global_sparse, strerror(errno));
     194           0 :                 return -1;
     195             :         }
     196             : 
     197           4 :         for(c=clist; c; c=c->next)
     198           3 :                 if(merge_in_client_sparse_indexes(c, global_sparse))
     199             :                         return -1;
     200             :         return 0;
     201             : }
     202             : 
     203           5 : int run_bsparse(int argc, char *argv[])
     204             : {
     205           5 :         int ret=1;
     206             :         int option;
     207           5 :         char *directory=NULL;
     208           5 :         char *dedup_group=NULL;
     209           5 :         const char *configfile=NULL;
     210           5 :         struct sdirs *sdirs=NULL;
     211           5 :         struct conf **conf=NULL;
     212             : 
     213           5 :         base64_init();
     214           5 :         configfile=config_default_path();
     215             : 
     216          11 :         while((option=getopt(argc, argv, "c:Vh?"))!=-1)
     217             :         {
     218           4 :                 switch(option)
     219             :                 {
     220             :                         case 'c':
     221           1 :                                 configfile=optarg;
     222           1 :                                 break;
     223             :                         case 'V':
     224           1 :                                 logfmt("%s-%s\n", prog, PACKAGE_VERSION);
     225           1 :                                 return 0;
     226             :                         case 'h':
     227             :                         case '?':
     228           2 :                                 return usage();
     229             :                 }
     230             :         }
     231             : 
     232           2 :         if(optind>=argc || optind<argc-1)
     233           1 :                 return usage();
     234             : 
     235           1 :         if(parse_directory(argv[optind], &directory, &dedup_group))
     236             :                 goto end;
     237             : 
     238           1 :         logp("config file: %s\n", configfile);
     239           1 :         logp("directory: %s\n", directory);
     240           1 :         logp("dedup_group: %s\n", dedup_group);
     241             : 
     242           1 :         if(!(conf=load_conf(configfile, directory, dedup_group))
     243           1 :           || !(sdirs=get_sdirs(conf)))
     244             :                 goto end;
     245             : 
     246           1 :         logp("clients: %s\n", sdirs->clients);
     247           1 :         logp("sparse file: %s\n", sdirs->global_sparse);
     248             : 
     249           1 :         setup_sighandler();
     250             : 
     251           1 :         if(get_sparse_lock(sdirs->global_sparse))
     252             :                 goto end;
     253             : 
     254           1 :         if(get_client_list(&clist, sdirs->clients, conf))
     255             :         {
     256           0 :                 logp("Did not find any client directories\n");
     257           0 :                 goto end;
     258             :         }
     259             : 
     260           1 :         if(get_client_locks(clist))
     261             :                 goto end;
     262             : 
     263           1 :         if(merge_in_all_sparse_indexes(sdirs->global_sparse))
     264             :                 goto end;
     265             : 
     266           1 :         if(sparse_minimise(conf, sdirs->global_sparse, sparse_lock, clist))
     267             :                 goto end;
     268             : 
     269           1 :         ret=0;
     270             : end:
     271           1 :         release_locks(clist);
     272           1 :         sdirs_free(&sdirs);
     273           1 :         free_w(&directory);
     274           1 :         free_w(&dedup_group);
     275           1 :         confs_free(&conf);
     276           1 :         clist_free(&clist);
     277           1 :         return ret;
     278             : }

Generated by: LCOV version 1.13