1 /*
2  * Copyright 2009-2017 Citrix Ltd and other contributors
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License as published
6  * by the Free Software Foundation; version 2.1 only. with the special
7  * exception on linking described in file LICENSE.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU Lesser General Public License for more details.
13  */
14 
15 #include <stdlib.h>
16 #include <sys/types.h>
17 #include <sys/stat.h>
18 #include <unistd.h>
19 
20 #include <libxl.h>
21 #include <libxl_utils.h>
22 #include <libxlutil.h>
23 
24 #include "xl.h"
25 #include "xl_utils.h"
26 #include "xl_parse.h"
27 
cd_insert(uint32_t domid,const char * virtdev,char * phys)28 static int cd_insert(uint32_t domid, const char *virtdev, char *phys)
29 {
30     libxl_device_disk disk;
31     char *buf = NULL;
32     XLU_Config *config = 0;
33     struct stat b;
34     int r;
35 
36     xasprintf(&buf, "vdev=%s,access=r,devtype=cdrom,target=%s",
37               virtdev, phys ? phys : "");
38 
39     parse_disk_config(&config, buf, &disk);
40 
41     /* ATM the existence of the backing file is not checked for qdisk
42      * in libxl_cdrom_insert() because RAW is used for remote
43      * protocols as well as plain files.  This will ideally be changed
44      * for 4.4, but this work-around fixes the problem of "cd-insert"
45      * returning success for non-existent files. */
46     if (disk.format != LIBXL_DISK_FORMAT_EMPTY
47         && stat(disk.pdev_path, &b)) {
48         fprintf(stderr, "Cannot stat file: %s\n",
49                 disk.pdev_path);
50         r = 1;
51         goto out;
52     }
53 
54     if (libxl_cdrom_insert(ctx, domid, &disk, NULL)) {
55         r = 1;
56         goto out;
57     }
58 
59     r = 0;
60 
61 out:
62     libxl_device_disk_dispose(&disk);
63     free(buf);
64 
65     return r;
66 }
67 
main_cd_eject(int argc,char ** argv)68 int main_cd_eject(int argc, char **argv)
69 {
70     uint32_t domid;
71     int opt = 0;
72     const char *virtdev;
73 
74     SWITCH_FOREACH_OPT(opt, "", NULL, "cd-eject", 2) {
75         /* No options */
76     }
77 
78     domid = find_domain(argv[optind]);
79     virtdev = argv[optind + 1];
80 
81     if (cd_insert(domid, virtdev, NULL))
82         return EXIT_FAILURE;
83 
84     return EXIT_SUCCESS;
85 }
86 
main_cd_insert(int argc,char ** argv)87 int main_cd_insert(int argc, char **argv)
88 {
89     uint32_t domid;
90     int opt = 0;
91     const char *virtdev;
92     char *file = NULL; /* modified by cd_insert tokenising it */
93 
94     SWITCH_FOREACH_OPT(opt, "", NULL, "cd-insert", 3) {
95         /* No options */
96     }
97 
98     domid = find_domain(argv[optind]);
99     virtdev = argv[optind + 1];
100     file = argv[optind + 2];
101 
102     if (cd_insert(domid, virtdev, file))
103         return EXIT_FAILURE;
104 
105     return EXIT_SUCCESS;
106 }
107 
108 /*
109  * Local variables:
110  * mode: C
111  * c-basic-offset: 4
112  * indent-tabs-mode: nil
113  * End:
114  */
115