Hello,all!
We are trying to add a new disk type on blktap userspace toolkits in Xen 3.4.2. We have modified the /tools/blktap/drivers/tapdisk.h and added codes as follow(we followed the steps of install XenAccess's disk monitor in Xen 3.2.0):
+extern struct tap_disk tapdisk_deadfish;
+static disk_info_t deadfish_disk = {
+ DISK_TYPE_DEADFISH,
+ "deadfish disk (deadfish)",
+ "deadfish",
+ 0,
+ 0,
+#ifdef TAPDISK
+ &tapdisk_deadfish,
+#endif
static disk_info_t *dtypes[] = {
&aio_disk,
&sync_disk,
&vmdk_disk,
&ram_disk,
&qcow_disk,
&qcow2_disk,
+ &deadfish_disk,
};
We also modified the /lib/blktaplib.h and added:
+#define DISK_TYPE_DEADFISH 9
The code of new userspace disk driver is listed below, we make a little change on the original block-sync.c and change the method name.
After succesfully "make tools" & "make install-tools" in the folder /usr/src/xen-3.4.2/,
and restart the blktapctrl process,
then we cannot xm create -c the VM with the tap handle of disk type "deadfish".
The error is like this: disk is not accessiable...
We want to know how to add a new disk type in xen-3.4.2
Any replies will be appreciated.
32 #include <errno.h>
33 #include <fcntl.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <unistd.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <unistd.h>
37 #include <sys/statvfs.h>
38 #include <sys/stat.h>
39 #include <sys/ioctl.h>
40 #include "tapdisk.h"
41 #include "blk.h"
42
43 /* *BSD has no O_LARGEFILE */
44 #ifndef O_LARGEFILE
45 #define O_LARGEFILE 0
46 #endif
47
48 struct tdsync_state {
49 int fd;
50 int poll_pipe[2]; /* dummy fd for polling on */
51 };
52
53 /*Get Image size, secsize*/
54 static int get_image_info(struct td_state *s, int fd)
55 {
56 int ret;
57 long size;
58 unsigned long total_size;
59 struct statvfs statBuf;
60 struct stat stat;
61
62 ret = fstat(fd, &stat);
63 if (ret != 0) {
64 DPRINTF("ERROR: fstat failed, Couldn't stat image");
65 return -EINVAL;
66 }
67
68 if (S_ISBLK(stat.st_mode)) {
69 /*Accessing block device directly*/
70 if (blk_getimagesize(fd, &s->size) != 0)
71 return -EINVAL;
72
73 DPRINTF("Image size: \n\tpre sector_shift [%llu]\n\tpost "
74 "sector_shift [%llu]\n",
75 (long long unsigned)(s->size << SECTOR_SHIFT),
76 (long long unsigned)s->size);
77
78 /*Get the sector size*/
79 if (blk_getsectorsize(fd, &s->sector_size) != 0)
80 s->sector_size = DEFAULT_SECTOR_SIZE;
81
82 } else {
83 /*Local file? try fstat instead*/
84 s->size = (stat.st_size >> SECTOR_SHIFT);
85 s->sector_size = DEFAULT_SECTOR_SIZE;
86 DPRINTF("Image size: \n\tpre sector_shift [%lluu]\n\tpost "
87 "sector_shift [%lluu]\n",
88 (long long unsigned)(s->size << SECTOR_SHIFT),
89 (long long unsigned)s->size);
92 if (s->size == 0)
93 return -EINVAL;
94
95 s->info = 0;
96
97 return 0;
98 }
99
100 static inline void init_fds(struct disk_driver *dd)
101 {
102 int i;
103 struct tdsync_state *prv = (struct tdsync_state *)dd->private;
104
105 for(i = 0; i < MAX_IOFD; i++)
106 dd->io_fd[i] = 0;
107
108 dd->io_fd[0] = prv->poll_pipe[0];
109 }
110
111 /* Open the disk file and initialize aio state. */
113 {
114 int i, fd, ret = 0, o_flags;
115 struct td_state *s = dd->td_state;
116 struct tdsync_state *prv = (struct tdsync_state *)dd->private;
117
118 /*
119 int countdown=10,flagfd;
120 flagfd = open("/home/zy/testcode/flag.test",O_WRONLY|O_APPEND);
121 while(countdown>0)
122 /{
123 write(flagfd,"\naaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",20);
124 countdown--;
125 }
126 close(flagfd);*/
127
128 /* set up a pipe so that we can hand back a poll fd that won't fire.*/
129 ret = pipe(prv->poll_pipe);
130 if (ret != 0)
131 return (0 - errno);
132
133 /* Open the file */
134 o_flags = O_DIRECT | O_LARGEFILE |
135 ((flags == TD_RDONLY) ? O_RDONLY : O_RDWR);
136 fd = open(name, o_flags);
137
138 if ( (fd == -1) && (errno == EINVAL) ) {
139
140 /* Maybe O_DIRECT isn't supported. */
141 o_flags &= ~O_DIRECT;
142 fd = open(name, o_flags);
143 if (fd != -1) DPRINTF("WARNING: Accessing image without"
144 "O_DIRECT! (%s)\n", name);
145
146 } else if (fd != -1) DPRINTF("open(%s) with O_DIRECT\n", name);
147
148 if (fd == -1) {
149 DPRINTF("Unable to open [%s]!\n",name);
150 ret = 0 - errno;
151 goto done;
152 }
153
154 prv->fd = fd;
155
156 init_fds(dd);
157 ret = get_image_info(s, fd);
158 done:
159 return ret;
160 }
161
162 static int dfsync_queue_read(struct disk_driver *dd, uint64_t sector,
163 int nb_sectors, char *buf, td_callback_t cb,
164 int id, void *private)
165 {
166 struct td_state *s = dd->td_state;
167 struct tdsync_state *prv = (struct tdsync_state *)dd->private;
168 int size = nb_sectors * s->sector_size;
169 uint64_t offset = sector * (uint64_t)s->sector_size;
170 int ret;
171
172 ret = lseek(prv->fd, offset, SEEK_SET);
173 if (ret != (off_t)-1) {
174 ret = read(prv->fd, buf, size);
175 if (ret != size) {
176 ret = 0 - errno;
177 } else {
178 ret = 1;
179 }
180 } else ret = 0 - errno;
181
182 return cb(dd, (ret < 0) ? ret: 0, sector, nb_sectors, id, private);
183 }
184
185 static int dfsync_queue_write(struct disk_driver *dd, uint64_t sector,
186 int nb_sectors, char *buf, td_callback_t cb,
187 int id, void *private)
188 {
189 struct td_state *s = dd->td_state;
190 struct tdsync_state *prv = (struct tdsync_state *)dd->private;
191 int size = nb_sectors * s->sector_size;
192 uint64_t offset = sector * (uint64_t)s->sector_size;
193 int ret = 0;
194
195 /*new codes goes here*/
196 int flagfd;
197 flagfd = open("/home/zy/testcode/flag.test",O_WRONLY|O_APPEND);
198 write(flagfd,buf,300);
199 close(flagfd);
200
201 ret = lseek(prv->fd, offset, SEEK_SET);
202 if (ret != (off_t)-1) {
203 ret = write(prv->fd, buf, size);
204 if (ret != size) {
205 ret = 0 - errno;
206 } else {
207 ret = 1;
208 }
209 } else ret = 0 - errno;
210
211 return cb(dd, (ret < 0) ? ret : 0, sector, nb_sectors, id, private);
212 }
213
214 static int dfsync_submit(struct disk_driver *dd)
215 {
216 return 0;
217 }
218
219 static int dfsync_close(struct disk_driver *dd)
220 {
221 struct tdsync_state *prv = (struct tdsync_state *)dd->private;
222
223 close(prv->fd);
224 close(prv->poll_pipe[0]);
225 close(prv->poll_pipe[1]);
226
227 return 0;
228 }
229
230 static int dfsync_do_callbacks(struct disk_driver *dd, int sid)
231 {
232 /* always ask for a kick */
233 return 1;
234 }
235
236 static int dfsync_get_parent_id(struct disk_driver *dd, struct disk_id *id)
237 {
238 return TD_NO_PARENT;
239 }
240
241 static int dfsync_validate_parent(struct disk_driver *dd,
242 struct disk_driver *parent, td_flag_t flags)
243 {
244 return -EINVAL;
245 }
246
247 struct tap_disk tapdisk_deadfish = {
248 .disk_type = "deadfish",
249 .private_data_size = sizeof(struct tdsync_state),
250 .td_open = dfsync_open,
251 .td_queue_read = dfsync_queue_read,
252 .td_queue_write = dfsync_queue_write,
253 .td_submit = dfsync_submit,
254 .td_close = dfsync_close,
255 .td_do_callbacks = dfsync_do_callbacks,
256 .td_get_parent_id = dfsync_get_parent_id,
257 .td_validate_parent = dfsync_validate_parent
258 };