direct-io.hg

changeset 10337:464324585311

This patch exposes XenBus functions to Mini-OS applications.

Signed-of-by: John D. Ramsdell <ramsdell@mitre.org>
author sos22@douglas.cl.cam.ac.uk
date Tue Jun 13 15:17:01 2006 +0100 (2006-06-13)
parents ac5e98c1c466
children e9dd58963e97
files extras/mini-os/include/xenbus.h extras/mini-os/xenbus/xenbus.c
line diff
     1.1 --- a/extras/mini-os/include/xenbus.h	Tue Jun 13 14:08:37 2006 +0100
     1.2 +++ b/extras/mini-os/include/xenbus.h	Tue Jun 13 15:17:01 2006 +0100
     1.3 @@ -1,6 +1,34 @@
     1.4  #ifndef XENBUS_H__
     1.5  #define XENBUS_H__
     1.6  
     1.7 +/* Initialize the XenBus system. */
     1.8  void init_xenbus(void);
     1.9  
    1.10 +/* Read the value associated with a path.  Returns a malloc'd error
    1.11 +   string on failure and sets *value to NULL.  On success, *value is
    1.12 +   set to a malloc'd copy of the value. */
    1.13 +char *xenbus_read(const char *path, char **value);
    1.14 +
    1.15 +/* Associates a value with a path.  Returns a malloc'd error string on
    1.16 +   failure. */
    1.17 +char *xenbus_write(const char *path, const char *value);
    1.18 +
    1.19 +/* Removes the value associated with a path.  Returns a malloc'd error
    1.20 +   string on failure. */
    1.21 +char *xenbus_rm(const char *path);
    1.22 +
    1.23 +/* List the contents of a directory.  Returns a malloc'd error string
    1.24 +   on failure and sets *contents to NULL.  On success, *contents is
    1.25 +   set to a malloc'd array of pointers to malloc'd strings.  The array
    1.26 +   is NULL terminated.  May block. */
    1.27 +char *xenbus_ls(const char *prefix, char ***contents);
    1.28 +
    1.29 +/* Reads permissions associated with a path.  Returns a malloc'd error
    1.30 +   string on failure and sets *value to NULL.  On success, *value is
    1.31 +   set to a malloc'd copy of the value. */
    1.32 +char *xenbus_get_perms(const char *path, char **value);
    1.33 +
    1.34 +/* Sets the permissions associated with a path.  Returns a malloc'd
    1.35 +   error string on failure. */
    1.36 +char *xenbus_set_perms(const char *path, domid_t dom, char perm);
    1.37  #endif /* XENBUS_H__ */
     2.1 --- a/extras/mini-os/xenbus/xenbus.c	Tue Jun 13 14:08:37 2006 +0100
     2.2 +++ b/extras/mini-os/xenbus/xenbus.c	Tue Jun 13 15:17:01 2006 +0100
     2.3 @@ -3,11 +3,12 @@
     2.4   * (C) 2006 - Cambridge University
     2.5   ****************************************************************************
     2.6   *
     2.7 - *        File: mm.c
     2.8 + *        File: xenbus.c
     2.9   *      Author: Steven Smith (sos22@cam.ac.uk) 
    2.10   *     Changes: Grzegorz Milos (gm281@cam.ac.uk)
    2.11 + *     Changes: John D. Ramsdell
    2.12   *              
    2.13 - *        Date: Mar 2006, chages Aug 2005
    2.14 + *        Date: Jun 2006, chages Aug 2005
    2.15   * 
    2.16   * Environment: Xen Minimal OS
    2.17   * Description: Minimal implementation of xenbus
    2.18 @@ -167,6 +168,7 @@ static int allocate_xenbus_id(void)
    2.19  void init_xenbus(void)
    2.20  {
    2.21      int err;
    2.22 +    printk("Initialising xenbus\n");
    2.23      DEBUG("init_xenbus called.\n");
    2.24      xenstore_buf = mfn_to_virt(start_info.store_mfn);
    2.25      create_thread("xenstore", xenbus_thread_func, NULL);
    2.26 @@ -262,15 +264,15 @@ static void xb_write(int type, int req_i
    2.27  /* Send a mesasge to xenbus, in the same fashion as xb_write, and
    2.28     block waiting for a reply.  The reply is malloced and should be
    2.29     freed by the caller. */
    2.30 -static void *xenbus_msg_reply(int type,
    2.31 +static struct xsd_sockmsg *
    2.32 +xenbus_msg_reply(int type,
    2.33          int trans,
    2.34          struct write_req *io,
    2.35          int nr_reqs)
    2.36  {
    2.37      int id;
    2.38      DEFINE_WAIT(w);
    2.39 -    void *rep;
    2.40 -    struct xsd_sockmsg *repmsg;
    2.41 +    struct xsd_sockmsg *rep;
    2.42  
    2.43      id = allocate_xenbus_id();
    2.44      add_waiter(w, req_info[id].waitq);
    2.45 @@ -281,13 +283,27 @@ static void *xenbus_msg_reply(int type,
    2.46      wake(current);
    2.47  
    2.48      rep = req_info[id].reply;
    2.49 -    repmsg = rep;
    2.50 -    BUG_ON(repmsg->req_id != id);
    2.51 +    BUG_ON(rep->req_id != id);
    2.52      release_xenbus_id(id);
    2.53 -
    2.54      return rep;
    2.55  }
    2.56  
    2.57 +static char *errmsg(struct xsd_sockmsg *rep)
    2.58 +{
    2.59 +    if (!rep) {
    2.60 +	char msg[] = "No reply";
    2.61 +	size_t len = strlen(msg) + 1;
    2.62 +	return memcpy(malloc(len), msg, len);
    2.63 +    }
    2.64 +    if (rep->type != XS_ERROR)
    2.65 +	return NULL;
    2.66 +    char *res = malloc(rep->len + 1);
    2.67 +    memcpy(res, rep + 1, rep->len);
    2.68 +    res[rep->len] = 0;
    2.69 +    free(rep);
    2.70 +    return res;
    2.71 +}	
    2.72 +
    2.73  /* Send a debug message to xenbus.  Can block. */
    2.74  static void xenbus_debug_msg(const char *msg)
    2.75  {
    2.76 @@ -296,27 +312,29 @@ static void xenbus_debug_msg(const char 
    2.77          { "print", sizeof("print") },
    2.78          { msg, len },
    2.79          { "", 1 }};
    2.80 -    void *reply;
    2.81 -    struct xsd_sockmsg *repmsg;
    2.82 +    struct xsd_sockmsg *reply;
    2.83  
    2.84 -    reply = xenbus_msg_reply(XS_DEBUG, 0, req, 3);
    2.85 -    repmsg = reply;
    2.86 +    reply = xenbus_msg_reply(XS_DEBUG, 0, req, ARRAY_SIZE(req));
    2.87      DEBUG("Got a reply, type %d, id %d, len %d.\n",
    2.88 -            repmsg->type, repmsg->req_id, repmsg->len);
    2.89 +            reply->type, reply->req_id, reply->len);
    2.90  }
    2.91  
    2.92  /* List the contents of a directory.  Returns a malloc()ed array of
    2.93     pointers to malloc()ed strings.  The array is NULL terminated.  May
    2.94     block. */
    2.95 -static char **xenbus_ls(const char *pre)
    2.96 +char *xenbus_ls(const char *pre, char ***contents)
    2.97  {
    2.98 -    void *reply;
    2.99 -    struct xsd_sockmsg *repmsg;
   2.100 +    struct xsd_sockmsg *reply, *repmsg;
   2.101      struct write_req req[] = { { pre, strlen(pre)+1 } };
   2.102      int nr_elems, x, i;
   2.103      char **res;
   2.104  
   2.105 -    repmsg = xenbus_msg_reply(XS_DIRECTORY, 0, req, 1);
   2.106 +    repmsg = xenbus_msg_reply(XS_DIRECTORY, 0, req, ARRAY_SIZE(req));
   2.107 +    char *msg = errmsg(repmsg);
   2.108 +    if (msg) {
   2.109 +	*contents = NULL;
   2.110 +	return msg;
   2.111 +    }
   2.112      reply = repmsg + 1;
   2.113      for (x = nr_elems = 0; x < repmsg->len; x++)
   2.114          nr_elems += (((char *)reply)[x] == 0);
   2.115 @@ -329,20 +347,91 @@ static char **xenbus_ls(const char *pre)
   2.116      }
   2.117      res[i] = NULL;
   2.118      free(repmsg);
   2.119 -    return res;
   2.120 +    *contents = res;
   2.121 +    return NULL;
   2.122  }
   2.123  
   2.124 -static char *xenbus_read(const char *path)
   2.125 +char *xenbus_read(const char *path, char **value)
   2.126  {
   2.127 -    struct write_req req[] = { {path, strlen(path) + 1}};
   2.128 +    struct write_req req[] = { {path, strlen(path) + 1} };
   2.129      struct xsd_sockmsg *rep;
   2.130      char *res;
   2.131 -    rep = xenbus_msg_reply(XS_READ, 0, req, 1);
   2.132 +    rep = xenbus_msg_reply(XS_READ, 0, req, ARRAY_SIZE(req));
   2.133 +    char *msg = errmsg(rep);
   2.134 +    if (msg) {
   2.135 +	*value = NULL;
   2.136 +	return msg;
   2.137 +    }
   2.138      res = malloc(rep->len + 1);
   2.139      memcpy(res, rep + 1, rep->len);
   2.140      res[rep->len] = 0;
   2.141      free(rep);
   2.142 -    return res;
   2.143 +    *value = res;
   2.144 +    return NULL;
   2.145 +}
   2.146 +
   2.147 +char *xenbus_write(const char *path, const char *value)
   2.148 +{
   2.149 +    struct write_req req[] = { 
   2.150 +	{path, strlen(path) + 1},
   2.151 +	{value, strlen(value) + 1},
   2.152 +    };
   2.153 +    struct xsd_sockmsg *rep;
   2.154 +    rep = xenbus_msg_reply(XS_WRITE, 0, req, ARRAY_SIZE(req));
   2.155 +    char *msg = errmsg(rep);
   2.156 +    if (msg)
   2.157 +	return msg;
   2.158 +    free(rep);
   2.159 +    return NULL;
   2.160 +}
   2.161 +
   2.162 +char *xenbus_rm(const char *path)
   2.163 +{
   2.164 +    struct write_req req[] = { {path, strlen(path) + 1} };
   2.165 +    struct xsd_sockmsg *rep;
   2.166 +    rep = xenbus_msg_reply(XS_RM, 0, req, ARRAY_SIZE(req));
   2.167 +    char *msg = errmsg(rep);
   2.168 +    if (msg)
   2.169 +	return msg;
   2.170 +    free(rep);
   2.171 +    return NULL;
   2.172 +}
   2.173 +
   2.174 +char *xenbus_get_perms(const char *path, char **value)
   2.175 +{
   2.176 +    struct write_req req[] = { {path, strlen(path) + 1} };
   2.177 +    struct xsd_sockmsg *rep;
   2.178 +    char *res;
   2.179 +    rep = xenbus_msg_reply(XS_GET_PERMS, 0, req, ARRAY_SIZE(req));
   2.180 +    char *msg = errmsg(rep);
   2.181 +    if (msg) {
   2.182 +	*value = NULL;
   2.183 +	return msg;
   2.184 +    }
   2.185 +    res = malloc(rep->len + 1);
   2.186 +    memcpy(res, rep + 1, rep->len);
   2.187 +    res[rep->len] = 0;
   2.188 +    free(rep);
   2.189 +    *value = res;
   2.190 +    return NULL;
   2.191 +}
   2.192 +
   2.193 +#define PERM_MAX_SIZE 32
   2.194 +char *xenbus_set_perms(const char *path, domid_t dom, char perm)
   2.195 +{
   2.196 +    char value[PERM_MAX_SIZE];
   2.197 +    snprintf(value, PERM_MAX_SIZE, "%c%hu", perm, dom);
   2.198 +    struct write_req req[] = { 
   2.199 +	{path, strlen(path) + 1},
   2.200 +	{value, strlen(value) + 1},
   2.201 +    };
   2.202 +    struct xsd_sockmsg *rep;
   2.203 +    rep = xenbus_msg_reply(XS_SET_PERMS, 0, req, ARRAY_SIZE(req));
   2.204 +    char *msg = errmsg(rep);
   2.205 +    if (msg)
   2.206 +	return msg;
   2.207 +    free(rep);
   2.208 +    return NULL;
   2.209  }
   2.210  
   2.211  static void do_ls_test(const char *pre)
   2.212 @@ -351,7 +440,12 @@ static void do_ls_test(const char *pre)
   2.213      int x;
   2.214  
   2.215      DEBUG("ls %s...\n", pre);
   2.216 -    dirs = xenbus_ls(pre);
   2.217 +    char *msg = xenbus_ls(pre, &dirs);
   2.218 +    if (msg) {
   2.219 +	DEBUG("Error in xenbus ls: %s\n", msg);
   2.220 +	free(msg);
   2.221 +	return;
   2.222 +    }
   2.223      for (x = 0; dirs[x]; x++) 
   2.224      {
   2.225          DEBUG("ls %s[%d] -> %s\n", pre, x, dirs[x]);
   2.226 @@ -364,7 +458,12 @@ static void do_read_test(const char *pat
   2.227  {
   2.228      char *res;
   2.229      DEBUG("Read %s...\n", path);
   2.230 -    res = xenbus_read(path);
   2.231 +    char *msg = xenbus_read(path, &res);
   2.232 +    if (msg) {
   2.233 +	DEBUG("Error in xenbus read: %s\n", msg);
   2.234 +	free(msg);
   2.235 +	return;
   2.236 +    }
   2.237      DEBUG("Read %s -> %s.\n", path, res);
   2.238      free(res);
   2.239  }
   2.240 @@ -383,5 +482,11 @@ void test_xenbus(void)
   2.241      DEBUG("Doing read test.\n");
   2.242      do_read_test("device/vif/0/mac");
   2.243      do_read_test("device/vif/0/backend");
   2.244 -    printk("Xenbus initialised.\n");
   2.245  }
   2.246 +
   2.247 +/*
   2.248 + * Local variables:
   2.249 + * mode: C
   2.250 + * c-basic-offset: 4
   2.251 + * End:
   2.252 + */