示例#1
0
/**
 * paxos_retrieve - Ask the originator of request data to send us data which
 * we do not have in our cache.
 *
 * We call this function when and only when we are issued a commit for an
 * instance whose associated request is not in our request cache.
 */
int
paxos_retrieve(struct paxos_instance *inst)
{
  int r;
  struct paxos_header hdr;
  struct paxos_acceptor *acc;
  struct paxos_yak py;

  // Initialize a header.  We set ph_inum to the instance number of the
  // request.
  header_init(&hdr, OP_RETRIEVE, inst->pi_hdr.ph_inum);

  // Pack the retrieve.
  paxos_payload_init(&py, 2);
  paxos_header_pack(&py, &hdr);
  paxos_payload_begin_array(&py, 2);
  paxos_paxid_pack(&py, pax->self_id);
  paxos_value_pack(&py, &inst->pi_val);

  // Determine the request originator and send.  If we are no longer connected
  // to the request originator, broadcast the retrieve instead.
  acc = acceptor_find(&pax->alist, inst->pi_val.pv_reqid.id);
  if (acc == NULL || acc->pa_peer == NULL) {
    r = paxos_broadcast(&py);
  } else {
    r = paxos_send(acc, &py);
  }
  paxos_payload_destroy(&py);

  return r;
}
示例#2
0
/**
 * acceptor_redirect - Tell a preparer that they are not the proposer and
 * thus do not have the right to prepare.
 */
int
acceptor_redirect(struct paxos_peer *source, struct paxos_header *orig_hdr)
{
  int r;
  struct paxos_header hdr;
  struct yakyak yy;

  // Initialize a header.  Our recipients should use ph_inum rather than the
  // ballot ID as the ID of the proposer we are suggesting, since, it may be
  // the case that the proposer has assumed the proposership but has not yet
  // prepared to us.
  header_init(&hdr, OP_REDIRECT, pax->proposer->pa_paxid);

  // Pack a payload, which includes the header we were sent which we believe
  // to be incorrect.
  yakyak_init(&yy, 2);
  paxos_header_pack(&yy, &hdr);
  paxos_header_pack(&yy, orig_hdr);

  // Send the payload.
  r = paxos_peer_send(source, yakyak_data(&yy), yakyak_size(&yy));
  yakyak_destroy(&yy);

  return r;
}
示例#3
0
文件: List.c 项目: bowlofstew/Cello
static var List_Alloc(struct List* l) {
    var item = calloc(1, 2 * sizeof(var) + sizeof(struct Header) + l->tsize);

#if CELLO_MEMORY_CHECK == 1
    if (item is NULL) {
        throw(OutOfMemoryError, "Cannot allocate List entry, out of memory!");
    }
#endif

    return header_init((struct Header*)(
                           (char*)item + 2 * sizeof(var)), l->type, AllocData);
}
示例#4
0
/* callbacks */
void stdin_cb(evutil_socket_t sock, short ev, void *arg) {
	UNUSED(ev);
	UNUSED(arg);

	static ssize_t len = 0, r = 0;

	struct proto_packet *packet = sendbuff_back(&packets);
	struct proto_header *header = &packet->header;

	TRY_SYS(r = read(sock, packet->data + len, psize - len));
	if (r) {
		len += r;
		if (len == psize) {
			/* packet is full, init */
			header_init(header, last_seqno++, len, PROTO_DATA);
			ASSERT(psize + (int) sizeof(struct proto_header) == packets.hpsize);
			ASSERT(packets.hpsize == (int) packet_length(packet));
			/* send */
			EXPECT(write(mcast_sock, packet, packets.hpsize) == packets.hpsize,
					"Sending streming data failed.");
			/* start new packet */
			len = 0;
			sendbuff_next(&packets);
		}
	} else {
		if (len) {
			/* end of input, init packet as is */
			header_init(header, last_seqno++, len, PROTO_DATA);
			/* send */
			ASSERT(len + sizeof(struct proto_header));
			len = packet_length(packet);
			EXPECT(write(mcast_sock, packet, len) == len,
					"Sending streaming data failed.");
			/* everything sent */
			len = 0;
		}
		/* end of input file, exit */
		event_base_loopexit(base, NULL);
	}
}
示例#5
0
/**
 * proposer_sync - Send a sync command to all acceptors.
 *
 * For a sync to succeed, all acceptors need to tell us the instance number
 * of their last contiguous learn.  We take the minimum of these values
 * and then command everyone to truncate everything before this minimum.
 */
