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