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