/* * backup_nonpoolset_requirements -- (internal) check backup requirements */ static int backup_nonpoolset_requirements(PMEMpoolcheck *ppc, location *loc) { LOG(3, "backup_path %s", ppc->backup_path); if (os_access(ppc->backup_path, F_OK)) { if (errno == ENOENT) { errno = 0; return 0; } else { return CHECK_ERR(ppc, "unable to access the backup destination: %s", ppc->backup_path); } } if ((size_t)util_file_get_size(ppc->backup_path) != ppc->pool->set_file->size) { ppc->result = CHECK_RESULT_ERROR; return CHECK_ERR(ppc, "destination of the backup does not match the size of the source pool file: %s", ppc->backup_path); } if (CHECK_WITHOUT_FIXING(ppc)) { location_release(loc); loc->step = CHECK_STEP_COMPLETE; return 0; } CHECK_ASK(ppc, Q_OVERWRITE_EXISTING_FILE, "destination of the backup already exists.|Do you want to overwrite it?"); return check_questions_sequence_validate(ppc); }
/* * pool_data_alloc -- allocate pool data and open set_file */ struct pool_data * pool_data_alloc(PMEMpoolcheck *ppc) { LOG(3, NULL); struct pool_data *pool = malloc(sizeof(*pool)); if (!pool) { ERR("!malloc"); return NULL; } TAILQ_INIT(&pool->arenas); pool->narenas = 0; pool->blk_no_layout = 0; pool->uuid_op = UUID_NOP; pool->set_file = NULL; pool->bttc.valid = false; if (pool_params_parse(ppc, &pool->params, 0)) goto error; int rdonly = CHECK_WITHOUT_FIXING(ppc); pool->set_file = pool_set_file_open(ppc->path, &pool->params, rdonly); if (!pool->set_file) goto error; return pool; error: pool_data_free(pool); return NULL; }
/* * backup_poolset_requirements -- (internal) check backup requirements */ static int backup_poolset_requirements(PMEMpoolcheck *ppc, location *loc) { LOG(3, "backup_path %s", ppc->backup_path); if (ppc->pool->set_file->poolset->nreplicas > 1) { CHECK_INFO(ppc, "backup of a poolset with multiple replicas is not supported"); goto err; } if (pool_set_parse(&loc->set, ppc->backup_path)) { CHECK_INFO(ppc, "invalid poolset backup file: %s", ppc->backup_path); goto err; } if (loc->set->nreplicas > 1) { CHECK_INFO(ppc, "backup to a poolset with multiple replicas is not supported"); goto err_poolset; } ASSERTeq(loc->set->nreplicas, 1); struct pool_replica *srep = ppc->pool->set_file->poolset->replica[0]; struct pool_replica *drep = loc->set->replica[0]; if (srep->nparts != drep->nparts) { CHECK_INFO(ppc, "number of part files in the backup poolset must match number of part files in the source poolset"); goto err_poolset; } int overwrite_required = 0; for (unsigned p = 0; p < srep->nparts; p++) { if (srep->part[p].filesize != drep->part[p].filesize) { CHECK_INFO(ppc, "size of the part %u of the backup poolset does not match source poolset", p); goto err_poolset; } if (os_access(drep->part[p].path, F_OK)) { if (errno == ENOENT) { errno = 0; continue; } else { CHECK_INFO(ppc, "unable to access the part of the destination poolset: %s", ppc->backup_path); goto err_poolset; } } overwrite_required = true; if ((size_t)util_file_get_size(drep->part[p].path) != srep->part[p].filesize) { CHECK_INFO(ppc, "destination of the backup part does not match size of the source part file: %s", drep->part[p].path); goto err_poolset; } } if (CHECK_WITHOUT_FIXING(ppc)) { location_release(loc); loc->step = CHECK_STEP_COMPLETE; return 0; } if (overwrite_required) { CHECK_ASK(ppc, Q_OVERWRITE_EXISTING_PARTS, "part files of the destination poolset of the backup already exist.|" "Do you want to overwrite them?"); } return check_questions_sequence_validate(ppc); err_poolset: location_release(loc); err: ppc->result = CHECK_RESULT_ERROR; return CHECK_ERR(ppc, "unable to backup poolset"); }