debuggers.hg

view xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_segment_proc.c @ 620:01725801761a

bitkeeper revision 1.322 (3f0d22cccb17_me9ZBYMkbZaFLovQg)

Get the new segment probing stuff to actually return useful
information...
author sos22@labyrinth.cl.cam.ac.uk
date Thu Jul 10 08:24:44 2003 +0000 (2003-07-10)
parents cc54519f9a1a
children fdb4cc73ddc7
line source
1 /*
2 * xl_segment_proc.c
3 *
4 * XenoLinux virtual disk proc interface .
5 */
7 #include "xl_block.h"
8 #include <linux/proc_fs.h>
9 #include <linux/delay.h>
10 #include <linux/seq_file.h>
11 #include <asm/hypervisor-ifs/segment.h>
13 static struct proc_dir_entry *vhd;
15 extern unsigned short xldev_to_physdev(kdev_t xldev);
17 static void *proc_vhd_next(struct seq_file *s, void *v, loff_t *pos)
18 {
19 xen_segment_info_t *data;
21 if ( pos != NULL )
22 ++(*pos);
24 data = v;
25 return data->count-- ? NULL : v;
26 }
28 static void *proc_vhd_start(struct seq_file *s, loff_t *ppos)
29 {
30 loff_t pos = *ppos;
31 xen_segment_info_t *data;
33 data = kmalloc(sizeof(*data), GFP_KERNEL);
34 xenolinux_control_msg(XEN_BLOCK_PROBE_SEG_ALL, (char *)data, sizeof(*data));
35 data->count -= pos;
37 if (data->count > 0)
38 return data;
40 kfree(data);
41 return NULL;
42 }
44 static int proc_vhd_show(struct seq_file *s, void *v)
45 {
46 xen_segment_info_t *data = v;
48 seq_printf (s,
49 "%x %x %10.10s %x\n",
50 data->segments[data->count - 1].domain,
51 data->segments[data->count - 1].seg_nr,
52 data->segments[data->count - 1].key,
53 data->segments[data->count - 1].device);
55 return 0;
56 }
58 static void proc_vhd_stop(struct seq_file *s, void *v)
59 {
60 kfree(v);
61 }
63 static struct seq_operations proc_vhd_op = {
64 .start = proc_vhd_start,
65 .next = proc_vhd_next,
66 .show = proc_vhd_show,
67 .stop = proc_vhd_stop
68 };
70 static int proc_open_vhd(struct inode *inode, struct file *file)
71 {
72 return seq_open(file, &proc_vhd_op);
73 }
76 #define isdelim(c) \
77 (c==' '||c==','||c=='\n'||c=='\r'||c=='\t'||c==':'||c=='('||c==')' ? 1 : 0)
79 char *get_string(char *string) /* a bit like strtok */
80 {
81 static char *temp;
82 int loop = 0;
84 if (string != NULL)
85 temp = string;
86 else
87 string = temp;
89 try_again:
91 while (!isdelim(string[loop]))
92 {
93 if (string[loop] == '\0')
94 return NULL;
95 loop++;
96 }
98 string[loop] = '\0';
99 temp = (string + loop + 1);
101 if (loop == 0)
102 {
103 string = temp;
104 goto try_again;
105 }
107 return string;
108 }
111 #define isdigit(c) (c >= '0' && c <= '9' ? 1 : 0)
112 unsigned long to_number(char *string) /* atoi */
113 {
114 unsigned long value = 0;
116 if (string == NULL) return 0;
118 while (!isdigit(*string) && *string != '\0') string++;
120 while (isdigit(*string))
121 {
122 value = value * 10 + (*string - '0');
123 string++;
124 }
126 return value;
127 }
129 static int proc_write_vhd(struct file *file, const char *buffer,
130 size_t count, loff_t *offp)
131 {
132 char *local = kmalloc((count + 1) * sizeof(char), GFP_KERNEL);
133 char *string;
134 int loop;
135 xv_disk_t xvd;
136 int res;
138 if (!local)
139 return -ENOMEM;
141 memset (&xvd, 0, sizeof(xvd));
143 if (copy_from_user(local, buffer, count))
144 {
145 res = -EFAULT;
146 goto out;
147 }
148 local[count] = '\0';
150 res = count;
151 string = get_string(local); /* domain specifier */
152 if (string == NULL)
153 {
154 goto out;
155 }
156 if (*string != 'd' && *string != 'D')
157 {
158 printk (KERN_ALERT
159 "error: domain specifier missing [%s]. should be \"domain\".\n",
160 string);
161 goto out;
162 }
164 string = get_string(NULL); /* domain number */
165 if (string == NULL)
166 {
167 printk (KERN_ALERT "error: domain number missing\n");
168 goto out;
169 }
170 xvd.domain = (int) to_number(string);
172 string = get_string(NULL);
173 if (string && (strcmp(string, "RO") == 0 || strcmp(string, "ro") == 0))
174 {
175 xvd.mode = XEN_DISK_READ_ONLY;
176 }
177 else if (string && (strcmp(string, "RW") == 0 || strcmp(string, "rw") == 0))
178 {
179 xvd.mode = XEN_DISK_READ_WRITE;
180 }
181 else
182 {
183 printk (KERN_ALERT
184 "error: bad mode [%s]. should be \"rw\" or \"ro\".\n",
185 string);
186 goto out;
187 }
189 string = get_string(NULL); /* look for Segment */
190 if (string == NULL || (*string != 's' && *string != 'S'))
191 {
192 printk (KERN_ALERT
193 "error: segment specifier missing [%s]. should be \"segment\".\n",
194 string);
195 goto out;
196 }
198 string = get_string(NULL); /* segment number */
199 if (string == NULL)
200 {
201 printk (KERN_ALERT "error: segment number missing\n");
202 goto out;
203 }
204 xvd.segment = (int) to_number(string);
206 string = get_string(NULL); /* look for key */
207 if (string == NULL || (*string != 'k' && *string != 'K'))
208 {
209 printk (KERN_ALERT
210 "error: key specifier missing [%s]. should be \"key\".\n",
211 string);
212 goto out;
213 }
214 string = get_string(NULL);
215 if (string == NULL || strlen(string) != XEN_SEGMENT_KEYSIZE)
216 {
217 printk (KERN_ALERT "error: key missing\n");
218 goto out;
219 }
220 memcpy(xvd.key, string, XEN_SEGMENT_KEYSIZE);
222 string = get_string(NULL); /* look for Extents */
223 if (string == NULL || (*string != 'e' && *string != 'E'))
224 {
225 printk (KERN_ALERT
226 "error: extents specifier missing [%s]. should be \"extents\".\n",
227 string);
228 goto out;
229 }
231 string = get_string(NULL); /* number of extents */
232 if (string == NULL)
233 {
234 printk (KERN_ALERT "error: number of extents missing\n");
235 goto out;
236 }
237 xvd.ext_count = (int) to_number(string);
239 /* ignore parenthesis */
241 for (loop = 0; loop < xvd.ext_count; loop++)
242 {
243 string = get_string(NULL); /* look for Disk */
244 if (string == NULL || (*string != 'd' && *string != 'D'))
245 {
246 printk (KERN_ALERT
247 "hmm, extent disk specifier missing [%s]. should be \"disk\".\n",
248 string);
249 goto out;
250 }
251 string = get_string(NULL); /* disk number */
252 if (string == NULL)
253 {
254 printk (KERN_ALERT "error: disk number missing\n");
255 goto out;
256 }
257 xvd.extents[loop].disk = xldev_to_physdev((int) to_number(string));
259 string = get_string(NULL); /* look for Offset */
260 if (string == NULL || (*string != 'o' && *string != 'O'))
261 {
262 printk (KERN_ALERT
263 "error: disk offset missing [%s]. should be \"offset\".\n",
264 string);
265 goto out;
266 }
267 string = get_string(NULL); /* offset */
268 if (string == NULL)
269 {
270 printk (KERN_ALERT "error: offset missing\n");
271 goto out;
272 }
273 xvd.extents[loop].offset = to_number(string);
275 string = get_string(NULL); /* look for Size */
276 if (string == NULL || (*string != 's' && *string != 'S'))
277 {
278 printk (KERN_ALERT
279 "error: extent size missing [%s]. should be \"size\".\n",
280 string);
281 goto out;
282 }
283 string = get_string(NULL); /* size */
284 if (string == NULL)
285 {
286 printk (KERN_ALERT "error: extent size missing\n");
287 goto out;
288 }
289 xvd.extents[loop].size = to_number(string);
290 }
292 xenolinux_control_msg(XEN_BLOCK_SEG_CREATE, (char *)&xvd, sizeof(xvd));
294 out:
295 kfree(local);
297 return res;
298 }
300 static struct file_operations proc_vhd_operations = {
301 open: proc_open_vhd,
302 read: seq_read,
303 llseek: seq_lseek,
304 release: seq_release,
305 write: proc_write_vhd
306 };
308 /******************************************************************/
310 int __init xlseg_proc_init(void)
311 {
312 vhd = create_proc_entry("xeno/dom0/vhd", 0644, NULL);
313 if (vhd == NULL)
314 {
315 panic ("xlseg_init: unable to create vhd proc entry\n");
316 }
317 vhd->data = NULL;
318 vhd->proc_fops = &proc_vhd_operations;
319 vhd->owner = THIS_MODULE;
321 printk(KERN_ALERT "XenoLinux Virtual Disk Device Monitor installed\n");
322 return 0;
323 }
325 static void __exit xlseg_proc_cleanup(void)
326 {
327 printk(KERN_ALERT "XenoLinux Virtual Disk Device Monitor uninstalled\n");
328 }
330 #ifdef MODULE
331 module_init(xlseg_proc_init);
332 module_exit(xlseg_proc_cleanup);
333 #endif