LCOV - code coverage report
Current view: top level - src/server/protocol2 - rblk.c (source / functions) Hit Total Coverage
Test: burp-coverage-clean.info Lines: 70 89 78.7 %
Date: 2020-05-31 21:14:12 Functions: 10 11 90.9 %

          Line data    Source code
       1             : #include "../../burp.h"
       2             : #include "../../alloc.h"
       3             : #include "../../cmd.h"
       4             : #include "../../fzp.h"
       5             : #include "../../hexmap.h"
       6             : #include "../../iobuf.h"
       7             : #include "../../log.h"
       8             : #include "../../prepend.h"
       9             : #include "../../protocol2/blk.h"
      10             : #include "rblk.h"
      11             : 
      12             : static ssize_t rblk_mem=0;
      13             : static ssize_t rblk_mem_max=0;
      14             : 
      15             : // For retrieving stored data.
      16             : struct rblk
      17             : {
      18             :         uint64_t hash_key;
      19             :         struct iobuf readbuf[DATA_FILE_SIG_MAX];
      20             :         uint16_t rlen;
      21             :         struct fzp *fzp;
      22             :         UT_hash_handle hh;
      23             : };
      24             : 
      25          56 : static void rblk_free_content(struct rblk *rblk)
      26             : {
      27         372 :         for(int j=0; j<rblk->rlen; j++)
      28             :         {
      29         316 :                 rblk_mem-=rblk->readbuf[j].len;
      30         316 :                 iobuf_free_content(&rblk->readbuf[j]);
      31             :         }
      32          56 :         fzp_close(&rblk->fzp);
      33          56 : }
      34             : 
      35          56 : static void rblk_free(struct rblk **rblk)
      36             : {
      37             : /*
      38             : uint16_t datno;
      39             : char *x;
      40             : x=uint64_to_savepathstr_with_sig_uint((*rblk)->hash_key, &datno);
      41             : logp("close: %s\n", x);
      42             : */
      43          56 :         rblk_free_content(*rblk);
      44          56 :         rblk_mem-=sizeof(struct rblk);
      45          56 :         free_v((void **)rblk);
      46          56 : }
      47             : 
      48             : static struct rblk *rblk_hash=NULL;
      49             : 
      50         316 : static struct rblk *rblk_hash_find(uint64_t savepath)
      51             : {
      52             :         struct rblk *rblk;
      53         316 :         HASH_FIND_INT(rblk_hash, &savepath, rblk);
      54         316 :         return rblk;
      55             : }
      56             : 
      57          56 : static void rblk_hash_add(struct rblk *rblk)
      58             : {
      59          56 :         HASH_ADD_INT(rblk_hash, hash_key, rblk);
      60          56 : }
      61             : 
      62          56 : static struct rblk *rblk_alloc(void)
      63             : {
      64             :         struct rblk *rblk;
      65          56 :         rblk=(struct rblk *)calloc_w(1, sizeof(struct rblk), __func__);
      66          56 :         if(rblk)
      67          56 :                 rblk_mem+=sizeof(struct rblk);
      68          56 :         return rblk;
      69             : }
      70             : 
      71           6 : void rblks_init(ssize_t rblk_memory_max)
      72             : {
      73           6 :         rblk_mem_max=rblk_memory_max;
      74           6 : }
      75             : 
      76           7 : void rblks_free(void)
      77             : {
      78             :         struct rblk *tmp;
      79             :         struct rblk *rblk;
      80             : 
      81          63 :         HASH_ITER(hh, rblk_hash, rblk, tmp)
      82             :         {
      83          56 :                 HASH_DEL(rblk_hash, rblk);
      84          56 :                 rblk_free(&rblk);
      85             :         }
      86           7 :         rblk_hash=NULL;
      87           7 : }
      88             : 
      89           0 : static int rblks_free_one_except(struct rblk *keep)
      90             : {
      91           0 :         uint64_t before=rblk_mem;
      92             :         struct rblk *tmp;
      93             :         struct rblk *rblk;
      94             : 
      95           0 :         HASH_ITER(hh, rblk_hash, rblk, tmp)
      96             :         {
      97           0 :                 if(rblk==keep)
      98           0 :                         continue;
      99           0 :                 HASH_DEL(rblk_hash, rblk);
     100           0 :                 rblk_free(&rblk);
     101           0 :                 break;
     102             :         }
     103           0 :         if(before!=rblk_mem)
     104             :                 return 0;
     105           0 :         return -1;
     106             : }
     107             : 
     108          56 : static int rblk_init(struct rblk *rblk, struct blk *blk,
     109             :         uint64_t hash_key, const char *datpath, const char *savepathstr)
     110             : {
     111          56 :         int ret=-1;
     112          56 :         char *fulldatpath=NULL;
     113             : 
     114          56 :         rblk->hash_key=hash_key;
     115          56 :         if(!(fulldatpath=prepend_s(datpath, savepathstr)))
     116             :                 goto end;
     117          56 :         logp("open: %s\n", savepathstr);
     118          56 :         if(!(rblk->fzp=fzp_open(fulldatpath, "rb")))
     119             :                 goto end;
     120          56 :         ret=0;
     121             : end:
     122          56 :         free_w(&fulldatpath);
     123          56 :         return ret;
     124             : }
     125             : 
     126         316 : static int rblk_load_more_chunks(struct rblk *rblk, uint16_t datno_target)
     127             : {
     128         316 :         int ret=-1;
     129         316 :         int done=0;
     130             :         struct iobuf rbuf;
     131             : 
     132         316 :         iobuf_init(&rbuf);
     133             : 
     134         948 :         for(
     135             :                 ;
     136        1264 :                 rblk->rlen<DATA_FILE_SIG_MAX && rblk->rlen<=datno_target;
     137         316 :                 rblk->rlen++
     138             :         ) {
     139         316 :                 switch(iobuf_fill_from_fzp_data(&rbuf, rblk->fzp))
     140             :                 {
     141             :                         case 0:
     142         316 :                                 if(rbuf.cmd!=CMD_DATA)
     143             :                                 {
     144           0 :                                         logp("unknown cmd in %s: %c\n",
     145             :                                                 __func__, rbuf.cmd);
     146           0 :                                         goto end;
     147             :                                 }
     148         316 :                                 iobuf_move(&rblk->readbuf[rblk->rlen], &rbuf);
     149         316 :                                 rblk_mem+=rblk->readbuf[rblk->rlen].len;
     150         316 :                                 continue;
     151             :                         case 1:
     152             :                                 done++;
     153             :                                 break;
     154             :                         default:
     155             :                                 goto end;
     156             :                 }
     157             :                 if(done)
     158             :                         break;
     159             :         }
     160             :         ret=0;
     161             : end:
     162         316 :         return ret;
     163             : }
     164             : 
     165         316 : int rblk_retrieve_data(struct asfd *asfd, struct cntr *cntr,
     166             :         struct blk *blk, const char *datpath)
     167             : {
     168         316 :         uint16_t datno=0;
     169             :         uint64_t hash_key;
     170             :         char *savepathstr;
     171         316 :         struct rblk *rblk=NULL;
     172             : 
     173         316 :         hash_key=uint64_to_savepath_hash_key(blk->savepath);
     174         316 :         savepathstr=uint64_to_savepathstr_with_sig_uint(blk->savepath, &datno);
     175             : 
     176         316 :         if(!(rblk=rblk_hash_find(hash_key)))
     177             :         {
     178          56 :                 if(!(rblk=rblk_alloc())
     179          56 :                   || rblk_init(rblk, blk, hash_key, datpath, savepathstr))
     180             :                 {
     181           0 :                         rblk_free(&rblk);
     182           0 :                         return -1;
     183             :                 }
     184          56 :                 rblk_hash_add(rblk);
     185             :         }
     186             : 
     187         316 :         if(datno>=rblk->rlen)
     188             :         {
     189             :                 // Need to load more from this data file.
     190         316 :                 if(rblk_load_more_chunks(rblk, datno))
     191             :                         return -1;
     192             :         }
     193             : 
     194         316 :         while(rblk_mem>rblk_mem_max)
     195             :         {
     196           0 :                 if(rblks_free_one_except(rblk))
     197             :                 {
     198           0 :                         logw(asfd, cntr, "rblk_memory_max is too low!\n");
     199           0 :                         break;
     200             :                 }
     201             :         }
     202             : 
     203             : // printf("lookup: %s (%u)\n", savepathstr, datno);
     204         316 :         if(datno>=rblk->rlen)
     205             :         {
     206           0 :                 logp("datno %d is greater than rlen: %d\n",
     207             :                         datno, rblk->rlen);
     208           0 :                 return -1;
     209             :         }
     210         316 :         blk->data=rblk->readbuf[datno].buf;
     211         316 :         blk->length=rblk->readbuf[datno].len;
     212             : // printf("length: %d\n", blk->length);
     213             : 
     214         316 :         return 0;
     215             : }

Generated by: LCOV version 1.13