LCOV - code coverage report
Current view: top level - src/server - backup.c (source / functions) Hit Total Coverage
Test: burp-coverage-clean.info Lines: 0 158 0.0 %
Date: 2016-05-01 Functions: 0 9 0.0 %

          Line data    Source code
       1             : #include "../burp.h"
       2             : #include "../action.h"
       3             : #include "../alloc.h"
       4             : #include "../asfd.h"
       5             : #include "../async.h"
       6             : #include "../conf.h"
       7             : #include "../cmd.h"
       8             : #include "../cntr.h"
       9             : #include "../fsops.h"
      10             : #include "../handy.h"
      11             : #include "../iobuf.h"
      12             : #include "../log.h"
      13             : #include "../run_script.h"
      14             : #include "auth.h"
      15             : #include "backup_phase1.h"
      16             : #include "backup_phase3.h"
      17             : #include "compress.h"
      18             : #include "delete.h"
      19             : #include "protocol1/backup_phase2.h"
      20             : #include "protocol1/backup_phase4.h"
      21             : #include "protocol2/backup_phase2.h"
      22             : #include "protocol2/backup_phase4.h"
      23             : #include "protocol2/champ_chooser/champ_client.h"
      24             : 
      25           0 : static int open_log(struct asfd *asfd,
      26             :         struct sdirs *sdirs, struct conf **cconfs)
      27             : {
      28           0 :         int ret=-1;
      29           0 :         char *logpath=NULL;
      30           0 :         const char *peer_version=get_string(cconfs[OPT_PEER_VERSION]);
      31             : 
      32           0 :         if(!(logpath=prepend_s(sdirs->rworking, "log"))) goto end;
      33           0 :         if(log_fzp_set(logpath, cconfs))
      34             :         {
      35           0 :                 logp("could not open log file: %s\n", logpath);
      36             :                 goto end;
      37             :         }
      38             : 
      39           0 :         logp("Client version: %s\n", peer_version?:"");
      40           0 :         logp("Protocol: %d\n", (int)get_protocol(cconfs));
      41           0 :         if(get_int(cconfs[OPT_CLIENT_IS_WINDOWS]))
      42           0 :                 logp("Client is Windows\n");
      43             : 
      44             :         // Make sure a warning appears in the backup log.
      45             :         // The client will already have been sent a message with logw.
      46             :         // This time, prevent it sending a logw to the client by specifying
      47             :         // NULL for cntr.
      48           0 :         if(get_int(cconfs[OPT_VERSION_WARN])) version_warn(asfd, NULL, cconfs);
      49             : 
      50             :         ret=0;
      51             : end:
      52           0 :         free_w(&logpath);
      53           0 :         return ret;
      54             : }
      55             : 
      56           0 : static int write_incexc(const char *realworking, const char *incexc)
      57             : {
      58           0 :         int ret=-1;
      59           0 :         struct fzp *fzp=NULL;
      60           0 :         char *path=NULL;
      61           0 :         if(!incexc || !*incexc) return 0;
      62           0 :         if(!(path=prepend_s(realworking, "incexc"))
      63           0 :           || !(fzp=fzp_open(path, "wb")))
      64             :                 goto end;
      65           0 :         fzp_printf(fzp, "%s", incexc);
      66           0 :         ret=0;
      67             : end:
      68           0 :         if(fzp_close(&fzp))
      69             :         {
      70           0 :                 logp("error writing to %s in write_incexc\n", path);
      71           0 :                 ret=-1;
      72             :         }
      73           0 :         free_w(&path);
      74           0 :         return ret;
      75             : }
      76             : 
      77           0 : static int backup_phase1_server(struct async *as,
      78             :         struct sdirs *sdirs, struct conf **cconfs)
      79             : {
      80           0 :         int breaking=get_int(cconfs[OPT_BREAKPOINT]);
      81           0 :         if(breaking==1)
      82           0 :                 return breakpoint(breaking, __func__);
      83           0 :         return backup_phase1_server_all(as, sdirs, cconfs);
      84             : }
      85             : 
      86           0 : static int backup_phase2_server(struct async *as, struct sdirs *sdirs,
      87             :         const char *incexc, int resume, struct conf **cconfs)
      88             : {
      89           0 :         int breaking=get_int(cconfs[OPT_BREAKPOINT]);
      90           0 :         if(breaking==2)
      91           0 :                 return breakpoint(breaking, __func__);
      92             : 
      93           0 :         switch(get_protocol(cconfs))
      94             :         {
      95             :                 case PROTO_1:
      96             :                         return backup_phase2_server_protocol1(as, sdirs,
      97           0 :                                 incexc, resume, cconfs);
      98             :                 default:
      99             :                         return backup_phase2_server_protocol2(as, sdirs,
     100           0 :                                 resume, cconfs);
     101             :         }
     102             : }
     103             : 
     104           0 : static int backup_phase3_server(struct sdirs *sdirs, struct conf **cconfs)
     105             : {
     106           0 :         int breaking=get_int(cconfs[OPT_BREAKPOINT]);
     107           0 :         if(breaking==3)
     108           0 :                 return breakpoint(breaking, __func__);
     109             : 
     110           0 :         return backup_phase3_server_all(sdirs, cconfs);
     111             : }
     112             : 
     113           0 : static int backup_phase4_server(struct sdirs *sdirs, struct conf **cconfs)
     114             : {
     115           0 :         int breaking=get_int(cconfs[OPT_BREAKPOINT]);
     116           0 :         if(breaking==4)
     117           0 :                 return breakpoint(breaking, __func__);
     118             : 
     119           0 :         log_fzp_set(NULL, cconfs);
     120             :         // Phase4 will open logfp again (in case it is resuming).
     121           0 :         switch(get_protocol(cconfs))
     122             :         {
     123             :                 case PROTO_1:
     124           0 :                         return backup_phase4_server_protocol1(sdirs, cconfs);
     125             :                 default:
     126           0 :                         return backup_phase4_server_protocol2(sdirs, cconfs);
     127             :         }
     128             : }
     129             : 
     130           0 : static void log_rshash(struct conf **confs)
     131             : {
     132           0 :         if(get_protocol(confs)!=PROTO_1) return;
     133             :         logp("Using librsync hash %s\n",
     134           0 :                 rshash_to_str(get_e_rshash(confs[OPT_RSHASH])));
     135             : }
     136             : 
     137           0 : static int do_backup_server(struct async *as, struct sdirs *sdirs,
     138             :         struct conf **cconfs, const char *incexc, int resume)
     139             : {
     140           0 :         int ret=0;
     141           0 :         int do_phase2=1;
     142           0 :         struct asfd *chfd=NULL;
     143           0 :         struct asfd *asfd=as->asfd;
     144           0 :         enum protocol protocol=get_protocol(cconfs);
     145             : 
     146           0 :         logp("in do_backup_server\n");
     147             : 
     148           0 :         log_rshash(cconfs);
     149             : 
     150           0 :         if(resume)
     151             :         {
     152           0 :                 if(sdirs_get_real_working_from_symlink(sdirs)
     153           0 :                   || sdirs_get_real_manifest(sdirs, protocol)
     154           0 :                   || open_log(asfd, sdirs, cconfs))
     155             :                         goto error;
     156             :         }
     157             :         else
     158             :         {
     159             :                 // Not resuming - need to set everything up fresh.
     160           0 :                 if(sdirs_create_real_working(sdirs,
     161           0 :                         get_string(cconfs[OPT_TIMESTAMP_FORMAT]))
     162           0 :                   || sdirs_get_real_manifest(sdirs, protocol)
     163           0 :                   || open_log(asfd, sdirs, cconfs))
     164             :                         goto error;
     165             : 
     166           0 :                 if(write_incexc(sdirs->rworking, incexc))
     167             :                 {
     168           0 :                         logp("unable to write incexc\n");
     169           0 :                         goto error;
     170             :                 }
     171             : 
     172           0 :                 if(backup_phase1_server(as, sdirs, cconfs))
     173             :                 {
     174           0 :                         logp("error in phase 1\n");
     175           0 :                         goto error;
     176             :                 }
     177             :         }
     178             : 
     179           0 :         if(protocol==PROTO_2
     180           0 :           && !(chfd=champ_chooser_connect(as, sdirs, cconfs, resume)))
     181             :         {
     182           0 :                 logp("problem connecting to champ chooser\n");
     183           0 :                 goto error;
     184             :         }
     185             : 
     186           0 :         if(resume)
     187             :         {
     188             :                 struct stat statp;
     189           0 :                 if(lstat(sdirs->phase1data, &statp)
     190           0 :                   && !lstat(sdirs->changed, &statp)
     191           0 :                   && !lstat(sdirs->unchanged, &statp))
     192             :                 {
     193             :                         // In this condition, it looks like there was an
     194             :                         // interruption during phase3. Skip phase2.
     195           0 :                         do_phase2=0;
     196             :                 }
     197             :         }
     198             : 
     199           0 :         if(do_phase2)
     200             :         {
     201           0 :                 if(backup_phase2_server(as, sdirs, incexc, resume, cconfs))
     202             :                 {
     203           0 :                         logp("error in backup phase 2\n");
     204           0 :                         goto error;
     205             :                 }
     206             : 
     207           0 :                 asfd->write_str(asfd, CMD_GEN, "okbackupend");
     208             :         }
     209             : 
     210             :         // Close the connection with the client, the rest of the job we can do
     211             :         // by ourselves.
     212           0 :         logp("Backup ending - disconnect from client.\n");
     213           0 :         if(asfd_flush_asio(asfd)) goto end;
     214           0 :         as->asfd_remove(as, asfd);
     215           0 :         asfd_close(asfd);
     216             : 
     217           0 :         if(backup_phase3_server(sdirs, cconfs))
     218             :         {
     219           0 :                 logp("error in backup phase 3\n");
     220           0 :                 goto error;
     221             :         }
     222             : 
     223           0 :         if(do_rename(sdirs->working, sdirs->finishing))
     224             :                 goto error;
     225             : 
     226           0 :         if(backup_phase4_server(sdirs, cconfs))
     227             :         {
     228           0 :                 logp("error in backup phase 4\n");
     229           0 :                 goto error;
     230             :         }
     231             : 
     232           0 :         cntr_print(get_cntr(cconfs), ACTION_BACKUP);
     233             :         cntr_stats_to_file(get_cntr(cconfs),
     234           0 :                 sdirs->rworking, ACTION_BACKUP, cconfs);
     235             : 
     236             :         // Move the symlink to indicate that we are now in the end phase. The
     237             :         // rename() race condition is automatically recoverable here.
     238           0 :         if(do_rename(sdirs->finishing, sdirs->current)) goto error;
     239             : 
     240           0 :         logp("Backup completed.\n");
     241           0 :         log_fzp_set(NULL, cconfs);
     242             :         compress_filename(sdirs->rworking,
     243           0 :                 "log", "log.gz", get_int(cconfs[OPT_COMPRESSION]));
     244             : 
     245           0 :         goto end;
     246             : error:
     247             :         ret=-1;
     248             : end:
     249             : 
     250           0 :         log_fzp_set(NULL, cconfs);
     251           0 :         if(chfd) as->asfd_remove(as, chfd);
     252           0 :         asfd_free(&chfd);
     253           0 :         return ret;
     254             : }
     255             : 
     256           0 : int run_backup(struct async *as, struct sdirs *sdirs, struct conf **cconfs,
     257             :         const char *incexc, int *timer_ret, int resume)
     258             : {
     259             :         int ret;
     260           0 :         char okstr[32]="";
     261           0 :         struct asfd *asfd=as->asfd;
     262           0 :         struct iobuf *rbuf=asfd->rbuf;
     263           0 :         const char *cname=get_string(cconfs[OPT_CNAME]);
     264             : 
     265           0 :         if(get_string(cconfs[OPT_RESTORE_CLIENT]))
     266             :         {
     267             :                 // This client is not the original client, so a backup might
     268             :                 // cause all sorts of trouble.
     269           0 :                 logp("Not allowing backup of %s\n", cname);
     270           0 :                 return asfd->write_str(asfd, CMD_GEN, "Backup is not allowed");
     271             :         }
     272             : 
     273             :         // Set quality of service bits on backups.
     274           0 :         asfd->set_bulk_packets(asfd);
     275             : 
     276           0 :         if(!strncmp_w(rbuf->buf, "backupphase1timed"))
     277             :         {
     278           0 :                 int a=0;
     279             :                 const char *args[12];
     280           0 :                 int checkonly=!strncmp_w(rbuf->buf, "backupphase1timedcheck");
     281           0 :                 if(checkonly) logp("Client asked for a timer check only.\n");
     282             : 
     283           0 :                 args[a++]=get_string(cconfs[OPT_TIMER_SCRIPT]);
     284           0 :                 args[a++]=cname;
     285           0 :                 args[a++]=sdirs->current;
     286           0 :                 args[a++]=sdirs->clients;
     287           0 :                 args[a++]="reserved1";
     288           0 :                 args[a++]="reserved2";
     289           0 :                 args[a++]=NULL;
     290           0 :                 if((*timer_ret=run_script(asfd, args,
     291             :                   get_strlist(cconfs[OPT_TIMER_ARG]),
     292             :                   cconfs,
     293             :                   1 /* wait */,
     294             :                   1 /* use logp */,
     295             :                   0 /* no log_remote */
     296           0 :                 ))<0)
     297             :                 {
     298             :                         logp("Error running timer script for %s\n",
     299           0 :                                 cname);
     300           0 :                         return *timer_ret;
     301             :                 }
     302           0 :                 if(*timer_ret)
     303             :                 {
     304           0 :                         if(!checkonly)
     305             :                                 logp("Not running backup of %s\n",
     306           0 :                                         cname);
     307             :                         return asfd->write_str(asfd,
     308           0 :                                 CMD_GEN, "timer conditions not met");
     309             :                 }
     310           0 :                 if(checkonly)
     311             :                 {
     312           0 :                         logp("Client asked for a timer check only,\n");
     313           0 :                         logp("so a backup is not happening right now.\n");
     314             :                         return asfd->write_str(asfd,
     315           0 :                                 CMD_GEN, "timer conditions met");
     316             :                 }
     317           0 :                 logp("Running backup of %s\n", cname);
     318             :         }
     319           0 :         else if(!get_int(cconfs[OPT_CLIENT_CAN_FORCE_BACKUP]))
     320             :         {
     321           0 :                 logp("Not allowing forced backup of %s\n", cname);
     322             :                 return asfd->write_str(asfd,
     323           0 :                         CMD_GEN, "Forced backup is not allowed");
     324             :         }
     325             : 
     326             :         snprintf(okstr, sizeof(okstr), "%s:%d",
     327           0 :                 resume?"resume":"ok", get_int(cconfs[OPT_COMPRESSION]));
     328           0 :         if(asfd->write_str(asfd, CMD_GEN, okstr)) return -1;
     329             : 
     330           0 :         if((ret=do_backup_server(as, sdirs, cconfs, incexc, resume)))
     331             :                 goto end;
     332           0 :         if((ret=delete_backups(sdirs, cname,
     333             :                 get_strlist(cconfs[OPT_KEEP]),
     334           0 :                 get_string(cconfs[OPT_MANUAL_DELETE]))))
     335             :                         goto end;
     336           0 :         if(get_protocol(cconfs)==PROTO_2)
     337           0 :                 ret=regenerate_client_dindex(sdirs);
     338             : end:
     339           0 :         return ret;
     340             : }

Generated by: LCOV version 1.10