int
proposer_sync()
{
  int r;
  struct paxos_header hdr;
  struct yakyak yy;

  // If we haven't finished preparing as the proposer, don't sync.
  if (pax->prep != NULL) {
    return 1;
  }

  // If not everyone is live, we should delay syncing.
  if (pax->live_count != LIST_COUNT(&pax->alist)) {
    return 1;
  }

  // If our local last contiguous learn is the same as the previous sync
  // point, we don't need to sync.
  if (pax->ihole - 1 == pax->sync_prev) {
    return 0;
  }

  // If we're already syncing, increment the skip counter.
  if (pax->sync != NULL) {
    // Resync if we've waited too long for the sync to finish.
    if (++pax->sync->ps_skips < SYNC_SKIP_THRESH) {
      return 1;
    } else {
      g_free(pax->sync);
    }
  }

  // Create a new sync.
  pax->sync = g_malloc0(sizeof(*(pax->sync)));
  pax->sync->ps_total = LIST_COUNT(&pax->alist);
  pax->sync->ps_acks = 1;  // Including ourselves.
  pax->sync->ps_skips = 0;
  pax->sync->ps_last = 0;

  // Initialize a header.
  header_init(&hdr, OP_SYNC, ++pax->sync_id);

  // Pack and broadcast the sync.
  yakyak_init(&yy, 1);
  paxos_header_pack(&yy, &hdr);
  r = paxos_broadcast(&yy);
  yakyak_destroy(&yy);

  return r;
}
示例#6
0
void ctrl_cb(evutil_socket_t sock, short ev, void *arg) {
	UNUSED(ev);
	UNUSED(arg);

	struct proto_header header;
	ssize_t r;
	struct sockaddr_in addr;
	socklen_t addr_len = sizeof(addr);

	TRY_SYS(r = recvfrom(sock, &header, sizeof(header), 0,
				(struct sockaddr *) &addr, &addr_len));
	if (validate_packet((struct proto_packet *) &header, r) && header_isempty(&header)) {
		if (header_flag_isset(&header, PROTO_RETQUERY)) {
			/* mark packet in buffer with PROTO_DORETR flag */
			seqno_t ask_seqno = header_seqno(&header);
			struct proto_packet *pack = sendbuff_getseqno(&packets, ask_seqno);

			if (pack) {
				header_flag_set(&pack->header, PROTO_DORETR);
			} else {
				/* invalid retransmission request - response directly to requester */
				header_init(&pack_ret_failed.header, ask_seqno, 0, PROTO_FAIL);

				EXPECT(sendto(ctrl_sock, &pack_ret_failed, sizeof(pack_ret_failed), 0,
							(struct sockaddr *) &addr, addr_len) == sizeof(pack_ret_failed),
						"Sending invalid retransmission response failed.");
			}
		}
		/* whatever we've done addr is still valid */
		if (header_flag_isset(&header, PROTO_IDQUERY)) {
			EXPECT(sendto(sock, &pack_my_ident, sizeof(pack_my_ident), 0, (struct sockaddr *)
						&addr, addr_len) == sizeof(pack_my_ident),
					"Sending id response failed.");
		}
	}
	/* else: ignore packet */
}
示例#7
0
/**
 * continue_ack_refuse - If we were able to reestablish connection with the
 * purported proposer, reset our proposer and reintroduce ourselves.
 */
int
do_continue_ack_refuse(GIOChannel *chan, struct paxos_acceptor *acc,
    struct paxos_continuation *k)
{
  int r = 0;
  struct paxos_header hdr;
  struct paxos_request *req;
  struct yakyak yy;

  // If we are the proposer and have finished preparing, anyone higher-ranked
  // than we are is dead to us.  However, their parts may not yet have gone
  // through, so we make sure to ignore attempts at reconnection.
  if (is_proposer() && pax->prep == NULL) {
    return 0;
  }

