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 : const char *rmanifest_relative=NULL;
48 5 : char *seed_src=get_string(confs[OPT_SEED_SRC]);
49 5 : char *seed_dst=get_string(confs[OPT_SEED_DST]);
50 :
51 5 : logp("Begin phase3 (merge manifests)\n");
52 :
53 5 : if(protocol==PROTO_2)
54 3 : rmanifest_relative=get_rmanifest_relative(sdirs, confs);
55 :
56 5 : if(!(manifesttmp=get_tmp_filename(sdirs->manifest))
57 5 : || !(newmanio=manio_open_phase3(manifesttmp,
58 5 : comp_level(get_int(confs[OPT_COMPRESSION])),
59 : protocol, rmanifest_relative))
60 5 : || !(chmanio=manio_open_phase2(sdirs->changed, "rb", protocol))
61 5 : || !(unmanio=manio_open_phase2(sdirs->unchanged, "rb", protocol))
62 5 : || !(usb=sbuf_alloc(protocol))
63 5 : || !(csb=sbuf_alloc(protocol)))
64 : goto end;
65 :
66 25 : while(chmanio || unmanio)
67 : {
68 20 : if(unmanio
69 17 : && !usb->path.buf)
70 : {
71 9 : switch(manio_read(unmanio, usb))
72 : {
73 : case -1:
74 : goto end;
75 : case 1:
76 3 : manio_close(&unmanio);
77 3 : break;
78 : }
79 : }
80 :
81 20 : if(chmanio
82 18 : && !csb->path.buf)
83 : {
84 9 : switch(manio_read(chmanio, csb))
85 : {
86 : case -1:
87 : goto end;
88 : case 1:
89 2 : manio_close(&chmanio);
90 2 : break;
91 : }
92 : }
93 :
94 20 : if(usb->path.buf && !csb->path.buf)
95 : {
96 2 : if(timed_operation_status_only(CNTR_STATUS_MERGING,
97 : usb->path.buf, confs)) goto end;
98 2 : switch(manio_copy_entry(usb, usb, unmanio, newmanio,
99 : seed_src, seed_dst))
100 : {
101 : case -1: goto end;
102 1 : case 1: manio_close(&unmanio);
103 : }
104 : }
105 18 : else if(!usb->path.buf && csb->path.buf)
106 : {
107 4 : if(timed_operation_status_only(CNTR_STATUS_MERGING,
108 : csb->path.buf, confs)) goto end;
109 4 : switch(manio_copy_entry(csb, csb, chmanio, newmanio,
110 : seed_src, seed_dst))
111 : {
112 : case -1: goto end;
113 2 : case 1: manio_close(&chmanio);
114 : }
115 : }
116 14 : else if(!usb->path.buf && !csb->path.buf)
117 : {
118 2 : continue;
119 : }
120 12 : else if(!(pcmp=sbuf_pathcmp(usb, csb)))
121 : {
122 : // They were the same - write one.
123 0 : if(timed_operation_status_only(CNTR_STATUS_MERGING,
124 0 : csb->path.buf, confs)) goto end;
125 0 : switch(manio_copy_entry(csb, csb, chmanio, newmanio,
126 : seed_src, seed_dst))
127 : {
128 : case -1: goto end;
129 0 : case 1: manio_close(&chmanio);
130 : }
131 : }
132 12 : else if(pcmp<0)
133 : {
134 6 : if(timed_operation_status_only(CNTR_STATUS_MERGING,
135 6 : usb->path.buf, confs)) goto end;
136 6 : switch(manio_copy_entry(usb, usb, unmanio, newmanio,
137 : seed_src, seed_dst))
138 : {
139 : case -1: goto end;
140 1 : case 1: manio_close(&unmanio);
141 : }
142 : }
143 : else
144 : {
145 6 : if(timed_operation_status_only(CNTR_STATUS_MERGING,
146 6 : csb->path.buf, confs)) goto end;
147 6 : switch(manio_copy_entry(csb, csb, chmanio, newmanio,
148 : seed_src, seed_dst))
149 : {
150 : case -1: goto end;
151 1 : case 1: manio_close(&chmanio);
152 : }
153 : }
154 : }
155 :
156 : // Flush to disk.
157 5 : if(manio_close(&newmanio))
158 : {
159 0 : logp("error gzclosing %s in backup_phase3_server\n",
160 : manifesttmp);
161 0 : goto end;
162 : }
163 :
164 : // Rename race condition should be of no consequence here, as the
165 : // manifest should just get recreated automatically.
166 5 : if(do_rename(manifesttmp, sdirs->manifest))
167 : goto end;
168 : else
169 : {
170 5 : recursive_delete(sdirs->changed);
171 5 : recursive_delete(sdirs->unchanged);
172 : }
173 :
174 5 : logp("End phase3 (merge manifests)\n");
175 5 : ret=0;
176 : end:
177 5 : manio_close(&newmanio);
178 5 : manio_close(&chmanio);
179 5 : manio_close(&unmanio);
180 5 : sbuf_free(&csb);
181 5 : sbuf_free(&usb);
182 5 : free_w(&manifesttmp);
183 5 : return ret;
184 : }
|