/* * pool_hdr_nondefault_fix -- (internal) fix custom value fields */ static int pool_hdr_nondefault_fix(PMEMpoolcheck *ppc, location *loc, uint32_t question, void *context) { LOG(3, NULL); ASSERTne(loc, NULL); uint64_t *flags = NULL; switch (question) { case Q_CRTIME: CHECK_INFO(ppc, "%ssetting pool_hdr.crtime to file's modtime: " "%s", loc->prefix, check_get_time_str(ppc->pool->set_file->mtime)); util_convert2h_hdr_nocheck(&loc->hdr); loc->hdr.crtime = (uint64_t)ppc->pool->set_file->mtime; util_convert2le_hdr(&loc->hdr); break; case Q_ARCH_FLAGS: flags = (uint64_t *)&loc->valid_part_hdrp->arch_flags; CHECK_INFO(ppc, "%ssetting pool_hdr.arch_flags to 0x%08" PRIx64 "%08" PRIx64, loc->prefix, flags[0], flags[1]); util_convert2h_hdr_nocheck(&loc->hdr); memcpy(&loc->hdr.arch_flags, &loc->valid_part_hdrp->arch_flags, sizeof(struct arch_flags)); util_convert2le_hdr(&loc->hdr); break; default: ERR("not implemented question id: %u", question); } return 0; }
/* * util_header_create -- (internal) create header of a single pool set file */ static int util_header_create(struct pool_set *set, unsigned repidx, unsigned partidx, const char *sig, uint32_t major, uint32_t compat, uint32_t incompat, uint32_t ro_compat, const unsigned char *prev_repl_uuid, const unsigned char *next_repl_uuid, const unsigned char *arch_flags) { LOG(3, "set %p repidx %u partidx %u sig %.8s major %u " "compat %#x incompat %#x ro_comapt %#x" "prev_repl_uuid %p next_repl_uuid %p arch_flags %p", set, repidx, partidx, sig, major, compat, incompat, ro_compat, prev_repl_uuid, next_repl_uuid, arch_flags); struct pool_replica *rep = set->replica[repidx]; /* opaque info lives at the beginning of mapped memory pool */ struct pool_hdr *hdrp = rep->part[partidx].hdr; /* check if the pool header is all zeros */ if (!util_is_zeroed(hdrp, sizeof(*hdrp))) { ERR("Non-empty file detected"); errno = EEXIST; return -1; } /* * Zero out the pool descriptor - just in case we fail right after * header checksum is stored. */ void *descp = (void *)((uintptr_t)hdrp + sizeof(*hdrp)); memset(descp, 0, POOL_HDR_SIZE - sizeof(*hdrp)); pmem_msync(descp, POOL_HDR_SIZE - sizeof(*hdrp)); /* create pool's header */ memcpy(hdrp->signature, sig, POOL_HDR_SIG_LEN); hdrp->major = major; hdrp->compat_features = compat; hdrp->incompat_features = incompat; hdrp->ro_compat_features = ro_compat; memcpy(hdrp->poolset_uuid, set->uuid, POOL_HDR_UUID_LEN); memcpy(hdrp->uuid, PART(rep, partidx).uuid, POOL_HDR_UUID_LEN); /* link parts */ memcpy(hdrp->prev_part_uuid, PART(rep, partidx - 1).uuid, POOL_HDR_UUID_LEN); memcpy(hdrp->next_part_uuid, PART(rep, partidx + 1).uuid, POOL_HDR_UUID_LEN); /* link replicas */ if (prev_repl_uuid) { memcpy(hdrp->prev_repl_uuid, prev_repl_uuid, POOL_HDR_UUID_LEN); } else { memcpy(hdrp->prev_repl_uuid, PART(REP(set, repidx - 1), 0).uuid, POOL_HDR_UUID_LEN); } if (next_repl_uuid) { memcpy(hdrp->next_repl_uuid, next_repl_uuid, POOL_HDR_UUID_LEN); } else { memcpy(hdrp->next_repl_uuid, PART(REP(set, repidx + 1), 0).uuid, POOL_HDR_UUID_LEN); } hdrp->crtime = (uint64_t)time(NULL); if (!arch_flags) { if (util_get_arch_flags(&hdrp->arch_flags)) { ERR("Reading architecture flags failed"); errno = EINVAL; return -1; } } util_convert2le_hdr(hdrp); if (arch_flags) { memcpy(&hdrp->arch_flags, arch_flags, sizeof(struct arch_flags)); } util_checksum(hdrp, sizeof(*hdrp), &hdrp->checksum, 1); /* store pool's header */ pmem_msync(hdrp, sizeof(*hdrp)); return 0; }