  // Register the reconnection.
  acc->pa_peer = paxos_peer_init(chan);
  if (acc->pa_peer != NULL) {
    // Account for a new acceptor.
    pax->live_count++;

    // Free any prep we have.  Although we dispatch as an acceptor when we
    // acknowledge a refuse, when the acknowledgement continues here, we may
    // have become the proposer.  Thus, if we are preparing, we should just
    // give up.  If the acceptor we are reconnecting to fails, we'll find
    // out about the drop and then reprepare.
    g_free(pax->prep);
    pax->prep = NULL;
    instance_container_destroy(&pax->idefer);

    // Say hello.
    ERR_ACCUM(r, paxos_hello(acc));

    if (acc->pa_paxid < pax->proposer->pa_paxid) {
      // Update the proposer only if we have not reconnected to an even
      // higher-ranked acceptor.
      pax->proposer = acc;

      // Resend our request.
      // XXX: What about the problematic case where A is connected to B, B
      // thinks it's the proposer and accepts A's request, but in fact B is not
      // the proposer and C, the real proposer, gets neither of their requests?
      header_init(&hdr, OP_REQUEST, pax->proposer->pa_paxid);

      req = request_find(&pax->rcache, k->pk_data.req.pr_val.pv_reqid);
      if (req == NULL) {
        req = &k->pk_data.req;
      }

      yakyak_init(&yy, 2);
      paxos_header_pack(&yy, &hdr);
      paxos_request_pack(&yy, req);

      ERR_ACCUM(r, paxos_send_to_proposer(&yy));
      yakyak_destroy(&yy);
    }
  }

  return r;
}
示例#8
0
static int packageSourceFolder(char **source, char *desintation, char *extensions[], int extCount)
{
  FTS *ftsp;
  FTSENT *p, *chp;
  int fts_options = FTS_COMFOLLOW | FTS_LOGICAL | FTS_NOCHDIR;
  int rval = 0; // remove if unused!
  char line[512];
  FILE *pakFile;
  FILE *file;
  unsigned int start_offset= 0;
  unsigned int f_index=0; // file index

  if (file = fopen(desintation, "r"))
    {
      printf("File exists, would you like to overwrite it y/n ?  ");

      int answer;
      int loop=1;
      fclose(file);

      while (loop){

        answer = getchar();

        switch(answer){
        case 'y':
          loop=0;
          break;
        case 'n':
          printf("Please run Bundle again with the correct output path.\n");
          exit(1);
        case 10: // \n
          break;
        default:
          printf("not sure ? ;) \n (y/n) >");
        }
      }
    }else {
    fclose(file);
  }


  pakFile = fopen(desintation,"wb+");

  printf("\n----------------\n");

  // initialize header with nuber of files
  if ((start_offset=header_init(pakFile, fileCountForHeader)) == -1){
    // perror("bundler_header");
    fprintf(stderr, "Cannot initialize header...exiting\n");
    return 0;
  }

  size_t header_size = fileCountForHeader* HEADER_OFFSET_SIZE + sizeof(int);

  if ((ftsp = fts_open(source, fts_options, NULL)) == NULL) {
    warn("fts_open");
    return -1;
  }

  /* Initialize ftsp with as many argv[] parts as possible. */
  chp = fts_children(ftsp, 0);
  if (chp == NULL) {
    return 0;               /* no files to traverse */
  }

  printf("\nCreating the Bundle\n\n");

  while ((p = fts_read(ftsp)) != NULL)
    {
      int tempFileExists = 0; //used to flag temp file for deletion
      switch (p->fts_info)
        {
        case FTS_D:
          printf(">dir: %s\n\n", p->fts_path);
          printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n\n");
          printData(pakFile, p->fts_path);
          break;
        case FTS_F:
          if((strstr(p->fts_path, ".DS_Store") != NULL)//ignore DS_Store and exe
             || (strstr(p->fts_path, ".exe") != NULL))
            {
              printf("Found file to ignore: %s\n", p->fts_path);
              printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n\n");
            }
          else
            {
              printf("\t>file: %s\n", p->fts_path);
              printData(pakFile, p->fts_path);

              FILE *tempFile;

              if(shouldCompressFileType(p->fts_path, extensions, extCount) == 1)
                {
                  /*    compress the fts_path file and write
                        the compressed data one to pak file
                  */
                  compress_one_file(p->fts_path, "temp.txt");
                  tempFile = fopen("temp.txt","rb");
                  tempFileExists = 1;
                }
              else
                {
                  tempFile = fopen(p->fts_path,"rb");
                }
              char byte;

              fseek(pakFile, 0L, SEEK_END);
              off_t offset = ftell(pakFile);

              //get the size of the file
              fseek(tempFile, 0L, SEEK_END);
              long size = ftell(tempFile);
              fseek(tempFile, 0L, SEEK_SET);
              offset= offset;//-HEADER_OFFSET_SIZE;
              char *fileName = p->fts_path;
              char *tempFileName = strdup(fileName);

              //update header
              //offset_p off= malloc(HEADER_OFFSET_SIZE);

              header_offset off;
              off.hash = __ac_X31_hash_string( filename(fileName) );
              off.size= size;
              off.offset_start= offset;

              header_write_offset(pakFile, &off, f_index++);

              // print the file info
              if(tempFileName)
                {
                  printf("\t>The offset for %s is %d\n", tempFileName, (unsigned int)offset);
                  printf("\t>The written size of %s is %lu\n", basename(tempFileName), size);
                  printf("\t>%s was added to the bundle\n\n", basename(tempFileName));
                  printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n\n");
                  free(tempFileName);
                }

              // copy the data from the temp compressed file to the pak file
              //                    fseek(pakFile, start_offset, SEEK_SET);
              //fseek(pakFile, 0L, SEEK_SET);
              fseek(pakFile, 0L, SEEK_END);

              int d= 0;
              while (!feof(tempFile))
                {

                  fread(&byte, sizeof(char), 1, tempFile);
                  fwrite(&byte, sizeof(char), 1, pakFile);
                }

              fclose(tempFile); // done!

              //delete the temporary file
              if(tempFileExists == 1)
                {
                  if (remove("temp.txt") == -1)
                    perror("Error in deleting temp file");
                }
              break;
            }
        default:
          break;
        }
    }
  fclose(pakFile);
  fts_close(ftsp);
  return 0;
}
示例#9
0
文件: Array.c 项目: 08opt/CPlus
static void Array_Alloc(struct Array* a, size_t i) {
  memset((char*)a->data + Array_Step(a) * i, 0, Array_Step(a));
  struct Header* head = (struct Header*)((char*)a->data + Array_Step(a) * i);
  header_init(head, a->type, AllocData);
}
示例#10
0
/**
 * paxos_request - Request that the proposer make a decree for us.
 *
 * If the request has data attached to it, we broadcast an out-of-band message
 * to all acceptors, asking that they cache our message until the proposer
 * commits it.
 *
 * We send the request as a header along with a two-object array consisting
 * of a paxos_value (itself an array) and a msgpack raw (i.e., a data
 * string).
 */
