// sends a write chunk request to client // returns -1 on error int network_write_chunk(int32_t id, int fd, int file_id, int node_id, int stripe_id, int chunk_num, int offset, void* buf, int count) { std::string name = chunk_id_formatter(file_id, node_id, stripe_id, chunk_num); if (!chunk_map.count(name)) { // name is not yet in the map chunk_map[name] = (char*) malloc(MAX_CHUNK); } char* base = &((chunk_map[name])[offset]); memcpy(base, buf, count); WriteChunkResponse writeResponse(id, fd, file_id, stripe_id, chunk_num, offset, count); write_response_handler(&writeResponse); return 1; }
void IO_Manager::process_write_stripe (uint32_t request_id, uint32_t replica_request_id, uint32_t *chunks_written, uint32_t *replica_chunks_written, uint32_t file_id, char *pathname, uint32_t stripe_id, uint32_t stripe_size, uint32_t chunk_size, const void *buf, int offset, size_t count) { uint32_t chunk_id, bytes_written = 0, write_size = 0; int chunk_offset, node_id, replica_node_id, write_result; assert (((int)count - offset) <= (int)stripe_size); printf ("\n(BARISTA) Process Write Stripe\n"); get_first_chunk (&chunk_id, chunk_size, &chunk_offset, offset); while (bytes_written < count) { struct file_chunk cur_chunk = {file_id, stripe_id, chunk_id}; // If the chunk does not exists, create it if (!chunk_exists (cur_chunk)) { node_id = put_chunk (file_id, pathname, stripe_id, chunk_id); printf ("\tchunk doesn't exist. Preparing to send chunk to node %d\n", node_id); chunk_to_node[cur_chunk] = node_id; } // If the replica does not exist, create it if (!chunk_replica_exists (cur_chunk)) { replica_node_id = put_replica (file_id, pathname, stripe_id, chunk_id); printf ("\tchunk replica doesn't exist. Preparing to send chunk replica to node %d\n", replica_node_id); chunk_to_replica_node[cur_chunk] = replica_node_id; } // Ensure that we have the proper node and replica id's to send data to node_id = chunk_to_node[cur_chunk]; replica_node_id = chunk_to_replica_node[cur_chunk]; // Determine the size of the write if (count - bytes_written > chunk_size - chunk_offset) { write_size = chunk_size - chunk_offset; } else { write_size = count - bytes_written; } // Send the write to the node // ADD FD HERE printf ("\tprocessing chunk %d (sending to node %d)\n", chunk_id, node_id); if (is_node_up(node_id)) { printf("%d is up :)", node_id); write_result = process_write_chunk (request_id, 0, file_id, node_id, stripe_id, chunk_id, chunk_offset, (uint8_t *)buf + bytes_written, write_size); printf ("\t\treceived %d from network call.\n", write_result); // If the write failed if (write_result == NODE_FAILURE) { WriteChunkResponse writeResponse(request_id, 0, file_id, stripe_id, chunk_id, chunk_offset, write_size); write_response_handler(&writeResponse); printf("The node write failed :("); // Set the node to "down" and try again set_node_down (node_id); } } else { printf ("%d is down :(\n", node_id); WriteChunkResponse writeResponse(request_id, 0, file_id, stripe_id, chunk_id, chunk_offset, write_size); write_response_handler(&writeResponse); // Create a todo WriteRequest void * temp = calloc(write_size, sizeof(uint8_t)); memcpy(temp, buf, write_size); WriteReq req = WriteReq{request_id, 0, file_id, node_id, stripe_id, chunk_id, chunk_offset, temp, write_size}; writeRequests.push_back(req); } //else { // Send the write to the replica node // ADD FD HERE printf ("\tprocessing chunk replica %d (sending to node %d)\n", chunk_id, replica_node_id); write_result = process_write_chunk (replica_request_id, 0, file_id, replica_node_id, stripe_id, chunk_id, chunk_offset, (uint8_t *)buf + bytes_written, write_size); // if the replica write failed if (write_result == NODE_FAILURE) { // Set the node to "down" set_node_down (replica_node_id); // Choose a different replica replica_node_id = put_replica (file_id, pathname, stripe_id, chunk_id); // Re-write the data process_write_chunk (replica_request_id, 0, file_id, replica_node_id, stripe_id, chunk_id, chunk_offset, (uint8_t *)buf + bytes_written, write_size); } // update counters chunk_offset = 0; bytes_written += write_size; chunk_id++; (*chunks_written)++; (*replica_chunks_written)++; } //} }