1 #include "libxlu_internal.h"
2 #include "libxlu_disk_l.h"
3 #include "libxlu_disk_i.h"
4 #include "libxlu_cfg_i.h"
5
xlu__disk_err(DiskParseContext * dpc,const char * erroneous,const char * message)6 void xlu__disk_err(DiskParseContext *dpc, const char *erroneous,
7 const char *message) {
8 fprintf(dpc->cfg->report,
9 "%s: config parsing error in disk specification: %s"
10 "%s%s%s"
11 " in `%s'\n",
12 dpc->cfg->config_source, message,
13 erroneous?": near `":"", erroneous?erroneous:"", erroneous?"'":"",
14 dpc->spec);
15 if (!dpc->err) dpc->err= EINVAL;
16 }
17
dpc_prep(DiskParseContext * dpc,const char * spec)18 static int dpc_prep(DiskParseContext *dpc, const char *spec) {
19 int e;
20
21 dpc->spec = spec;
22
23 e = xlu__disk_yylex_init_extra(dpc, &dpc->scanner);
24 if (e) goto fail;
25
26 dpc->buf = xlu__disk_yy_scan_bytes(spec, strlen(spec), dpc->scanner);
27 if (!dpc->buf) { e = ENOMEM; goto fail; }
28
29 return 0;
30
31 fail:
32 fprintf(dpc->cfg->report, "cannot init disk scanner: %s\n",
33 strerror(errno));
34 return e;
35 }
36
dpc_dispose(DiskParseContext * dpc)37 static void dpc_dispose(DiskParseContext *dpc) {
38 if (dpc->buf) {
39 xlu__disk_yy_delete_buffer(dpc->buf, dpc->scanner);
40 dpc->buf = 0;
41 }
42 if (dpc->scanner) {
43 xlu__disk_yylex_destroy(dpc->scanner);
44 dpc->scanner = 0;
45 }
46 }
47
xlu_disk_parse(XLU_Config * cfg,int nspecs,const char * const * specs,libxl_device_disk * disk)48 int xlu_disk_parse(XLU_Config *cfg,
49 int nspecs, const char *const *specs,
50 libxl_device_disk *disk) {
51 DiskParseContext dpc;
52 int i, e;
53
54 memset(&dpc,0,sizeof(dpc));
55 dpc.cfg = cfg;
56 dpc.scanner = 0;
57 dpc.disk = disk;
58
59 disk->readwrite = 1;
60
61 for (i=0; i<nspecs; i++) {
62 e = dpc_prep(&dpc, specs[i]);
63 if (e) { dpc.err = e; goto x_err; }
64
65 xlu__disk_yylex(dpc.scanner);
66 assert(!e);
67 if (dpc.err) goto x_err;
68
69 dpc_dispose(&dpc);
70 }
71
72 if (disk->format == LIBXL_DISK_FORMAT_UNKNOWN) {
73 disk->format = LIBXL_DISK_FORMAT_RAW;
74 }
75 if (disk->is_cdrom) {
76 disk->removable = 1;
77 disk->readwrite = 0;
78 if (!disk->pdev_path || !strcmp(disk->pdev_path, ""))
79 disk->format = LIBXL_DISK_FORMAT_EMPTY;
80 }
81
82 if (!disk->vdev) {
83 xlu__disk_err(&dpc,0, "no vdev specified");
84 goto x_err;
85 }
86 if (!disk->pdev_path && !disk->removable) {
87 xlu__disk_err(&dpc,0,"no target specified (and device not removable)");
88 goto x_err;
89 }
90
91 x_err:
92 dpc_dispose(&dpc);
93 return dpc.err;
94 }
95
96 /*
97 * Local variables:
98 * mode: C
99 * c-basic-offset: 4
100 * indent-tabs-mode: nil
101 * End:
102 */
103