LCOV - code coverage report
Current view: top level - src/server - resume.c (source / functions) Hit Total Coverage
Test: burp-coverage-clean.info Lines: 86 217 39.6 %
Date: 2015-10-31 Functions: 3 7 42.9 %

          Line data    Source code
       1             : #include "../burp.h"
       2             : #include "../cmd.h"
       3             : #include "../cntr.h"
       4             : #include "../iobuf.h"
       5             : #include "../log.h"
       6             : #include "../pathcmp.h"
       7             : #include "../sbuf.h"
       8             : #include "dpth.h"
       9             : #include "resume.h"
      10             : #include "backup_phase1.h"
      11             : #include "protocol1/dpth.h"
      12             : 
      13             : // Used on resume, this just reads the phase1 file and sets up cntr.
      14           0 : static int read_phase1(struct manio *p1manio, struct conf **cconfs)
      15             : {
      16           0 :         int ret=-1;
      17             :         struct sbuf *p1b;
      18           0 :         enum protocol protocol=get_protocol(cconfs);
      19           0 :         struct cntr *cntr=get_cntr(cconfs);
      20           0 :         if(!(p1b=sbuf_alloc(protocol))) return -1;
      21             :         while(1)
      22             :         {
      23           0 :                 sbuf_free_content(p1b);
      24           0 :                 switch(manio_read(p1manio, p1b))
      25             :                 {
      26           0 :                         case 0: break;
      27           0 :                         case 1: ret=0;
      28           0 :                         default: goto end;
      29             :                 }
      30           0 :                 cntr_add_phase1(cntr, p1b->path.cmd, 0);
      31             : 
      32           0 :                 if(sbuf_is_filedata(p1b))
      33             :                         cntr_add_val(cntr, CMD_BYTES_ESTIMATED,
      34           0 :                                 (uint64_t)p1b->statp.st_size, 0);
      35             :         }
      36             : end:
      37           0 :         sbuf_free(&p1b);
      38           0 :         return ret;
      39             : }
      40             : 
      41           0 : static int set_higher_datapth(struct sbuf *sb, struct dpth *dpth)
      42             : {
      43             :         // Make sure we end up with the highest datapth we can possibly
      44             :         // find - dpth_protocol1_set_from_string() will only set it if
      45             :         // it is higher.
      46           0 :         if(sb->protocol1 && sb->protocol1->datapth.buf
      47           0 :           && dpth_protocol1_set_from_string(dpth,
      48           0 :                 sb->protocol1->datapth.buf))
      49             :         {
      50             :                 logp("unable to set datapath: %s\n",
      51           0 :                         sb->protocol1->datapth.buf);
      52           0 :                 return -1;
      53             :         }
      54           0 :         return 0;
      55             : }
      56             : 
      57             : #ifndef UTEST
      58             : static
      59             : #endif
      60          48 : int forward_past_entry(struct manio *manio, struct iobuf *target,
      61             :         enum protocol protocol, man_off_t **pos)
      62             : {
      63          48 :         struct sbuf *sb=NULL;
      64             : 
      65          48 :         if(!(sb=sbuf_alloc(protocol)))
      66           0 :                 goto error;
      67             : 
      68          48 :         man_off_t_free(pos);
      69          48 :         if(!(*pos=manio_tell(manio)))
      70             :         {
      71             :                 logp("Could not manio_tell first pos in %s(): %s\n",
      72           0 :                         __func__, strerror(errno));
      73           0 :                 goto error;
      74             :         }
      75             : 
      76             :         while(1)
      77             :         {
      78        1744 :                 sbuf_free_content(sb);
      79        1744 :                 switch(manio_read(manio, sb))
      80             :                 {
      81        1744 :                         case 0: break;
      82           0 :                         case 1: logp("End of file in %s()\n", __func__);
      83           0 :                                 goto error;
      84             :                         default:
      85           0 :                                 logp("Error in %s()\n", __func__);
      86             :                                 // Treat error in unchanged manio as not OK.
      87           0 :                                 goto error;
      88             :                 }
      89             : 
      90        3488 :                 if(target->cmd==sb->path.cmd
      91        1744 :                   && !pathcmp(target->buf, sb->path.buf))
      92             :                 {
      93          48 :                         man_off_t_free(pos);
      94          48 :                         if(!(*pos=manio_tell(manio)))
      95             :                         {
      96             :                                 logp("Could not get pos in %s(): %s\n",
      97           0 :                                         __func__, strerror(errno));
      98           0 :                                 goto error;
      99             :                         }
     100          48 :                         sbuf_free(&sb);
     101          48 :                         return 0;
     102             :                 }
     103             :         }
     104             : 
     105             : error:
     106           0 :         sbuf_free(&sb);
     107           0 :         man_off_t_free(pos);
     108        1696 :         return -1;
     109             : }
     110             : 
     111             : #ifndef UTEST
     112             : static
     113             : #endif
     114          88 : int forward_before_entry(struct manio *manio, struct iobuf *target,
     115             :         struct cntr *cntr, struct dpth *dpth, enum protocol protocol,
     116             :         man_off_t **pos)
     117             : {
     118          88 :         int ars=0;
     119          88 :         struct sbuf *sb=NULL;
     120             : 
     121          88 :         if(!(sb=sbuf_alloc(protocol)))
     122           0 :                 goto error;
     123             : 
     124          88 :         man_off_t_free(pos);
     125          88 :         if(!(*pos=manio_tell(manio)))
     126             :         {
     127             :                 logp("Could not manio_tell first pos in %s(): %s\n",
     128           0 :                         __func__, strerror(errno));
     129           0 :                 goto error;
     130             :         }
     131             : 
     132             :         while(1)
     133             :         {
     134        6380 :                 if(sb->endfile.buf
     135        6380 :                   || (sb->path.buf && !sbuf_is_filedata(sb)))
     136             :                 {
     137        4240 :                         man_off_t_free(pos);
     138        4240 :                         if(!(*pos=manio_tell(manio)))
     139             :                         {
     140             :                                 logp("Could not manio_tell pos in %s(): "
     141           0 :                                         "%s\n", __func__, strerror(errno));
     142           0 :                                 goto error;
     143             :                         }
     144             :                 }
     145             : 
     146        6380 :                 sbuf_free_content(sb);
     147        6380 :                 ars=manio_read(manio, sb);
     148        6380 :                 if(dpth && set_higher_datapth(sb, dpth)) goto error;
     149             : 
     150        6380 :                 switch(ars)
     151             :                 {
     152        6364 :                         case 0: break;
     153             :                         case 1:
     154           6 :                                 sbuf_free(&sb);
     155           6 :                                 return 0;
     156             :                         default:
     157             :                                 logp("Error in %s(), but continuing\n",
     158          10 :                                         __func__);
     159             :                                 // Treat error in unchanged manio as
     160             :                                 // OK - could have been a short write.
     161          10 :                                 sbuf_free(&sb);
     162          10 :                                 return 0;
     163             :                 }
     164             : 
     165        6364 :                 if(iobuf_pathcmp(target, &sb->path)<=0)
     166             :                 {
     167          72 :                         sbuf_free(&sb);
     168          72 :                         return 0;
     169             :                 }
     170             : 
     171        6292 :                 if(cntr)
     172             :                 {
     173           0 :                         cntr_add_same(cntr, sb->path.cmd);
     174           0 :                         if(sb->endfile.buf)
     175             :                         {
     176           0 :                                 uint64_t e=strtoull(sb->endfile.buf, NULL, 10);
     177           0 :                                 cntr_add_bytes(cntr, e);
     178           0 :                                 cntr_add_recvbytes(cntr, e);
     179             :                         }
     180             :                 }
     181             :         }
     182             : 
     183             : error:
     184           0 :         sbuf_free(&sb);
     185           0 :         man_off_t_free(pos);
     186        6292 :         return -1;
     187             : }
     188             : 
     189             : #ifndef UTEST
     190             : static
     191             : #endif
     192         208 : int get_last_good_entry(struct manio *manio, struct iobuf *result,
     193             :         struct cntr *cntr, struct dpth *dpth, enum protocol protocol,
     194             :         man_off_t **pos)
     195             : {
     196         208 :         int ars=0;
     197         208 :         int got_vss_start=0;
     198         208 :         struct sbuf *sb=NULL;
     199             :         struct iobuf lastpath;
     200             : 
     201         208 :         if(!(sb=sbuf_alloc(protocol)))
     202           0 :                 goto error;
     203             : 
     204         208 :         iobuf_init(&lastpath);
     205             : 
     206         208 :         man_off_t_free(pos);
     207         208 :         if(!(*pos=manio_tell(manio)))
     208             :         {
     209             :                 logp("Could not manio_tell first pos in %s(): %s\n",
     210           0 :                         __func__, strerror(errno));
     211           0 :                 goto error;
     212             :         }
     213             : 
     214             :         while(1)
     215             :         {
     216       12690 :                 if(sb->path.buf && !got_vss_start)
     217             :                 {
     218        8270 :                         iobuf_free_content(&lastpath);
     219        8270 :                         iobuf_move(&lastpath, &sb->path);
     220       16540 :                         if(!sbuf_is_filedata(sb)
     221        8270 :                           && !sbuf_is_vssdata(sb))
     222             :                         {
     223         104 :                                 iobuf_free_content(result);
     224         104 :                                 iobuf_move(result, &lastpath);
     225             : 
     226         104 :                                 man_off_t_free(pos);
     227         104 :                                 if(!(*pos=manio_tell(manio)))
     228             :                                 {
     229             :                                         logp("Could not manio_tell pos in %s(): %s\n",
     230           0 :                                                 __func__, strerror(errno));
     231           0 :                                         goto error;
     232             :                                 }
     233             :                         }
     234             :                 }
     235       12690 :                 if(sb->endfile.buf && !got_vss_start)
     236             :                 {
     237        8152 :                         iobuf_free_content(result);
     238        8152 :                         iobuf_move(result, &lastpath);
     239             : 
     240        8152 :                         man_off_t_free(pos);
     241        8152 :                         if(!(*pos=manio_tell(manio)))
     242             :                         {
     243             :                                 logp("Could not manio_tell pos in %s(): %s\n",
     244           0 :                                         __func__, strerror(errno));
     245           0 :                                 goto error;
     246             :                         }
     247             :                 }
     248             : 
     249       12690 :                 sbuf_free_content(sb);
     250       12690 :                 ars=manio_read(manio, sb);
     251       12690 :                 if(dpth && set_higher_datapth(sb, dpth)) goto error;
     252             : 
     253       12690 :                 switch(ars)
     254             :                 {
     255       12482 :                         case 0: break;
     256         169 :                         case 1: iobuf_free_content(&lastpath);
     257         169 :                                 sbuf_free(&sb);
     258         169 :                                 return 0;
     259             :                         default:
     260          39 :                                 if(result->buf)
     261             :                                         logp("Error after %s in %s()\n",
     262          32 :                                                 result->buf, __func__);
     263             :                                 // Treat error in changed manio as
     264             :                                 // OK - could have been a short write.
     265          39 :                                 iobuf_free_content(&lastpath);
     266          39 :                                 sbuf_free(&sb);
     267          39 :                                 return 0;
     268             :                 }
     269             : 
     270             :                 // Some hacks for split_vss.
     271       12482 :                 switch(sb->path.cmd)
     272             :                 {
     273             :                         case CMD_VSS:
     274             :                         case CMD_ENC_VSS:
     275          74 :                                 got_vss_start=1;
     276          74 :                                 break;
     277             :                         case CMD_VSS_T:
     278             :                         case CMD_ENC_VSS_T:
     279          10 :                                 got_vss_start=0;
     280          10 :                                 break;
     281             :                         case CMD_FILE:
     282             :                         case CMD_ENC_FILE:
     283        8154 :                                 if(S_ISDIR(sb->statp.st_mode))
     284          48 :                                         got_vss_start=0;
     285        8154 :                                 break;
     286             :                         default:
     287        4244 :                                 break;
     288             :                 }
     289             : 
     290       12482 :                 if(cntr)
     291             :                 {
     292           0 :                         cntr_add_changed(cntr, sb->path.cmd);
     293           0 :                         if(sb->endfile.buf)
     294             :                         {
     295           0 :                                 uint64_t e=strtoull(sb->endfile.buf, NULL, 10);
     296           0 :                                 cntr_add_bytes(cntr, e);
     297           0 :                                 cntr_add_recvbytes(cntr, e);
     298             :                         }
     299             :                 }
     300             :         }
     301             : 
     302             : error:
     303           0 :         iobuf_free_content(&lastpath);
     304           0 :         sbuf_free(&sb);
     305           0 :         man_off_t_free(pos);
     306       12482 :         return -1;
     307             : }
     308             : 
     309             : // Return p1manio position.
     310           0 : static man_off_t *do_resume_work(struct sdirs *sdirs,
     311             :         struct dpth *dpth, struct conf **cconfs)
     312             : {
     313           0 :         man_off_t *pos=NULL;
     314           0 :         man_off_t *p1pos=NULL;
     315           0 :         struct iobuf *chb=NULL;
     316           0 :         struct manio *cmanio=NULL;
     317           0 :         struct manio *umanio=NULL;
     318           0 :         struct manio *p1manio=NULL;
     319           0 :         enum protocol protocol=get_protocol(cconfs);
     320           0 :         struct cntr *cntr=get_cntr(cconfs);
     321           0 :         int compression=get_int(cconfs[OPT_COMPRESSION]);
     322             : 
     323           0 :         if(!(p1manio=manio_open_phase1(sdirs->phase1data, "rb", protocol))
     324           0 :           || !(cmanio=manio_open_phase2(sdirs->changed, "rb", protocol))
     325           0 :           || !(umanio=manio_open_phase2(sdirs->unchanged, "rb", protocol)))
     326           0 :                 goto end;
     327             : 
     328           0 :         if(!(chb=iobuf_alloc()))
     329           0 :                 return NULL;
     330             : 
     331           0 :         logp("Setting up resume positions...\n");
     332             : 
     333           0 :         if(get_last_good_entry(cmanio, chb, cntr, dpth, protocol, &pos))
     334           0 :                 goto error;
     335           0 :         if(manio_close_and_truncate(&cmanio, pos, compression)) goto error;
     336           0 :         man_off_t_free(&pos);
     337           0 :         if(chb->buf)
     338             :         {
     339           0 :                 logp("  last good entry:    %s\n", chb->buf);
     340             :                 // Now need to go to the appropriate places in p1manio and
     341             :                 // unchanged.
     342           0 :                 if(forward_past_entry(p1manio, chb, protocol, &p1pos))
     343           0 :                         goto error;
     344             : 
     345             :                 // The unchanged file needs to be positioned just before the
     346             :                 // found entry, otherwise it ends up having a duplicated entry.
     347           0 :                 if(forward_before_entry(umanio,
     348           0 :                         chb, cntr, dpth, protocol, &pos))
     349           0 :                                 goto error;
     350           0 :                 if(manio_close_and_truncate(&umanio, pos, compression))
     351           0 :                         goto error;
     352           0 :                 man_off_t_free(&pos);
     353             :         }
     354             :         else
     355             :         {
     356           0 :                 logp("  nothing previously transferred\n");
     357           0 :                 if(!(p1pos=manio_tell(p1manio)))
     358           0 :                         goto error;
     359           0 :                 if(!(pos=manio_tell(umanio)))
     360           0 :                         goto error;
     361           0 :                 if(manio_close_and_truncate(&umanio, pos, compression))
     362           0 :                         goto error;
     363             :         }
     364             : 
     365             :         // Now should have all file pointers in the right places to resume.
     366             : 
     367           0 :         if(get_int(cconfs[OPT_SEND_CLIENT_CNTR])
     368           0 :           && cntr_send(get_cntr(cconfs))) goto error;
     369             : 
     370           0 :         goto end;
     371             : error:
     372           0 :         man_off_t_free(&p1pos);
     373             : end:
     374           0 :         iobuf_free(&chb);
     375           0 :         man_off_t_free(&pos);
     376           0 :         manio_close(&p1manio);
     377           0 :         manio_close(&cmanio);
     378           0 :         manio_close(&umanio);
     379           0 :         return p1pos;
     380             : }
     381             : 
     382           0 : man_off_t *do_resume(struct sdirs *sdirs,
     383             :         struct dpth *dpth, struct conf **cconfs)
     384             : {
     385           0 :         man_off_t *p1pos=NULL;
     386           0 :         struct manio *cmanio=NULL;
     387           0 :         struct manio *umanio=NULL;
     388           0 :         struct manio *p1manio=NULL;
     389           0 :         enum protocol protocol=get_protocol(cconfs);
     390             : 
     391           0 :         logp("Begin phase1 (read previous file system scan)\n");
     392           0 :         if(!(p1manio=manio_open_phase1(sdirs->phase1data, "rb", protocol))
     393           0 :           || read_phase1(p1manio, cconfs))
     394           0 :                 goto end;
     395           0 :         manio_close(&p1manio);
     396             : 
     397             :         // First, open them in append mode, so that they will be created if
     398             :         // they do not exist.
     399           0 :         if(!(cmanio=manio_open_phase2(sdirs->changed, "ab", protocol))
     400           0 :           || !(umanio=manio_open_phase2(sdirs->unchanged, "ab", protocol)))
     401           0 :                 goto end;
     402           0 :         manio_close(&cmanio);
     403           0 :         manio_close(&umanio);
     404             : 
     405           0 :         if(!(p1pos=do_resume_work(sdirs, dpth, cconfs))) goto end;
     406             : 
     407           0 :         if(dpth_incr(dpth)) goto end;
     408             : 
     409           0 :         logp("End phase1 (read previous file system scan)\n");
     410             : end:
     411           0 :         manio_close(&p1manio);
     412           0 :         manio_close(&cmanio);
     413           0 :         manio_close(&umanio);
     414           0 :         return p1pos;
     415             : }

Generated by: LCOV version 1.10