diff --git a/errors/errno.fugu b/errors/errno.fugu index ac78baf..127ece6 100755 --- a/errors/errno.fugu +++ b/errors/errno.fugu @@ -705,6 +705,10 @@ errors proc_mgmt PROC_MGMT_ERR_ { failure DOMAIN_NOT_RUNNING "Domain is not currently running", failure ALREADY_SPANNED "Domain has already been spanned to the given core", failure KILL "Failed to kill requested domain", + failure NAME_BUF_TOO_SMALL "Failed to return name because the buffer is too small", + failure PID_BUF_TOO_SMALL "Failed to return pids because the buffer is too small", + failure NAME_TOO_LONG "Process name is too long", + failure ALLOCATE_PID "Failed to allocate pid", }; // errors from ELF library @@ -1383,7 +1387,6 @@ errors aos AOS_ERR_ { failure RPC_ARG_TOO_BIG "RPC argument is too big", failure RPC_RET_TOO_BIG "RPC return value is too big", failure RPC_UNKNOWN_MSG_TYPE "RPC with unknown message type", - failure RPC_PROCESS_UNKNOWN_PID "Requested process name for an unknown PID", success RPC_ASYNC_REPLY "The RPC call will complete asynchronously", }; diff --git a/include/aos/aos_rpc.h b/include/aos/aos_rpc.h index c3d47c3..8b7ebcd 100644 --- a/include/aos/aos_rpc.h +++ b/include/aos/aos_rpc.h @@ -32,6 +32,7 @@ enum rpc_mtype { RPC_MTYPE_PROCESS_SPAWN, RPC_MTYPE_PROCESS_GET_NAME, RPC_MTYPE_PROCESS_GET_ALL_PIDS, + RPC_MTYPE_ALLOCATE_PID, RPC_MTYPE_GET_BOOTINFO, RPC_MTYPE_COUNT // How many message types exist }; diff --git a/include/spawn/spawn.h b/include/spawn/spawn.h index b8618cb..4e3208f 100644 --- a/include/spawn/spawn.h +++ b/include/spawn/spawn.h @@ -28,9 +28,6 @@ struct spawninfo { domainid_t pid; // < unique id for this domain - // Information about the binary - char * binary_name; // Name of the binary - // TODO(M2): Add fields you need to store state // when spawning a new dispatcher, // e.g. references to the child's @@ -63,7 +60,9 @@ struct spawninfo { struct aos_rpc_server rpc_server; }; -struct spawninfo *spawn_get_process_list(void); +errval_t allocate_pid (const char *process_name, domainid_t *pid); +errval_t get_process_name (domainid_t pid, char *process_name, size_t *len); +errval_t get_all_pids (domainid_t *pids, size_t *count); // parse a commandline into arguments void spawn_parse_cmd(char *cmdline, int *argc, char **argv); diff --git a/lib/grading/grading.c b/lib/grading/grading.c index 3f31cf8..1d4adf0 100644 --- a/lib/grading/grading.c +++ b/lib/grading/grading.c @@ -20,10 +20,12 @@ extern coreid_t my_core_id; void grading_setup_bsp_init(int argc, char **argv) { + debug_printf("grading_setup_bsp_init(argc=%d)\n", argc); } void grading_setup_app_init(struct bootinfo * bi) { + debug_printf("grading_setup_app_init(bi=%p)\n", bi); } void diff --git a/lib/spawn/rpc_server.c b/lib/spawn/rpc_server.c index 8fa5e2e..b23d900 100644 --- a/lib/spawn/rpc_server.c +++ b/lib/spawn/rpc_server.c @@ -289,28 +289,8 @@ static errval_t handle_rpc_process_get_name( grading_rpc_handler_process_get_name(pid); - // search for the pid - char *name = NULL; - for (struct spawninfo *si = spawn_get_process_list(); si != NULL; si = si->next) { - if (si->pid == pid) { - name = si->binary_name; - break; - } - } - - if (name == NULL) { - return AOS_ERR_RPC_PROCESS_UNKNOWN_PID; - } - - size_t name_len = strlen(name) + 1; - if(name_len > RPC_SHARED_SIZE) { - return AOS_ERR_RPC_RET_TOO_BIG; - } - - memcpy(rpc->shared_mem, name, name_len); - *ret_size = name_len; - - return SYS_ERR_OK; + *ret_size = RPC_SHARED_SIZE; + return get_process_name(pid, rpc->shared_mem, ret_size); } static errval_t handle_rpc_process_get_all_pids( @@ -320,23 +300,28 @@ static errval_t handle_rpc_process_get_all_pids( ) { grading_rpc_handler_process_get_all_pids(); - // size in bytes - size_t list_size = 0; domainid_t *buf = rpc->shared_mem; + size_t list_size = RPC_SHARED_SIZE / sizeof(domainid_t); + errval_t err = get_all_pids(buf, &list_size); + if (err_is_fail(err)) return err; + *ret_size = list_size * sizeof(domainid_t); + return SYS_ERR_OK; +} - // get all PIDs that fit into the given space - for (struct spawninfo *si = spawn_get_process_list(); si != NULL; si = si->next) { - if (list_size + sizeof(domainid_t) > RPC_SHARED_SIZE) { - return AOS_ERR_RPC_RET_TOO_BIG; - } - - *buf = si->pid; - ++buf; - list_size += sizeof(domainid_t); +static errval_t handle_rpc_allocate_pid( + struct generic_rpc_server *rpc, + struct capref arg_cap, size_t arg_size, uintptr_t arg0, uintptr_t arg1, + struct capref *ret_cap, size_t *ret_size, uintptr_t *ret0, uintptr_t *ret1 +) { + const char* process_name = rpc->shared_mem; + if (arg_size == 0 || process_name[arg_size - 1] != '\0') { + return ERR_INVALID_ARGS; } - *ret_size = list_size; - + domainid_t pid; + errval_t err = allocate_pid(process_name, &pid); + if (err_is_fail(err)) return err; + *ret0 = pid; return SYS_ERR_OK; } @@ -435,5 +420,6 @@ rpc_handler_t rpc_handlers[RPC_MTYPE_COUNT] = { [RPC_MTYPE_PROCESS_SPAWN] = handle_rpc_process_spawn, [RPC_MTYPE_PROCESS_GET_NAME] = handle_rpc_process_get_name, [RPC_MTYPE_PROCESS_GET_ALL_PIDS] = handle_rpc_process_get_all_pids, + [RPC_MTYPE_ALLOCATE_PID] = handle_rpc_allocate_pid, [RPC_MTYPE_GET_BOOTINFO] = handle_rpc_get_bootinfo, }; diff --git a/lib/spawn/spawn.c b/lib/spawn/spawn.c index cfa2dd5..6169d66 100644 --- a/lib/spawn/spawn.c +++ b/lib/spawn/spawn.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -15,13 +16,46 @@ extern struct bootinfo *bi; extern coreid_t my_core_id; +extern struct aos_urpc urpc_to_bsp; -struct spawninfo *spawn_process_list = NULL; +static struct spawninfo *spawn_process_list = NULL; + +// All PIDs are allocated on the BSP core. // TODO: handle "freeing" of PIDs in case we learn how to detect stopped child processes -domainid_t spawn_last_pid = 1; +static domainid_t spawn_next_pid = 1; +#define MAX_PID 1023 +static char *process_names[1024]; -struct spawninfo *spawn_get_process_list(void) { - return spawn_process_list; +errval_t allocate_pid (const char *process_name, domainid_t *pid) { + if (spawn_next_pid > MAX_PID) return SPAWN_ERR_OUT_OF_PIDS; + + char *name_copy = strdup(process_name); + if (name_copy == NULL) return LIB_ERR_MALLOC_FAIL; + process_names[spawn_next_pid] = name_copy; + + debug_printf("Allocated pid %"PRIuDOMAINID" for process \"%s\".\n", spawn_next_pid, process_name); + + *pid = spawn_next_pid; + spawn_next_pid++; + return SYS_ERR_OK; +} + +errval_t get_process_name (domainid_t pid, char *process_name, size_t *len) { + if (pid == 0 || pid >= spawn_next_pid) return PROC_MGMT_ERR_DOMAIN_TABLE_FIND; + size_t actual_len = strlen(process_names[pid]) + 1; + if (actual_len > *len) return PROC_MGMT_ERR_NAME_BUF_TOO_SMALL; + *len = actual_len; + memcpy(process_name, process_names[pid], actual_len); + return SYS_ERR_OK; +} + +errval_t get_all_pids (domainid_t *pids, size_t *count) { + if (*count < spawn_next_pid - 1) return PROC_MGMT_ERR_PID_BUF_TOO_SMALL; + *count = spawn_next_pid - 1; + for (size_t i = 0; i < *count; i++) { + pids[i] = i + 1; + } + return SYS_ERR_OK; } /** @@ -331,24 +365,35 @@ errval_t spawn_load_argv(int argc, char *argv[], struct spawninfo *si, domainid_t *pid) { errval_t err; - if(spawn_last_pid == MAX_DOMAINID) { - return SPAWN_ERR_OUT_OF_PIDS; - } - if(argc == 0) { debug_printf("[spawn_load_argv] argc == 0 (no arguments)\n"); return SPAWN_ERR_FIND_MODULE; } + assert(argc < MAX_CMDLINE_ARGS); + + // Allocate pid + if (my_core_id == 0) { + err = allocate_pid(argv[0], pid); + if (err_is_fail(err)) return err_push(err, PROC_MGMT_ERR_ALLOCATE_PID); + } else { + size_t name_len = strlen(argv[0]) + 1; + if (name_len > RPC_SHARED_SIZE) return PROC_MGMT_ERR_NAME_TOO_LONG; + memcpy(urpc_to_bsp.shared_mem, argv[0], name_len); + uintptr_t pid_ret; + err = do_aos_urpc( + &urpc_to_bsp, RPC_MTYPE_ALLOCATE_PID, + NULL_CAP, name_len, 0, 0, + NULL, NULL, &pid_ret, NULL + ); + if (err_is_fail(err)) return err_push(err, PROC_MGMT_ERR_ALLOCATE_PID); + *pid = pid_ret; + } + si->pid = *pid; + // - Initialize the spawn_info struct // TODO // copy name to spawninfo struct - size_t binary_name_len = strlen(argv[0]) + 1; - si->binary_name = malloc(binary_name_len); - if (si->binary_name == NULL) { - return LIB_ERR_MALLOC_FAIL; - } - memcpy(si->binary_name, argv[0], binary_name_len); // - Get the module from the multiboot image // and map it (take a look at multiboot.c) @@ -359,8 +404,6 @@ errval_t spawn_load_argv(int argc, char *argv[], struct spawninfo *si, // } // printf("\n"); - assert(argc > 0); - assert(argc < MAX_CMDLINE_ARGS); struct mem_region *module = multiboot_find_module(bi, argv[0]); if (module == NULL) return SPAWN_ERR_FIND_MODULE; size_t elf_bytes = module->mrmod_size; @@ -640,10 +683,6 @@ errval_t spawn_load_argv(int argc, char *argv[], struct spawninfo *si, ); if (err_is_fail(err)) return err_push(err, SPAWN_ERR_RUN); - // Get a unique PID - si->pid = ++spawn_last_pid; - *pid = si->pid; - // add to process list si->next = spawn_process_list; spawn_process_list = si; diff --git a/usr/init/main.c b/usr/init/main.c index fa7a968..730b3c2 100644 --- a/usr/init/main.c +++ b/usr/init/main.c @@ -38,7 +38,7 @@ coreid_t my_core_id; struct platform_info platform_info; // only valid on app core -static struct aos_urpc urpc_to_bsp; +struct aos_urpc urpc_to_bsp; // only valid on app core static struct aos_urpc_server urpc_to_app_server;