debuggers.hg

view tools/libxl/libxl_utils.c @ 20637:91555131e235

libxenlight: implement cdrom insert/eject

This patch implements functions in libxenlight to change the cdrom in
a VM at run time and to handle cdrom eject requests from guests.

This patch adds two new commands to xl: cd-insert and cd-eject; it
also modifies xl to handle cdrom eject requests coming from guests
(actually coming from qemu).

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Tue Dec 08 07:47:52 2009 +0000 (2009-12-08)
parents b647216151cd
children 74ca2cb026a5
line source
1 /*
2 * Copyright (C) 2009 Citrix Ltd.
3 * Author Stefano Stabellini <stefano.stabellini@eu.citrix.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License as published
7 * by the Free Software Foundation; version 2.1 only. with the special
8 * exception on linking described in file LICENSE.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public License for more details.
14 */
16 #include "libxl_osdeps.h"
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <stdint.h>
21 #include <string.h>
22 #include <xs.h>
23 #include <xenctrl.h>
24 #include <ctype.h>
25 #include <errno.h>
26 #include <sys/stat.h>
27 #include <sys/types.h>
28 #include <unistd.h>
30 #include "libxl_utils.h"
31 #include "libxl_internal.h"
34 unsigned long libxl_get_required_shadow_memory(unsigned long maxmem_kb, unsigned int smp_cpus)
35 {
36 /* 256 pages (1MB) per vcpu,
37 plus 1 page per MiB of RAM for the P2M map,
38 plus 1 page per MiB of RAM to shadow the resident processes.
39 This is higher than the minimum that Xen would allocate if no value
40 were given (but the Xen minimum is for safety, not performance).
41 */
42 return 4 * (256 * smp_cpus + 2 * (maxmem_kb / 1024));
43 }
45 char *libxl_domid_to_name(struct libxl_ctx *ctx, uint32_t domid)
46 {
47 unsigned int len;
48 char path[strlen("/local/domain") + 12];
49 char *s;
51 snprintf(path, sizeof(path), "/local/domain/%d/name", domid);
52 s = xs_read(ctx->xsh, XBT_NULL, path, &len);
53 libxl_ptr_add(ctx, s);
54 return s;
55 }
57 int libxl_name_to_domid(struct libxl_ctx *ctx, char *name, uint32_t *domid)
58 {
59 unsigned int num, len;
60 char path[strlen("/local/domain") + 12];
61 int i, j, nb_domains;
62 char *domname, **l;
63 struct libxl_dominfo *dominfo;
65 dominfo = libxl_domain_list(ctx, &nb_domains);
67 l = xs_directory(ctx->xsh, XBT_NULL, "/local/domain", &num);
68 for (i = 0; i < num; i++) {
69 snprintf(path, sizeof(path), "/local/domain/%s/name", l[i]);
70 domname = xs_read(ctx->xsh, XBT_NULL, path, &len);
71 if (domname != NULL && len == strlen(name) && !strncmp(domname, name, len)) {
72 int domid_i = atoi(l[i]);
73 for (j = 0; j < nb_domains; j++) {
74 if (dominfo[j].domid == domid_i) {
75 *domid = domid_i;
76 free(dominfo);
77 free(l);
78 free(domname);
79 return 0;
80 }
81 }
82 }
83 free(domname);
84 }
85 free(dominfo);
86 free(l);
87 return -1;
88 }
90 int libxl_uuid_to_domid(struct libxl_ctx *ctx, xen_uuid_t *uuid, uint32_t *domid)
91 {
92 int nb_domain, i;
93 struct libxl_dominfo *info = libxl_domain_list(ctx, &nb_domain);
94 for (i = 0; i < nb_domain; i++) {
95 if (!xen_uuid_compare(&(info[i].uuid), uuid)) {
96 *domid = info[i].domid;
97 free(info);
98 return 0;
99 }
100 }
101 free(info);
102 return -1;
103 }
105 int libxl_domid_to_uuid(struct libxl_ctx *ctx, xen_uuid_t **uuid, uint32_t domid)
106 {
107 int nb_domain, i;
108 struct libxl_dominfo *info = libxl_domain_list(ctx, &nb_domain);
109 for (i = 0; i < nb_domain; i++) {
110 if (domid == info[i].domid) {
111 *uuid = libxl_zalloc(ctx, sizeof(xen_uuid_t));
112 xen_uuid_copy(*uuid, &(info[i].uuid));
113 free(info);
114 return 0;
115 }
116 }
117 free(info);
118 return -1;
119 }
121 int libxl_is_uuid(char *s)
122 {
123 int i;
124 if (!s || strlen(s) != UUID_LEN_STR)
125 return 0;
126 for (i = 0; i < UUID_LEN_STR; i++) {
127 if (i == 8 || i == 13 || i == 18 || i == 23) {
128 if (s[i] != '-')
129 return 0;
130 } else {
131 if (!isxdigit((uint8_t)s[i]))
132 return 0;
133 }
134 }
135 return 1;
136 }
138 xen_uuid_t *libxl_string_to_uuid(struct libxl_ctx *ctx, char *s)
139 {
140 xen_uuid_t *uuid;
141 if (!s || !ctx)
142 return NULL;
143 uuid = libxl_zalloc(ctx, sizeof(*uuid));
144 xen_uuid_from_string(uuid, s);
145 return uuid;
146 }
148 char *libxl_uuid_to_string(struct libxl_ctx *ctx, xen_uuid_t *uuid)
149 {
150 char uuid_str[UUID_LEN_STR + 3];
151 if (!uuid)
152 return NULL;
153 xen_uuid_to_string(uuid, uuid_str, sizeof(uuid_str));
154 return libxl_sprintf(ctx, "%s", uuid_str);
155 }
157 int libxl_param_to_domid(struct libxl_ctx *ctx, char *p, uint32_t *domid)
158 {
159 xen_uuid_t *uuid;
160 uint32_t d;
162 if (libxl_is_uuid(p)) {
163 uuid = libxl_string_to_uuid(ctx, p);
164 return libxl_uuid_to_domid(ctx, uuid, domid);
165 }
166 errno = 0;
167 d = strtoul(p, (char **) NULL, 10);
168 if (!errno && d != 0 && d != ULONG_MAX && d != LONG_MIN) {
169 *domid = d;
170 return 0;
171 }
172 return libxl_name_to_domid(ctx, p, domid);
173 }
175 int libxl_get_stubdom_id(struct libxl_ctx *ctx, int guest_domid)
176 {
177 char * stubdom_id_s = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/image/device-model-domid", libxl_xs_get_dompath(ctx, guest_domid)));
178 if (stubdom_id_s)
179 return atoi(stubdom_id_s);
180 else
181 return 0;
182 }
184 int libxl_is_stubdom(struct libxl_ctx *ctx, int domid)
185 {
186 char *target = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/target", libxl_xs_get_dompath(ctx, domid)));
187 if (target)
188 return atoi(target);
189 else
190 return 0;
191 }
193 int libxl_create_logfile(struct libxl_ctx *ctx, char *name, char **full_name)
194 {
195 struct stat stat_buf;
196 char *logfile, *logfile_new;
197 int i;
199 logfile = libxl_sprintf(ctx, "/var/log/xen/%s.log", name);
200 if (stat(logfile, &stat_buf) == 0) {
201 /* file exists, rotate */
202 logfile = libxl_sprintf(ctx, "/var/log/xen/%s.log.10", name);
203 unlink(logfile);
204 for (i = 9; i > 0; i--) {
205 logfile = libxl_sprintf(ctx, "/var/log/xen/%s.log.%d", name, i);
206 logfile_new = libxl_sprintf(ctx, "/var/log/xen/%s.log.%d", name, i + 1);
207 rename(logfile, logfile_new);
208 }
209 logfile = libxl_sprintf(ctx, "/var/log/xen/%s.log", name);
210 logfile_new = libxl_sprintf(ctx, "/var/log/xen/%s.log.1", name);
211 rename(logfile, logfile_new);
212 }
213 *full_name = strdup(logfile);
214 return 0;
215 }
217 int libxl_string_to_phystype(struct libxl_ctx *ctx, char *s, libxl_disk_phystype *phystype)
218 {
219 char *p;
220 int rc = 0;
222 if (!strcmp(s, "phy")) {
223 *phystype = PHYSTYPE_PHY;
224 } else if (!strcmp(s, "file")) {
225 *phystype = PHYSTYPE_FILE;
226 } else if (!strcmp(s, "tap")) {
227 p = strchr(s, ':');
228 if (!p) {
229 rc = -1;
230 goto out;
231 }
232 p++;
233 if (!strcmp(p, "aio")) {
234 *phystype = PHYSTYPE_AIO;
235 } else if (!strcmp(p, "vhd")) {
236 *phystype = PHYSTYPE_VHD;
237 } else if (!strcmp(p, "qcow")) {
238 *phystype = PHYSTYPE_QCOW;
239 } else if (!strcmp(p, "qcow2")) {
240 *phystype = PHYSTYPE_QCOW2;
241 }
242 }
243 out:
244 return rc;
245 }