ia64/xen-unstable

view tools/blktap2/drivers/block-ram.c @ 19817:b7f73a7f3078

blktap2: portability fixes for NetBSD

- Use standard off_t and lseek() instead of non-portable off64_t and
lseek64()
- Use uuid API as documented in DCE 1.1 RPC specification
- Add NetBSD implementation for blk_getimagesize() and
blk_getsectorsize()
- Use blk_getimagesize() and blk_getsectorsize()
- Fix uuid header check

Signed-off-by: Christoph Egger <Christoph.Egger@amd.com>
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Tue Jun 23 17:24:14 2009 +0100 (2009-06-23)
parents 1c627434605e
children 7750bae3d042
line source
1 /*
2 * Copyright (c) 2007, XenSource Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of XenSource Inc. nor the names of its contributors
13 * may be used to endorse or promote products derived from this software
14 * without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
20 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
29 #include <errno.h>
30 #include <fcntl.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <unistd.h>
34 #include <sys/statvfs.h>
35 #include <sys/stat.h>
36 #include <sys/ioctl.h>
37 #include <string.h>
39 #include "blk.h"
40 #include "tapdisk.h"
41 #include "tapdisk-driver.h"
42 #include "tapdisk-interface.h"
44 char *img;
45 long int disksector_size;
46 long int disksize;
47 long int diskinfo;
48 static int connections = 0;
50 struct tdram_state {
51 int fd;
52 };
54 /*Get Image size, secsize*/
55 static int get_image_info(int fd, td_disk_info_t *info)
56 {
57 int ret;
58 long size;
59 unsigned long total_size;
60 struct statvfs statBuf;
61 struct stat stat;
63 ret = fstat(fd, &stat);
64 if (ret != 0) {
65 DPRINTF("ERROR: fstat failed, Couldn't stat image");
66 return -EINVAL;
67 }
69 if (S_ISBLK(stat.st_mode)) {
70 /*Accessing block device directly*/
71 info->size = 0;
72 if (blk_getimagesize(fd, &info->size) != 0)
73 return -EINVAL;
75 DPRINTF("Image size: \n\tpre sector_shift [%llu]\n\tpost "
76 "sector_shift [%llu]\n",
77 (long long unsigned)(info->size << SECTOR_SHIFT),
78 (long long unsigned)info->size);
80 /*Get the sector size*/
81 if (blk_getsectorsize(fd, &info->sector_size) != 0)
82 info->sector_size = DEFAULT_SECTOR_SIZE;
84 } else {
85 /*Local file? try fstat instead*/
86 info->size = (stat.st_size >> SECTOR_SHIFT);
87 info->sector_size = DEFAULT_SECTOR_SIZE;
88 DPRINTF("Image size: \n\tpre sector_shift [%llu]\n\tpost "
89 "sector_shift [%llu]\n",
90 (long long unsigned)(info->size << SECTOR_SHIFT),
91 (long long unsigned)info->size);
92 }
94 if (info->size == 0) {
95 info->size =((uint64_t) MAX_RAMDISK_SIZE);
96 info->sector_size = DEFAULT_SECTOR_SIZE;
97 }
98 info->info = 0;
100 /*Store variables locally*/
101 disksector_size = info->sector_size;
102 disksize = info->size;
103 diskinfo = info->info;
104 DPRINTF("Image sector_size: \n\t[%lu]\n",
105 info->sector_size);
107 return 0;
108 }
110 /* Open the disk file and initialize ram state. */
111 int tdram_open (td_driver_t *driver, const char *name, td_flag_t flags)
112 {
113 char *p;
114 uint64_t size;
115 int i, fd, ret = 0, count = 0, o_flags;
116 struct tdram_state *prv = (struct tdram_state *)driver->data;
118 connections++;
120 if (connections > 1) {
121 driver->info.sector_size = disksector_size;
122 driver->info.size = disksize;
123 driver->info.info = diskinfo;
124 DPRINTF("Image already open, returning parameters:\n");
125 DPRINTF("Image size: \n\tpre sector_shift [%llu]\n\tpost "
126 "sector_shift [%llu]\n",
127 (long long unsigned)(driver->info.size << SECTOR_SHIFT),
128 (long long unsigned)driver->info.size);
129 DPRINTF("Image sector_size: \n\t[%lu]\n",
130 driver->info.sector_size);
132 prv->fd = -1;
133 goto done;
134 }
136 /* Open the file */
137 o_flags = O_DIRECT | O_LARGEFILE |
138 ((flags == TD_OPEN_RDONLY) ? O_RDONLY : O_RDWR);
139 fd = open(name, o_flags);
141 if ((fd == -1) && (errno == EINVAL)) {
143 /* Maybe O_DIRECT isn't supported. */
144 o_flags &= ~O_DIRECT;
145 fd = open(name, o_flags);
146 if (fd != -1) DPRINTF("WARNING: Accessing image without"
147 "O_DIRECT! (%s)\n", name);
149 } else if (fd != -1) DPRINTF("open(%s) with O_DIRECT\n", name);
151 if (fd == -1) {
152 DPRINTF("Unable to open [%s]!\n",name);
153 ret = 0 - errno;
154 goto done;
155 }
157 prv->fd = fd;
159 ret = get_image_info(fd, &driver->info);
160 size = MAX_RAMDISK_SIZE;
162 if (driver->info.size > size) {
163 DPRINTF("Disk exceeds limit, must be less than [%d]MB",
164 (MAX_RAMDISK_SIZE<<SECTOR_SHIFT)>>20);
165 return -ENOMEM;
166 }
168 /*Read the image into memory*/
169 if (posix_memalign((void **)&img,
170 DEFAULT_SECTOR_SIZE,
171 driver->info.size << SECTOR_SHIFT)) {
172 DPRINTF("Mem malloc failed\n");
173 return -errno;
174 }
175 p = img;
176 DPRINTF("Reading %llu bytes.......",
177 (long long unsigned)driver->info.size << SECTOR_SHIFT);
179 for (i = 0; i < driver->info.size; i++) {
180 ret = read(prv->fd, p, driver->info.sector_size);
181 if (ret != driver->info.sector_size) {
182 DPRINTF("ret = %d, errno = %d\n", ret, errno);
183 ret = 0 - errno;
184 break;
185 } else {
186 count += ret;
187 p = img + count;
188 }
189 }
190 DPRINTF("[%d]\n",count);
191 if (count != driver->info.size << SECTOR_SHIFT) {
192 ret = -1;
193 } else {
194 ret = 0;
195 }
197 done:
198 return ret;
199 }
201 void tdram_queue_read(td_driver_t *driver, td_request_t treq)
202 {
203 struct tdram_state *prv = (struct tdram_state *)driver->data;
204 int size = treq.secs * driver->info.sector_size;
205 uint64_t offset = treq.sec * (uint64_t)driver->info.sector_size;
207 memcpy(treq.buf, img + offset, size);
209 td_complete_request(treq, 0);
210 }
212 void tdram_queue_write(td_driver_t *driver, td_request_t treq)
213 {
214 struct tdram_state *prv = (struct tdram_state *)driver->data;
215 int size = treq.secs * driver->info.sector_size;
216 uint64_t offset = treq.sec * (uint64_t)driver->info.sector_size;
218 /* We assume that write access is controlled
219 * at a higher level for multiple disks */
220 memcpy(img + offset, treq.buf, size);
222 td_complete_request(treq, 0);
223 }
225 int tdram_close(td_driver_t *driver)
226 {
227 struct tdram_state *prv = (struct tdram_state *)driver->data;
229 connections--;
231 return 0;
232 }
234 int tdram_get_parent_id(td_driver_t *driver, td_disk_id_t *id)
235 {
236 return TD_NO_PARENT;
237 }
239 int tdram_validate_parent(td_driver_t *driver,
240 td_driver_t *pdriver, td_flag_t flags)
241 {
242 return -EINVAL;
243 }
245 struct tap_disk tapdisk_ram = {
246 .disk_type = "tapdisk_ram",
247 .flags = 0,
248 .private_data_size = sizeof(struct tdram_state),
249 .td_open = tdram_open,
250 .td_close = tdram_close,
251 .td_queue_read = tdram_queue_read,
252 .td_queue_write = tdram_queue_write,
253 .td_get_parent_id = tdram_get_parent_id,
254 .td_validate_parent = tdram_validate_parent,
255 .td_debug = NULL,
256 };