int do_delete_server(struct asfd *asfd, struct sdirs *sdirs, struct cntr *cntr, const char *cname, const char *backup, const char *manual_delete) { int ret=-1; int found=0; unsigned long bno=0; struct bu *bu=NULL; struct bu *bu_list=NULL; logp("in do_delete\n"); if(bu_get_list(sdirs, &bu_list) || write_status(CNTR_STATUS_DELETING, NULL, cntr)) goto end; if(backup && *backup) bno=strtoul(backup, NULL, 10); for(bu=bu_list; bu; bu=bu->next) { if(!backup || !*backup) continue; if(!found && (!strcmp(bu->timestamp, backup) || bu->bno==bno)) { if(bu->flags & BU_DELETABLE) { found=1; if(asfd->write_str(asfd, CMD_GEN, "ok") || delete_backup(sdirs, cname, bu, manual_delete)) goto end; } else { asfd->write_str(asfd, CMD_ERROR, "backup not deletable"); goto end; } break; } } if(backup && *backup && !found) { asfd->write_str(asfd, CMD_ERROR, "backup not found"); goto end; } ret=0; end: bu_list_free(&bu_list); return ret; }
static int range_loop(struct sdirs *sdirs, const char *cname, struct strlist *keep, unsigned long rmin, struct bu *bu_list, struct bu *last, const char *manual_delete, int *deleted) { struct bu *bu=NULL; unsigned long r=0; unsigned long rmax=0; rmax=rmin*keep->next->flag; // This is going over each range. for(r=rmax; r>rmin; r-=rmin) { int count=0; unsigned long s=r-rmin; // Count the backups in the range. for(bu=bu_list; bu; bu=bu->next) if(s<bu->trbno && bu->trbno<=r) count++; // Want to leave one entry in each range. if(count<=1) continue; // Try to delete from the most recent in each // so that hardlinked backups get taken out // last. for(bu=last; bu; bu=bu->prev) { if(s<bu->trbno && bu->trbno<r && (bu->flags & BU_DELETABLE)) { if(delete_backup(sdirs, cname, bu, manual_delete)) return -1; (*deleted)++; if(--count<=1) break; } } } return 0; }
static int do_delete_backups(struct sdirs *sdirs, struct conf *cconf) { int ret=-1; int deleted=0; unsigned long m=1; struct bu *bu=NULL; struct bu *last=NULL; struct bu *bu_list=NULL; struct strlist *keep=NULL; if(bu_list_get(sdirs, &bu_list)) goto end; // Find the last entry in the list. for(bu=bu_list; bu; bu=bu->next) last=bu; // For each of the 'keep' values, generate ranges in which to keep // one backup. for(keep=cconf->keep; keep; keep=keep->next) { unsigned long rmin=0; rmin=m * keep->flag; if(keep->next && range_loop(sdirs, cconf, keep, rmin, bu_list, last, &deleted)) goto end; m=rmin; } // Remove the very oldest backups. for(bu=bu_list; bu; bu=bu->next) if(bu->trbno>m) break; for(; bu; bu=bu->prev) { if(delete_backup(sdirs, cconf, bu)) goto end; deleted++; } ret=deleted; end: bu_list_free(&bu_list); return ret; }
static int do_delete_backups(struct sdirs *sdirs, const char *cname, struct strlist *keep, struct bu *bu_list, const char *manual_delete) { int ret=-1; int deleted=0; unsigned long m=1; struct bu *bu=NULL; struct bu *last=NULL; struct strlist *k=NULL; // Find the last entry in the list. for(bu=bu_list; bu; bu=bu->next) last=bu; // For each of the 'keep' values, generate ranges in which to keep // one backup. for(k=keep; k; k=k->next) { unsigned long rmin=0; rmin=m * k->flag; if(k->next && range_loop(sdirs, cname, k, rmin, bu_list, last, manual_delete, &deleted)) goto end; m=rmin; } // Remove the very oldest backups. for(bu=bu_list; bu; bu=bu->next) if(bu->trbno>m) break; for(; bu; bu=bu->prev) { if(delete_backup(sdirs, cname, bu, manual_delete)) goto end; deleted++; } ret=deleted; end: return ret; }
int do_remove_old_backups(const char *basedir, struct config *cconf, const char *client) { int a=0; int b=0; int x=0; int ret=0; int deleted=0; unsigned long m=1; struct bu *arr=NULL; struct strlist **kplist=NULL; kplist=cconf->keep; if(get_current_backups(basedir, &arr, &a, 1)) return -1; // For each of the 'keep' values, generate ranges in which to keep // one backup. for(x=0; x<cconf->kpcount; x++) { unsigned long n=0; n=m * kplist[x]->flag; //printf("keep[%d]: %d - m:%lu n:%lu\n", // x, cconf->keep[x]->flag, m, n); if(x+1 < cconf->kpcount) { unsigned long r=0; unsigned long s=0; unsigned long upto=0; upto=n*cconf->keep[x+1]->flag; //printf("upto: %lu\n", upto); // This is going over each range. for(r=upto; r>n; r-=n) { int count=0; s=r-n; //printf(" try: %lu - %lu\n", s, r); // Count the backups in the range. for(b=0; b<a; b++) { if(s<arr[b].trindex && arr[b].trindex<=r) { //printf(" check backup %lu (%lu) %d\n", arr[b].index, arr[b].trindex, arr[b].deletable); count++; } } // Want to leave one entry in each range. if(count>1) { // Try to delete from the most recent in each // so that hardlinked backups get taken out // last. for(b=a-1; b>=0; b--) { if(s<arr[b].trindex && arr[b].trindex<=r && arr[b].deletable) { //printf("deleting backup %lu (%lu)\n", arr[b].index, arr[b].trindex); if(delete_backup(basedir, arr, a, b, client)) { ret=-1; break; } deleted++; if(--count<=1) break; } } } if(ret) break; } } m=n; if(ret) break; } if(!ret) { // Remove the very oldest backups. //printf("back from: %lu\n", m); for(b=0; b<a; b++) { //printf(" %d: %lu (%lu)\n", b, arr[b].index, arr[b].trindex); if(arr[b].trindex>m) break; } for(; b>=0 && b<a; b--) { if(delete_backup(basedir, arr, a, b, client)) { ret=-1; break; } deleted++; } } free_current_backups(&arr, a); if(ret) return ret; return deleted; }