Esempio n. 1
0
extern "C" void write_response_handler (WriteChunkResponse *write_response) {
  printf ("~~~~~~~~~ Write Response id: %d", write_response->id);
  if (replace_request_exists(write_response->id)) {
    printf("(BARISTA) Processing replacement...\n");
    return;
  }

  assert (write_request_exists (write_response->id));

  struct write_request request = write_request_lookups[write_response->id];

  printf ("(BARISTA) Processing write response for file %d.\n",
             active_write_requests[request].info.file_id);

  // If this is a primary chunk response
  if (write_response->id == request.request_id) {
    active_write_requests[request].info.chunks_received++;
    active_write_requests[request].count += write_response->count;
  }
  // Replica response
  else {
    active_write_requests[request].replica_info.chunks_received++;
  }
  check_write_complete(write_response->id);
}
Esempio n. 2
0
extern "C" void write_file (int fd, const void *buf, size_t count, struct client client) {
  struct file_instance inst;
  struct decafs_file_stat stat;
  uint32_t stripe_id, num_chunks = 0, num_replica_chunks = 0;
  uint32_t chunks_written, replica_chunks_written;
  int file_offset, stripe_offset, bytes_written = 0, write_size = 0;
  uint32_t request_id = get_new_request_id();
  uint32_t replica_request_id = get_new_request_id();
  struct write_request request = {request_id, replica_request_id};

  assert (fd > 0);

  inst = get_file_info((uint32_t)fd);

  printf ("\n(BARISTA) Write request (%d bytes) from file %d\n",
             (int)count, (int)inst.file_id);

  // If the client does not have permission to write, return an error
  if (has_exclusive_lock (client, inst.file_id) <= 0) {
    if (send_write_result (client, 0, FILE_NOT_OPEN_FOR_WRITE) < 0) {
      printf ("\tWrite result could not reach client.\n");
    }
    return;
  }

  if (decafs_file_stat (inst.file_id, &stat, client) < 0) {
    if (send_write_result (client, 0, UNABLE_TO_STAT_FILE) < 0) {
      printf ("\tWrite result could not reach client.\n");
    }
    return;
  }

  if ((file_offset = get_file_cursor (fd)) < 0) {
    if (send_write_result (client, 0, FILE_NOT_OPEN_FOR_WRITE) < 0) {
      printf ("\tWrite result could not reach client.\n");
    }
    return;
  }

  // If we are requesting 0 bytes, return 0 bytes written
  if (count == 0) {
    if (send_write_result (client, 0, 0) < 0) {
      printf ("\tWrite result could not reach client.\n");
    }
    return;
  }

  // Save the request id
  write_request_lookups[request_id] = request;
  write_request_lookups[replica_request_id] = request;
  active_write_requests[request] = write_request_info (client, inst.file_id,
                                                       fd);

  // TODO: make some assertion about max write size here
  get_first_stripe (&stripe_id, &stripe_offset, stat.stripe_size, file_offset);

  while (bytes_written < (int)count) {
    if (count - bytes_written > stat.stripe_size - stripe_offset) {
      write_size = stat.stripe_size - stripe_offset;
    }
    else {
      write_size = count - bytes_written;
    }

    printf ("\t(request: (%d,%d)) sending stripe %d for processing (%d bytes)\n",
               request_id, replica_request_id, stripe_id, write_size);
    // TODO: add pathname here, get from persistent meta

    chunks_written = 0;
    replica_chunks_written = 0;

    process_write_stripe (request_id, replica_request_id,
                          &chunks_written, &replica_chunks_written,
                          inst.file_id, (char *)"", stripe_id,
                          stat.stripe_size, stat.chunk_size,
                          (uint8_t *)buf + bytes_written, stripe_offset,
                          write_size);

    num_chunks += chunks_written;
    num_replica_chunks += replica_chunks_written;

    // TODO (?): Move the file size update and cursor to check_write_complete()
    update_file_size (inst.file_id, write_size, client);
    set_file_cursor (fd, get_file_cursor (fd) + write_size, client);
    stripe_offset = 0;
    bytes_written += write_size;
    ++stripe_id;
  }
  assert (write_request_exists (request_id));
  active_write_requests[request].info.chunks_expected = num_chunks;
  active_write_requests[request].replica_info.chunks_expected =
                                              num_replica_chunks;
  check_write_complete(request_id);
}
Esempio n. 3
0
File: rcv.c Progetto: Ezran/cs437
int main(int argc, char* argv[])
{
	int 			active, w, write_complete, loss, sr, ss, target_num, num, received_len, from_ip, last_ack, timeout_limit;
	char* 			target_name;
	struct sockaddr_in 	my_addr, received_addr;
	fd_set			mask, reset_mask;
	struct timeval		timeout;
	FILE*			fp;
	data_packet*		received;
	ack_packet*		ret;

	received_len = sizeof(received_addr);	
	write_complete = 0;
	active = 0;

	if (argc < 2){
		printf("Useage: server <loss>\n");
		exit(0);
	}
	loss = atoi(argv[1]);

	sr = socket(AF_INET, SOCK_DGRAM, 0);
	if (sr < 0){
		printf("SR Error\n");
		exit(1);
	}

	my_addr.sin_family = AF_INET;
	my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	my_addr.sin_port = htons(PORT);

	if ( bind(sr, (struct sockaddr*)&my_addr, sizeof(my_addr)) < 0){
		printf("SR Bind error\n");
		exit(1);
	}	
	
	ss = socket(AF_INET, SOCK_DGRAM, 0);
	if (ss < 0){
		printf("SS error\n");
		exit(1);
	}

	printf("sockets initialized.\n");

	fp = fopen("received", "w");
	last_ack = -1;

	ret = malloc(sizeof(ack_packet));  //for ack response
	if (ret == NULL){
		printf("malloc error\n");
		exit(1);
	}

	FD_ZERO( &reset_mask);
	FD_SET( sr, &reset_mask);

	sendto_dbg_init(loss);
	timeout.tv_sec = 0;
	timeout.tv_usec = 1000;
	for(;;) {
		mask = reset_mask;
		num = select( FD_SETSIZE, &mask, NULL, NULL, &timeout);
		if (num > 0 && FD_ISSET(sr, &mask)) { //we receive a packet from client 
			timeout_limit = 0;
			active = 1;
			received = malloc(sizeof(data_packet));	
			recvfrom(sr, (char*)received, sizeof(data_packet), 0, (struct sockaddr*)&received_addr , &received_len);
			received_addr.sin_port = htons(PORT);			
			
			if (received->index == last_ack+1){ //next chunck, write direct to file
				check_write_complete(fwrite(received->payload, 1, received->payload_len, fp), received, fp);
				last_ack++;
			}  
			else if (received->index > last_ack+1) //chunk out of order, store in queue
				push(received);
			while(get_size() > 0 && peek()->index == last_ack+1) {  //try to empty the queue
				data_packet * tmp = pop();
				check_write_complete(fwrite(tmp->payload, 1, tmp->payload_len, fp), received, fp);
				last_ack++;
			}	
			ret->index = last_ack;  //send ack
			sendto_dbg(ss, (char*)ret, sizeof(ret), 0, (struct sockaddr*)&received_addr, sizeof(received_addr));
		} 
		else {
			if (active == 1) 
				sendto_dbg(ss, (char*)ret, sizeof(ret), 0, (struct sockaddr*)&received_addr, sizeof(received_addr));
		}
	}
}