static struct wipe_desc * do_wipe(struct wipe_desc *wp, const char *devname, int flags) { int mode = O_RDWR, reread = 0; blkid_probe pr; struct wipe_desc *w, *wp0; int zap = (flags & WP_FL_ALL) ? 1 : wp->zap; char *backup = NULL; if (!(flags & WP_FL_FORCE)) mode |= O_EXCL; pr = new_probe(devname, mode); if (!pr) return NULL; if (zap && (flags & WP_FL_BACKUP)) { const char *home = getenv ("HOME"); if (!home) errx(EXIT_FAILURE, _("failed to create a signature backup, $HOME undefined")); xasprintf (&backup, "%s/wipefs-%s-", home, basename(devname)); } wp0 = clone_offset(wp); while (blkid_do_probe(pr) == 0) { wp = get_desc_for_probe(wp, pr); if (!wp) break; /* Check if offset is in provided list */ w = wp0; while(w && w->offset != wp->offset) w = w->next; if (wp0 && !w) continue; /* Mark done if found in provided list */ if (w) w->on_disk = wp->on_disk; if (!wp->on_disk) continue; if (zap) { if (backup) do_backup(wp, backup); do_wipe_real(pr, devname, wp, flags); if (wp->is_parttable) reread = 1; } } for (w = wp0; w != NULL; w = w->next) { if (!w->on_disk && !(flags & WP_FL_QUIET)) warnx(_("%s: offset 0x%jx not found"), devname, w->offset); } fsync(blkid_probe_get_fd(pr)); if (reread) rereadpt(blkid_probe_get_fd(pr), devname); close(blkid_probe_get_fd(pr)); blkid_free_probe(pr); free_wipe(wp0); free(backup); return wp; }
/* * This is the engine called by jobq.c:jobq_add() when we were pulled * from the work queue. * At this point, we are running in our own thread and all * necessary resources are allocated -- see jobq.c */ static void *job_thread(void *arg) { JCR *jcr = (JCR *)arg; pthread_detach(pthread_self()); Dsm_check(100); Dmsg0(200, "=====Start Job=========\n"); jcr->setJobStatus(JS_Running); /* this will be set only if no error */ jcr->start_time = time(NULL); /* set the real start time */ jcr->jr.StartTime = jcr->start_time; if (jcr->job->MaxStartDelay != 0 && jcr->job->MaxStartDelay < (utime_t)(jcr->start_time - jcr->sched_time)) { jcr->setJobStatus(JS_Canceled); Jmsg(jcr, M_FATAL, 0, _("Job canceled because max start delay time exceeded.\n")); } if (job_check_maxrunschedtime(jcr)) { jcr->setJobStatus(JS_Canceled); Jmsg(jcr, M_FATAL, 0, _("Job canceled because max run sched time exceeded.\n")); } /* TODO : check if it is used somewhere */ if (jcr->job->RunScripts == NULL) { Dmsg0(200, "Warning, job->RunScripts is empty\n"); jcr->job->RunScripts = New(alist(10, not_owned_by_alist)); } if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) { Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db)); } /* Run any script BeforeJob on dird */ run_scripts(jcr, jcr->job->RunScripts, "BeforeJob"); /* * We re-update the job start record so that the start * time is set after the run before job. This avoids * that any files created by the run before job will * be saved twice. They will be backed up in the current * job, but not in the next one unless they are changed. * Without this, they will be backed up in this job and * in the next job run because in that case, their date * is after the start of this run. */ jcr->start_time = time(NULL); jcr->jr.StartTime = jcr->start_time; if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) { Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db)); } generate_job_event(jcr, "JobRun"); generate_plugin_event(jcr, bDirEventJobRun); switch (jcr->getJobType()) { case JT_BACKUP: if (!job_canceled(jcr) && do_backup(jcr)) { do_autoprune(jcr); } else { backup_cleanup(jcr, JS_ErrorTerminated); } break; case JT_VERIFY: if (!job_canceled(jcr) && do_verify(jcr)) { do_autoprune(jcr); } else { verify_cleanup(jcr, JS_ErrorTerminated); } break; case JT_RESTORE: if (!job_canceled(jcr) && do_restore(jcr)) { do_autoprune(jcr); } else { restore_cleanup(jcr, JS_ErrorTerminated); } break; case JT_ADMIN: if (!job_canceled(jcr) && do_admin(jcr)) { do_autoprune(jcr); } else { admin_cleanup(jcr, JS_ErrorTerminated); } break; case JT_COPY: case JT_MIGRATE: if (!job_canceled(jcr) && do_migration(jcr)) { do_autoprune(jcr); } else { migration_cleanup(jcr, JS_ErrorTerminated); } break; default: Pmsg1(0, _("Unimplemented job type: %d\n"), jcr->getJobType()); break; } run_scripts(jcr, jcr->job->RunScripts, "AfterJob"); /* Send off any queued messages */ if (jcr->msg_queue && jcr->msg_queue->size() > 0) { dequeue_messages(jcr); } generate_daemon_event(jcr, "JobEnd"); generate_plugin_event(jcr, bDirEventJobEnd); Dmsg1(50, "======== End Job stat=%c ==========\n", jcr->JobStatus); Dsm_check(100); return NULL; }
static struct wipe_desc * do_wipe(struct wipe_desc *wp, const char *devname, int flags) { int mode = O_RDWR, reread = 0, need_force = 0; blkid_probe pr; struct wipe_desc *w, *wp0; int zap = (flags & WP_FL_ALL) ? 1 : wp->zap; char *backup = NULL; if (!(flags & WP_FL_FORCE)) mode |= O_EXCL; pr = new_probe(devname, mode); if (!pr) return NULL; if (zap && (flags & WP_FL_BACKUP)) { const char *home = getenv ("HOME"); char *tmp = xstrdup(devname); if (!home) errx(EXIT_FAILURE, _("failed to create a signature backup, $HOME undefined")); xasprintf (&backup, "%s/wipefs-%s-", home, basename(tmp)); free(tmp); } wp0 = clone_offset(wp); while (blkid_do_probe(pr) == 0) { wp = get_desc_for_probe(wp, pr); if (!wp) break; /* Check if offset is in provided list */ w = wp0; while(w && w->offset != wp->offset) w = w->next; if (wp0 && !w) continue; /* Mark done if found in provided list */ if (w) w->on_disk = wp->on_disk; if (!wp->on_disk) continue; if (!(flags & WP_FL_FORCE) && wp->is_parttable && !blkid_probe_is_wholedisk(pr)) { warnx(_("%s: ignoring nested \"%s\" partition table " "on non-whole disk device"), devname, wp->type); need_force = 1; continue; } if (zap) { if (backup) do_backup(wp, backup); do_wipe_real(pr, devname, wp, flags); if (wp->is_parttable) reread = 1; } } for (w = wp0; w != NULL; w = w->next) { if (!w->on_disk && !(flags & WP_FL_QUIET)) warnx(_("%s: offset 0x%jx not found"), devname, (uintmax_t)w->offset); } if (need_force) warnx(_("Use the --force option to force erase.")); fsync(blkid_probe_get_fd(pr)); #ifdef BLKRRPART if (reread && (mode & O_EXCL)) rereadpt(blkid_probe_get_fd(pr), devname); #endif close(blkid_probe_get_fd(pr)); blkid_free_probe(pr); free_wipe(wp0); free(backup); return wp; }
/* backup in this order: 6 win 5 win/draw 4 draw if draw/loss 3 win/draw/loss 2 draw 1 draw/loss 0 lose return true if fully solved, false if it's unknown or partially unknown */ bool Player::do_backup(Node * node, Node * backup, int toplay){ int nodeoutcome = node->outcome; if(nodeoutcome >= 0) //already proven, probably by a different thread return true; if(backup->outcome == -3) //nothing proven by this child, so no chance return false; uint8_t proofdepth = backup->proofdepth; if(backup->outcome != toplay){ uint64_t sims = 0, bestsims = 0, outcome = 0, bestoutcome = 0; backup = NULL; Node * child = node->children.begin(), * end = node->children.end(); for( ; child != end; child++){ int childoutcome = child->outcome; //save a copy to avoid race conditions if(proofdepth < child->proofdepth+1) proofdepth = child->proofdepth+1; //these should be sorted in likelyness of matching, most likely first if(childoutcome == -3){ // win/draw/loss outcome = 3; }else if(childoutcome == toplay){ //win backup = child; outcome = 6; proofdepth = child->proofdepth+1; break; }else if(childoutcome == 3-toplay){ //loss outcome = 0; }else if(childoutcome == 0){ //draw if(nodeoutcome == toplay-3) //draw/loss outcome = 4; else outcome = 2; }else if(childoutcome == -toplay){ //win/draw outcome = 5; }else if(childoutcome == toplay-3){ //draw/loss outcome = 1; }else{ logerr("childoutcome == " + to_str(childoutcome) + "\n"); assert(false && "How'd I get here? All outcomes should be tested above"); } sims = child->exp.num(); if(bestoutcome < outcome){ //better outcome is always preferable bestoutcome = outcome; bestsims = sims; backup = child; }else if(bestoutcome == outcome && ((outcome == 0 && bestsims < sims) || bestsims > sims)){ //find long losses or easy wins/draws bestsims = sims; backup = child; } } if(bestoutcome == 3) //no win, but found an unknown return false; } if(CAS(node->outcome, nodeoutcome, backup->outcome)){ node->bestmove = backup->move; node->proofdepth = proofdepth; }else //if it was in a race, try again, might promote a partial solve to full solve return do_backup(node, backup, toplay); return (node->outcome >= 0); }
int main(int argc, char **argv) { destor_start(); int job = DESTOR_BACKUP; int revision = -1; int opt = 0; while ((opt = getopt_long(argc, argv, short_options, long_options, NULL)) != -1) { switch (opt) { case 'r': job = DESTOR_RESTORE; revision = atoi(optarg); break; case 's': destor_stat(); break; case 't': job = DESTOR_MAKE_TRACE; break; case 'h': usage(); break; case 'p': { sds param = sdsnew(optarg); load_config_from_string(param); break; } default: return 0; } } sds path = NULL; switch (job) { case DESTOR_BACKUP: if (argc > optind) { path = sdsnew(argv[optind]); } else { fprintf(stderr, "backup job needs a protected path!\n"); usage(); } do_backup(path); /* * The backup concludes. * GC starts * */ if(destor.backup_retention_time >= 0 && jcr.id >= destor.backup_retention_time){ NOTICE("GC is running!"); do_delete(jcr.id - destor.backup_retention_time); } sdsfree(path); break; case DESTOR_RESTORE: if (revision < 0) { fprintf(stderr, "A job id is required!\n"); usage(); } if (argc > optind) { path = sdsnew(argv[optind]); } else { fprintf(stderr, "A target directory is required!\n"); usage(); } do_restore(revision, path[0] == 0 ? 0 : path); sdsfree(path); break; case DESTOR_MAKE_TRACE: { if (argc > optind) { path = sdsnew(argv[optind]); } else { fprintf(stderr, "A target directory is required!\n"); usage(); } make_trace(path); sdsfree(path); break; } default: fprintf(stderr, "Invalid job type!\n"); usage(); } destor_shutdown(); return 0; }
/* * Entry point of pg_arman command. */ int main(int argc, char *argv[]) { const char *cmd = NULL; const char *range1 = NULL; const char *range2 = NULL; pgBackupRange range; int i; /* do not buffer progress messages */ setvbuf(stdout, 0, _IONBF, 0); /* TODO: remove this */ /* initialize configuration */ catalog_init_config(¤t); /* overwrite configuration with command line arguments */ i = pgut_getopt(argc, argv, options); for (; i < argc; i++) { if (cmd == NULL) cmd = argv[i]; else if (range1 == NULL) range1 = argv[i]; else if (range2 == NULL) range2 = argv[i]; else elog(ERROR, "too many arguments"); } /* command argument (backup/restore/show/...) is required. */ if (cmd == NULL) { help(false); return 1; } /* get object range argument if any */ if (range1 && range2) parse_range(&range, range1, range2); else if (range1) parse_range(&range, range1, ""); else range.begin = range.end = 0; /* Read default configuration from file. */ if (backup_path) { char path[MAXPGPATH]; /* Check if backup_path is directory. */ struct stat stat_buf; int rc = stat(backup_path, &stat_buf); /* If rc == -1, there is no file or directory. So it's OK. */ if (rc != -1 && !S_ISDIR(stat_buf.st_mode)) elog(ERROR, "-B, --backup-path must be a path to directory"); join_path_components(path, backup_path, PG_RMAN_INI_FILE); pgut_readopt(path, options, ERROR); } /* BACKUP_PATH is always required */ if (backup_path == NULL) elog(ERROR, "required parameter not specified: BACKUP_PATH (-B, --backup-path)"); /* path must be absolute */ if (backup_path != NULL && !is_absolute_path(backup_path)) elog(ERROR, "-B, --backup-path must be an absolute path"); if (pgdata != NULL && !is_absolute_path(pgdata)) elog(ERROR, "-D, --pgdata must be an absolute path"); if (arclog_path != NULL && !is_absolute_path(arclog_path)) elog(ERROR, "-A, --arclog-path must be an absolute path"); /* Sanity checks with commands */ if (pg_strcasecmp(cmd, "delete") == 0 && arclog_path == NULL) elog(ERROR, "delete command needs ARCLOG_PATH (-A, --arclog-path) to be set"); /* setup exclusion list for file search */ for (i = 0; pgdata_exclude[i]; i++) /* find first empty slot */ ; if (arclog_path) pgdata_exclude[i++] = arclog_path; /* do actual operation */ if (pg_strcasecmp(cmd, "init") == 0) return do_init(); else if (pg_strcasecmp(cmd, "backup") == 0) { pgBackupOption bkupopt; int res; bkupopt.smooth_checkpoint = smooth_checkpoint; bkupopt.keep_data_generations = keep_data_generations; bkupopt.keep_data_days = keep_data_days; /* Do the backup */ res = do_backup(bkupopt); if (res != 0) return res; /* If validation has been requested, do it */ range.begin = current.start_time; range.end = current.start_time + 1; if (backup_validate) do_validate(&range); } else if (pg_strcasecmp(cmd, "restore") == 0) return do_restore(target_time, target_xid, target_inclusive, target_tli); else if (pg_strcasecmp(cmd, "show") == 0) return do_show(&range, show_all); else if (pg_strcasecmp(cmd, "validate") == 0) return do_validate(&range); else if (pg_strcasecmp(cmd, "delete") == 0) return do_delete(&range); else elog(ERROR, "invalid command \"%s\"", cmd); return 0; }