/* * replica_check_store_size -- (internal) store size from pool descriptor for * replica */ static int replica_check_store_size(struct pool_set *set, struct poolset_health_status *set_hs, unsigned repn) { LOG(3, "set %p, set_hs %p, repn %u", set, set_hs, repn); struct pool_replica *rep = set->replica[repn]; struct pmemobjpool pop; if (rep->remote) { memcpy(&pop.hdr, rep->part[0].hdr, sizeof(pop.hdr)); void *descr = (void *)((uintptr_t)&pop + POOL_HDR_SIZE); if (Rpmem_read(rep->remote->rpp, descr, POOL_HDR_SIZE, sizeof(pop) - POOL_HDR_SIZE, 0)) { return -1; } } else { /* round up map size to Mmap align size */ if (util_map_part(&rep->part[0], NULL, MMAP_ALIGN_UP(sizeof(pop)), 0, MAP_SHARED, 1)) { return -1; } memcpy(&pop, rep->part[0].addr, sizeof(pop)); util_unmap_part(&rep->part[0]); } void *dscp = (void *)((uintptr_t)&pop + sizeof(pop.hdr)); if (!util_checksum(dscp, OBJ_DSC_P_SIZE, &pop.checksum, 0, 0)) { set_hs->replica[repn]->flags |= IS_BROKEN; return 0; } set_hs->replica[repn]->pool_size = pop.heap_offset + pop.heap_size; return 0; }
/* * replica_check_store_size -- (internal) store size from pool descriptor for * replica */ static int replica_check_store_size(struct pool_set *set, struct poolset_health_status *set_hs, unsigned r) { struct pool_replica *rep = set->replica[r]; struct pmemobjpool pop; if (rep->remote) { memcpy(&pop.hdr, rep->part[0].hdr, sizeof(pop.hdr)); void *descr = (void *)((uintptr_t)&pop + POOL_HDR_SIZE); if (Rpmem_read(rep->remote->rpp, descr, 0, sizeof(pop) - POOL_HDR_SIZE)) { return -1; } } else { if (util_map_part(&rep->part[0], NULL, sizeof(pop), 0, MAP_PRIVATE|MAP_NORESERVE)) { return -1; } memcpy(&pop, rep->part[0].addr, sizeof(pop)); util_unmap_part(&rep->part[0]); } void *dscp = (void *)((uintptr_t)&pop + sizeof(pop.hdr)); if (!util_checksum(dscp, OBJ_DSC_P_SIZE, &pop.checksum, 0)) { set_hs->replica[r]->flags |= IS_BROKEN; return 0; } set_hs->replica[r]->pool_size = pop.heap_offset + pop.heap_size; return 0; }
/* * copy_data_to_broken_parts -- (internal) copy data to all parts created * in place of the broken ones */ static int copy_data_to_broken_parts(struct pool_set *set, unsigned healthy_replica, unsigned flags, struct poolset_health_status *set_hs) { /* get pool size from healthy replica */ size_t poolsize = set->poolsize; for (unsigned r = 0; r < set_hs->nreplicas; ++r) { /* skip unbroken and consistent replicas */ if (replica_is_replica_healthy(r, set_hs)) continue; struct pool_replica *rep = REP(set, r); struct pool_replica *rep_h = REP(set, healthy_replica); for (unsigned p = 0; p < rep->nparts; ++p) { /* skip unbroken parts from consistent replicas */ if (!replica_is_part_broken(r, p, set_hs) && replica_is_replica_consistent(r, set_hs)) continue; const struct pool_set_part *part = &rep->part[p]; size_t off = replica_get_part_data_offset(set, r, p); size_t len = replica_get_part_data_len(set, r, p); if (rep->remote) len = poolsize - off; /* do not allow copying too much data */ if (off >= poolsize) continue; /* * First part of replica is mapped * with header */ size_t fpoff = (p == 0) ? POOL_HDR_SIZE : 0; void *dst_addr = ADDR_SUM(part->addr, fpoff); if (rep->remote) { int ret = Rpmem_persist(rep->remote->rpp, off - POOL_HDR_SIZE, len, 0); if (ret) { LOG(1, "Copying data to remote node " "failed -- '%s' on '%s'", rep->remote->pool_desc, rep->remote->node_addr); return -1; } } else if (rep_h->remote) { int ret = Rpmem_read(rep_h->remote->rpp, dst_addr, off - POOL_HDR_SIZE, len); if (ret) { LOG(1, "Reading data from remote node " "failed -- '%s' on '%s'", rep_h->remote->pool_desc, rep_h->remote->node_addr); return -1; } } else { if (off + len > poolsize) len = poolsize - off; void *src_addr = ADDR_SUM(rep_h->part[0].addr, off); /* copy all data */ memcpy(dst_addr, src_addr, len); pmem_msync(dst_addr, len); } } } return 0; }