1/* 2 * Copyright (c) 2016, ETH Zurich. 3 * All rights reserved. 4 * 5 * This file is distributed under the terms in the attached LICENSE file. 6 * If you do not find this file, copies can be found by writing to: 7 * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group. 8 */ 9 10#include <stdio.h> 11#include <string.h> 12 13#include <barrelfish/barrelfish.h> 14#include <barrelfish/spawn_client.h> 15 16#include <driverkit/driverkit.h> 17 18#include "kaluga.h" 19 20#define DRIVER_DOMAIN_NAME "driverdomain" 21 22// Add an argument to argc/argv pair. argv must be mallocd! 23static void argv_push(int * argc, char *** argv, char * new_arg){ 24 int new_size = *argc + 1; 25 *argv = realloc(*argv, (new_size+1) * sizeof(char*)); // +1 for last NULL entry. 26 if(*argv == NULL){ 27 USER_PANIC("Could not allocate argv memory"); 28 } 29 *argc = new_size; 30 (*argv)[new_size-1] = new_arg; 31 (*argv)[new_size] = NULL; 32} 33 34static errval_t launch_driver_domain(coreid_t where, uint64_t did, struct module_info* ddomain) 35{ 36 assert(ddomain != NULL); 37 errval_t err = SYS_ERR_OK; 38 39 char **argv = NULL; 40 int argc = ddomain->argc; 41 argv = malloc(sizeof(char*)*ddomain->argc); // +1 for trailing NULL 42 assert(argv != NULL); 43 44 memcpy(argv, ddomain->argv, (argc+1) * sizeof(char *)); 45 assert(argv[argc] == NULL); 46 47 char* did_str = calloc(26, sizeof(char)); 48 assert(did_str != NULL); 49 snprintf(did_str, 26, "%"PRIu64"", did); 50 argv_push(&argc, &argv, did_str); 51 52 err = spawn_program_with_caps(where, ddomain->path, argv, 53 environ, NULL_CAP, NULL_CAP, 54 0, get_did_ptr(ddomain)); 55 if (err_is_fail(err)) { 56 DEBUG_ERR(err, "Spawning %s failed.", ddomain->path); 57 } 58 59 free(argv); 60 return err; 61} 62 63static void wait_for_id(struct domain_instance* di) { 64 while (di->b == NULL) { 65 messages_wait_and_handle_next(); 66 } 67 KALUGA_DEBUG("%s:%s:%d: done with waiting for ID\n", __FILE__, __FUNCTION__, __LINE__); 68} 69 70struct domain_instance* instantiate_driver_domain(char* name, coreid_t where) { 71 static uint64_t did = 1; 72 73 errval_t err = launch_driver_domain(where, did, find_module(name)); 74 if (err_is_fail(err)) { 75 USER_PANIC_ERR(err, "call failed."); 76 } 77 struct domain_instance* di = ddomain_create_domain_instance(did); 78 did++; 79 80 wait_for_id(di); 81 82 return di; 83} 84