1/* 2 * Copyright 2016, Data61 3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 * ABN 41 687 119 230. 5 * 6 * This software may be distributed and modified according to the terms of 7 * the BSD 2-Clause license. Note that NO WARRANTY is provided. 8 * See "LICENSE_BSD2.txt" for details. 9 * 10 * @TAG(D61_BSD) 11 */ 12 13#include <assert.h> 14#include <stdio.h> 15#include <stdlib.h> 16#include <string.h> 17#include <sel4/sel4.h> 18 19#include <refos-rpc/name_client.h> 20#include <refos-rpc/name_client_helper.h> 21#include <refos-rpc/proc_client.h> 22#include <refos-rpc/proc_client_helper.h> 23#include <refos-util/dprintf.h> 24 25static bool 26nsv_check_path_resolved(char* path) 27{ 28 if (!path) { 29 return false; 30 } 31 if (path[0] == '/') { 32 path++; 33 } 34 35 int len = strlen(path); 36 for (int i = 0; i < len; i++) { 37 if (path[i] == '/') { 38 return false; 39 } 40 } 41 42 return true; 43} 44 45void 46nsv_mountpoint_release(nsv_mountpoint_t *m) 47{ 48 if (!m || !m->success || !m->serverAnon) { 49 return; 50 } 51 m->success = false; 52 if (m->serverAnon != REFOS_PROCSERV_EP) { 53 proc_del_endpoint(m->serverAnon); 54 } 55 m->serverAnon = 0; 56 memset(m, 0, sizeof(nsv_mountpoint_t)); 57} 58 59nsv_mountpoint_t 60nsv_resolve(char* path) 61{ 62 nsv_mountpoint_t ret; 63 memset(&ret, 0, sizeof(nsv_mountpoint_t)); 64 65 if (!path) { 66 REFOS_SET_ERRNO(EINVALIDPARAM); 67 return ret; 68 } 69 70 char *cpath = path; 71 seL4_CPtr nameServer = REFOS_NAMESERV_EP; 72 73 while (1) { 74 int resolvedBytes = 0; 75 seL4_CPtr nextNameServer = 0; 76 77 /* Check if path has already been resolved. */ 78 bool resolved = nsv_check_path_resolved(cpath); 79 if (!resolved) { 80 nextNameServer = nsv_resolve_segment(nameServer, cpath, &resolvedBytes); 81 } 82 83 /* Have we reached the leaf of the path? */ 84 if (resolved || resolvedBytes == NAMESERV_RESOLVED) { 85 ret.success = true; 86 ret.serverAnon = nameServer; 87 ret.nameservRoot = REFOS_NAMESERV_EP; 88 strcpy(ret.dspaceName, cpath); 89 strncpy(ret.nameservPathPrefix, path, cpath - path); 90 REFOS_SET_ERRNO(ESUCCESS); 91 return ret; 92 } 93 94 /* Delete the name server. */ 95 if (nameServer != REFOS_NAMESERV_EP) { 96 assert(nameServer); 97 proc_del_endpoint(nameServer); 98 nameServer = 0; 99 } 100 101 /* Was resolve invalid? */ 102 if (resolvedBytes == 0) { 103 ret.success = false; 104 REFOS_SET_ERRNO(ESERVERNOTFOUND); 105 return ret; 106 } 107 108 /* External resolve. */ 109 assert(nextNameServer); 110 nameServer = nextNameServer; 111 cpath += resolvedBytes; 112 if (cpath[0] == '/') { 113 cpath++; 114 } 115 } 116}