debuggers.hg
changeset 6787:80afc502461b
Change xenbus_dev interface from ioctl to read/write.
Check boundaries so we can recover if userspace dies.
Also simplifies libxenstore.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
Check boundaries so we can recover if userspace dies.
Also simplifies libxenstore.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
author | cl349@firebug.cl.cam.ac.uk |
---|---|
date | Mon Sep 12 21:12:16 2005 +0000 (2005-09-12) |
parents | 282d5698ea40 |
children | d8637529daff |
files | .hgignore linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c tools/xenstore/Makefile tools/xenstore/xs.c |
line diff
1.1 --- a/.hgignore Mon Sep 12 20:46:37 2005 +0000 1.2 +++ b/.hgignore Mon Sep 12 21:12:16 2005 +0000 1.3 @@ -152,7 +152,6 @@ 1.4 ^tools/xenstat/xentop/xentop$ 1.5 ^tools/xenstore/testsuite/tmp/.*$ 1.6 ^tools/xenstore/xen$ 1.7 -^tools/xenstore/xenbus_dev.h$ 1.8 ^tools/xenstore/xenstored$ 1.9 ^tools/xenstore/xenstored_test$ 1.10 ^tools/xenstore/xenstore-read$
2.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c Mon Sep 12 20:46:37 2005 +0000 2.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c Mon Sep 12 21:12:16 2005 +0000 2.3 @@ -5,6 +5,7 @@ 2.4 * to xenstore. 2.5 * 2.6 * Copyright (c) 2005, Christian Limpach 2.7 + * Copyright (c) 2005, Rusty Russell, IBM Corporation 2.8 * 2.9 * This file may be distributed separately from the Linux kernel, or 2.10 * incorporated into other software packages, subject to the following license: 2.11 @@ -41,105 +42,97 @@ 2.12 2.13 #include <asm/uaccess.h> 2.14 #include <asm-xen/xenbus.h> 2.15 -#include <asm-xen/linux-public/xenbus_dev.h> 2.16 #include <asm-xen/xen_proc.h> 2.17 2.18 struct xenbus_dev_data { 2.19 - int in_transaction; 2.20 + /* Are there bytes left to be read in this message? */ 2.21 + int bytes_left; 2.22 + /* Are we still waiting for the reply to a message we wrote? */ 2.23 + int awaiting_reply; 2.24 + /* Buffer for outgoing messages. */ 2.25 + unsigned int len; 2.26 + union { 2.27 + struct xsd_sockmsg msg; 2.28 + char buffer[PAGE_SIZE]; 2.29 + } u; 2.30 }; 2.31 2.32 static struct proc_dir_entry *xenbus_dev_intf; 2.33 2.34 -void *xs_talkv(enum xsd_sockmsg_type type, const struct kvec *iovec, 2.35 - unsigned int num_vecs, unsigned int *len); 2.36 - 2.37 -static int xenbus_dev_talkv(struct xenbus_dev_data *u, unsigned long data) 2.38 +/* Reply can be long (dir, getperm): don't buffer, just examine 2.39 + * headers so we can discard rest if they die. */ 2.40 +static ssize_t xenbus_dev_read(struct file *filp, 2.41 + char __user *ubuf, 2.42 + size_t len, loff_t *ppos) 2.43 { 2.44 - struct xenbus_dev_talkv xt; 2.45 - unsigned int len; 2.46 - void *resp, *base; 2.47 - struct kvec *iovec; 2.48 - int ret = -EFAULT, v = 0; 2.49 - 2.50 - if (copy_from_user(&xt, (void *)data, sizeof(xt))) 2.51 - return -EFAULT; 2.52 - 2.53 - iovec = kmalloc(xt.num_vecs * sizeof(struct kvec), GFP_KERNEL); 2.54 - if (iovec == NULL) 2.55 - return -ENOMEM; 2.56 + struct xenbus_dev_data *data = filp->private_data; 2.57 + struct xsd_sockmsg msg; 2.58 + int err; 2.59 2.60 - if (copy_from_user(iovec, xt.iovec, 2.61 - xt.num_vecs * sizeof(struct kvec))) 2.62 - goto out; 2.63 + /* Refill empty buffer? */ 2.64 + if (data->bytes_left == 0) { 2.65 + if (len < sizeof(msg)) 2.66 + return -EINVAL; 2.67 2.68 - for (v = 0; v < xt.num_vecs; v++) { 2.69 - base = iovec[v].iov_base; 2.70 - iovec[v].iov_base = kmalloc(iovec[v].iov_len, GFP_KERNEL); 2.71 - if (iovec[v].iov_base == NULL || 2.72 - copy_from_user(iovec[v].iov_base, base, iovec[v].iov_len)) 2.73 - { 2.74 - if (iovec[v].iov_base) 2.75 - kfree(iovec[v].iov_base); 2.76 - else 2.77 - ret = -ENOMEM; 2.78 - v--; 2.79 - goto out; 2.80 - } 2.81 + err = xb_read(&msg, sizeof(msg)); 2.82 + if (err) 2.83 + return err; 2.84 + data->bytes_left = msg.len; 2.85 + if (ubuf && copy_to_user(ubuf, &msg, sizeof(msg)) != 0) 2.86 + return -EFAULT; 2.87 + /* We can receive spurious XS_WATCH_EVENT messages. */ 2.88 + if (msg.type != XS_WATCH_EVENT) 2.89 + data->awaiting_reply = 0; 2.90 + return sizeof(msg); 2.91 } 2.92 2.93 - resp = xs_talkv(xt.type, iovec, xt.num_vecs, &len); 2.94 - if (IS_ERR(resp)) { 2.95 - ret = PTR_ERR(resp); 2.96 - goto out; 2.97 - } 2.98 + /* Don't read over next header, or over temporary buffer. */ 2.99 + if (len > sizeof(data->u.buffer)) 2.100 + len = sizeof(data->u.buffer); 2.101 + if (len > data->bytes_left) 2.102 + len = data->bytes_left; 2.103 2.104 - switch (xt.type) { 2.105 - case XS_TRANSACTION_START: 2.106 - u->in_transaction = 1; 2.107 - break; 2.108 - case XS_TRANSACTION_END: 2.109 - u->in_transaction = 0; 2.110 - break; 2.111 - default: 2.112 - break; 2.113 - } 2.114 + err = xb_read(data->u.buffer, len); 2.115 + if (err) 2.116 + return err; 2.117 2.118 - ret = len; 2.119 - if (len > xt.len) 2.120 - len = xt.len; 2.121 - 2.122 - if (copy_to_user(xt.buf, resp, len)) 2.123 - ret = -EFAULT; 2.124 - 2.125 - kfree(resp); 2.126 - out: 2.127 - while (v-- > 0) 2.128 - kfree(iovec[v].iov_base); 2.129 - kfree(iovec); 2.130 - return ret; 2.131 + data->bytes_left -= len; 2.132 + if (ubuf && copy_to_user(ubuf, data->u.buffer, len) != 0) 2.133 + return -EFAULT; 2.134 + return len; 2.135 } 2.136 2.137 -static int xenbus_dev_ioctl(struct inode *inode, struct file *filp, 2.138 - unsigned int cmd, unsigned long data) 2.139 +/* We do v. basic sanity checking so they don't screw up kernel later. */ 2.140 +static ssize_t xenbus_dev_write(struct file *filp, 2.141 + const char __user *ubuf, 2.142 + size_t len, loff_t *ppos) 2.143 { 2.144 - struct xenbus_dev_data *u = filp->private_data; 2.145 - int ret = -ENOSYS; 2.146 + struct xenbus_dev_data *data = filp->private_data; 2.147 + int err; 2.148 2.149 - switch (cmd) { 2.150 - case IOCTL_XENBUS_DEV_TALKV: 2.151 - ret = xenbus_dev_talkv(u, data); 2.152 - break; 2.153 - default: 2.154 - ret = -EINVAL; 2.155 - break; 2.156 + /* We gather data in buffer until we're ready to send it. */ 2.157 + if (len > data->len + sizeof(data->u)) 2.158 + return -EINVAL; 2.159 + if (copy_from_user(data->u.buffer + data->len, ubuf, len) != 0) 2.160 + return -EFAULT; 2.161 + data->len += len; 2.162 + if (data->len >= sizeof(data->u.msg) + data->u.msg.len) { 2.163 + err = xb_write(data->u.buffer, data->len); 2.164 + if (err) 2.165 + return err; 2.166 + data->len = 0; 2.167 + data->awaiting_reply = 1; 2.168 } 2.169 - return ret; 2.170 + return len; 2.171 } 2.172 2.173 static int xenbus_dev_open(struct inode *inode, struct file *filp) 2.174 { 2.175 struct xenbus_dev_data *u; 2.176 2.177 + /* Don't try seeking. */ 2.178 + nonseekable_open(inode, filp); 2.179 + 2.180 u = kmalloc(sizeof(*u), GFP_KERNEL); 2.181 if (u == NULL) 2.182 return -ENOMEM; 2.183 @@ -155,20 +148,25 @@ static int xenbus_dev_open(struct inode 2.184 2.185 static int xenbus_dev_release(struct inode *inode, struct file *filp) 2.186 { 2.187 - struct xenbus_dev_data *u = filp->private_data; 2.188 + struct xenbus_dev_data *data = filp->private_data; 2.189 2.190 - if (u->in_transaction) 2.191 - xenbus_transaction_end(1); 2.192 + /* Discard any unread replies. */ 2.193 + while (data->bytes_left || data->awaiting_reply) 2.194 + xenbus_dev_read(filp, NULL, sizeof(data->u.buffer), NULL); 2.195 + 2.196 + /* Harmless if no transaction in progress. */ 2.197 + xenbus_transaction_end(1); 2.198 2.199 up(&xenbus_lock); 2.200 2.201 - kfree(u); 2.202 + kfree(data); 2.203 2.204 return 0; 2.205 } 2.206 2.207 static struct file_operations xenbus_dev_file_ops = { 2.208 - .ioctl = xenbus_dev_ioctl, 2.209 + .read = xenbus_dev_read, 2.210 + .write = xenbus_dev_write, 2.211 .open = xenbus_dev_open, 2.212 .release = xenbus_dev_release, 2.213 };
3.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c Mon Sep 12 20:46:37 2005 +0000 3.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c Mon Sep 12 21:12:16 2005 +0000 3.3 @@ -106,10 +106,10 @@ void xenbus_debug_write(const char *str, 3.4 } 3.5 3.6 /* Send message to xs, get kmalloc'ed reply. ERR_PTR() on error. */ 3.7 -void *xs_talkv(enum xsd_sockmsg_type type, 3.8 - const struct kvec *iovec, 3.9 - unsigned int num_vecs, 3.10 - unsigned int *len) 3.11 +static void *xs_talkv(enum xsd_sockmsg_type type, 3.12 + const struct kvec *iovec, 3.13 + unsigned int num_vecs, 3.14 + unsigned int *len) 3.15 { 3.16 struct xsd_sockmsg msg; 3.17 void *ret = NULL;
4.1 --- a/linux-2.6-xen-sparse/include/asm-xen/linux-public/xenbus_dev.h Mon Sep 12 20:46:37 2005 +0000 4.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 4.3 @@ -1,47 +0,0 @@ 4.4 -/* 4.5 - * xenbus_dev.h 4.6 - * 4.7 - * Copyright (c) 2005, Christian Limpach 4.8 - * 4.9 - * This file may be distributed separately from the Linux kernel, or 4.10 - * incorporated into other software packages, subject to the following license: 4.11 - * 4.12 - * Permission is hereby granted, free of charge, to any person obtaining a copy 4.13 - * of this source file (the "Software"), to deal in the Software without 4.14 - * restriction, including without limitation the rights to use, copy, modify, 4.15 - * merge, publish, distribute, sublicense, and/or sell copies of the Software, 4.16 - * and to permit persons to whom the Software is furnished to do so, subject to 4.17 - * the following conditions: 4.18 - * 4.19 - * The above copyright notice and this permission notice shall be included in 4.20 - * all copies or substantial portions of the Software. 4.21 - * 4.22 - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 4.23 - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 4.24 - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 4.25 - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 4.26 - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 4.27 - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 4.28 - * IN THE SOFTWARE. 4.29 - */ 4.30 - 4.31 -#ifndef _XENBUS_DEV_H_ 4.32 -#define _XENBUS_DEV_H_ 4.33 - 4.34 -struct xenbus_dev_talkv { 4.35 - enum xsd_sockmsg_type type; 4.36 - const struct kvec *iovec; 4.37 - unsigned int num_vecs; 4.38 - char *buf; 4.39 - unsigned int len; 4.40 -}; 4.41 - 4.42 -/* 4.43 - * @cmd: IOCTL_XENBUS_DEV_TALKV 4.44 - * @arg: struct xenbus_dev_talkv 4.45 - * Return: 0 on success, error code on failure. 4.46 - */ 4.47 -#define IOCTL_XENBUS_DEV_TALKV \ 4.48 - _IOC(_IOC_NONE, 'X', 0, sizeof(struct xenbus_dev_talkv)) 4.49 - 4.50 -#endif /* _XENBUS_DEV_H_ */
5.1 --- a/tools/xenstore/Makefile Mon Sep 12 20:46:37 2005 +0000 5.2 +++ b/tools/xenstore/Makefile Mon Sep 12 21:12:16 2005 +0000 5.3 @@ -17,7 +17,6 @@ BASECFLAGS+= -O3 $(PROFILE) 5.4 BASECFLAGS+= -I$(XEN_ROOT)/tools/libxc 5.5 BASECFLAGS+= -I$(XEN_ROOT)/xen/include/public 5.6 BASECFLAGS+= -I. 5.7 -BASECFLAGS+= -I$(XEN_ROOT)/linux-2.6-xen-sparse/include/asm-xen/linux-public 5.8 5.9 CFLAGS += $(BASECFLAGS) 5.10 LDFLAGS += $(PROFILE) -L$(XEN_LIBXC)
6.1 --- a/tools/xenstore/xs.c Mon Sep 12 20:46:37 2005 +0000 6.2 +++ b/tools/xenstore/xs.c Mon Sep 12 21:12:16 2005 +0000 6.3 @@ -36,12 +36,10 @@ 6.4 #include "xenstored.h" 6.5 #include "xs_lib.h" 6.6 #include "utils.h" 6.7 -#include "xenbus_dev.h" 6.8 6.9 struct xs_handle 6.10 { 6.11 int fd; 6.12 - enum { SOCK, DEV } type; 6.13 }; 6.14 6.15 /* Get the socket from the store daemon handle. 6.16 @@ -68,7 +66,6 @@ static struct xs_handle *get_socket(cons 6.17 h = malloc(sizeof(*h)); 6.18 if (h) { 6.19 h->fd = sock; 6.20 - h->type = SOCK; 6.21 return h; 6.22 } 6.23 } 6.24 @@ -82,16 +79,15 @@ static struct xs_handle *get_socket(cons 6.25 static struct xs_handle *get_dev(const char *connect_to) 6.26 { 6.27 int fd, saved_errno; 6.28 - struct xs_handle *h = NULL; 6.29 + struct xs_handle *h; 6.30 6.31 - fd = open(connect_to, O_RDONLY); 6.32 + fd = open(connect_to, O_RDWR); 6.33 if (fd < 0) 6.34 return NULL; 6.35 6.36 h = malloc(sizeof(*h)); 6.37 if (h) { 6.38 h->fd = fd; 6.39 - h->type = DEV; 6.40 return h; 6.41 } 6.42 6.43 @@ -190,9 +186,9 @@ static void *read_reply(int fd, enum xsd 6.44 } 6.45 6.46 /* Send message to xs, get malloc'ed reply. NULL and set errno on error. */ 6.47 -static void *xs_talkv_sock(struct xs_handle *h, enum xsd_sockmsg_type type, 6.48 - const struct iovec *iovec, unsigned int num_vecs, 6.49 - unsigned int *len) 6.50 +static void *xs_talkv(struct xs_handle *h, enum xsd_sockmsg_type type, 6.51 + const struct iovec *iovec, unsigned int num_vecs, 6.52 + unsigned int *len) 6.53 { 6.54 struct xsd_sockmsg msg; 6.55 void *ret = NULL; 6.56 @@ -253,54 +249,6 @@ close_fd: 6.57 return NULL; 6.58 } 6.59 6.60 -/* Send message to xs, get malloc'ed reply. NULL and set errno on error. */ 6.61 -static void *xs_talkv_dev(struct xs_handle *h, enum xsd_sockmsg_type type, 6.62 - const struct iovec *iovec, unsigned int num_vecs, 6.63 - unsigned int *len) 6.64 -{ 6.65 - struct xenbus_dev_talkv dt; 6.66 - char *buf; 6.67 - int err, buflen = 1024; 6.68 - 6.69 - again: 6.70 - buf = malloc(buflen); 6.71 - if (buf == NULL) { 6.72 - errno = ENOMEM; 6.73 - return NULL; 6.74 - } 6.75 - dt.type = type; 6.76 - dt.iovec = (struct kvec *)iovec; 6.77 - dt.num_vecs = num_vecs; 6.78 - dt.buf = buf; 6.79 - dt.len = buflen; 6.80 - err = ioctl(h->fd, IOCTL_XENBUS_DEV_TALKV, &dt); 6.81 - if (err < 0) { 6.82 - free(buf); 6.83 - errno = err; 6.84 - return NULL; 6.85 - } 6.86 - if (err > buflen) { 6.87 - free(buf); 6.88 - buflen = err; 6.89 - goto again; 6.90 - } 6.91 - if (len) 6.92 - *len = err; 6.93 - return buf; 6.94 -} 6.95 - 6.96 -/* Send message to xs, get malloc'ed reply. NULL and set errno on error. */ 6.97 -static void *xs_talkv(struct xs_handle *h, enum xsd_sockmsg_type type, 6.98 - const struct iovec *iovec, unsigned int num_vecs, 6.99 - unsigned int *len) 6.100 -{ 6.101 - if (h->type == SOCK) 6.102 - return xs_talkv_sock(h, type, iovec, num_vecs, len); 6.103 - if (h->type == DEV) 6.104 - return xs_talkv_dev(h, type, iovec, num_vecs, len); 6.105 - return NULL; 6.106 -} 6.107 - 6.108 /* free(), but don't change errno. */ 6.109 static void free_no_errno(void *p) 6.110 {