debuggers.hg

view xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_segment_proc.c @ 628:3e071d151e22

bitkeeper revision 1.329 (3f0d30d74QKz0HxzOWPKez8__UdvjQ)

Merge labyrinth.cl.cam.ac.uk:/auto/groups/xeno/users/rac61/xeno.bk
into labyrinth.cl.cam.ac.uk:/auto/groups/xeno/users/sos22/xeno.bk
author sos22@labyrinth.cl.cam.ac.uk
date Thu Jul 10 09:24:39 2003 +0000 (2003-07-10)
parents fdb4cc73ddc7 5ed7375f954a
children be5a056550e9 681598b3259f
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);
16 extern dev_t physdev_to_xldev(unsigned short physdev);
18 static void *proc_vhd_next(struct seq_file *s, void *v, loff_t *pos)
19 {
20 xen_segment_info_t *data;
22 if ( pos != NULL )
23 ++(*pos);
25 data = v;
26 return data->count-- ? NULL : v;
27 }
29 static void *proc_vhd_start(struct seq_file *s, loff_t *ppos)
30 {
31 loff_t pos = *ppos;
32 xen_segment_info_t *data;
34 data = kmalloc(sizeof(*data), GFP_KERNEL);
35 xenolinux_control_msg(XEN_BLOCK_PROBE_SEG_ALL, (char *)data, sizeof(*data));
36 data->count -= pos;
38 if (data->count > 0)
39 return data;
41 kfree(data);
42 return NULL;
43 }
45 static int proc_vhd_show(struct seq_file *s, void *v)
46 {
47 xen_segment_info_t *data = v;
49 seq_printf (s,
50 "%x %x %10.10s %x\n",
51 data->segments[data->count - 1].domain,
52 data->segments[data->count - 1].seg_nr,
53 data->segments[data->count - 1].key,
54 data->segments[data->count - 1].mode);
56 return 0;
57 }
59 static void proc_vhd_stop(struct seq_file *s, void *v)
60 {
61 kfree(v);
62 }
64 static struct seq_operations proc_vhd_op = {
65 .start = proc_vhd_start,
66 .next = proc_vhd_next,
67 .show = proc_vhd_show,
68 .stop = proc_vhd_stop
69 };
71 static int proc_open_vhd(struct inode *inode, struct file *file)
72 {
73 return seq_open(file, &proc_vhd_op);
74 }
77 #define isdelim(c) \
78 (c==' '||c==','||c=='\n'||c=='\r'||c=='\t'||c==':'||c=='('||c==')' ? 1 : 0)
80 char *get_string(char *string) /* a bit like strtok */
81 {
82 static char *temp;
83 int loop = 0;
85 if (string != NULL)
86 temp = string;
87 else
88 string = temp;
90 try_again:
92 while (!isdelim(string[loop]))
93 {
94 if (string[loop] == '\0')
95 return NULL;
96 loop++;
97 }
99 string[loop] = '\0';
100 temp = (string + loop + 1);
102 if (loop == 0)
103 {
104 string = temp;
105 goto try_again;
106 }
108 return string;
109 }
112 #define isdigit(c) (c >= '0' && c <= '9' ? 1 : 0)
113 unsigned long to_number(char *string) /* atoi */
114 {
115 unsigned long value = 0;
117 if (string == NULL) return 0;
119 while (!isdigit(*string) && *string != '\0') string++;
121 while (isdigit(*string))
122 {
123 value = value * 10 + (*string - '0');
124 string++;
125 }
127 return value;
128 }
130 static int proc_write_vhd(struct file *file, const char *buffer,
131 size_t count, loff_t *offp)
132 {
133 char *local = kmalloc((count + 1) * sizeof(char), GFP_KERNEL);
134 char *string;
135 int loop;
136 xv_disk_t xvd;
137 int res;
139 if (!local)
140 return -ENOMEM;
142 memset (&xvd, 0, sizeof(xvd));
144 if (copy_from_user(local, buffer, count))
145 {
146 res = -EFAULT;
147 goto out;
148 }
149 local[count] = '\0';
151 res = count;
152 string = get_string(local); /* domain specifier */
153 if (string == NULL)
154 {
155 goto out;
156 }
157 if (*string != 'd' && *string != 'D')
158 {
159 printk (KERN_ALERT
160 "error: domain specifier missing [%s]. should be \"domain\".\n",
161 string);
162 goto out;
163 }
165 string = get_string(NULL); /* domain number */
166 if (string == NULL)
167 {
168 printk (KERN_ALERT "error: domain number missing\n");
169 goto out;
170 }
171 xvd.domain = (int) to_number(string);
173 string = get_string(NULL);
174 if (string && (strcmp(string, "RO") == 0 || strcmp(string, "ro") == 0))
175 {
176 xvd.mode = XEN_DISK_READ_ONLY;
177 }
178 else if (string && (strcmp(string, "RW") == 0 || strcmp(string, "rw") == 0))
179 {
180 xvd.mode = XEN_DISK_READ_WRITE;
181 }
182 else
183 {
184 printk (KERN_ALERT
185 "error: bad mode [%s]. should be \"rw\" or \"ro\".\n",
186 string);
187 goto out;
188 }
190 string = get_string(NULL); /* look for Segment */
191 if (string == NULL || (*string != 's' && *string != 'S'))
192 {
193 printk (KERN_ALERT
194 "error: segment specifier missing [%s]. should be \"segment\".\n",
195 string);
196 goto out;
197 }
199 string = get_string(NULL); /* segment number */
200 if (string == NULL)
201 {
202 printk (KERN_ALERT "error: segment number missing\n");
203 goto out;
204 }
205 xvd.segment = (int) to_number(string);
207 string = get_string(NULL); /* look for key */
208 if (string == NULL || (*string != 'k' && *string != 'K'))
209 {
210 printk (KERN_ALERT
211 "error: key specifier missing [%s]. should be \"key\".\n",
212 string);
213 goto out;
214 }
215 string = get_string(NULL);
216 if (string == NULL || strlen(string) != XEN_SEGMENT_KEYSIZE)
217 {
218 printk (KERN_ALERT "error: key missing\n");
219 goto out;
220 }
221 memcpy(xvd.key, string, XEN_SEGMENT_KEYSIZE);
223 string = get_string(NULL); /* look for Extents */
224 if (string == NULL || (*string != 'e' && *string != 'E'))
225 {
226 printk (KERN_ALERT
227 "error: extents specifier missing [%s]. should be \"extents\".\n",
228 string);
229 goto out;
230 }
232 string = get_string(NULL); /* number of extents */
233 if (string == NULL)
234 {
235 printk (KERN_ALERT "error: number of extents missing\n");
236 goto out;
237 }
238 xvd.ext_count = (int) to_number(string);
240 /* ignore parenthesis */
242 for (loop = 0; loop < xvd.ext_count; loop++)
243 {
244 string = get_string(NULL); /* look for Disk */
245 if (string == NULL || (*string != 'd' && *string != 'D'))
246 {
247 printk (KERN_ALERT
248 "hmm, extent disk specifier missing [%s]. should be \"disk\".\n",
249 string);
250 goto out;
251 }
252 string = get_string(NULL); /* disk number */
253 if (string == NULL)
254 {
255 printk (KERN_ALERT "error: disk number missing\n");
256 goto out;
257 }
258 xvd.extents[loop].disk = xldev_to_physdev((int) to_number(string));
260 string = get_string(NULL); /* look for Offset */
261 if (string == NULL || (*string != 'o' && *string != 'O'))
262 {
263 printk (KERN_ALERT
264 "error: disk offset missing [%s]. should be \"offset\".\n",
265 string);
266 goto out;
267 }
268 string = get_string(NULL); /* offset */
269 if (string == NULL)
270 {
271 printk (KERN_ALERT "error: offset missing\n");
272 goto out;
273 }
274 xvd.extents[loop].offset = to_number(string);
276 string = get_string(NULL); /* look for Size */
277 if (string == NULL || (*string != 's' && *string != 'S'))
278 {
279 printk (KERN_ALERT
280 "error: extent size missing [%s]. should be \"size\".\n",
281 string);
282 goto out;
283 }
284 string = get_string(NULL); /* size */
285 if (string == NULL)
286 {
287 printk (KERN_ALERT "error: extent size missing\n");
288 goto out;
289 }
290 xvd.extents[loop].size = to_number(string);
291 }
293 xenolinux_control_msg(XEN_BLOCK_SEG_CREATE, (char *)&xvd, sizeof(xvd));
295 out:
296 kfree(local);
298 return res;
299 }
301 static struct file_operations proc_vhd_operations = {
302 open: proc_open_vhd,
303 read: seq_read,
304 llseek: seq_lseek,
305 release: seq_release,
306 write: proc_write_vhd
307 };
309 /******************************************************************/
311 int __init xlseg_proc_init(void)
312 {
313 vhd = create_proc_entry("xeno/dom0/vhd", 0644, NULL);
314 if (vhd == NULL)
315 {
316 panic ("xlseg_init: unable to create vhd proc entry\n");
317 }
318 vhd->data = NULL;
319 vhd->proc_fops = &proc_vhd_operations;
320 vhd->owner = THIS_MODULE;
322 printk(KERN_ALERT "XenoLinux Virtual Disk Device Monitor installed\n");
323 return 0;
324 }
326 static void __exit xlseg_proc_cleanup(void)
327 {
328 printk(KERN_ALERT "XenoLinux Virtual Disk Device Monitor uninstalled\n");
329 }
331 #ifdef MODULE
332 module_init(xlseg_proc_init);
333 module_exit(xlseg_proc_cleanup);
334 #endif