int se_scheduler_backup(void *arg) { se *e = arg; sescheduler *s = &e->sched; if (ssunlikely(e->conf.backup_path == NULL)) { sr_error(&e->error, "%s", "backup is not enabled"); return -1; } /* begin backup procedure * state 0 * * disable log garbage-collection */ sl_poolgc_enable(&e->lp, 0); ss_mutexlock(&s->lock); if (ssunlikely(s->backup > 0)) { ss_mutexunlock(&s->lock); sl_poolgc_enable(&e->lp, 1); /* in progress */ return 0; } uint64_t bsn = sr_seq(&e->seq, SR_BSNNEXT); s->backup = 1; s->backup_bsn = bsn; ss_mutexunlock(&s->lock); return 0; }
static inline int se_backuperror(sescheduler *s) { se *e = (se*)s->env; sl_poolgc_enable(&e->lp, 1); s->backup = 0; s->backup_last_complete = 0; return 0; }
int sc_backupstop(sc *s) { sl_poolgc_enable(s->lp, 1); ss_mutexlock(&s->lock); s->backup = 0; s->backup_bsn_last_complete = 0; ss_mutexunlock(&s->lock); return 0; }
static inline int se_backupcomplete(sescheduler *s, seworker *w) { /* * a. rotate log file * b. copy log files * c. enable log gc * d. rename <bsn.incomplete> into <bsn> * e. set last backup, set COMPLETE */ se *e = (se*)s->env; /* force log rotation */ ss_trace(&w->trace, "%s", "log rotation for backup"); int rc = sl_poolrotate(&e->lp); if (ssunlikely(rc == -1)) return -1; /* copy log files */ ss_trace(&w->trace, "%s", "log files backup"); char path[1024]; snprintf(path, sizeof(path), "%s/%" PRIu32 ".incomplete/log", e->conf.backup_path, s->backup_bsn); rc = sl_poolcopy(&e->lp, path, &w->dc.c); if (ssunlikely(rc == -1)) { sr_errorrecover(&e->error); return -1; } /* enable log gc */ sl_poolgc_enable(&e->lp, 1); /* complete backup */ snprintf(path, sizeof(path), "%s/%" PRIu32 ".incomplete", e->conf.backup_path, s->backup_bsn); char newpath[1024]; snprintf(newpath, sizeof(newpath), "%s/%" PRIu32, e->conf.backup_path, s->backup_bsn); rc = rename(path, newpath); if (ssunlikely(rc == -1)) { sr_error(&e->error, "backup directory '%s' rename error: %s", path, strerror(errno)); return -1; } /* complete */ s->backup_last = s->backup_bsn; s->backup_last_complete = 1; s->backup = 0; s->backup_bsn = 0; return 0; }
int sc_backupstart(sc *s) { /* begin backup procedure * state 0 * * disable log garbage-collection */ sl_poolgc_enable(s->lp, 0); ss_mutexlock(&s->lock); if (ssunlikely(s->backup > 0)) { ss_mutexunlock(&s->lock); sl_poolgc_enable(s->lp, 1); /* in progress */ return 1; } uint64_t bsn = sr_seq(s->r->seq, SR_BSNNEXT); s->backup = 1; s->backup_bsn = bsn; ss_mutexunlock(&s->lock); return 0; }
int sc_backupend(sc *s, scworker *w) { /* * a. rotate log file * b. copy log files * c. enable log gc * d. rename <bsn.incomplete> into <bsn> * e. set last backup, set COMPLETE */ /* force log rotation */ ss_trace(&w->trace, "%s", "log rotation for backup"); int rc = sl_poolrotate(s->lp); if (ssunlikely(rc == -1)) return -1; /* copy log files */ ss_trace(&w->trace, "%s", "log files backup"); char path[1024]; snprintf(path, sizeof(path), "%s/%" PRIu32 ".incomplete/log", s->backup_path, s->backup_bsn); rc = sl_poolcopy(s->lp, path, &w->dc.c); if (ssunlikely(rc == -1)) return -1; /* complete backup */ snprintf(path, sizeof(path), "%s/%" PRIu32 ".incomplete", s->backup_path, s->backup_bsn); char newpath[1024]; snprintf(newpath, sizeof(newpath), "%s/%" PRIu32, s->backup_path, s->backup_bsn); rc = ss_vfsrename(s->r->vfs, path, newpath); if (ssunlikely(rc == -1)) { sr_error(s->r->e, "backup directory '%s' rename error: %s", path, strerror(errno)); return -1; } /* enable log gc */ sl_poolgc_enable(s->lp, 1); /* complete */ ss_mutexlock(&s->lock); s->backup_bsn_last = s->backup_bsn; s->backup_bsn_last_complete = 1; s->backup_in_progress = 0; s->backup = 0; s->backup_bsn = 0; ss_mutexunlock(&s->lock); return 0; }