uint64_t log_and_send_append_entries(struct server_context_t *s, uint64_t req_id, unsigned char *buf, size_t bufsize) { DBG_LOG(LOG_DEBUG, "[%s][%d] logging request for client with req_id = %llu" , ss[s->state], s->current_term, req_id); assert(s->state == LEADER); struct log_entry_t *prev = get_last_entry(s->log); uint64_t cur_index = 1; if(prev) { cur_index = prev->index + 1; } //else this is first entry hence cur_index = 1 struct log_entry_t *cur = append_log_entry(s->log, s->current_term, cur_index, req_id, buf, bufsize); if(!cur) { return -1; } s->last_entry = cur; for(int i = 0; i < s->quoram_size - 1; i++) { send_append_entries(s, cur_index, i); } return cur_index; }
struct log_entry_t *append_log_entries(struct p_log *log, struct log_entry_t **entries, int nentries) { struct log_entry_t *last = NULL; for(int i = 0; i < nentries; i++) { //TODO: better implementation where log_entry_t are not reallocated last = append_log_entry(log, entries[i]->term, entries[i]->index, entries[i]->req_id, entries[i]->buffer, entries[i]->bufsize); if(!last) { return NULL; } } //for(int i = 0; i < nentries; i++) { // free(entries[i]); //} //free(entries); return last; }
int main(void) { struct p_log *l = init_log("/home/swapnil/tmp/test_searaft"); if(l) { #ifdef RUN_WRITE_TEST for(int i = 0; i < 100; i++) { if(!append_log_entry(l, 1, i+1, u_strdup("test"), 5)) { printf("failed: log writing failed for %d\n", i+1); return 1; } } #else struct log_entry_t *le = get_last_entry(l); if(le) { if(le->term == 1 && le->index == 100 && le->bufsize == 5) { if(!le->buffer || 0 != strcmp(le->buffer, "test")) { printf("failed: incorrect buffer in log entry\n"); } } else { printf("failed: incorrect log entry %d\n", le->index); } } else { printf("failed: cant read log entry\n"); } le = get_log_entry_at(l, 25); if(le) { if(le->term == 1 && le->index == 25 && le->bufsize == 5) { if(!le->buffer || 0 != strcmp(le->buffer, "test")) { printf("failed: incorrect buffer in log entry\n"); } } else { printf("failed: incorrect log entry\n"); } } else { printf("failed: cant read log entry at index\n"); } if(!append_log_entry(l, 1, 75, u_strdup("test"), 5)) { printf("failed: log writing failed for %d\n", 75); return 1; } struct log_entry_t **entries = (struct log_entry_t **)malloc(sizeof(struct log_entry_t *)*25); for(int i = 0; i < 25; i++) { entries[i] = (struct log_entry_t *)malloc(sizeof(struct log_entry_t)); entries[i]->term = 1; entries[i]->index = 76 + i; entries[i]->buffer = u_strdup("test"); entries[i]->bufsize = 5; } le = append_log_entries(l, entries, 25); if(le) { if(le->term == 1 && le->index == 100 && le->bufsize == 5) { if(!le->buffer || 0 != strcmp(le->buffer, "test")) { printf("failed: incorrect buffer in log entry\n"); } } else { printf("failed: incorrect log entry %d\n", le->index); } } else { printf("failed: cant read log entry at index\n"); } #endif deinit_log(l); } else { printf("failed: cant read log directory\n"); } return 0; }
int main(int argc, char **argv) { bool non_batch = false; bool batch = false; bool employee = false; bool guest = false; bool arrival = false; bool departure = false; int32_t timestamp = -1; const char *token = NULL; const char *name = NULL; int32_t room = -1; const char *filename = NULL; struct log_entry l; int opt; static const char *optstr = "T:K:E:G:ALR:B"; opterr = 0; while((opt = getopt(argc, argv, optstr)) != -1) { switch(opt) { case 'T': non_batch = true; if (!parse_num(optarg, ×tamp)) invalid(true); if (!validate_int_range(timestamp, TIMESTAMP_MIN, TIMESTAMP_MAX)) invalid(true); break; case 'K': non_batch = true; token = optarg; if (!validate_token(token)) invalid(true); break; case 'E': non_batch = true; if (guest) invalid(true); employee = true; name = optarg; if (!validate_name(name)) invalid(true); break; case 'G': non_batch = true; if (employee) invalid(true); guest = true; name = optarg; if (!validate_name(name)) invalid(true); break; case 'A': non_batch = true; if (departure) invalid(true); arrival = true; break; case 'L': non_batch = true; if (arrival) invalid(true); departure = true; break; case 'R': non_batch = true; if (!parse_num(optarg, &room)) invalid(true); if (!validate_int_range(room, ROOM_MIN, ROOM_MAX)) invalid(true); break; case 'B': if (non_batch) invalid(true); batch = true; break; default: invalid(true); break; } } if (optind >= argc) invalid(true); else filename = argv[optind]; if (filename && !validate_filename(filename)) invalid(true); if (batch && non_batch) invalid(true); if (batch) { batch_mode(filename); } else { int ret; if (!timestamp || !token || !(employee || guest) || !(arrival || departure)) invalid(true); if (employee && guest) invalid(true); l.timestamp = (uint32_t) timestamp; l.room = room; l.action = arrival ? ARRIVAL : DEPARTURE; l.type = guest ? GUEST : EMPLOYEE; l.name = strdup(name); ret = append_log_entry(&l, filename, token); free((void *)l.name); l.name = NULL; if (ret != CAPSTONE_EXIT_SUCCESS) { invalid(true); } } exit(CAPSTONE_EXIT_SUCCESS); }