int
paxos_request(struct paxos_session *session, dkind_t dkind, const void *msg,
    size_t len)
{
  int r, needs_cached;
  struct paxos_header hdr;
  struct paxos_request *req;
  struct paxos_yak py;

  // Set the session.  The client should pass us a pointer to the correct
  // session object which we returned when the session was created.
  pax = session;

  // We can't make requests if we're not part of a protocol.
  if (pax == NULL) {
    return 1;
  }

  // Do we need to cache this request?
  needs_cached = request_needs_cached(dkind);

  // Initialize a header.  We overload ph_inum to the ID of the acceptor who
  // we believe to be the proposer.
  header_init(&hdr, OP_REQUEST, pax->proposer->pa_paxid);

  // Allocate a request and initialize it.
  req = g_malloc0(sizeof(*req));
  req->pr_val.pv_dkind = dkind;
  req->pr_val.pv_reqid.id = pax->self_id;
  req->pr_val.pv_reqid.gen = (++pax->req_id);  // Increment our req_id.
  req->pr_val.pv_extra = 0; // Always 0 for requests.

  req->pr_size = len;
  req->pr_data = g_memdup(msg, len);

  // Add it to the request cache if needed.
  if (needs_cached) {
    request_insert(&pax->rcache, req);
  }

  if (!is_proposer() || needs_cached) {
    // We need to send iff either we are not the proposer or the request
    // has nontrivial data.
    paxos_payload_init(&py, 2);
    paxos_header_pack(&py, &hdr);
    paxos_request_pack(&py, req);

    // Broadcast only if it needs caching.
    if (!needs_cached) {
      r = paxos_send_to_proposer(&py);
    } else {
      r = paxos_broadcast(&py);
    }

    paxos_payload_destroy(&py);
    if (r) {
      return r;
    }
  }

  // Decree the request if we're the proposer; otherwise just return.
  if (is_proposer()) {
    return proposer_decree_request(req);
  } else {
    return 0;
  }
}