static int lock(const GPtrArray *distribution_array, const GPtrArray *target_array, gchar *profile) { unsigned int i; GPtrArray *try_array = g_ptr_array_new(); GPtrArray *lock_array = g_ptr_array_new(); int exit_status = 0; int status; /* For each machine acquire a lock */ for(i = 0; i < distribution_array->len; i++) { DistributionItem *item = g_ptr_array_index(distribution_array, i); Target *target = find_target(target_array, item->target); gchar *interface = find_target_client_interface(target); g_print("[target: %s]: Acquiring a lock\n", item->target); status = exec_lock(interface, item->target, profile); /* If a process fails, change the exit status */ if(status == -1) { g_printerr("[target: %s]: Error with forking lock process!\n", item->target); exit_status = -1; } else g_ptr_array_add(try_array, item); } /* Wait until every lock is acquired */ for(i = 0; i < try_array->len; i++) { status = wait_to_finish(0); /* If a process fails, change the exit status */ if(status != 0) { g_printerr("Failed to acquire a lock!\n"); exit_status = status; } else if(interrupted) { g_printerr("[coordinator]: The lock phase has been interrupted!\n"); exit_status = 1; } } /* If a lock fails then unlock every machine that is locked */ if(!exit_status) unlock(lock_array, target_array, profile); /* Cleanup */ g_ptr_array_free(try_array, TRUE); g_ptr_array_free(lock_array, TRUE); /* Return exit status, which is 0 if everything succeeds */ return exit_status; }
static pid_t lock_distribution_item(void *data, DistributionItem *item, Target *target) { LockData *lock_data = (LockData*)data; g_print("[target: %s]: Acquiring a lock on profile: %s\n", item->target, item->profile); return exec_lock((char*)target->client_interface, (char*)item->target, (char*)lock_data->profile); }
void do_command(const char *command_line) { skip_spaces(&command_line); char *command = parse_word(&command_line); if (command == NULL) return; skip_spaces(&command_line); int command_length = strlen(command); #define CMD_COND1(str) ( ( command_length == sizeof(str) - 1 && !strcmp(command, str) ) ) #define CMD_COND2(str) ( ( command_length == 1 && command[0] == str[0] ) || ( ( command_length == sizeof(str) - 1 ) && !strcmp(command, str) ) ) #define PARSE_ID(fail_label) int *id; id = parse_int(&command_line); \ if (!id) { printf("ID required\n"); goto fail_label; } \ if (*id < 0 || *id >= files_count) { printf("Invalid ID. Valid values are from %d to %d\n", 0, files_count); goto fail_label; } if (CMD_COND2("help")) { exec_help(); } else if (CMD_COND2("info")) { exec_info(); } // open ID mode else if (CMD_COND2("open")) { char *mode = NULL; PARSE_ID(open_cleanup) skip_spaces(&command_line); mode = parse_until_space(&command_line); if (!mode) { printf("MODE required\n"); goto open_cleanup; } exec_open(*id, mode); open_cleanup: if (id) free(id); if (mode) free(mode); goto cleanup; } else if (CMD_COND2("lock")) { char *operation = NULL; PARSE_ID(lock_cleanup) skip_spaces(&command_line); operation = parse_until_space(&command_line); if (!operation) { printf("Operation required\n"); goto lock_cleanup; } int op; if (!strcmp(operation, "shnb")) op = LOCK_SH | LOCK_NB; else if (!strcmp(operation, "sh")) op = LOCK_SH; else if (!strcmp(operation ,"exnb")) op = LOCK_EX | LOCK_NB; else if (!strcmp(operation, "ex")) op = LOCK_EX; else if (!strcmp(operation, "unnb")) op = LOCK_UN | LOCK_NB; else if (!strcmp(operation, "un")) op = LOCK_UN; else { printf("Invalid <operation>\n"); goto lock_cleanup; } exec_lock(*id, op); lock_cleanup: if (id) free(id); if (operation) free(operation); goto cleanup; } else if (CMD_COND2("close")) { PARSE_ID(close_cleaup) exec_close(*id); close_cleaup: if (id) free(id); goto cleanup; } else if (CMD_COND2("seek")) { int *offset = NULL; char *whence_str = NULL; PARSE_ID(seek_cleanup) skip_spaces(&command_line); int sign = 1; if (command_line[0] == '-') { sign = -1; command_line++; } offset = parse_int(&command_line); if (!offset) { printf("Invalid <offset>\n"); goto seek_cleanup; } *offset = *offset * sign; skip_spaces(&command_line); whence_str = parse_until_space(&command_line); if (!whence_str) { printf("Invalid <whence>. Valid values are: set, end, cur\n"); goto seek_cleanup; } int whence = 0; if (!strcmp(whence_str, "set")) { whence = SEEK_SET; } else if (!strcmp(whence_str, "end")) { whence = SEEK_END; } else if (!strcmp(whence_str, "cur")) { whence = SEEK_CUR; } exec_seek(*id, *offset, whence); seek_cleanup: if (id) free(id); if (offset) free(offset); if (whence_str) free(whence_str); goto cleanup; } else if (CMD_COND2("tell")) { PARSE_ID(tell_cleanup) skip_spaces(&command_line); exec_tell(*id); tell_cleanup: if (id) free(id); goto cleanup; } else if (CMD_COND2("write")) { printf("not implemented\n"); goto write_cleanup; write_cleanup: goto cleanup; } else if (CMD_COND2("read")) { int *length = NULL; PARSE_ID(read_cleanup); skip_spaces(&command_line); int hex = 0; if (command_line[0] == 'x') { hex = 1; command_line++; skip_spaces(&command_line); } length = parse_int(&command_line); if (!length) { printf("Invalid <length>\n"); goto read_cleanup; } exec_read(*id, *length, hex); read_cleanup: if (id) free(id); if (length) free(length); goto cleanup; } else if (CMD_COND1("truncate")) { int *length = NULL; PARSE_ID(truncate_cleanup) skip_spaces(&command_line); length = parse_int(&command_line); if (!length) { printf("Invalid <length>\n"); goto truncate_cleanup; } exec_truncate(*id, *length); truncate_cleanup: if (id) free(id); if (length) free(length); goto cleanup; } else { printf("Unknown command\n"); } cleanup: free(command); }