debuggers.hg

view xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_segment_proc.c @ 648:cda951fc1bef

bitkeeper revision 1.341 (3f1120a2WW6KGE81TArq_p654xy38Q)

Merge labyrinth.cl.cam.ac.uk:/auto/groups/xeno/BK/xeno.bk
into labyrinth.cl.cam.ac.uk:/auto/anfs/scratch/labyrinth/iap10/xeno-clone/xeno.bk
author iap10@labyrinth.cl.cam.ac.uk
date Sun Jul 13 09:04:34 2003 +0000 (2003-07-13)
parents 681598b3259f 9339f3942f4e
children
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 static void *proc_vhd_next(struct seq_file *s, void *v, loff_t *pos)
16 {
17 xen_segment_info_t *data;
19 if ( pos != NULL )
20 ++(*pos);
22 data = v;
23 return data->count-- ? NULL : v;
24 }
26 static void *proc_vhd_start(struct seq_file *s, loff_t *ppos)
27 {
28 loff_t pos = *ppos;
29 xen_segment_info_t *data;
31 data = kmalloc(sizeof(*data), GFP_KERNEL);
32 xenolinux_control_msg(XEN_BLOCK_PROBE_SEG_ALL, (char *)data, sizeof(*data));
33 data->count -= pos;
35 if (data->count > 0)
36 return data;
38 kfree(data);
39 return NULL;
40 }
42 static int proc_vhd_show(struct seq_file *s, void *v)
43 {
44 xen_segment_info_t *data = v;
46 seq_printf (s,
47 "%x %x %10.10s %x\n",
48 data->segments[data->count - 1].domain,
49 data->segments[data->count - 1].seg_nr,
50 data->segments[data->count - 1].key,
51 data->segments[data->count - 1].mode);
53 return 0;
54 }
56 static void proc_vhd_stop(struct seq_file *s, void *v)
57 {
58 kfree(v);
59 }
61 static struct seq_operations proc_vhd_op = {
62 .start = proc_vhd_start,
63 .next = proc_vhd_next,
64 .show = proc_vhd_show,
65 .stop = proc_vhd_stop
66 };
68 static int proc_open_vhd(struct inode *inode, struct file *file)
69 {
70 return seq_open(file, &proc_vhd_op);
71 }
74 #define isdelim(c) \
75 (c==' '||c==','||c=='\n'||c=='\r'||c=='\t'||c==':'||c=='('||c==')' ? 1 : 0)
77 char *get_string(char *string) /* a bit like strtok */
78 {
79 static char *temp;
80 int loop = 0;
82 if (string != NULL)
83 temp = string;
84 else
85 string = temp;
87 try_again:
89 while (!isdelim(string[loop]))
90 {
91 if (string[loop] == '\0')
92 return NULL;
93 loop++;
94 }
96 string[loop] = '\0';
97 temp = (string + loop + 1);
99 if (loop == 0)
100 {
101 string = temp;
102 goto try_again;
103 }
105 return string;
106 }
109 #define isdigit(c) (c >= '0' && c <= '9' ? 1 : 0)
110 unsigned long to_number(char *string) /* atoi */
111 {
112 unsigned long value = 0;
114 if (string == NULL) return 0;
116 while (!isdigit(*string) && *string != '\0') string++;
118 while (isdigit(*string))
119 {
120 value = value * 10 + (*string - '0');
121 string++;
122 }
124 return value;
125 }
127 static int proc_write_vhd(struct file *file, const char *buffer,
128 size_t count, loff_t *offp)
129 {
130 char *local = kmalloc((count + 1) * sizeof(char), GFP_KERNEL);
131 char *string;
132 int loop;
133 xv_disk_t xvd;
134 int res;
136 if (!local)
137 return -ENOMEM;
139 memset (&xvd, 0, sizeof(xvd));
141 if (copy_from_user(local, buffer, count))
142 {
143 res = -EFAULT;
144 goto out;
145 }
146 local[count] = '\0';
148 res = count;
149 string = get_string(local); /* domain specifier */
150 if (string == NULL)
151 {
152 goto out;
153 }
154 if (*string != 'd' && *string != 'D')
155 {
156 printk (KERN_ALERT
157 "error: domain specifier missing [%s]. should be \"domain\".\n",
158 string);
159 goto out;
160 }
162 string = get_string(NULL); /* domain number */
163 if (string == NULL)
164 {
165 printk (KERN_ALERT "error: domain number missing\n");
166 goto out;
167 }
168 xvd.domain = (int) to_number(string);
170 string = get_string(NULL);
171 if (string && (strcmp(string, "RO") == 0 || strcmp(string, "ro") == 0))
172 {
173 xvd.mode = XEN_DISK_READ_ONLY;
174 }
175 else if (string && (strcmp(string, "RW") == 0 || strcmp(string, "rw") == 0))
176 {
177 xvd.mode = XEN_DISK_READ_WRITE;
178 }
179 else
180 {
181 printk (KERN_ALERT
182 "error: bad mode [%s]. should be \"rw\" or \"ro\".\n",
183 string);
184 goto out;
185 }
187 string = get_string(NULL); /* look for Segment */
188 if (string == NULL || (*string != 's' && *string != 'S'))
189 {
190 printk (KERN_ALERT
191 "error: segment specifier missing [%s]. should be \"segment\".\n",
192 string);
193 goto out;
194 }
196 string = get_string(NULL); /* segment number */
197 if (string == NULL)
198 {
199 printk (KERN_ALERT "error: segment number missing\n");
200 goto out;
201 }
202 xvd.segment = (int) to_number(string);
204 string = get_string(NULL); /* look for key */
205 if (string == NULL || (*string != 'k' && *string != 'K'))
206 {
207 printk (KERN_ALERT
208 "error: key specifier missing [%s]. should be \"key\".\n",
209 string);
210 goto out;
211 }
212 string = get_string(NULL);
213 if (string == NULL || strlen(string) != XEN_SEGMENT_KEYSIZE)
214 {
215 printk (KERN_ALERT "error: key missing\n");
216 goto out;
217 }
218 memcpy(xvd.key, string, XEN_SEGMENT_KEYSIZE);
220 string = get_string(NULL); /* look for Extents */
221 if (string == NULL || (*string != 'e' && *string != 'E'))
222 {
223 printk (KERN_ALERT
224 "error: extents specifier missing [%s]. should be \"extents\".\n",
225 string);
226 goto out;
227 }
229 string = get_string(NULL); /* number of extents */
230 if (string == NULL)
231 {
232 printk (KERN_ALERT "error: number of extents missing\n");
233 goto out;
234 }
235 xvd.ext_count = (int) to_number(string);
237 /* ignore parenthesis */
239 for (loop = 0; loop < xvd.ext_count; loop++)
240 {
241 string = get_string(NULL); /* look for Disk */
242 if (string == NULL || (*string != 'd' && *string != 'D'))
243 {
244 printk (KERN_ALERT
245 "hmm, extent disk specifier missing [%s]. should be \"disk\".\n",
246 string);
247 goto out;
248 }
249 string = get_string(NULL); /* disk number */
250 if (string == NULL)
251 {
252 printk (KERN_ALERT "error: disk number missing\n");
253 goto out;
254 }
255 xvd.extents[loop].disk = xldev_to_physdev((int) to_number(string));
257 string = get_string(NULL); /* look for Offset */
258 if (string == NULL || (*string != 'o' && *string != 'O'))
259 {
260 printk (KERN_ALERT
261 "error: disk offset missing [%s]. should be \"offset\".\n",
262 string);
263 goto out;
264 }
265 string = get_string(NULL); /* offset */
266 if (string == NULL)
267 {
268 printk (KERN_ALERT "error: offset missing\n");
269 goto out;
270 }
271 xvd.extents[loop].offset = to_number(string);
273 string = get_string(NULL); /* look for Size */
274 if (string == NULL || (*string != 's' && *string != 'S'))
275 {
276 printk (KERN_ALERT
277 "error: extent size missing [%s]. should be \"size\".\n",
278 string);
279 goto out;
280 }
281 string = get_string(NULL); /* size */
282 if (string == NULL)
283 {
284 printk (KERN_ALERT "error: extent size missing\n");
285 goto out;
286 }
287 xvd.extents[loop].size = to_number(string);
288 }
290 xenolinux_control_msg(XEN_BLOCK_SEG_CREATE, (char *)&xvd, sizeof(xvd));
292 out:
293 kfree(local);
295 return res;
296 }
298 static struct file_operations proc_vhd_operations = {
299 open: proc_open_vhd,
300 read: seq_read,
301 llseek: seq_lseek,
302 release: seq_release,
303 write: proc_write_vhd
304 };
306 /******************************************************************/
308 int __init xlseg_proc_init(void)
309 {
310 if ( !(start_info.flags & SIF_PRIVILEGED) )
311 return 0;
313 vhd = create_proc_entry("xeno/vhd", 0600, NULL);
314 if ( vhd == NULL )
315 panic ("xlseg_init: unable to create vhd proc entry\n");
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