Пример #1
0
uint32_t IO_Manager::process_delete_file (uint32_t request_id, uint32_t file_id) {
  std::vector<struct file_chunk> chunks = get_all_chunks (file_id); 
  uint32_t num_chunks = 0;

  for (std::vector<struct file_chunk>::iterator it = chunks.begin();
       it != chunks.end(); it++) {
    if (chunk_exists (*it)) {
      int chunk_node = get_node_id (file_id, (*it).stripe_id, (*it).chunk_num);
      if (is_node_up (chunk_node)) {
        process_delete_chunk (request_id, file_id, chunk_node, (*it).stripe_id, (*it).chunk_num);
        chunk_to_node.erase (*it);
        num_chunks++;
      }
    }
    if (chunk_replica_exists (*it)) {
      int chunk_node = get_replica_node_id (file_id, (*it).stripe_id,
                                            (*it).chunk_num);
      if (is_node_up (chunk_node)) {
        process_delete_chunk (request_id, file_id, chunk_node, (*it).stripe_id, (*it).chunk_num);
        chunk_to_replica_node.erase (*it);
        num_chunks++;
      }
    }
  }
  return num_chunks;
}
Пример #2
0
int IO_Manager::get_node_id (uint32_t file_id, uint32_t stripe_id,
                             uint32_t chunk_num) {
  struct file_chunk chunk = {file_id, stripe_id, chunk_num};
  if (chunk_exists (chunk)) {
    return chunk_to_node[chunk];
  }
  return CHUNK_NOT_FOUND;
}
Пример #3
0
char * IO_Manager::process_file_storage_stat (struct decafs_file_stat file_info) {
  stringstream storage_info;
  std::vector<struct file_chunk> chunks = get_all_chunks (file_info.file_id); 
  int last_stripe = -1;
  bool first_stripe = true;

  // Print basic file information
  storage_info << "{\n  \"file_id\": ";
  storage_info << file_info.file_id;
  storage_info << "\n  \"stripe_size\": ";
  storage_info << file_info.stripe_size;
  storage_info << "\n  \"chunk_size\": ";
  storage_info << file_info.chunk_size;
  storage_info << "\n  \"stripes\": [";

  for (std::vector<struct file_chunk>::iterator it = chunks.begin();
       it != chunks.end(); it++) {
    if (chunk_exists (*it)) {
      if ((int)(*it).stripe_id > last_stripe) {
        last_stripe = (*it).stripe_id;
        if (first_stripe) {
          first_stripe = false;
        }
        else {
          storage_info << "\n      ]\n    }";
        }
        storage_info << "\n    {\n      \"stripe_id\": ";
        storage_info << last_stripe;
        storage_info << "\n      \"chunks\": [";
      }
      storage_info << "\n        {";
      storage_info << "\n          \"chunk_num\": ";
      storage_info << (*it).chunk_num;
      storage_info << "\n          \"node\": ";
      storage_info << chunk_to_node[*it];
      if (chunk_replica_exists (*it)) {
        storage_info << "\n          \"replica_node\": ";
        storage_info << chunk_to_replica_node[*it];
      }
      storage_info << "\n        }";
    }
  }

  // end json
  if (!first_stripe) {
    storage_info << "\n      ]\n    }";
  }

  storage_info << "\n  ]\n}\n";

  return strdup(storage_info.str().c_str());
}
// TODO: improve, caching
void allocator_dealloc(allocator_t *allocator, void *p)
{
  pthread_mutex_lock(&allocator->lock);
  dllist_link *l = allocator->chunks.head;
  for (; l; l = l->next) {
    chunk_t *tmp = DLLIST_ELEMENT(l, chunk_t, link);
    if (chunk_exists(tmp, allocator->block_size, p)) {
      chunk_dealloc(tmp, p, allocator->block_size);
      break;
    }
  }
  pthread_mutex_unlock(&allocator->lock);
}
Пример #5
0
void render_tiny_region_map(image *img, const int32_t rpx, const int32_t rpy, region *reg,
		const options *opts)
{
	open_region_file(reg);
	if (reg == NULL || reg->file == NULL) return;

	uint8_t colour_on[CHANNELS] = {255, 255, 255, 255};
	uint8_t colour_off[CHANNELS] = {0, 0, 0, 255};

	for (uint8_t rcz = 0; rcz < REGION_CHUNK_LENGTH; rcz++)
	{
		for (uint8_t rcx = 0; rcx < REGION_CHUNK_LENGTH; rcx++)
		{
			// colour this pixel
			uint8_t *pixel = &img->data[((rpy + rcz) * img->width + rpx + rcx) * CHANNELS];
			uint8_t *colour = chunk_exists(reg, rcx, rcz, opts->rotate) ? colour_on : colour_off;
			memcpy(pixel, colour, CHANNELS);
		}
	}

	close_region_file(reg);
}
Пример #6
0
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);
    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) {
      // Set the node to "down" and try again
      set_node_down (node_id);
    }
    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)++;
    }
  }
}
Пример #7
0
uint32_t IO_Manager::process_read_stripe (uint32_t request_id, 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_read = 0, read_size = 0, num_chunks = 0;
  int chunk_offset, chunk_result, node_id;
  
  assert (((int)count - offset) <= (int)stripe_size);
  
  printf ("\n(BARISTA) Process Read Stripe\n");

  get_first_chunk (&chunk_id, chunk_size, &chunk_offset, offset);
  
  while (bytes_read < count) {
    struct file_chunk cur_chunk = {file_id, stripe_id, chunk_id};

    if (!chunk_exists (cur_chunk)) {
      // Current chunk does not exist. Report and error and stop the read.
      fprintf (stderr, "Could only read %d bytes (out of %d requested.\n",
                  (int)bytes_read, (int)count);
      break;
    }

    // The chunk exists, so set the node_id
    node_id = chunk_to_node[cur_chunk];

    // If the node isn't up, switch to the replica
    if (!is_node_up (node_id)) {
      assert (chunk_replica_exists (cur_chunk));
      node_id = chunk_to_replica_node[cur_chunk];
    }
   
    // Determine how much data to read from the current chunk
    if (count - bytes_read > chunk_size - chunk_offset) {
      read_size = chunk_size - chunk_offset;
    }
    else {
      read_size = count - bytes_read;
    }
    
    printf ("\tprocessing chunk %d (sending to node %d)\n", chunk_id, node_id);
    printf ("\t\toffset: %d, size: %d\n", chunk_offset, read_size);
    // Send the read to the node
                   // ADD FD HERE
    chunk_result = process_read_chunk (request_id, 0, file_id, node_id, stripe_id,
                                      chunk_id, chunk_offset, 
                                      (uint8_t *)buf + bytes_read,
                                      read_size);
    
    printf ("\t\treceived %d from network call.\n", chunk_result);
    // If the node cannot be read from
    if (chunk_result == NODE_FAILURE) {
      // Mark the node as "down"
      set_node_down (node_id);
    }
    // The read suceeded, so move on
    else {
      // update counters
      chunk_offset = 0;
      bytes_read += read_size;
      chunk_id++;
      num_chunks++;
    }
  }
  return num_chunks;
}