static xmlrpc_value * service_remove (xmlrpc_env *env, xmlrpc_value *param_array, void *user_data) { char *service_identifier; RCWorldService *service; xmlrpc_parse_value (env, param_array, "(s)", &service_identifier); XMLRPC_FAIL_IF_FAULT (env); service = service_lookup (service_identifier); if (!service) { xmlrpc_env_set_fault_formatted (env, RCD_RPC_FAULT_INVALID_SERVICE, "Unable to unmount service for '%s'", service_identifier); goto cleanup; } rc_world_multi_remove_subworld (RC_WORLD_MULTI (rc_get_world ()), RC_WORLD (service)); rcd_services_save (); cleanup: if (env->fault_occurred) return NULL; return xmlrpc_build_value (env, "i", 0); }
// FIXME: Should be able to return a list. return_t exec_lookup (exec_service_t *exec) { // FIXME: lame size_t services = 1; service_t service; // FIXME: Take this as a function parameter (bug #60). service_lookup_t lookup = { "exec", /* protocol_name */ NULL, /* service_vendor */ NULL, /* device_vendor */ NULL, /* model */ NULL, /* device_id */ EXEC_PROTOCOL_MAJOR_VERSION, /* major_version */ EXEC_PROTOCOL_MINOR_VERSION, /* minor_version */ }; /* Find the exec service. */ if (service_lookup (&lookup, &services, &service) != STORM_RETURN_SUCCESS) { debug_print ("Failed to lookup exec service provider.\n"); return EXEC_RETURN_SERVICE_UNAVAILABLE; } service.service_info (exec); return EXEC_RETURN_SUCCESS; }
// FIXME: Should be able to return a list. return_t block_lookup (block_service_t *block) { // FIXME: Support more than one block service. :-) size_t services = 1; service_t service; service_lookup_t lookup = { "block", NULL, NULL, NULL, NULL, BLOCK_PROTOCOL_MAJOR_VERSION, BLOCK_PROTOCOL_MINOR_VERSION }; /* Find the block service. */ if (service_lookup (&lookup, &services, &service) != STORM_RETURN_SUCCESS) { debug_print ("Failed to lookup block service provider.\n"); return BLOCK_RETURN_SERVICE_UNAVAILABLE; } service.service_info (block); // FIXME: Free the memory allocated by service_resolve. return BLOCK_RETURN_SUCCESS; }
static xmlrpc_value * service_set_url (xmlrpc_env *env, xmlrpc_value *param_array, void *user_data) { char *service_identifier; char *old_url, *new_url; RCWorldService *service; xmlrpc_parse_value (env, param_array, "(ss)", &service_identifier, &new_url); XMLRPC_FAIL_IF_FAULT (env); service = service_lookup (service_identifier); if (!service) { xmlrpc_env_set_fault_formatted (env, RCD_RPC_FAULT_INVALID_SERVICE, "Unable to unmount service for '%s'", service_identifier); goto cleanup; } old_url = service->url; service->url = g_strdup (new_url); /* FIXME: This is wrong. rc_world_refresh () returns pending only if refresh has not completed yet. Pending needs to be unref'ed when we're done with it as well. It's not a big deal right now as nothing actually calls this anymore. */ if (!rc_world_refresh (RC_WORLD (service))) { xmlrpc_env_set_fault_formatted (env, RCD_RPC_FAULT_INVALID_SERVICE, "Unable to change mirrors for '%s'", service->name); g_free (service->url); service->url = old_url; goto cleanup; } g_free (old_url); rcd_services_save (); cleanup: if (env->fault_occurred) return NULL; return xmlrpc_build_value (env, "i", 0); }
errval_t driver_store_lookup(lpaddr_t mem_low, size_t size, uint8_t numa_node, struct dma_mgr_driver_info **info) { DS_DEBUG("lookup: {%016lx, %016lx, %u}\n", mem_low, size, numa_node); struct dma_service *svc = service_lookup(mem_low, size, numa_node); if (svc == NULL) { return DMA_ERR_SVC_VOID; } DS_DEBUG("lookup: {%016lx, %016lx, %u} @ %x\n", mem_low, size, numa_node, svc->info.iref); *info = &svc->info; return SYS_ERR_OK; }
static xmlrpc_value * service_get_mirrors (xmlrpc_env *env, xmlrpc_value *param_array, void *user_data) { char *service_identifier; RCWorldMulti *multi; RCWorldService *service; struct GetAllInfo info; xmlrpc_parse_value (env, param_array, "(s)", &service_identifier); XMLRPC_FAIL_IF_FAULT (env); multi = RC_WORLD_MULTI (rc_get_world ()); service = service_lookup (service_identifier); if (!service || !g_type_is_a (G_TYPE_FROM_INSTANCE (service), RCD_TYPE_WORLD_REMOTE)) { xmlrpc_env_set_fault_formatted (env, RCD_RPC_FAULT_INVALID_SERVICE, "Unable to find service '%s'", service_identifier); goto cleanup; } info.env = env; info.array = xmlrpc_build_value (env, "()"); info.failed = FALSE; rcd_world_remote_foreach_mirror (RCD_WORLD_REMOTE (service), add_mirror_cb, &info); cleanup: if (env->fault_occurred) return NULL; return info.array; }
/* Lookup the first virtual filesystem service provider. FIXME: Should be able to return a list. */ return_t vfs_lookup (vfs_service_t *vfs) { // FIXME: Lame. size_t services = 1; service_t service; service_lookup_t lookup; /* Find the virtual filesystem service. */ lookup.protocol_name = "vfs"; lookup.major_version = VFS_PROTOCOL_MAJOR_VERSION; lookup.minor_version = VFS_PROTOCOL_MINOR_VERSION; if (service_lookup (&lookup, &services, &service) != STORM_RETURN_SUCCESS) { debug_print ("Failed to lookup virtual filesystem service provider.\n"); return VFS_RETURN_SERVICE_UNAVAILABLE; } service.service_info (vfs); return VFS_RETURN_SUCCESS; }
static xmlrpc_value * service_activate (xmlrpc_env *env, xmlrpc_value *param_array, void *user_data) { xmlrpc_value *activation_info; char *activation_code; char *email = NULL, *service_identifier = NULL, *alias = NULL; RCWorldService *service; char *err_msg; xmlrpc_parse_value (env, param_array, "(V)", &activation_info); XMLRPC_FAIL_IF_FAULT (env); RCD_XMLRPC_STRUCT_GET_STRING (env, activation_info, "activation_code", activation_code); if (xmlrpc_struct_has_key (env, activation_info, "email")) { RCD_XMLRPC_STRUCT_GET_STRING (env, activation_info, "email", email); } if (xmlrpc_struct_has_key (env, activation_info, "alias")) { RCD_XMLRPC_STRUCT_GET_STRING (env, activation_info, "alias", alias); } if (xmlrpc_struct_has_key (env, activation_info, "service")) { RCD_XMLRPC_STRUCT_GET_STRING (env, activation_info, "service", service_identifier); service = service_lookup (service_identifier); if (!service || !g_type_is_a (G_TYPE_FROM_INSTANCE (service), RCD_TYPE_WORLD_REMOTE)) { xmlrpc_env_set_fault_formatted (env, RCD_RPC_FAULT_INVALID_SERVICE, "Unable to find service '%s'", service_identifier); goto cleanup; } } else { service = NULL; if (rc_world_multi_foreach_subworld_by_type ( RC_WORLD_MULTI (rc_get_world ()), RCD_TYPE_WORLD_REMOTE, get_singleton_remote_cb, &service) < 0) { xmlrpc_env_set_fault_formatted (env, RCD_RPC_FAULT_INVALID_SERVICE, "You must specify a specific service"); goto cleanup; } } if (!rcd_world_remote_activate (RCD_WORLD_REMOTE (service), activation_code, email, alias, &err_msg)) { xmlrpc_env_set_fault_formatted (env, RCD_RPC_FAULT_CANT_ACTIVATE, "%s", err_msg); g_free (err_msg); goto cleanup; } cleanup: if (env->fault_occurred) return NULL; return xmlrpc_build_value (env, "i", 0); }
static xmlrpc_value * service_refresh_blocking (xmlrpc_env *env, xmlrpc_value *param_array, void *user_data) { int size; RCWorld *world; RCPending *pending = NULL; GSList *pending_list; char *err_msg = NULL; if (rcd_transaction_is_locked ()) { xmlrpc_env_set_fault (env, RCD_RPC_FAULT_LOCKED, "Transaction lock in place"); return NULL; } size = xmlrpc_array_size (env, param_array); XMLRPC_FAIL_IF_FAULT (env); if (size > 0) { char *service_identifier; xmlrpc_parse_value (env, param_array, "(s)", &service_identifier); XMLRPC_FAIL_IF_FAULT (env); world = RC_WORLD (service_lookup (service_identifier)); if (!world) { xmlrpc_env_set_fault_formatted (env, RCD_RPC_FAULT_INVALID_SERVICE, "Unable to find service '%s'", service_identifier); goto cleanup; } } else { world = rc_get_world (); } /* FIXME: err_msg ? */ pending = rc_world_refresh (world); if (err_msg) { xmlrpc_env_set_fault_formatted ( env, RCD_RPC_FAULT_CANT_REFRESH, "Unable to download channel data: %s", err_msg); goto cleanup; } pending_list = g_slist_prepend (NULL, pending); rcd_rpc_block_on_pending_list (env, pending_list, FALSE, RCD_RPC_FAULT_CANT_REFRESH); g_slist_free (pending_list); cleanup: if (pending) g_object_unref (pending); if (err_msg) g_free (err_msg); if (env->fault_occurred) return NULL; return xmlrpc_build_value (env, "i", 0); }
/* sends off a frame to the relevant swap file (in or out) * * returns True if the root server needs to be notified immediately (ie not * waiting for an async reply */ static int mmap_queue_schedule (int direction, vaddr_t vaddr, struct frameinfo *frame, void* callback, struct pawpaw_event* evt) { struct mmap_queue_item* q = mmap_queue_new (frame, callback, evt); if (!q) { return false; } //assert (frame); if (direction == PAGE_SWAP_IN) { assert (frame->file); assert (frame->file->file); /* FIXME: seriously this needs work */ struct seen_item *item = regd_caps; while (item) { if (item->cap == frame->file->file) { break; } item = item->next; } /* register with the filesystem for async notifications if this is our * first time with this file */ if (!item) { seL4_MessageInfo_t reg_msg = seL4_MessageInfo_new (0, 0, 1, 1); seL4_CPtr their_cap = cspace_mint_cap (cur_cspace, cur_cspace, _mmap_ep, seL4_AllRights, seL4_CapData_Badge_new ((seL4_Word)frame)); assert (their_cap); seL4_SetMR (0, VFS_REGISTER_CAP); seL4_SetCap (0, their_cap); seL4_Call (frame->file->file, reg_msg); seL4_Word id = seL4_GetMR (0); assert (id > 0); item = malloc (sizeof (struct seen_item)); assert (item); item->cap = frame->file->file; item->id = id; item->next = regd_caps; regd_caps = item; } seL4_MessageInfo_t msg = seL4_MessageInfo_new (0, 0, 1, 4); seL4_Word id = cid_next (); maps_append (id, ((thread_t)evt->args[1])->pid, vaddr); /* create a "valid badge" in the badgemap so we can mount the * shared buffer */ seL4_CPtr badge_cap = cspace_mint_cap ( cur_cspace, cur_cspace, _badgemap_ep, seL4_AllRights, seL4_CapData_Badge_new (id)); assert (badge_cap); assert (frame->file); msg = seL4_MessageInfo_new (0, 0, 1, 7); seL4_SetCap (0, badge_cap); seL4_SetMR (0, VFS_READ_OFFSET); seL4_SetMR (1, id); seL4_SetMR (2, frame->file->load_length); seL4_SetMR (3, frame->file->file_offset); seL4_SetMR (4, frame->file->load_offset); seL4_SetMR (5, item->id); /* async ID */ seL4_SetMR (6, (seL4_Word)frame); /* use frame ptr as "event id" */ seL4_Send (frame->file->file, msg); /* and we go back to waiting on our EP */ } else if (direction == PAGE_SWAP_OUT) { seL4_MessageInfo_t msg = seL4_MessageInfo_new (0, 0, 1, 4); /* FIXME: needs to be cleaned up on successful swap */ seL4_Word id = cid_next (); maps_append (id, 0, vaddr); /* create a "valid badge" in the badgemap so we can mount the shared * buffer */ seL4_CPtr badge_cap = cspace_mint_cap (cur_cspace, cur_cspace, _badgemap_ep, seL4_AllRights, seL4_CapData_Badge_new (id)); assert (badge_cap); seL4_Word page_id = last_page_id * PAGE_SIZE; last_page_id++; seL4_Word wrote = 0; while (wrote < PAGE_SIZE) { msg = seL4_MessageInfo_new (0, 0, 1, 7); seL4_SetCap (0, badge_cap); seL4_SetMR (0, VFS_WRITE_OFFSET); seL4_SetMR (1, id); seL4_SetMR (2, PAGE_SIZE - wrote); /* write whole page out */ seL4_SetMR (3, page_id + wrote); /* file offset */ seL4_SetMR (4, wrote); /* load into start of share */ //seL4_SetMR (5, swap_id); /* async ID - NOT USED */ seL4_SetMR (6, (seL4_Word)frame); /* and write it out */ seL4_Call (swap_cap, msg); seL4_Word wrote_this_call = seL4_GetMR (0); assert (wrote_this_call >= 0); wrote += wrote_this_call; } cspace_delete_cap (cur_cspace, badge_cap); /* memory map it */ frame->file = frame_create_mmap (swap_cap, 0, page_id, PAGE_SIZE); assert (frame->file); mmap_move_done (q); return true; /* and we go back to waiting on our EP */ } else if (direction == BUFFER_OPEN_LOAD) { seL4_Word share_id = cid_next (); maps_append (share_id, 0, vaddr); /* create a "valid badge" in the badgemap so we can mount the shared * buffer */ seL4_CPtr badge_cap = cspace_mint_cap (cur_cspace, cur_cspace, _badgemap_ep, seL4_AllRights, seL4_CapData_Badge_new (share_id)); assert (badge_cap); seL4_CPtr recv_cap = cspace_alloc_slot (cur_cspace); assert (recv_cap); seL4_SetCapReceivePath (cur_cspace->root_cnode, recv_cap, CSPACE_DEPTH); printf ("OK, asking VFS to open our file '%s'\n", (char*)vaddr); seL4_MessageInfo_t msg = seL4_MessageInfo_new (0, 0, 1, 4); seL4_SetCap (0, badge_cap); seL4_SetMR (0, VFS_OPEN); seL4_SetMR (1, share_id); seL4_SetMR (2, FM_READ); seL4_SetMR (3, 0); /* XXX: hack of the century - should really ask VFS async * for cap */ seL4_CPtr nfs_fs_cap = service_lookup ("fs_nfs"); while (!nfs_fs_cap) { printf ("failed to find nfs service\n"); nfs_fs_cap = service_lookup ("fs_nfs"); //return false; } printf ("calling on %d\n", nfs_fs_cap); seL4_MessageInfo_t reply = seL4_Call (nfs_fs_cap, msg); if (seL4_GetMR (0) != 0) { printf ("%s: failed to open file\n", __FUNCTION__); //return false; mmap_move_done (q); q->frame = NULL; return true; } assert (seL4_MessageInfo_get_capsUnwrapped (reply) == 0); if (seL4_MessageInfo_get_extraCaps (reply) != 1) { /* could not find file */ printf ("%s: did not have cap\n", __FUNCTION__); return false; } printf ("yum, setting evt arg\n"); evt->args[2] = recv_cap; /* then, load in the first page worth of the file into kmem, so we * can read the headers we need */ printf ("sweeto, trying to read in data...\n"); msg = seL4_MessageInfo_new (0, 0, 1, 3); seL4_SetCap (0, badge_cap); seL4_SetMR (0, VFS_READ); seL4_SetMR (1, share_id); seL4_SetMR (2, PAGE_SIZE); //seL4_SetMR (3, 0); /* offset */ printf ("ASKING TO READ FILE\n"); seL4_Call (recv_cap, msg); if (seL4_GetMR (0) <= 0) { printf ("%s: read was empty/failed\n", __FUNCTION__); //return NULL; return false; } printf("read was ok\n"); mmap_move_done (q); return true; } return false; }