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; }
int main(int argc, char **argv) { char * target_file_path; char target_file_name[256]; unsigned int tpath_index, tfile_index; struct ext2_inode parent, target; if(argc != 3) { fprintf(stderr, "Usage: ext2_rm <image file name> <target path>\n"); exit(1); } if (ext2_init(argv[1]) == -1){ exit(1); } // check target path if(!check_file_path(argv[2]) ) { printf("invaid abs path\n"); return ENOENT; } // get target file path and name target_file_path = malloc(strlen(argv[2])); get_last_entry(argv[2],target_file_name, target_file_path); // check if it is vaild target file name if (! strlen(target_file_name)){ printf("invaid target file name\n"); return ENOENT; } if (is_dir(argv[2])){ printf("invaid target file name\n"); return ENOENT; } // get inode index for source file and target file tfile_index = get_inode_index(argv[2]); tpath_index = get_inode_index(target_file_path); free(target_file_path); // check if source path and target path vaild if(!tpath_index){ printf("No such file or directory\n"); return ENOENT; } // check if the target is the file if(tfile_index){ if(! (get_inode(tfile_index)->i_mode & EXT2_S_IFREG)){ printf("%s not a file\n", target_file_name); return ENOENT; } } remove_inode(get_inode(tpath_index), get_inode(tfile_index), tfile_index); return 0; }
void retornar(t_valor_variable retorno) { if(status_check() != EXECUTING) return; //1) Obtengo el stack index t_stack * actual_stack_index = actual_pcb->stack_index; //2) Obtengo la entrada actual t_stack_entry *last_entry = get_last_entry(actual_stack_index); //3) Actualizo el PC a la posicion de retorno de la entrada actual actual_pcb->program_counter = last_entry->ret_pos; //4) Asigno el valor de retorno de la entrada actual a la variable de retorno asignar(obtener_t_posicion(last_entry->ret_vars), retorno); //5) Libero la ultima entrada del indice de stack free(pop_stack(actual_stack_index)); }
t_posicion obtenerPosicionVariable(t_nombre_variable variable) { if(status_check() != EXECUTING) return ERROR; logical_addr * direccion_logica = NULL; int i = 0; //1) Obtener el stack index actual t_stack_entry* current_stack_index = get_last_entry(actual_pcb->stack_index); //2) Obtener puntero a las variables t_var* indice_variable = current_stack_index->vars; for (i = 0; i < current_stack_index->cant_vars ; i++) { if( (indice_variable + i)->var_id == variable ) { return get_t_posicion(indice_variable + i); // (t_posicion) (indice_variable->page_number * setup->PAGE_SIZE) + indice_variable->offset; } } return ERROR; }
void llamarConRetorno(t_nombre_etiqueta etiqueta, t_puntero donde_retornar) { if(status_check() != EXECUTING) return; t_ret_var * ret_var_addr = calloc(1, sizeof(t_ret_var)); //1) Obtengo la direccion a donde apunta la variable de retorno ret_var_addr = armar_direccion_logica_variable(donde_retornar, setup->PAGE_SIZE); t_stack_entry * actual_stack_entry = get_last_entry(actual_pcb->stack_index); //2) Creo la nueva entrada del stack t_stack_entry* new_stack_entry = create_new_stack_entry(); //3) Guardo la posicion de PC actual como retpos de la nueva entrada new_stack_entry->pos = actual_stack_entry->pos + 1; new_stack_entry->ret_pos = actual_pcb->program_counter; //4) Agrego la retvar a la entrada add_ret_var(&new_stack_entry, ret_var_addr); //5) Agrego la strack entry a la queue de stack queue_push(actual_pcb->stack_index, new_stack_entry); // (t_stack_entry*) list_get(actual_pcb->stack_index->elements, 1) //6) Asigno el PC a la etiqueta objetivo irAlLabel(etiqueta); }
int get_pcb() { //Pido por kernel process data actual_kernel_data = calloc(1, sizeof(t_kernel_data)); log_info(cpu_log, "Waiting for kernel PCB and Quantum data"); if (recibir_pcb(kernelSocketClient, actual_kernel_data) <= 0) { log_error(cpu_log, "Error receiving PCB and Quantum data from KERNEL"); return ERROR; } //Deserializo el PCB que recibo actual_pcb = (t_pcb *) calloc(1,sizeof(t_pcb)); int last_buffer_index = 0; deserialize_pcb(&actual_pcb, actual_kernel_data->serialized_pcb, &last_buffer_index); //Inicializo si tengo que if (get_last_entry(actual_pcb->stack_index)== NULL) { actual_pcb->stack_index = queue_create(); t_stack_entry * first_empty_entry = calloc(1, sizeof(t_stack_entry)); queue_push(actual_pcb->stack_index, first_empty_entry); } status_update(EXECUTING); return SUCCESS; }
struct server_context_t *init_raft_server(int id, const char *basedir, const char *host, int port, enum rpc_proto proto, long election_timeout, long heartbeat_timeout) { struct server_context_t *s = (struct server_context_t *)malloc( sizeof(struct server_context_t)); if(!s) { return NULL; } s->host = u_strdup(host); s->port = port; s->id = id; s->state = FOLLOWER; s->current_term = 0; s->commit_index = 0; s->commit_term = 0; s->log_last_applied = 0; s->quoram_size = 1; //TODO: read from config file s->current_votes = 0; s->basedir = u_strdup(basedir); char *logdir = path_join(basedir, RAFT_LOGDIR); s->log = init_log(logdir); if(!s->log) { deinit_raft_server(s); free(logdir); return NULL; } free(logdir); s->last_entry = get_last_entry(s->log); load_state(s); s->next_index = 0; s->match_index = 0; s->stm = init_stm(s); s->base = event_base_new(); if(!s->base) { //LOG:FATAL event loop init failed deinit_raft_server(s); return NULL; } s->timer_el = event_new(s->base, -1, EV_PERSIST, election_timeout_callback, s); s->timer_hb = event_new(s->base, -1, EV_PERSIST, heartbeat_timeout_callback, s); s->election_timeout_ = election_timeout; s->election_timeout = time_in_timeval(election_timeout); s->heartbeat_timeout_ = heartbeat_timeout; s->heartbeat_timeout = time_in_timeval(heartbeat_timeout); if(!s->timer_el || !s->timer_hb || !s->election_timeout || !s->heartbeat_timeout) { //LOG:FATAL timer creation failed deinit_raft_server(s); return NULL; } s->last_heartbeat_at = 0; //initially just add election timer and add heartbeat timer later //when this server elected as the leader if(event_add(s->timer_el, s->election_timeout)) { //LOG:FATAL timer event registration failed deinit_raft_server(s); return NULL; } s->rpc_s = init_rpc(s->base); s->rpc_c = init_rpc(s->base); if(!s->rpc_s || !s->rpc_c) { //LOG:FATAL RPC init failed deinit_raft_server(s); return NULL; } struct rpc_target *listen_dest = (struct rpc_target *) malloc(sizeof(struct rpc_target)); if(!listen_dest) { deinit_raft_server(s); return NULL; } listen_dest->proto = HTTP; listen_dest->host = s->host; listen_dest->port = s->port; int res = 0; res |= init_rpc_server(s->rpc_s, listen_dest); res |= init_rpc_client(s->rpc_c); if(res) { //LOG:FATAL rpc server init failed deinit_raft_server(s); return NULL; } free(listen_dest); res = 0; res |= rpc_register(s->rpc_s, APPEND_ENTRIES_RPC, handle_append_entries, s); res |= rpc_register(s->rpc_s, REQUEST_VOTE_RPC, handle_request_vote, s); if(res) { //LOG:FATAL method registration failed deinit_raft_server(s); return NULL; } s->current_leader = -1; return s; }
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; }
t_posicion definirVariable(t_nombre_variable variable) { if(status_check() != EXECUTING) return ERROR; //1) Obtener el stack index actual t_stack* actual_stack_index = actual_pcb->stack_index; //2) Obtengo la primera posicion libre del stack t_posicion actual_stack_pointer = (t_posicion) actual_pcb->stack_pointer; //3) Armamos la logical address requerida logical_addr* direccion_espectante = armar_direccion_logica_variable(actual_stack_pointer, setup->PAGE_SIZE); int valor = 0; t_list * pedidos = NULL; //TODO: CAMBIAR ESTO PARA QUE LA LISTA DE PEDIDOS SEA DE NUMEROS, NO DE SPRINTF obtener_lista_operaciones_escritura(&pedidos, actual_stack_pointer, ANSISOP_VAR_SIZE, valor); int index = 0; t_nodo_send * nodo = NULL; char * umc_response_buffer = calloc(1, sizeof(char)); if(umc_response_buffer == NULL) { log_error(cpu_log, "definirVariable umc_response_buffer mem alloc failed"); return ERROR; } char operation; int page, offset, size, print_index = 0; while (list_size(pedidos) > 0) { nodo = list_remove(pedidos, index); deserialize_data(&operation, sizeof(char), nodo->data, &print_index); deserialize_data(&page, sizeof(int), nodo->data, &print_index); deserialize_data(&offset, sizeof(int), nodo->data, &print_index); deserialize_data(&size, sizeof(int), nodo->data, &print_index); log_info(cpu_log, "Sending request op:%c (%d,%d,%d) to define variable '%c' with value %d", operation, page, offset, size, variable, valor); if( send(umcSocketClient, nodo->data , (size_t ) nodo->data_length, 0) < 0) { log_error(cpu_log, "UMC expected addr send failed"); return ERROR; } if(check_umc_response(recv_umc_response_status()) != SUCCESS) { return ERROR; } } list_destroy(pedidos); //Liberamos la estructura de lista reservada free(umc_response_buffer); //5) Si esta bien, agregamos la nueva t_var al stack t_var * nueva_variable = calloc(1, sizeof(t_var)); nueva_variable->var_id = variable; nueva_variable->page_number = direccion_espectante->page_number; nueva_variable->offset = direccion_espectante->offset; nueva_variable->tamanio = direccion_espectante->tamanio; //6) Actualizo el stack pointer actual_pcb->stack_pointer += nueva_variable->tamanio; free(direccion_espectante); t_stack_entry *last_entry = get_last_entry(actual_stack_index); add_var( &last_entry, nueva_variable); //7) y retornamos la t_posicion asociada t_posicion posicion_nueva_variable = get_t_posicion(nueva_variable); return posicion_nueva_variable; }