static int recov_list(recov_type_e state) { struct lmgr_iterator_t *it; int rc; entry_id_t id; attr_set_t attrs; char buff[128]; recov_status_t st; const char *status; /* TODO iter opt */ it = ListMgr_RecovList(&lmgr, state); if (it == NULL) { fprintf(stderr, "ERROR: cannot get the list of entries\n"); return -1; } attrs.attr_mask = RECOV_ATTR_MASK; printf("%-8s %-15s %-40s %s\n", "type", "state", "path", "size"); while (!terminate && ((rc = ListMgr_RecovGetNext(it, &id, &attrs, &st)) != DB_END_OF_LIST)) { if (rc) { fprintf(stderr, "ERROR %d getting entry from recovery table\n", rc); ListMgr_CloseIterator(it); return rc; } FormatFileSize(buff, 128, ATTR(&attrs, size)); switch (st) { case RS_FILE_OK: status = "done"; break; case RS_FILE_DELTA: status = "done_old_data"; break; case RS_NON_FILE: status = "done_non_file"; break; case RS_FILE_EMPTY: status = "done_empty"; break; case RS_NOBACKUP: status = "done_no_backup"; break; case RS_ERROR: status = "failed"; break; case -1: status = "todo"; break; default: status = "?"; } printf("%-8s %-15s %-40s %s\n", ATTR(&attrs, type), status, ATTR(&attrs, fullpath), buff); /* reset mask */ attrs.attr_mask = RECOV_ATTR_MASK; } return 0; }
/** * Bulk filtering in the DB. */ static int list_bulk(void) { attr_set_t root_attrs, attrs; entry_id_t root_id, id; int rc; struct stat st; struct lmgr_iterator_t *it; /* no tranvsersal => no wagon * so we need the path from the DB. */ query_mask |= ATTR_MASK_fullpath; ATTR_MASK_INIT(&root_attrs); rc = retrieve_root_id(&root_id); if (rc) return rc; /* root is not a part of the DB: print it now */ ATTR_MASK_SET(&root_attrs, fullpath); strcpy(ATTR(&root_attrs, fullpath), config.global_config.fs_path); if (lstat(ATTR(&root_attrs, fullpath), &st) == 0) { PosixStat2EntryAttr(&st, &root_attrs, TRUE); ListMgr_GenerateFields(&root_attrs, disp_mask | query_mask); } /* root has no name... */ ATTR_MASK_SET(&root_attrs, name); ATTR(&root_attrs, name)[0] = '\0'; /* match condition on dirs parent */ if (!is_expr || (EntryMatches(&root_id, &root_attrs, &match_expr, NULL) == POLICY_MATCH)) { /* don't display dirs if no_dir is specified */ if (! (prog_options.no_dir && ATTR_MASK_TEST(&root_attrs, type) && !strcasecmp(ATTR(&root_attrs, type), STR_TYPE_DIR))) { wagon_t w; w.id = root_id; w.fullname = ATTR(&root_attrs, fullpath); print_entry(&w, &root_attrs); } } /* list all, including dirs */ it = ListMgr_Iterator(&lmgr, &entry_filter, NULL, NULL); if (!it) { DisplayLog(LVL_MAJOR, FIND_TAG, "ERROR: cannot retrieve entry list from database"); return -1; } attrs.attr_mask = disp_mask | query_mask; while ((rc = ListMgr_GetNext(it, &id, &attrs)) == DB_SUCCESS) { if (!is_expr || (EntryMatches(&id, &attrs, &match_expr, NULL) == POLICY_MATCH)) { /* don't display dirs if no_dir is specified */ if (! (prog_options.no_dir && ATTR_MASK_TEST(&attrs, type) && !strcasecmp(ATTR(&attrs, type), STR_TYPE_DIR))) { wagon_t w; w.id = id; w.fullname = ATTR(&attrs, fullpath); print_entry(&w, &attrs); } /* don't display non dirs is dir_only is specified */ else if (! (prog_options.dir_only && ATTR_MASK_TEST(&attrs, type) && strcasecmp(ATTR(&attrs, type), STR_TYPE_DIR))) { wagon_t w; w.id = id; w.fullname = ATTR(&attrs, fullpath); print_entry(&w, &attrs); } else /* return entry don't match? */ DisplayLog(LVL_DEBUG, FIND_TAG, "Warning: returned DB entry doesn't match filter: %s", ATTR(&attrs, fullpath)); } ListMgr_FreeAttrs(&attrs); /* prepare next call */ attrs.attr_mask = disp_mask | query_mask; } ListMgr_CloseIterator(it); return 0; }
static int recov_resume(int retry_errors) { struct lmgr_iterator_t *it; int rc, st; entry_id_t id, new_id; attr_set_t attrs, new_attrs; char buff[128]; /* TODO iter opt */ it = ListMgr_RecovResume(&lmgr, path_filter, retry_errors, NULL); if (it == NULL) { fprintf(stderr, "ERROR: cannot get the list of entries to be recovered\n"); return -1; } attrs.attr_mask = RECOV_ATTR_MASK; while (!terminate && ((rc = ListMgr_RecovGetNext(it, &id, &attrs, NULL)) != DB_END_OF_LIST)) { if (rc) { fprintf(stderr, "ERROR %d getting entry from recovery table\n", rc); ListMgr_CloseIterator(it); return rc; } FormatFileSize(buff, 128, ATTR(&attrs, size)); if (ATTR_MASK_TEST(&attrs, fullpath)) printf("Restoring %s (%s)...", ATTR(&attrs, fullpath), buff); else printf("Restoring " DFID " (%s)...", PFID(&id), buff); /* TODO process entries asynchronously, in parallel, in separate * threads */ st = rbhext_recover(&id, &attrs, &new_id, &new_attrs, NULL); if ((st == RS_FILE_OK) || (st == RS_FILE_EMPTY) || (st == RS_NON_FILE) || (st == RS_FILE_DELTA)) { /* don't insert readonly attrs */ new_attrs.attr_mask &= ~readonly_attr_set; /* insert the entry in the database, and update recovery status */ rc = ListMgr_Insert(&lmgr, &new_id, &new_attrs, true); if (rc) { fprintf(stderr, "DB insert failure for '%s'\n", ATTR(&new_attrs, fullpath)); st = RS_ERROR; } } /* old id must be used for impacting recovery table */ if (ListMgr_RecovSetState(&lmgr, &id, st)) st = RS_ERROR; switch (st) { case RS_FILE_OK: printf(" OK\n"); break; case RS_FILE_DELTA: printf(" OK (old version)\n"); break; case RS_NON_FILE: printf(" OK (non-file)\n"); break; case RS_FILE_EMPTY: printf(" OK (empty file)\n"); break; case RS_NOBACKUP: printf(" No backup available\n"); break; case RS_ERROR: printf(" FAILED\n"); break; default: printf(" ERROR st=%d, rc=%d\n", st, rc); break; } /* reset mask */ attrs.attr_mask = RECOV_ATTR_MASK; } return 0; }