LCOV - code coverage report
Current view: top level - src - cntr.c (source / functions) Hit Total Coverage
Test: burp-coverage-clean.info Lines: 140 432 32.4 %
Date: 2017-05-01 Functions: 20 36 55.6 %

          Line data    Source code
       1             : #include "burp.h"
       2             : #include "alloc.h"
       3             : #include "asfd.h"
       4             : #include "async.h"
       5             : #include "cmd.h"
       6             : #include "cntr.h"
       7             : #include "cstat.h"
       8             : #include "fsops.h"
       9             : #include "handy.h"
      10             : #include "iobuf.h"
      11             : #include "log.h"
      12             : 
      13             : #include "client/monitor/sel.h"
      14             : #include "client/monitor/json_input.h"
      15             : #include "server/bu_get.h"
      16             : #include "server/monitor/json_output.h"
      17             : 
      18             : #include <limits.h>
      19             : 
      20             : #define CNTR_VERSION            3
      21             : #define CNTR_PATH_BUF_LEN       256
      22             : 
      23        2575 : static void cntr_ent_free_content(struct cntr_ent *cntr_ent)
      24             : {
      25        5150 :         if(!cntr_ent) return;
      26        2575 :         free_w(&cntr_ent->field);
      27        2575 :         free_w(&cntr_ent->label);
      28             : }
      29             : 
      30        2575 : static void cntr_ent_free(struct cntr_ent **cntr_ent)
      31             : {
      32        5150 :         if(!cntr_ent || !*cntr_ent) return;
      33        2575 :         cntr_ent_free_content(*cntr_ent);
      34        2575 :         free_v((void **)cntr_ent);
      35             : }
      36             : 
      37         103 : struct cntr *cntr_alloc(void)
      38             : {
      39         103 :         return (struct cntr *)calloc_w(1, sizeof(struct cntr), __func__);
      40             : }
      41             : 
      42        2575 : static int add_cntr_ent(struct cntr *cntr, int flags,
      43             :         enum cmd cmd, const char *field, const char *label)
      44             : {
      45        2575 :         struct cntr_ent *cenew=NULL;
      46        2575 :         if(!(cenew=(struct cntr_ent *)
      47        2575 :             calloc_w(1, sizeof(struct cntr_ent), __func__))
      48        2575 :           || !(cenew->field=strdup_w(field, __func__))
      49        2575 :           || !(cenew->label=strdup_w(label, __func__)))
      50             :                 goto error;
      51        2575 :         cenew->flags=flags;
      52        2575 :         cenew->cmd=cmd;
      53             : 
      54        2575 :         if(cntr->list) cenew->next=cntr->list;
      55        2575 :         cntr->list=cenew;
      56             : 
      57        2575 :         cntr->ent[(uint8_t)cmd]=cenew;
      58        2575 :         return 0;
      59             : error:
      60           0 :         cntr_ent_free(&cenew);
      61           0 :         return -1;
      62             : }
      63             : 
      64         103 : static size_t calc_max_str_len(struct cntr *cntr, const char *cname)
      65             : {
      66         103 :         size_t slen=0;
      67             :         char ullmax[64];
      68         103 :         struct cntr_ent *e=NULL;
      69             : 
      70             :         // See cntr_to_str().
      71             :         // First section - name/version/status
      72         103 :         slen+=strlen(cname);
      73         103 :         slen+=16; // More than enough space.
      74             : 
      75             :         // Second section.
      76             :         snprintf(ullmax, sizeof(ullmax),
      77             :                 " %" PRIu64 "\n", (uint64_t)ULLONG_MAX);
      78        2678 :         for(e=cntr->list; e; e=e->next)
      79             :         {
      80        2575 :                 if(e->flags & CNTR_SINGLE_FIELD)
      81             :                         // %c%llu\t
      82         927 :                         slen+=strlen(ullmax)+2;
      83             :                 else
      84             :                         // %c%llu/%llu/%llu/%llu/%llu\t
      85        1648 :                         slen+=(strlen(ullmax)*5)+6;
      86             :         }
      87             : 
      88             :         // Fourth section - a path. Cannot know how long this might be. Guess.
      89         103 :         slen+=CNTR_PATH_BUF_LEN+3; // %c%s\t\n
      90             : 
      91         103 :         slen+=1; // Terminating character.
      92             : 
      93         103 :         return slen;
      94             : }
      95             : 
      96         103 : int cntr_init(struct cntr *cntr, const char *cname)
      97             : {
      98         103 :         if(!cname)
      99             :         {
     100           0 :                 logp("%s called with no client name\n", __func__);
     101           0 :                 return -1;
     102             :         }
     103             : 
     104             :         // Add in reverse order, so that iterating over from the beginning
     105             :         // comes out in the right order.
     106         103 :         if(
     107         103 :              add_cntr_ent(cntr, CNTR_SINGLE_FIELD,
     108             :                 CMD_TIMESTAMP_END, "time_end", "End time")
     109         103 :           || add_cntr_ent(cntr, CNTR_SINGLE_FIELD,
     110             :                 CMD_TIMESTAMP, "time_start", "Start time")
     111         103 :           || add_cntr_ent(cntr, CNTR_SINGLE_FIELD,
     112             :                 CMD_BYTES_SENT, "bytes_sent", "Bytes sent")
     113         103 :           || add_cntr_ent(cntr, CNTR_SINGLE_FIELD,
     114             :                 CMD_BYTES_RECV, "bytes_received", "Bytes received")
     115         103 :           || add_cntr_ent(cntr, CNTR_SINGLE_FIELD,
     116             :                 CMD_BYTES, "bytes", "Bytes")
     117         103 :           || add_cntr_ent(cntr, CNTR_SINGLE_FIELD,
     118             :                 CMD_BYTES_ESTIMATED, "bytes_estimated", "Bytes estimated")
     119         103 :           || add_cntr_ent(cntr, CNTR_SINGLE_FIELD,
     120             :                 CMD_MESSAGE, "messages", "Messages")
     121         103 :           || add_cntr_ent(cntr, CNTR_SINGLE_FIELD,
     122             :                 CMD_WARNING, "warnings", "Warnings")
     123         103 :           || add_cntr_ent(cntr, CNTR_TABULATE,
     124             :                 CMD_GRAND_TOTAL, "grand_total", "Grand total")
     125         103 :           || add_cntr_ent(cntr, 0,
     126             :                 CMD_TOTAL, "total", "Total")
     127         103 :           || add_cntr_ent(cntr, CNTR_SINGLE_FIELD,
     128             :                 CMD_ERROR, "errors", "Errors")
     129         103 :           || add_cntr_ent(cntr, CNTR_TABULATE,
     130             :                 CMD_DATA, "blocks", "Blocks")
     131         103 :           || add_cntr_ent(cntr, CNTR_TABULATE,
     132             :                 CMD_EFS_FILE, "efs_files", "EFS files")
     133         103 :           || add_cntr_ent(cntr, CNTR_TABULATE,
     134             :                 CMD_ENC_VSS_T, "vss_footers_encrypted", "VSS footers (enc)")
     135         103 :           || add_cntr_ent(cntr, CNTR_TABULATE,
     136             :                 CMD_VSS_T, "vss_footers", "VSS footers")
     137         103 :           || add_cntr_ent(cntr, CNTR_TABULATE,
     138             :                 CMD_ENC_VSS, "vss_headers_encrypted", "VSS headers (enc)")
     139         103 :           || add_cntr_ent(cntr, CNTR_TABULATE,
     140             :                 CMD_VSS, "vss_headers", "VSS headers")
     141         103 :           || add_cntr_ent(cntr, CNTR_TABULATE,
     142             :                 CMD_SPECIAL, "special_files", "Special files")
     143         103 :           || add_cntr_ent(cntr, CNTR_TABULATE,
     144             :                 CMD_SOFT_LINK, "hard_links", "Soft links")
     145         103 :           || add_cntr_ent(cntr, CNTR_TABULATE,
     146             :                 CMD_HARD_LINK, "soft_links", "Hard links")
     147         103 :           || add_cntr_ent(cntr, CNTR_TABULATE,
     148             :                 CMD_DIRECTORY, "directories", "Directories")
     149         103 :           || add_cntr_ent(cntr, CNTR_TABULATE,
     150             :                 CMD_ENC_METADATA, "meta_data_encrypted", "Meta data (enc)")
     151         103 :           || add_cntr_ent(cntr, CNTR_TABULATE,
     152             :                 CMD_METADATA, "meta_data", "Meta data")
     153         103 :           || add_cntr_ent(cntr, CNTR_TABULATE,
     154             :                 CMD_ENC_FILE, "files_encrypted", "Files (encrypted)")
     155         103 :           || add_cntr_ent(cntr, CNTR_TABULATE,
     156             :                 CMD_FILE, "files", "Files")
     157             :         )
     158             :                 return -1;
     159             : 
     160         103 :         cntr->ent[(uint8_t)CMD_TIMESTAMP]->count=(uint64_t)time(NULL);
     161             : 
     162         103 :         cntr->str_max_len=calc_max_str_len(cntr, cname);
     163         103 :         if(!(cntr->str=(char *)calloc_w(1, cntr->str_max_len, __func__))
     164         103 :           || !(cntr->cname=strdup_w(cname, __func__)))
     165             :                 return -1;
     166             : 
     167             :         return 0;
     168             : }
     169             : 
     170         103 : static void cntr_free_content(struct cntr *cntr)
     171             : {
     172             :         struct cntr_ent *e;
     173         103 :         struct cntr_ent *l=NULL;
     174        2678 :         for(e=cntr->list; e; e=l)
     175             :         {
     176        2575 :                 l=e->next;
     177        2575 :                 cntr_ent_free(&e);
     178             :         }
     179         103 :         cntr->list=NULL;
     180         103 :         free_w(&cntr->str);
     181         103 :         free_w(&cntr->cname);
     182         103 : }
     183             : 
     184         440 : void cntr_free(struct cntr **cntr)
     185             : {
     186         880 :         if(!cntr || !*cntr) return;
     187         103 :         cntr_free_content(*cntr);
     188         103 :         free_v((void **)cntr);
     189             : }
     190             : 
     191           2 : const char *bytes_to_human(uint64_t counter)
     192             : {
     193             :         static char ret[32]="";
     194           2 :         float div=(float)counter;
     195           2 :         char units[3]="";
     196             : 
     197           2 :         if(div<1024) return "";
     198             : 
     199           0 :         if((div/=1024)<1024)
     200             :                 snprintf(units, sizeof(units), "KB");
     201           0 :         else if((div/=1024)<1024)
     202             :                 snprintf(units, sizeof(units), "MB");
     203           0 :         else if((div/=1024)<1024)
     204             :                 snprintf(units, sizeof(units), "GB");
     205           0 :         else if((div/=1024)<1024)
     206             :                 snprintf(units, sizeof(units), "TB");
     207           0 :         else if((div/=1024)<1024)
     208             :                 snprintf(units, sizeof(units), "EB");
     209             :         else
     210             :         {
     211           0 :                 div/=1024;
     212             :                 snprintf(units, sizeof(units), "PB");
     213             :         }
     214           0 :         snprintf(ret, sizeof(ret), " (%.2f %s)", div, units);
     215           0 :         return ret;
     216             : }
     217             : 
     218             : static void border(void)
     219             : {
     220           0 :         logc("--------------------------------------------------------------------------------\n");
     221             : }
     222             : 
     223           0 : static void table_border(enum action act)
     224             : {
     225           0 :         if(act==ACTION_BACKUP
     226           0 :           || act==ACTION_BACKUP_TIMED)
     227             :         {
     228           0 :           logc("%18s ------------------------------------------------------------\n", "");
     229             :         }
     230           0 :         if(act==ACTION_RESTORE
     231           0 :           || act==ACTION_VERIFY)
     232             :         {
     233           0 :           logc("%18s ------------------------------\n", "");
     234             :         }
     235           0 : }
     236             : 
     237             : static void set_count_val(struct cntr *cntr, char ch, uint64_t val)
     238             : {
     239           0 :         if(!cntr) return;
     240           0 :         if(cntr->ent[(uint8_t)ch]) cntr->ent[(uint8_t)ch]->count=val;
     241             : }
     242             : 
     243             : static void set_changed_val(struct cntr *cntr, char ch, uint64_t val)
     244             : {
     245           0 :         if(!cntr) return;
     246           0 :         if(cntr->ent[(uint8_t)ch]) cntr->ent[(uint8_t)ch]->changed=val;
     247             : }
     248             : 
     249             : static void set_same_val(struct cntr *cntr, char ch, uint64_t val)
     250             : {
     251           0 :         if(!cntr) return;
     252           0 :         if(cntr->ent[(uint8_t)ch]) cntr->ent[(uint8_t)ch]->same=val;
     253             : }
     254             : 
     255             : static void set_deleted_val(struct cntr *cntr, char ch, uint64_t val)
     256             : {
     257           0 :         if(!cntr) return;
     258           0 :         if(cntr->ent[(uint8_t)ch]) cntr->ent[(uint8_t)ch]->deleted=val;
     259             : }
     260             : 
     261             : static void set_phase1_val(struct cntr *cntr, char ch, uint64_t val)
     262             : {
     263           0 :         if(!cntr) return;
     264           0 :         if(cntr->ent[(uint8_t)ch]) cntr->ent[(uint8_t)ch]->phase1=val;
     265             : }
     266             : 
     267             : static void incr_count_val(struct cntr *cntr, char ch, uint64_t val)
     268             : {
     269          25 :         if(!cntr) return;
     270           5 :         if(cntr->ent[(uint8_t)ch]) cntr->ent[(uint8_t)ch]->count+=val;
     271             : }
     272             : 
     273             : static void incr_same_val(struct cntr *cntr, char ch, uint64_t val)
     274             : {
     275       37878 :         if(!cntr) return;
     276           0 :         if(cntr->ent[(uint8_t)ch]) cntr->ent[(uint8_t)ch]->same+=val;
     277             : }
     278             : 
     279             : static void incr_changed_val(struct cntr *cntr, char ch, uint64_t val)
     280             : {
     281          12 :         if(!cntr) return;
     282           0 :         if(cntr->ent[(uint8_t)ch]) cntr->ent[(uint8_t)ch]->changed+=val;
     283             : }
     284             : 
     285             : static void incr_deleted_val(struct cntr *cntr, char ch, uint64_t val)
     286             : {
     287           6 :         if(!cntr) return;
     288           0 :         if(cntr->ent[(uint8_t)ch]) cntr->ent[(uint8_t)ch]->deleted+=val;
     289             : }
     290             : 
     291             : static void incr_phase1_val(struct cntr *cntr, char ch, uint64_t val)
     292             : {
     293           0 :         if(!cntr) return;
     294           0 :         if(cntr->ent[(uint8_t)ch]) cntr->ent[(uint8_t)ch]->phase1+=val;
     295             : }
     296             : 
     297             : static void incr_count(struct cntr *cntr, char ch)
     298             : {
     299           5 :         return incr_count_val(cntr, ch, 1);
     300             : }
     301             : 
     302             : static void incr_same(struct cntr *cntr, char ch)
     303             : {
     304       37878 :         return incr_same_val(cntr, ch, 1);
     305             : }
     306             : 
     307             : static void incr_changed(struct cntr *cntr, char ch)
     308             : {
     309          12 :         return incr_changed_val(cntr, ch, 1);
     310             : }
     311             : 
     312             : static void incr_deleted(struct cntr *cntr, char ch)
     313             : {
     314           6 :         return incr_deleted_val(cntr, ch, 1);
     315             : }
     316             : 
     317             : static void incr_phase1(struct cntr *cntr, char ch)
     318             : {
     319           0 :         return incr_phase1_val(cntr, ch, 1);
     320             : }
     321             : 
     322             : static void print_end(uint64_t val)
     323             : {
     324           0 :         if(val) logc(" %" PRIu64 "\n", val);
     325             : }
     326             : 
     327       42393 : void cntr_add(struct cntr *c, char ch, int print)
     328             : {
     329             :         struct cntr_ent *grand_total_ent;
     330       42393 :         if(!c) return;
     331           5 :         if(!(grand_total_ent=c->ent[CMD_GRAND_TOTAL])) return;
     332           5 :         if(print)
     333             :         {
     334           5 :                 if(ch!=CMD_MESSAGE && ch!=CMD_WARNING)
     335           0 :                         logc("%c", ch);
     336             :         }
     337           5 :         if(ch==CMD_FILE_CHANGED)
     338             :         {
     339             :                 incr_changed(c, CMD_FILE);
     340             :                 incr_changed(c, CMD_TOTAL);
     341             :                 incr_changed(c, CMD_GRAND_TOTAL);
     342             :         }
     343             :         else
     344             :         {
     345           5 :                 incr_count(c, ch);
     346           5 :                 if(ch==CMD_WARNING || ch==CMD_MESSAGE) return;
     347             :                 incr_count(c, CMD_TOTAL);
     348             :         }
     349             : 
     350           0 :         if(!((++grand_total_ent->count)%64) && print)
     351           0 :                 print_end(grand_total_ent->count);
     352           0 :         fflush(stdout);
     353             : }
     354             : 
     355           0 : void cntr_add_phase1(struct cntr *c, char ch, int print)
     356             : {
     357             :         static struct cntr_ent *total;
     358           0 :         incr_phase1(c, ch);
     359             : 
     360           0 :         total=c->ent[(uint8_t)CMD_GRAND_TOTAL];
     361           0 :         ++total->phase1;
     362           0 :         if(!print) return;
     363           0 :         if(total->phase1==1) logc("\n");
     364           0 :         logc("%c", ch);
     365           0 :         if(!((total->phase1)%64))
     366           0 :                 print_end(total->phase1);
     367           0 :         fflush(stdout);
     368             : }
     369             : 
     370           0 : void cntr_add_val(struct cntr *c, char ch, uint64_t val)
     371             : {
     372           0 :         incr_count_val(c, ch, val);
     373           0 : }
     374             : 
     375       33720 : void cntr_add_new(struct cntr *c, char ch)
     376             : {
     377       33720 :         cntr_add(c, ch, 0);
     378       33720 : }
     379             : 
     380       12626 : void cntr_add_same(struct cntr *c, char ch)
     381             : {
     382       12626 :         incr_same(c, ch);
     383             :         incr_same(c, CMD_TOTAL);
     384             :         incr_same(c, CMD_GRAND_TOTAL);
     385       12626 : }
     386             : 
     387           0 : void cntr_add_same_val(struct cntr *c, char ch, uint64_t val)
     388             : {
     389           0 :         incr_same_val(c, ch, val);
     390             :         incr_same_val(c, CMD_TOTAL, val);
     391             :         incr_same_val(c, CMD_GRAND_TOTAL, val);
     392           0 : }
     393             : 
     394           4 : void cntr_add_changed(struct cntr *c, char ch)
     395             : {
     396           4 :         incr_changed(c, ch);
     397             :         incr_changed(c, CMD_TOTAL);
     398             :         incr_changed(c, CMD_GRAND_TOTAL);
     399           4 : }
     400             : 
     401           0 : void cntr_add_changed_val(struct cntr *c, char ch, uint64_t val)
     402             : {
     403           0 :         incr_changed_val(c, ch, val);
     404             :         incr_changed_val(c, CMD_TOTAL, val);
     405             :         incr_changed_val(c, CMD_GRAND_TOTAL, val);
     406           0 : }
     407             : 
     408           2 : void cntr_add_deleted(struct cntr *c, char ch)
     409             : {
     410           2 :         incr_deleted(c, ch);
     411             :         incr_deleted(c, CMD_TOTAL);
     412             :         incr_deleted(c, CMD_GRAND_TOTAL);
     413           2 : }
     414             : 
     415          20 : void cntr_add_bytes(struct cntr *c, uint64_t bytes)
     416             : {
     417             :         incr_count_val(c, CMD_BYTES, bytes);
     418          20 : }
     419             : 
     420             : static void cntr_set_sentbytes(struct cntr *c, uint64_t bytes)
     421             : {
     422             :         set_count_val(c, CMD_BYTES_SENT, bytes);
     423             : }
     424             : 
     425             : static void cntr_set_recvbytes(struct cntr *c, uint64_t bytes)
     426             : {
     427             :         set_count_val(c, CMD_BYTES_RECV, bytes);
     428             : }
     429             : 
     430           0 : static void quint_print(struct cntr_ent *ent, enum action act)
     431             : {
     432             :         uint64_t a;
     433             :         uint64_t b;
     434             :         uint64_t c;
     435             :         uint64_t d;
     436             :         uint64_t e;
     437           0 :         if(!ent) return;
     438           0 :         a=ent->count;
     439           0 :         b=ent->changed;
     440           0 :         c=ent->same;
     441           0 :         d=ent->deleted;
     442           0 :         e=ent->phase1;
     443             : 
     444           0 :         if(!(ent->flags & CNTR_TABULATE)) return;
     445             : 
     446           0 :         if(!e && !a && !b && !c) return;
     447           0 :         logc("%18s:", ent->label);
     448           0 :         if(act==ACTION_BACKUP
     449           0 :           || act==ACTION_BACKUP_TIMED)
     450             :         {
     451           0 :                 logc("%9" PRIu64 " ", a);
     452           0 :                 logc("%9" PRIu64 " ", b);
     453           0 :                 logc("%9" PRIu64 " ", c);
     454           0 :                 logc("%9" PRIu64 " ", d);
     455             :         }
     456           0 :         if(act==ACTION_RESTORE
     457           0 :           || act==ACTION_VERIFY)
     458             :         {
     459           0 :                 logc("%9s ", "");
     460             :                 //logc("%9s ", "");
     461             :                 //logc("%9s ", "");
     462             :                 //logc("%9s ", "");
     463             :         }
     464           0 :         if(act==ACTION_ESTIMATE)
     465             :         {
     466           0 :                 logc("%9s ", "");
     467           0 :                 logc("%9s ", "");
     468           0 :                 logc("%9" PRIu64 "\n", e);
     469             :         }
     470             :         else
     471             :         {
     472           0 :                 logc("%9" PRIu64 " |", a+b+c);
     473           0 :                 logc("%9" PRIu64 "\n", e);
     474             :         }
     475             : }
     476             : 
     477             : static uint64_t get_count(struct cntr_ent **ent, enum cmd cmd)
     478             : {
     479           0 :         if(!ent[(uint8_t)cmd]) return 0;
     480           0 :         return ent[(uint8_t)cmd]->count;
     481             : }
     482             : 
     483           0 : static void bottom_part(struct cntr *c, enum action act)
     484             : {
     485             :         uint64_t l;
     486           0 :         struct cntr_ent **e=c->ent;
     487           0 :         logc("\n");
     488           0 :         logc("             Messages:   %11" PRIu64 "\n", get_count(e, CMD_MESSAGE));
     489           0 :         logc("             Warnings:   %11" PRIu64 "\n", get_count(e, CMD_WARNING));
     490           0 :         logc("\n");
     491           0 :         logc("      Bytes estimated:   %11" PRIu64, get_count(e, CMD_BYTES_ESTIMATED));
     492           0 :         logc("%s\n", bytes_to_human(get_count(e, CMD_BYTES_ESTIMATED)));
     493             : 
     494           0 :         if(act==ACTION_ESTIMATE) return;
     495             : 
     496           0 :         if(act==ACTION_BACKUP
     497           0 :           || act==ACTION_BACKUP_TIMED)
     498             :         {
     499           0 :                 l=get_count(e, CMD_BYTES);
     500           0 :                 logc("      Bytes in backup:   %11" PRIu64, l);
     501           0 :                 logc("%s\n", bytes_to_human(l));
     502             :         }
     503           0 :         if(act==ACTION_RESTORE)
     504             :         {
     505           0 :                 l=get_count(e, CMD_BYTES);
     506           0 :                 logc("      Bytes attempted:   %11" PRIu64, l);
     507           0 :                 logc("%s\n", bytes_to_human(l));
     508             :         }
     509           0 :         if(act==ACTION_VERIFY)
     510             :         {
     511           0 :                 l=get_count(e, CMD_BYTES);
     512           0 :                 logc("        Bytes checked:   %11" PRIu64, l);
     513           0 :                 logc("%s\n", bytes_to_human(l));
     514             :         }
     515             : 
     516           0 :         l=get_count(e, CMD_BYTES_RECV);
     517           0 :         logc("       Bytes received:   %11" PRIu64, l);
     518           0 :         logc("%s\n", bytes_to_human(l));
     519             : 
     520           0 :         l=get_count(e, CMD_BYTES_SENT);
     521           0 :         logc("           Bytes sent:   %11" PRIu64, l);
     522           0 :         logc("%s\n", bytes_to_human(l));
     523             : }
     524             : 
     525          28 : void cntr_print(struct cntr *cntr, enum action act, struct asfd *asfd)
     526             : {
     527             :         struct cntr_ent *e;
     528             :         time_t now;
     529             :         time_t start;
     530             :         char time_start_str[32];
     531             :         char time_end_str[32];
     532          56 :         if(!cntr) return;
     533             : 
     534           0 :         if(asfd)
     535             :         {
     536           0 :                 cntr_set_sentbytes(cntr, asfd->sent);
     537           0 :                 cntr_set_recvbytes(cntr, asfd->rcvd);
     538             :         }
     539           0 :         now=time(NULL);
     540           0 :         start=(time_t)cntr->ent[(uint8_t)CMD_TIMESTAMP]->count;
     541           0 :         cntr->ent[(uint8_t)CMD_TIMESTAMP_END]->count=(uint64_t)now;
     542             : 
     543             :         border();
     544           0 :         encode_time(start, time_start_str);
     545           0 :         encode_time(now, time_end_str);
     546           0 :         logc("Start time: %s\n", time_start_str);
     547           0 :         logc("  End time: %s\n", time_end_str);
     548           0 :         logc("Time taken: %s\n", time_taken(now-start));
     549           0 :         if(act==ACTION_BACKUP
     550           0 :           || act==ACTION_BACKUP_TIMED)
     551             :         {
     552           0 :           logc("%18s %9s %9s %9s %9s %9s |%9s\n",
     553             :             " ", "New", "Changed", "Duplicate", "Deleted", "Total", "Scanned");
     554             :         }
     555           0 :         if(act==ACTION_RESTORE
     556           0 :           || act==ACTION_VERIFY)
     557             :         {
     558           0 :           logc("%18s %9s %9s |%9s\n",
     559             :             " ", "", "Attempted", "Expected");
     560             :         }
     561           0 :         if(act==ACTION_ESTIMATE)
     562             :         {
     563           0 :           logc("%18s %9s %9s %9s\n",
     564             :             " ", "", "", "Scanned");
     565             :         }
     566           0 :         table_border(act);
     567             : 
     568           0 :         for(e=cntr->list; e; e=e->next)
     569           0 :                 quint_print(e, act);
     570             : 
     571           0 :         table_border(act);
     572           0 :         bottom_part(cntr, act);
     573             : 
     574             :         border();
     575             : }
     576             : 
     577             : #ifndef HAVE_WIN32
     578             : 
     579           6 : int cntr_stats_to_file(struct cntr *cntr,
     580             :         const char *directory, enum action act)
     581             : {
     582           6 :         int ret=-1;
     583           6 :         int fd=-1;
     584           6 :         char *path=NULL;
     585           6 :         const char *fname=NULL;
     586           6 :         struct async *as=NULL;
     587           6 :         struct asfd *wfd=NULL;
     588           6 :         if(!cntr)
     589             :                 return 0;
     590           0 :         cntr->ent[(uint8_t)CMD_TIMESTAMP_END]->count
     591           0 :                 =(uint64_t)time(NULL);
     592             : 
     593           0 :         if(act==ACTION_BACKUP
     594           0 :           ||  act==ACTION_BACKUP_TIMED)
     595             :                 fname="backup_stats";
     596           0 :         else if(act==ACTION_RESTORE)
     597             :                 fname="restore_stats";
     598           0 :         else if(act==ACTION_VERIFY)
     599             :                 fname="verify_stats";
     600             :         else
     601             :                 return 0;
     602             : 
     603           0 :         if(!(path=prepend_s(directory, fname)))
     604             :                 goto end;
     605           0 :         if((fd=open(path, O_WRONLY|O_CREAT, 0666))<0)
     606             :         {
     607           0 :                 logp("Could not open %s for writing in %s: %s\n",
     608           0 :                         path, __func__, strerror(errno));
     609           0 :                 goto end;
     610             :         }
     611             : 
     612           0 :         if(!(as=async_alloc())
     613           0 :           || as->init(as, 0)
     614           0 :           || !(wfd=setup_asfd_linebuf_write(as, "stats file", &fd)))
     615             :                         goto end;
     616             : 
     617           0 :         if(json_cntr(wfd, cntr))
     618             :                 goto end;
     619             : 
     620           0 :         ret=0;
     621             : end:
     622           0 :         close_fd(&fd);
     623           0 :         free_w(&path);
     624           0 :         async_free(&as);
     625           0 :         asfd_free(&wfd);
     626           0 :         return ret;
     627             : }
     628             : 
     629             : #endif
     630             : 
     631          22 : void cntr_print_end(struct cntr *cntr)
     632             : {
     633             :         struct cntr_ent *grand_total_ent;
     634          44 :         if(!cntr) return;
     635           0 :         grand_total_ent=cntr->ent[CMD_GRAND_TOTAL];
     636           0 :         if(grand_total_ent)
     637             :         {
     638           0 :                 print_end(grand_total_ent->count);
     639           0 :                 logc("\n");
     640             :         }
     641             : }
     642             : 
     643           0 : void cntr_print_end_phase1(struct cntr *cntr)
     644             : {
     645             :         struct cntr_ent *grand_total_ent;
     646           0 :         if(!cntr) return;
     647           0 :         grand_total_ent=cntr->ent[CMD_GRAND_TOTAL];
     648           0 :         if(grand_total_ent)
     649             :         {
     650           0 :                 print_end(grand_total_ent->phase1);
     651           0 :                 logc("\n");
     652             :         }
     653             : }
     654             : 
     655             : #ifndef HAVE_WIN32
     656             : // Return string length.
     657           0 : size_t cntr_to_str(struct cntr *cntr, const char *path)
     658             : {
     659             :         static char tmp[CNTR_PATH_BUF_LEN+3]="";
     660           0 :         struct cntr_ent *e=NULL;
     661           0 :         char *str=cntr->str;
     662             : 
     663           0 :         cntr->ent[(uint8_t)CMD_TIMESTAMP_END]->count=time(NULL);
     664             : 
     665           0 :         snprintf(str, cntr->str_max_len-1, "%s\t%d\t%d\t",
     666           0 :                 cntr->cname, CNTR_VERSION, cntr->cntr_status);
     667             : 
     668           0 :         for(e=cntr->list; e; e=e->next)
     669             :         {
     670           0 :                 if(e->flags & CNTR_SINGLE_FIELD)
     671           0 :                         snprintf(tmp, sizeof(tmp),
     672           0 :                                 "%c%" PRIu64"\t", e->cmd, e->count);
     673             :                 else
     674           0 :                         snprintf(tmp, sizeof(tmp),
     675             :                         "%c%" PRIu64
     676             :                         "/%" PRIu64
     677             :                         "/%" PRIu64
     678             :                         "/%" PRIu64
     679             :                         "/%" PRIu64
     680             :                         "\t",
     681           0 :                                 e->cmd, e->count, e->changed,
     682             :                                 e->same, e->deleted, e->phase1);
     683             :                 strcat(str, tmp);
     684             :         }
     685             : 
     686             :         // Abuse CMD_DATAPTH.
     687           0 :         snprintf(tmp, sizeof(tmp), "%c%s\t\n", CMD_DATAPTH, path?path:"");
     688             :         strcat(str, tmp);
     689             : 
     690           0 :         return strlen(str);
     691             : }
     692             : #endif
     693             : 
     694           0 : static int extract_ul(const char *value, struct cntr_ent *ent)
     695             : {
     696           0 :         char *as=NULL;
     697           0 :         char *bs=NULL;
     698           0 :         char *cs=NULL;
     699           0 :         char *ds=NULL;
     700           0 :         char *es=NULL;
     701           0 :         char *copy=NULL;
     702           0 :         if(!value || !(copy=strdup_w(value, __func__))) return -1;
     703             : 
     704             :         // Do not want to use strtok, just in case I end up running more
     705             :         // than one at a time.
     706           0 :         as=copy;
     707           0 :         if((bs=strchr(as, '/')))
     708             :         {
     709           0 :                 *bs='\0';
     710           0 :                 ent->count=strtoull(as, NULL, 10);
     711           0 :                 if((cs=strchr(++bs, '/')))
     712             :                 {
     713           0 :                         *cs='\0';
     714           0 :                         ent->changed=strtoull(bs, NULL, 10);
     715           0 :                         if((ds=strchr(++cs, '/')))
     716             :                         {
     717           0 :                                 *ds='\0';
     718           0 :                                 ent->same=strtoull(cs, NULL, 10);
     719           0 :                                 if((es=strchr(++ds, '/')))
     720             :                                 {
     721           0 :                                         ent->deleted=strtoull(ds, NULL, 10);
     722           0 :                                         *es='\0';
     723           0 :                                         es++;
     724           0 :                                         ent->phase1=strtoull(es, NULL, 10);
     725             :                                 }
     726             :                         }
     727             :                 }
     728             :         }
     729             :         else
     730             :         {
     731             :                 // Single field.
     732           0 :                 ent->count=strtoull(as, NULL, 10);
     733             :         }
     734           0 :         free_w(&copy);
     735           0 :         return 0;
     736             : }
     737             : 
     738             : /*
     739             : static char *get_backup_str(const char *s, int *deletable)
     740             : {
     741             :         static char str[32]="";
     742             :         const char *cp=NULL;
     743             :         const char *dp=NULL;
     744             :         if(!s || !*s) return NULL;
     745             :         if(!(cp=strchr(s, ' '))
     746             :           || !(dp=strchr(cp+1, ' ')))
     747             :                 snprintf(str, sizeof(str), "never");
     748             :         else
     749             :         {
     750             :                 uint64_t backupnum=0;
     751             :                 backupnum=strtoul(s, NULL, 10);
     752             :                 snprintf(str, sizeof(str),
     753             :                         "%07lu %s", backupnum, getdatestr(atol(dp+1)));
     754             :                 if(*(cp+1)=='1') *deletable=1;
     755             :         }
     756             :         return str;
     757             : }
     758             : */
     759             : 
     760             : /*
     761             : static int add_to_backup_list(struct strlist **backups, const char *tok)
     762             : {
     763             :         int deletable=0;
     764             :         const char *str=NULL;
     765             :         if(!(str=get_backup_str(tok, &deletable))) return 0;
     766             :         if(strlist_add(backups, (char *)str, deletable)) return -1;
     767             :         return 0;
     768             : }
     769             : */
     770             : 
     771           0 : static int extract_cntrs(struct cstat *cstat, char **path)
     772             : {
     773             :         char *tok;
     774           0 :         struct cntr *cntr=cstat->cntr;
     775           0 :         while((tok=strtok(NULL, "\t\n")))
     776             :         {
     777           0 :                 switch(tok[0])
     778             :                 {
     779             :                         case CMD_DATAPTH:
     780           0 :                                 free_w(path);
     781           0 :                                 if(!(*path=strdup_w(tok+1, __func__)))
     782             :                                         return -1;
     783             :                                 break;
     784             :                         default:
     785           0 :                                 if(cntr->ent[(uint8_t)tok[0]]
     786           0 :                                   && extract_ul(tok+1,
     787             :                                         cntr->ent[(uint8_t)tok[0]]))
     788             :                                                 return -1;
     789             :                                 break;
     790             :                 }
     791             :         }
     792             :         return 0;
     793             : }
     794             : 
     795           0 : int str_to_cntr(const char *str, struct cstat *cstat, char **path)
     796             : {
     797           0 :         int ret=-1;
     798           0 :         char *tok=NULL;
     799           0 :         char *copy=NULL;
     800             : 
     801           0 :         if(!(copy=strdup_w(str, __func__)))
     802             :                 return -1;
     803             : 
     804           0 :         if((tok=strtok(copy, "\t\n")))
     805             :         {
     806           0 :                 char *tmp=NULL;
     807             :                 // First token is the client name. Do not need that here.
     808             :                 // Second is the cntr version.
     809           0 :                 if(!(tmp=strtok(NULL, "\t\n")))
     810             :                 {
     811           0 :                         logp("Parsing problem in %s: null version\n",
     812             :                                 __func__);
     813           0 :                         goto end;
     814             :                 }
     815           0 :                 if(atoi(tmp)!=CNTR_VERSION)
     816             :                 {
     817             :                         ret=0;
     818             :                         goto end;
     819             :                 }
     820             :                 // Third is cstat_status.
     821           0 :                 if(!(tmp=strtok(NULL, "\t\n")))
     822             :                 {
     823           0 :                         logp("Parsing problem in %s: null cstat_status\n",
     824             :                                 __func__);
     825           0 :                         goto end;
     826             :                 }
     827           0 :                 cstat->cntr->cntr_status=(enum cntr_status)atoi(tmp);
     828             : 
     829           0 :                 if(extract_cntrs(cstat, path)) goto end;
     830             :         }
     831             : 
     832             :         ret=0;
     833             : end:
     834           0 :         free_w(&copy);
     835           0 :         return ret;
     836             : }
     837             : 
     838             : #ifndef HAVE_WIN32
     839           6 : int cntr_send_bu(struct asfd *asfd, struct bu *bu, struct conf **confs)
     840             : {
     841           6 :         int ret=-1;
     842             :         uint16_t flags;
     843           6 :         struct cstat *clist=NULL;
     844           6 :         struct cstat *cstat=NULL;
     845             : 
     846           6 :         if(!get_int(confs[OPT_SEND_CLIENT_CNTR]))
     847             :                 return 0;
     848             : 
     849           0 :         flags=bu->flags;
     850             : 
     851             :         // Want to setup a cstat and a bu so that we can piggy-back on the
     852             :         // status monitor cntr json code.
     853             : 
     854           0 :         if(!(cstat=cstat_alloc())
     855           0 :           || cstat_init(cstat,
     856           0 :                 get_string(confs[OPT_CNAME]), NULL/*clientconfdir*/))
     857             :                         goto end;
     858           0 :         cstat->cntr=get_cntr(confs);
     859             : 
     860             :         // Hacky provocation to get the json stuff to send counters in the
     861             :         // case where we are actually doing a restore.
     862           0 :         bu->flags|=BU_WORKING;
     863           0 :         cstat->bu=bu;
     864             : 
     865           0 :         clist=cstat;
     866             : 
     867           0 :         ret=json_send(asfd,
     868             :                 clist,
     869             :                 cstat,
     870             :                 bu,
     871             :                 NULL /* logfile */,
     872             :                 NULL /* browse */,
     873             :                 0 /* use_cache */);
     874             : end:
     875           0 :         cstat->bu=NULL; // 'bu' was not ours to mess with.
     876           0 :         cstat->cntr=NULL; // 'cntr' was not ours to mess with.
     877           0 :         bu->flags=flags; // Set flags back to what the were before.
     878           0 :         cstat_free(&cstat);
     879           0 :         return ret;
     880             : }
     881             : 
     882           0 : int cntr_send_sdirs(struct asfd *asfd,
     883             :         struct sdirs *sdirs, struct conf **confs)
     884             : {
     885           0 :         int ret=-1;
     886           0 :         struct bu *bu=NULL;
     887           0 :         struct bu *bu_list=NULL;
     888             : 
     889             :         // FIX THIS:
     890             :         // It would be better just to set up the correct 'bu' entry instead
     891             :         // of loading everything and then looking through the list.
     892           0 :         if(bu_get_list_with_working(sdirs, &bu_list, NULL))
     893             :                 goto end;
     894           0 :         for(bu=bu_list; bu; bu=bu->next)
     895           0 :                 if((bu->flags & BU_WORKING)
     896           0 :                   || (bu->flags & BU_FINISHING))
     897             :                         break;
     898           0 :         if(!bu)
     899             :         {
     900           0 :                 logp("could not find working or finishing backup in %s\n",
     901             :                         __func__);
     902           0 :                 goto end;
     903             :         }
     904           0 :         ret=cntr_send_bu(asfd, bu, confs);
     905             : end:
     906           0 :         bu_list_free(&bu_list);
     907           0 :         return ret;
     908             : }
     909             : #endif
     910             : 
     911           0 : static enum asl_ret cntr_recv_func(struct asfd *asfd,
     912             :         struct conf **confs,
     913             :         void *param)
     914             : {
     915           0 :         struct sel *sel=(struct sel *)param;
     916           0 :         switch(json_input(asfd, sel))
     917             :         {
     918             :                 case 0: return ASL_CONTINUE;
     919           0 :                 case 1: return ASL_END_OK;
     920           0 :                 default: return ASL_END_ERROR;
     921             :         }
     922             : }
     923             : 
     924           8 : int cntr_recv(struct asfd *asfd, struct conf **confs)
     925             : {
     926           8 :         int ret=-1;
     927           8 :         struct sel *sel=NULL;
     928             :         struct cntr_ent *e;
     929           8 :         struct cntr *cntr=get_cntr(confs);
     930             : 
     931           8 :         if(!(sel=sel_alloc()))
     932             :                 goto end;
     933           8 :         if(!get_int(confs[OPT_SEND_CLIENT_CNTR]))
     934             :                 goto ok;
     935           0 :         if(json_input_init())
     936             :                 goto end;
     937           0 :         if(asfd->simple_loop(asfd, confs, sel, __func__, cntr_recv_func)
     938           0 :           || !sel->clist || !sel->clist->cntr)
     939             :                 goto end;
     940           0 :         for(e=sel->clist->cntr->list; e; e=e->next)
     941             :         {
     942           0 :                 set_count_val(cntr, e->cmd, e->count);
     943           0 :                 set_changed_val(cntr, e->cmd, e->changed);
     944           0 :                 set_same_val(cntr, e->cmd, e->same);
     945           0 :                 set_deleted_val(cntr, e->cmd, e->deleted);
     946           0 :                 set_phase1_val(cntr, e->cmd, e->phase1);
     947             :         }
     948             : ok:
     949             :         ret=0;
     950             : end:
     951           8 :         json_input_free();
     952           8 :         sel_free(&sel);
     953           8 :         return ret;
     954             : }
     955             : 
     956           0 : const char *cntr_status_to_str(struct cntr *cntr)
     957             : {
     958           0 :         switch(cntr->cntr_status)
     959             :         {
     960             :                 case CNTR_STATUS_SCANNING: return CNTR_STATUS_STR_SCANNING;
     961             :                 case CNTR_STATUS_BACKUP: return CNTR_STATUS_STR_BACKUP;
     962             :                 case CNTR_STATUS_MERGING: return CNTR_STATUS_STR_MERGING;
     963             :                 case CNTR_STATUS_SHUFFLING: return CNTR_STATUS_STR_SHUFFLING;
     964             :                 case CNTR_STATUS_LISTING: return CNTR_STATUS_STR_LISTING;
     965             :                 case CNTR_STATUS_RESTORING: return CNTR_STATUS_STR_RESTORING;
     966             :                 case CNTR_STATUS_VERIFYING: return CNTR_STATUS_STR_VERIFYING;
     967             :                 case CNTR_STATUS_DELETING: return CNTR_STATUS_STR_DELETING;
     968             :                 case CNTR_STATUS_DIFFING: return CNTR_STATUS_STR_DIFFING;
     969             :                 default: return "unknown";
     970             :         }
     971             : }
     972             : 
     973           0 : enum cntr_status cntr_str_to_status(const char *str)
     974             : {
     975           0 :         if(!strcmp(str, CNTR_STATUS_STR_SCANNING))
     976             :                 return CNTR_STATUS_SCANNING;
     977           0 :         else if(!strcmp(str, CNTR_STATUS_STR_BACKUP))
     978             :                 return CNTR_STATUS_BACKUP;
     979           0 :         else if(!strcmp(str, CNTR_STATUS_STR_MERGING))
     980             :                 return CNTR_STATUS_MERGING;
     981           0 :         else if(!strcmp(str, CNTR_STATUS_STR_SHUFFLING))
     982             :                 return CNTR_STATUS_SHUFFLING;
     983           0 :         else if(!strcmp(str, CNTR_STATUS_STR_LISTING))
     984             :                 return CNTR_STATUS_LISTING;
     985           0 :         else if(!strcmp(str, CNTR_STATUS_STR_RESTORING))
     986             :                 return CNTR_STATUS_RESTORING;
     987           0 :         else if(!strcmp(str, CNTR_STATUS_STR_VERIFYING))
     988             :                 return CNTR_STATUS_VERIFYING;
     989           0 :         else if(!strcmp(str, CNTR_STATUS_STR_DELETING))
     990             :                 return CNTR_STATUS_DELETING;
     991           0 :         else if(!strcmp(str, CNTR_STATUS_STR_DIFFING))
     992             :                 return CNTR_STATUS_DIFFING;
     993           0 :         return CNTR_STATUS_UNSET;
     994             : }

Generated by: LCOV version 1.10