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