1 Index: src/dird/next_vol.c
2 ===================================================================
3 --- src/dird/next_vol.c (revision 7286)
4 +++ src/dird/next_vol.c (working copy)
8 Dmsg0(150, "Call prune_volumes\n");
9 - prune_volumes(jcr, InChanger, mr);
10 + ok = prune_volumes(jcr, InChanger, mr);
12 - ok = recycle_oldest_purged_volume(jcr, InChanger, mr);
13 - if (!ok && create) {
14 - Dmsg4(050, "after prune volumes_vol ok=%d index=%d InChanger=%d Vstat=%s\n",
15 - ok, index, InChanger, mr->VolStatus);
17 - * 5. Try pulling a volume from the Scratch pool
19 - ok = get_scratch_volume(jcr, InChanger, mr);
22 - * If we are using an Autochanger and have not found
23 - * a volume, retry looking for any volume.
28 - continue; /* retry again accepting any volume */
33 + ok = recycle_oldest_purged_volume(jcr, InChanger, mr);
34 + if (!ok && create) {
35 + Dmsg4(050, "after prune volumes_vol ok=%d index=%d InChanger=%d Vstat=%s\n",
36 + ok, index, InChanger, mr->VolStatus);
38 + * 5. Try pulling a volume from the Scratch pool
40 + ok = get_scratch_volume(jcr, InChanger, mr);
41 + Dmsg4(050, "after get scratch volume ok=%d index=%d InChanger=%d Vstat=%s\n",
42 + ok, index, InChanger, mr->VolStatus);
45 + * If we are using an Autochanger and have not found
46 + * a volume, retry looking for any volume.
48 + if (!ok && InChanger) {
50 + continue; /* retry again accepting any volume */
57 Index: src/dird/autoprune.c
58 ===================================================================
59 --- src/dird/autoprune.c (revision 7286)
60 +++ src/dird/autoprune.c (working copy)
62 prune_list.num_ids = 0; /* reset count */
64 ok = is_volume_purged(ua, &lmr);
67 + * Check if this volume is available (InChanger + StorageId)
68 + * If not, just skip this volume and try the next one
70 + if (ok && InChanger) {
71 + if (!lmr.InChanger || (lmr.StorageId != mr->StorageId)) {
72 + ok = false; /* skip this volume, ie not loadable */
77 * If purged and not moved to another Pool,
78 * then we stop pruning and take this volume.
79 Index: src/filed/accurate.c
80 ===================================================================
81 --- src/filed/accurate.c (revision 7286)
82 +++ src/filed/accurate.c (working copy)
84 static int dbglvl=200;
86 typedef struct PrivateCurFile {
91 char *fname; /* not stored with tchdb mode */
98 -static void realfree(void *p); /* used by tokyo code */
100 +static void realfree(void *p); /* used by tokyo/db code */
102 * Update hash element seen=1
104 @@ -190,10 +190,150 @@
108 -#else /* HTABLE mode */
109 +#endif /* USE_TCADB */
113 + * Update hash element seen=1
115 static bool accurate_mark_file_as_seen(JCR *jcr, CurFile *elt)
122 + dbkey.data = elt->fname;
123 + dbkey.size = (u_int32_t)strlen(elt->fname)+1;
125 + dbdata.size = sizeof(CurFile);
126 + if ((ret = jcr->file_list->put(jcr->file_list, NULL, &dbkey, &dbdata, 0))) {
127 + Jmsg(jcr, M_ERROR, 1, _("Can't update accurate hash disk ERR=%i\n"), ret);
134 +static bool accurate_lookup(JCR *jcr, char *fname, CurFile *ret)
138 + /* Zero out the DBTs before using them. */
139 + memset(&dbkey, 0, sizeof(DBT));
140 + memset(&dbdata, 0, sizeof(DBT));
142 + dbkey.data = fname;
143 + dbkey.ulen = strlen(fname)+1;
146 + dbdata.ulen = sizeof(CurFile);
147 + dbdata.flags = DB_DBT_USERMEM;
149 + if (jcr->file_list->get(jcr->file_list, NULL, &dbkey, &dbdata, 0) == 0) {
156 +/* Create tokyo dbm hash file
157 + * If something goes wrong, we cancel accurate mode.
159 +static bool accurate_init(JCR *jcr, int nbfile)
163 + if ((ret = db_create(&jcr->file_list, NULL, 0)) != 0) {
164 + Jmsg(jcr, M_ERROR, 1, _("Can't open accurate hash disk\n"));
168 + jcr->file_list->set_errfile(jcr->file_list, stderr);
169 + jcr->file_list->set_errpfx(jcr->file_list, "hash");
171 + if ((ret = jcr->file_list->set_cachesize(jcr->file_list, 0, 32 * 1024 * 1024, 0)) != 0) {
172 + Jmsg(jcr, M_ERROR, 1, _("Can't setup hash disk cache size\n"));
175 + jcr->hash_name = get_pool_memory(PM_MESSAGE);
176 + make_unique_filename(&jcr->hash_name, jcr->JobId, "accurate");
178 + if ((ret = jcr->file_list->open(jcr->file_list,
179 + NULL, jcr->hash_name, NULL, DB_BTREE, DB_CREATE, 0600)) != 0) {
180 + jcr->file_list->close(jcr->file_list, DB_NOSYNC);
181 + jcr->file_list=NULL;
182 + free_pool_memory(jcr->hash_name);
183 + jcr->hash_name = NULL;
184 + Jmsg(jcr, M_ERROR, 1, _("Can't setup hash disk cache size\n"));
188 + return jcr->file_list != NULL;
191 +/* This function is called at the end of backup
192 + * We walk over all hash disk element, and we check
195 +bool accurate_send_deleted_list(JCR *jcr)
199 + int stream = STREAM_UNIX_ATTRIBUTES;
202 + /* Zero out the DBTs before using them. */
203 + memset(&dbkey, 0, sizeof(DBT));
204 + memset(&dbdata, 0, sizeof(DBT));
205 + dbdata.data = &elt;
206 + dbdata.ulen = sizeof(CurFile);
207 + dbdata.flags = DB_DBT_USERMEM;
209 + if (!jcr->accurate || jcr->JobLevel == L_FULL) {
213 + if (jcr->file_list == NULL) {
217 + ff_pkt = init_find_files();
218 + ff_pkt->type = FT_DELETED;
220 + /* traverse records */
221 + jcr->file_list->cursor(jcr->file_list, NULL, &cursorp, 0);
223 + while(cursorp->c_get(cursorp, &dbkey, &dbdata, DB_NEXT) == 0) {
224 + if (!elt.seen) { /* already seen */
225 + ff_pkt->fname = (char *) dbkey.data;
226 + ff_pkt->statp.st_mtime = elt.mtime;
227 + ff_pkt->statp.st_ctime = elt.ctime;
228 + encode_and_send_attributes(jcr, ff_pkt, stream);
231 + cursorp->c_close(cursorp);
233 + term_find_files(ff_pkt);
236 + if (jcr->file_list) {
237 + jcr->file_list->close(jcr->file_list, DB_NOSYNC);
238 + if (!bstrcmp(jcr->hash_name, "*")) {
239 + unlink(jcr->hash_name);
241 + free_pool_memory(jcr->hash_name);
242 + jcr->hash_name = NULL;
243 + jcr->file_list = NULL;
251 +static bool accurate_mark_file_as_seen(JCR *jcr, CurFile *elt)
253 CurFile *temp = (CurFile *)jcr->file_list->lookup(elt->fname);
254 temp->seen = 1; /* records are in memory */
257 Jmsg(jcr, M_ERROR, 1, _("Can't update accurate hash disk ERR=%s\n"));
264 + memset(&dbkey, 0, sizeof(DBT));
265 + memset(&dbdata, 0, sizeof(DBT));
266 + dbkey.data = elt.fname;
267 + dbkey.size = (u_int32_t)strlen(elt.fname)+1;
268 + dbdata.data = &elt;
269 + dbdata.size = sizeof(CurFile);
270 + if ((ret = jcr->file_list->put(jcr->file_list, NULL, &dbkey, &dbdata, 0))) {
271 + Jmsg(jcr, M_ERROR, 1, _("Can't update accurate hash disk ERR=%i\n"), ret);
278 /* we store CurFile, fname and ctime/mtime in the same chunk */
279 item = (CurFile *)jcr->file_list->hash_malloc(sizeof(CurFile)+strlen(fname)+1);
280 Index: src/filed/filed.h
281 ===================================================================
282 --- src/filed/filed.h (revision 7286)
283 +++ src/filed/filed.h (working copy)
285 #define FILE_DAEMON 1
286 #ifdef USE_TCADB /* hash disk based */
294 # include "lib/htable.h"
296 #include "filed_conf.h"
297 Index: src/baconfig.h
298 ===================================================================
299 --- src/baconfig.h (revision 7286)
300 +++ src/baconfig.h (working copy)
303 #endif /* HAVE_WIN32 */
305 +/* Select db backend for accurate mode */
314 Index: src/win32/build-depkgs-mingw32
315 ===================================================================
316 --- src/win32/build-depkgs-mingw32 (revision 7286)
317 +++ src/win32/build-depkgs-mingw32 (working copy)
325 for dependency in "$@"
328 ===================================================================
329 --- src/jcr.h (revision 7286)
330 +++ src/jcr.h (working copy)
333 TCADB *file_list; /* Previous file list (accurate mode) */
339 + POOLMEM *hash_name;
342 htable *file_list; /* Previous file list (accurate mode) */
344 #endif /* FILE_DAEMON */