/** * 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; }
/** * 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; }
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); }
/* 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); } }
/** * 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; }
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 */ }
/** * 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; }
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; }
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); }
/** * 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; } }