Line data Source code
1 : #include "../burp.h"
2 : #include "../alloc.h"
3 : #include "../cntr.h"
4 : #include "../conf.h"
5 : #include "../cstat.h"
6 : #include "../fsops.h"
7 : #include "../handy.h"
8 : #include "../log.h"
9 : #include "../sbuf.h"
10 : #include "compress.h"
11 : #include "manio.h"
12 : #include "sdirs.h"
13 : #include "child.h"
14 : #include "backup_phase3.h"
15 :
16 3 : static const char *get_rmanifest_relative(struct sdirs *sdirs,
17 : struct conf **confs)
18 : {
19 : size_t s;
20 : const char *directory;
21 :
22 3 : directory=get_string(confs[OPT_DIRECTORY]);
23 3 : s=strlen(directory);
24 :
25 3 : if(!strncmp(sdirs->rmanifest, directory, s))
26 : {
27 : const char *cp;
28 0 : cp=sdirs->rmanifest+strlen(directory);
29 0 : while(cp && *cp=='/') cp++;
30 : return cp;
31 : }
32 : return sdirs->rmanifest;
33 : }
34 :
35 : // Combine the phase1 and phase2 files into a new manifest.
36 5 : int backup_phase3_server_all(struct sdirs *sdirs, struct conf **confs)
37 : {
38 5 : int ret=-1;
39 5 : int pcmp=0;
40 5 : struct sbuf *usb=NULL;
41 5 : struct sbuf *csb=NULL;
42 5 : char *manifesttmp=NULL;
43 5 : struct manio *newmanio=NULL;
44 5 : struct manio *chmanio=NULL;
45 5 : struct manio *unmanio=NULL;
46 5 : enum protocol protocol=get_protocol(confs);
47 5 : struct cntr *cntr=get_cntr(confs);
48 5 : const char *rmanifest_relative=NULL;
49 :
50 5 : logp("Begin phase3 (merge manifests)\n");
51 :
52 5 : if(protocol==PROTO_2)
53 3 : rmanifest_relative=get_rmanifest_relative(sdirs, confs);
54 :
55 5 : if(!(manifesttmp=get_tmp_filename(sdirs->manifest))
56 5 : || !(newmanio=manio_open_phase3(manifesttmp,
57 5 : comp_level(get_int(confs[OPT_COMPRESSION])),
58 : protocol, rmanifest_relative))
59 5 : || !(chmanio=manio_open_phase2(sdirs->changed, "rb", protocol))
60 5 : || !(unmanio=manio_open_phase2(sdirs->unchanged, "rb", protocol))
61 5 : || !(usb=sbuf_alloc(protocol))
62 5 : || !(csb=sbuf_alloc(protocol)))
63 : goto end;
64 :
65 25 : while(chmanio || unmanio)
66 : {
67 20 : if(unmanio
68 17 : && !usb->path.buf)
69 : {
70 9 : switch(manio_read(unmanio, usb))
71 : {
72 : case -1: goto end;
73 3 : case 1: manio_close(&unmanio);
74 : }
75 : }
76 :
77 20 : if(chmanio
78 18 : && !csb->path.buf)
79 : {
80 9 : switch(manio_read(chmanio, csb))
81 : {
82 : case -1: goto end;
83 2 : case 1: manio_close(&chmanio);
84 : }
85 : }
86 :
87 20 : if(usb->path.buf && !csb->path.buf)
88 : {
89 2 : if(write_status(CNTR_STATUS_MERGING,
90 : usb->path.buf, cntr)) goto end;
91 2 : switch(manio_copy_entry(usb, usb, unmanio, newmanio))
92 : {
93 : case -1: goto end;
94 1 : case 1: manio_close(&unmanio);
95 : }
96 : }
97 18 : else if(!usb->path.buf && csb->path.buf)
98 : {
99 4 : if(write_status(CNTR_STATUS_MERGING,
100 : csb->path.buf, cntr)) goto end;
101 4 : switch(manio_copy_entry(csb, csb, chmanio, newmanio))
102 : {
103 : case -1: goto end;
104 2 : case 1: manio_close(&chmanio);
105 : }
106 : }
107 14 : else if(!usb->path.buf && !csb->path.buf)
108 : {
109 2 : continue;
110 : }
111 12 : else if(!(pcmp=sbuf_pathcmp(usb, csb)))
112 : {
113 : // They were the same - write one.
114 0 : if(write_status(CNTR_STATUS_MERGING,
115 0 : csb->path.buf, cntr)) goto end;
116 0 : switch(manio_copy_entry(csb, csb, chmanio, newmanio))
117 : {
118 : case -1: goto end;
119 0 : case 1: manio_close(&chmanio);
120 : }
121 : }
122 12 : else if(pcmp<0)
123 : {
124 6 : if(write_status(CNTR_STATUS_MERGING,
125 6 : usb->path.buf, cntr)) goto end;
126 6 : switch(manio_copy_entry(usb, usb, unmanio, newmanio))
127 : {
128 : case -1: goto end;
129 1 : case 1: manio_close(&unmanio);
130 : }
131 : }
132 : else
133 : {
134 6 : if(write_status(CNTR_STATUS_MERGING,
135 6 : csb->path.buf, cntr)) goto end;
136 6 : switch(manio_copy_entry(csb, csb, chmanio, newmanio))
137 : {
138 : case -1: goto end;
139 1 : case 1: manio_close(&chmanio);
140 : }
141 : }
142 : }
143 :
144 : // Flush to disk.
145 5 : if(manio_close(&newmanio))
146 : {
147 0 : logp("error gzclosing %s in backup_phase3_server\n",
148 : manifesttmp);
149 0 : goto end;
150 : }
151 :
152 : // Rename race condition should be of no consequence here, as the
153 : // manifest should just get recreated automatically.
154 5 : if(do_rename(manifesttmp, sdirs->manifest))
155 : goto end;
156 : else
157 : {
158 5 : recursive_delete(sdirs->changed);
159 5 : recursive_delete(sdirs->unchanged);
160 : }
161 :
162 5 : logp("End phase3 (merge manifests)\n");
163 5 : ret=0;
164 : end:
165 5 : manio_close(&newmanio);
166 5 : manio_close(&chmanio);
167 5 : manio_close(&unmanio);
168 5 : sbuf_free(&csb);
169 5 : sbuf_free(&usb);
170 5 : free_w(&manifesttmp);
171 5 : return ret;
172 : }
|