aboutsummaryrefslogtreecommitdiffstats
path: root/tools/blktap
diff options
context:
space:
mode:
authorJake Wires <jwires@xensource.com>2007-02-23 17:26:07 -0800
committerJake Wires <jwires@xensource.com>2007-02-23 17:26:07 -0800
commita3d17a18e59a22c7be99d6e82910af29568d0057 (patch)
treef87c22e4b2de1edb7ebd3212fedc7431029d33ca /tools/blktap
parent99a8295b9686e4addbc1469f8eea0014238e9e02 (diff)
downloadxen-a3d17a18e59a22c7be99d6e82910af29568d0057.tar.gz
xen-a3d17a18e59a22c7be99d6e82910af29568d0057.tar.bz2
xen-a3d17a18e59a22c7be99d6e82910af29568d0057.zip
[TAPDISK] honor read-only attributes when creating tap-based VBDs
Signed-off-by: Jake Wires <jwires@xensource.com>
Diffstat (limited to 'tools/blktap')
-rw-r--r--tools/blktap/drivers/blktapctrl.c2
-rw-r--r--tools/blktap/drivers/block-qcow.c2
-rw-r--r--tools/blktap/drivers/tapdisk.c40
-rw-r--r--tools/blktap/drivers/tapdisk.h1
-rw-r--r--tools/blktap/lib/blktaplib.h1
-rw-r--r--tools/blktap/lib/xenbus.c7
6 files changed, 38 insertions, 15 deletions
diff --git a/tools/blktap/drivers/blktapctrl.c b/tools/blktap/drivers/blktapctrl.c
index f2022fcc97..5f78cede2a 100644
--- a/tools/blktap/drivers/blktapctrl.c
+++ b/tools/blktap/drivers/blktapctrl.c
@@ -303,6 +303,7 @@ static int write_msg(int fd, int msgtype, void *ptr, void *ptr2)
msg->type = CTLMSG_PARAMS;
msg->len = msglen;
msg->drivertype = blkif->drivertype;
+ msg->readonly = blkif->readonly;
gettimeofday(&timeout, NULL);
msg->cookie = blkif->cookie;
@@ -410,7 +411,6 @@ static int read_msg(int fd, int msgtype, void *ptr)
if (select(fd+1, &readfds, (fd_set *) 0,
(fd_set *) 0, &timeout) > 0) {
ret = read(fd, buf, msglen);
-
}
if (ret > 0) {
msg = (msg_hdr_t *)buf;
diff --git a/tools/blktap/drivers/block-qcow.c b/tools/blktap/drivers/block-qcow.c
index 185c670111..36f77e6f05 100644
--- a/tools/blktap/drivers/block-qcow.c
+++ b/tools/blktap/drivers/block-qcow.c
@@ -422,7 +422,7 @@ static int qtruncate(int fd, off_t length, int sparse)
return -1;
if (S_ISBLK(st.st_mode))
return 0;
-
+
sectors = (length + DEFAULT_SECTOR_SIZE - 1)/DEFAULT_SECTOR_SIZE;
current = (st.st_size + DEFAULT_SECTOR_SIZE - 1)/DEFAULT_SECTOR_SIZE;
rem = st.st_size % DEFAULT_SECTOR_SIZE;
diff --git a/tools/blktap/drivers/tapdisk.c b/tools/blktap/drivers/tapdisk.c
index 965dbd9b7d..954901b2a8 100644
--- a/tools/blktap/drivers/tapdisk.c
+++ b/tools/blktap/drivers/tapdisk.c
@@ -268,7 +268,8 @@ static int map_new_dev(struct td_state *s, int minor)
}
static struct disk_driver *disk_init(struct td_state *s,
- struct tap_disk *drv, char *name)
+ struct tap_disk *drv,
+ char *name, td_flag_t flags)
{
struct disk_driver *dd;
@@ -285,14 +286,17 @@ static struct disk_driver *disk_init(struct td_state *s,
dd->drv = drv;
dd->td_state = s;
dd->name = name;
+ dd->flags = flags;
return dd;
}
-static int open_disk(struct td_state *s, struct tap_disk *drv, char *path)
+static int open_disk(struct td_state *s,
+ struct tap_disk *drv, char *path, td_flag_t flags)
{
int err;
char *dup;
+ td_flag_t pflags;
struct disk_id id;
struct disk_driver *d;
@@ -301,16 +305,17 @@ static int open_disk(struct td_state *s, struct tap_disk *drv, char *path)
return -ENOMEM;
memset(&id, 0, sizeof(struct disk_id));
- s->disks = d = disk_init(s, drv, dup);
+ s->disks = d = disk_init(s, drv, dup, flags);
if (!d)
return -ENOMEM;
- err = drv->td_open(d, path, 0);
+ err = drv->td_open(d, path, flags);
if (err) {
free_driver(d);
s->disks = NULL;
return -ENOMEM;
}
+ pflags = flags | TD_RDONLY;
/* load backing files as necessary */
while ((err = d->drv->td_get_parent_id(d, &id)) == 0) {
@@ -324,11 +329,11 @@ static int open_disk(struct td_state *s, struct tap_disk *drv, char *path)
if (!dup)
goto fail;
- new = disk_init(s, get_driver(id.drivertype), dup);
+ new = disk_init(s, get_driver(id.drivertype), dup, pflags);
if (!new)
goto fail;
- err = new->drv->td_open(new, new->name, TD_RDONLY);
+ err = new->drv->td_open(new, new->name, pflags);
if (err)
goto fail;
@@ -342,6 +347,8 @@ static int open_disk(struct td_state *s, struct tap_disk *drv, char *path)
free(id.name);
}
+ s->info |= ((flags & TD_RDONLY) ? VDISK_READONLY : 0);
+
if (err >= 0)
return 0;
@@ -404,7 +411,8 @@ static int read_msg(char *buf)
goto params_done;
/*Open file*/
- ret = open_disk(s, drv, path);
+ ret = open_disk(s, drv, path,
+ ((msg->readonly) ? TD_RDONLY : 0));
if (ret)
goto params_done;
@@ -510,7 +518,8 @@ void io_done(struct disk_driver *dd, int sid)
if (!run) return; /*We have received signal to close*/
- if (drv->td_do_callbacks(dd, sid) > 0) kick_responses(dd->td_state);
+ if (sid > MAX_IOFD || drv->td_do_callbacks(dd, sid) > 0)
+ kick_responses(dd->td_state);
return;
}
@@ -661,6 +670,12 @@ static void get_io_request(struct td_state *s)
sector_nr = req->sector_number;
}
+ if ((dd->flags & TD_RDONLY) &&
+ (req->operation == BLKIF_OP_WRITE)) {
+ blkif->pending_list[idx].status = BLKIF_RSP_ERROR;
+ goto send_response;
+ }
+
for (i = start_seg; i < req->nr_segments; i++) {
nsects = req->seg[i].last_sect -
req->seg[i].first_sect + 1;
@@ -726,10 +741,12 @@ static void get_io_request(struct td_state *s)
}
sector_nr += nsects;
}
+ send_response:
blkif->pending_list[idx].submitting = 0;
/* force write_rsp_to_ring for synchronous case */
if (blkif->pending_list[idx].secs_pending == 0)
- dd->early += send_responses(dd, 0, 0, 0, idx, (void *)0);
+ dd->early += send_responses(dd, 0, 0, 0, idx,
+ (void *)(long)0);
}
out:
@@ -737,7 +754,7 @@ static void get_io_request(struct td_state *s)
td_for_each_disk(s, dd) {
dd->early += dd->drv->td_submit(dd);
if (dd->early > 0) {
- io_done(dd, 10);
+ io_done(dd, MAX_IOFD + 1);
dd->early = 0;
}
}
@@ -820,7 +837,8 @@ int main(int argc, char *argv[])
dd->early +=
dd->drv->td_submit(dd);
if (dd->early > 0) {
- io_done(dd, 10);
+ io_done(dd,
+ MAX_IOFD + 1);
dd->early = 0;
}
}
diff --git a/tools/blktap/drivers/tapdisk.h b/tools/blktap/drivers/tapdisk.h
index b76d46cce5..5c68a5e9c8 100644
--- a/tools/blktap/drivers/tapdisk.h
+++ b/tools/blktap/drivers/tapdisk.h
@@ -94,6 +94,7 @@ struct disk_driver {
int early;
char *name;
void *private;
+ td_flag_t flags;
int io_fd[MAX_IOFD];
struct tap_disk *drv;
struct td_state *td_state;
diff --git a/tools/blktap/lib/blktaplib.h b/tools/blktap/lib/blktaplib.h
index 0ba3c04ec8..078a293185 100644
--- a/tools/blktap/lib/blktaplib.h
+++ b/tools/blktap/lib/blktaplib.h
@@ -173,6 +173,7 @@ typedef struct msg_hdr {
uint16_t len;
uint16_t drivertype;
uint16_t cookie;
+ uint8_t readonly;
} msg_hdr_t;
typedef struct msg_newdev {
diff --git a/tools/blktap/lib/xenbus.c b/tools/blktap/lib/xenbus.c
index d50e492784..fb36e748fe 100644
--- a/tools/blktap/lib/xenbus.c
+++ b/tools/blktap/lib/xenbus.c
@@ -177,8 +177,11 @@ static void ueblktap_setup(struct xs_handle *h, char *bepath)
}
/* Check to see if device is to be opened read-only. */
- asprintf(&path, "%s/%s", bepath, "read-only");
- if (xs_exists(h, path))
+ deverr = xs_gather(h, bepath, "mode", NULL, &path, NULL);
+ if (deverr) {
+ DPRINTF("ERROR: could not find read/write mode\n");
+ goto fail;
+ } else if (path[0] == 'r')
be->readonly = 1;
if (be->blkif == NULL) {