int locate_cmp(sxi_hdist_t *model1, sxi_hdist_t *model2, uint64_t hash, int replica, int bidx) { sx_nodelist_t *nodelist1, *nodelist2; int i; nodelist1 = sxi_hdist_locate(model1, hash, replica, bidx); if(!nodelist1) { CRIT("Can't locate hash with model1"); return 1; } nodelist2 = sxi_hdist_locate(model2, hash, replica, bidx); if(!nodelist1) { CRIT("Can't locate hash with model2"); sx_nodelist_delete(nodelist1); return 1; } if(sx_nodelist_count(nodelist1) != sx_nodelist_count(nodelist2) || sx_nodelist_count(nodelist1) != replica) { CRIT("Numbers of target nodes don't match"); sx_nodelist_delete(nodelist1); sx_nodelist_delete(nodelist2); return 1; } if(dbg) fprintf(stderr, "Locate (hash: %llx, replica: %u, bidx: %d) = ", (unsigned long long) hash, replica, bidx); for(i = 0; i < sx_nodelist_count(nodelist1); i++) { if(strcmp(sx_node_uuid_str(sx_nodelist_get(nodelist1, i)), sx_node_uuid_str(sx_nodelist_get(nodelist2, i)))) { CRIT("Different nodes reported for duplicate models"); sx_nodelist_delete(nodelist1); sx_nodelist_delete(nodelist2); return 1; } if(dbg) fprintf(stderr, "%s ", sx_node_addr(sx_nodelist_get(nodelist1, i))); } if(dbg) fprintf(stderr, "\n"); sx_nodelist_delete(nodelist1); sx_nodelist_delete(nodelist2); return 0; }
static void blockmgr_process_queue(struct blockmgr_data_t *q) { sxc_client_t *sx = sx_hashfs_client(q->hashfs); sxi_conns_t *clust = sx_hashfs_conns(q->hashfs); sxi_hostlist_t uploadto; sxi_hostlist_init(&uploadto); while(!terminate) { unsigned int i, trigger_jobmgr = 0; const char *host, *token = NULL; sxi_hashop_t hc; uint8_t *curb; int r; r = schedule_blocks_sfq(q); if(r <= 0) { /* no blocks(0) or error (<1) */ break; } sxi_hostlist_empty(&uploadto); host = sx_node_internal_addr(q->target); if(sxi_hostlist_add_host(sx, &uploadto, host)) { WARN("Cannot generate hostlist"); break; } if(sx_hashfs_make_token(q->hashfs, CLUSTER_USER, NULL, 0, time(NULL) + JOB_FILE_MAX_TIME, &token)) { WARN("Cannot create upload token"); break; } /* just check for presence, reservation was already done by the failed INUSE */ sxi_hashop_begin(&hc, clust, hcb, HASHOP_CHECK, 0, NULL, NULL, NULL, &q->hashlist, 0); for(i=0; i<q->hashlist.nblocks; i++) { if(sxi_hashop_batch_add(&hc, host, i, q->hashlist.binhs[i].b, q->blocksize) != 0) { WARN("Cannot verify block presence: %s", sxc_geterrmsg(sx)); blockmgr_reschedule_xfer(q, q->hashlist.ids[i]); } } if(sxi_hashop_end(&hc) == -1) { WARN("Cannot verify block presence on node %s (%s): %s", sx_node_uuid_str(q->target), host, sxc_geterrmsg(sx)); for(i=0; i<q->hashlist.nblocks; i++) blockmgr_reschedule_xfer(q, q->hashlist.ids[i]); continue; } curb = upbuffer; for(i=0; i<q->hashlist.nblocks; i++) { const uint8_t *b; if(q->hashlist.havehs[i]) { /* TODO: print actual hash */ DEBUG("Block %d was found remotely", i); blockmgr_del_xfer(q, q->hashlist.ids[i]); } else if(sx_hashfs_block_get(q->hashfs, q->blocksize, &q->hashlist.binhs[i], &b)) { INFO("Block %ld was not found locally", q->hashlist.ids[i]); blockmgr_reschedule_xfer(q, q->hashlist.ids[i]); } else { memcpy(curb, b, q->blocksize); curb += q->blocksize; } if(sizeof(upbuffer) - (curb - upbuffer) < q->blocksize || i == q->hashlist.nblocks - 1) { /* upload chunk */ int j; if(sxi_upload_block_from_buf(clust, &uploadto, token, upbuffer, q->blocksize, curb-upbuffer)) { WARN("Block transfer failed"); for(j=0; j<=i; j++) if(!q->hashlist.havehs[j]) blockmgr_reschedule_xfer(q, q->hashlist.ids[j]); break; } curb = upbuffer; for(j=0; j<=i; j++) { char debughash[sizeof(sx_hash_t)*2+1]; const sx_hash_t *hash = &q->hashlist.binhs[j]; if(q->hashlist.havehs[j]) continue; bin2hex(hash->b, sizeof(hash->b), debughash, sizeof(debughash)); DEBUG("Block %ld #%s# was transferred successfully", q->hashlist.ids[j], debughash); blockmgr_del_xfer(q, q->hashlist.ids[j]); q->hashlist.havehs[j] = 1; trigger_jobmgr = 1; } } } if(trigger_jobmgr) sx_hashfs_job_trigger(q->hashfs); } sxi_hostlist_empty(&uploadto); }