~serge-hallyn/ubuntu/raring/libvirt/libvirt-hugepages

0.2.1 by Guido Günther
Import upstream version 0.7.2
1
/*
2
 * xen_internal.c: direct access to Xen hypervisor level
3
 *
1.2.13 by Chuck Short
Import upstream version 0.9.12
4
 * Copyright (C) 2005-2012 Red Hat, Inc.
0.2.1 by Guido Günther
Import upstream version 0.7.2
5
 *
6
 * See COPYING.LIB for the License of this software
7
 *
8
 * Daniel Veillard <veillard@redhat.com>
9
 */
10
11
#include <config.h>
12
13
#include <stdio.h>
14
#include <string.h>
15
/* required for uint8_t, uint32_t, etc ... */
16
#include <stdint.h>
17
#include <sys/types.h>
18
#include <sys/stat.h>
19
#include <unistd.h>
20
#include <fcntl.h>
21
#include <sys/mman.h>
22
#include <sys/ioctl.h>
23
#include <limits.h>
24
#include <stdint.h>
25
#include <regex.h>
26
#include <errno.h>
27
#include <sys/utsname.h>
28
29
#ifdef __sun
0.2.6 by Guido Günther
Import upstream version 0.8.0
30
# include <sys/systeminfo.h>
31
32
# include <priv.h>
33
34
# ifndef PRIV_XVM_CONTROL
35
#  define PRIV_XVM_CONTROL ((const char *)"xvm_control")
36
# endif
0.2.1 by Guido Günther
Import upstream version 0.7.2
37
38
#endif /* __sun */
39
40
/* required for dom0_getdomaininfo_t */
41
#include <xen/dom0_ops.h>
42
#include <xen/version.h>
43
#ifdef HAVE_XEN_LINUX_PRIVCMD_H
0.2.6 by Guido Günther
Import upstream version 0.8.0
44
# include <xen/linux/privcmd.h>
0.2.1 by Guido Günther
Import upstream version 0.7.2
45
#else
0.2.6 by Guido Günther
Import upstream version 0.8.0
46
# ifdef HAVE_XEN_SYS_PRIVCMD_H
47
#  include <xen/sys/privcmd.h>
48
# endif
0.2.1 by Guido Günther
Import upstream version 0.7.2
49
#endif
50
51
/* required for shutdown flags */
52
#include <xen/sched.h>
53
54
#include "virterror_internal.h"
55
#include "logging.h"
56
#include "datatypes.h"
57
#include "driver.h"
58
#include "util.h"
59
#include "xen_driver.h"
60
#include "xen_hypervisor.h"
61
#include "xs_internal.h"
62
#include "stats_linux.h"
63
#include "block_stats.h"
64
#include "xend_internal.h"
65
#include "buf.h"
66
#include "capabilities.h"
67
#include "memory.h"
0.4.4 by Guido Günther
Import upstream version 0.9.4~rc1
68
#include "virfile.h"
0.5.4 by Guido Günther
Import upstream version 0.9.8~rc1
69
#include "virnodesuspend.h"
1.2.13 by Chuck Short
Import upstream version 0.9.12
70
#include "virtypedparam.h"
0.2.1 by Guido Günther
Import upstream version 0.7.2
71
72
#define VIR_FROM_THIS VIR_FROM_XEN
73
74
/*
75
 * so far there is 2 versions of the structures usable for doing
76
 * hypervisor calls.
77
 */
78
/* the old one */
79
typedef struct v0_hypercall_struct {
80
    unsigned long op;
81
    unsigned long arg[5];
82
} v0_hypercall_t;
83
84
#ifdef __linux__
0.2.6 by Guido Günther
Import upstream version 0.8.0
85
# define XEN_V0_IOCTL_HYPERCALL_CMD \
0.2.1 by Guido Günther
Import upstream version 0.7.2
86
        _IOC(_IOC_NONE, 'P', 0, sizeof(v0_hypercall_t))
87
/* the new one */
88
typedef struct v1_hypercall_struct
89
{
90
    uint64_t op;
91
    uint64_t arg[5];
92
} v1_hypercall_t;
0.2.6 by Guido Günther
Import upstream version 0.8.0
93
# define XEN_V1_IOCTL_HYPERCALL_CMD                  \
0.2.1 by Guido Günther
Import upstream version 0.7.2
94
    _IOC(_IOC_NONE, 'P', 0, sizeof(v1_hypercall_t))
95
typedef v1_hypercall_t hypercall_t;
96
#elif defined(__sun)
97
typedef privcmd_hypercall_t hypercall_t;
98
#else
0.2.6 by Guido Günther
Import upstream version 0.8.0
99
# error "unsupported platform"
0.2.1 by Guido Günther
Import upstream version 0.7.2
100
#endif
101
102
#ifndef __HYPERVISOR_sysctl
0.2.6 by Guido Günther
Import upstream version 0.8.0
103
# define __HYPERVISOR_sysctl 35
0.2.1 by Guido Günther
Import upstream version 0.7.2
104
#endif
105
#ifndef __HYPERVISOR_domctl
0.2.6 by Guido Günther
Import upstream version 0.8.0
106
# define __HYPERVISOR_domctl 36
0.2.1 by Guido Günther
Import upstream version 0.7.2
107
#endif
108
109
#ifdef WITH_RHEL5_API
0.2.6 by Guido Günther
Import upstream version 0.8.0
110
# define SYS_IFACE_MIN_VERS_NUMA 3
0.2.1 by Guido Günther
Import upstream version 0.7.2
111
#else
0.2.6 by Guido Günther
Import upstream version 0.8.0
112
# define SYS_IFACE_MIN_VERS_NUMA 4
0.2.1 by Guido Günther
Import upstream version 0.7.2
113
#endif
114
115
static int xen_ioctl_hypercall_cmd = 0;
116
static int initialized = 0;
117
static int in_init = 0;
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
118
static struct xenHypervisorVersions hv_versions = {
119
    .hv = 0,
120
    .hypervisor = 2,
121
    .sys_interface = -1,
122
    .dom_interface = -1,
123
};
124
0.2.1 by Guido Günther
Import upstream version 0.7.2
125
static int kb_per_pages = 0;
126
127
/* Regular expressions used by xenHypervisorGetCapabilities, and
128
 * compiled once by xenHypervisorInit.  Note that these are POSIX.2
129
 * extended regular expressions (regex(7)).
130
 */
131
static const char *flags_hvm_re = "^flags[[:blank:]]+:.* (vmx|svm)[[:space:]]";
132
static regex_t flags_hvm_rec;
133
static const char *flags_pae_re = "^flags[[:blank:]]+:.* pae[[:space:]]";
134
static regex_t flags_pae_rec;
135
static const char *xen_cap_re = "(xen|hvm)-[[:digit:]]+\\.[[:digit:]]+-(x86_32|x86_64|ia64|powerpc64)(p|be)?";
136
static regex_t xen_cap_rec;
137
138
/*
139
 * The content of the structures for a getdomaininfolist system hypercall
140
 */
141
#ifndef DOMFLAGS_DYING
0.2.6 by Guido Günther
Import upstream version 0.8.0
142
# define DOMFLAGS_DYING     (1<<0) /* Domain is scheduled to die.             */
143
# define DOMFLAGS_HVM       (1<<1) /* Domain is HVM                           */
144
# define DOMFLAGS_SHUTDOWN  (1<<2) /* The guest OS has shut down.             */
145
# define DOMFLAGS_PAUSED    (1<<3) /* Currently paused by control software.   */
146
# define DOMFLAGS_BLOCKED   (1<<4) /* Currently blocked pending an event.     */
147
# define DOMFLAGS_RUNNING   (1<<5) /* Domain is currently running.            */
148
# define DOMFLAGS_CPUMASK      255 /* CPU to which this domain is bound.      */
149
# define DOMFLAGS_CPUSHIFT       8
150
# define DOMFLAGS_SHUTDOWNMASK 255 /* DOMFLAGS_SHUTDOWN guest-supplied code.  */
151
# define DOMFLAGS_SHUTDOWNSHIFT 16
0.2.1 by Guido Günther
Import upstream version 0.7.2
152
#endif
153
154
/*
155
 * These flags explain why a system is in the state of "shutdown".  Normally,
156
 * They are defined in xen/sched.h
157
 */
158
#ifndef SHUTDOWN_poweroff
0.2.6 by Guido Günther
Import upstream version 0.8.0
159
# define SHUTDOWN_poweroff   0  /* Domain exited normally. Clean up and kill. */
160
# define SHUTDOWN_reboot     1  /* Clean up, kill, and then restart.          */
161
# define SHUTDOWN_suspend    2  /* Clean up, save suspend info, kill.         */
162
# define SHUTDOWN_crash      3  /* Tell controller we've crashed.             */
0.2.1 by Guido Günther
Import upstream version 0.7.2
163
#endif
164
165
#define XEN_V0_OP_GETDOMAININFOLIST	38
166
#define XEN_V1_OP_GETDOMAININFOLIST	38
167
#define XEN_V2_OP_GETDOMAININFOLIST	6
168
169
struct xen_v0_getdomaininfo {
170
    domid_t  domain;	/* the domain number */
171
    uint32_t flags;	/* flags, see before */
172
    uint64_t tot_pages;	/* total number of pages used */
173
    uint64_t max_pages;	/* maximum number of pages allowed */
174
    unsigned long shared_info_frame; /* MFN of shared_info struct */
175
    uint64_t cpu_time;  /* CPU time used */
176
    uint32_t nr_online_vcpus;  /* Number of VCPUs currently online. */
177
    uint32_t max_vcpu_id; /* Maximum VCPUID in use by this domain. */
178
    uint32_t ssidref;
179
    xen_domain_handle_t handle;
180
};
181
typedef struct xen_v0_getdomaininfo xen_v0_getdomaininfo;
182
183
struct xen_v2_getdomaininfo {
184
    domid_t  domain;	/* the domain number */
185
    uint32_t flags;	/* flags, see before */
186
    uint64_t tot_pages;	/* total number of pages used */
187
    uint64_t max_pages;	/* maximum number of pages allowed */
188
    uint64_t shared_info_frame; /* MFN of shared_info struct */
189
    uint64_t cpu_time;  /* CPU time used */
190
    uint32_t nr_online_vcpus;  /* Number of VCPUs currently online. */
191
    uint32_t max_vcpu_id; /* Maximum VCPUID in use by this domain. */
192
    uint32_t ssidref;
193
    xen_domain_handle_t handle;
194
};
195
typedef struct xen_v2_getdomaininfo xen_v2_getdomaininfo;
196
197
198
/* As of Hypervisor Call v2,  DomCtl v5 we are now 8-byte aligned
199
   even on 32-bit archs when dealing with uint64_t */
200
#define ALIGN_64 __attribute__((aligned(8)))
201
202
struct xen_v2d5_getdomaininfo {
203
    domid_t  domain;	/* the domain number */
204
    uint32_t flags;	/* flags, see before */
205
    uint64_t tot_pages ALIGN_64;	/* total number of pages used */
206
    uint64_t max_pages ALIGN_64;	/* maximum number of pages allowed */
207
    uint64_t shared_info_frame ALIGN_64; /* MFN of shared_info struct */
208
    uint64_t cpu_time ALIGN_64;  /* CPU time used */
209
    uint32_t nr_online_vcpus;  /* Number of VCPUs currently online. */
210
    uint32_t max_vcpu_id; /* Maximum VCPUID in use by this domain. */
211
    uint32_t ssidref;
212
    xen_domain_handle_t handle;
213
};
214
typedef struct xen_v2d5_getdomaininfo xen_v2d5_getdomaininfo;
215
0.2.4 by Laurent Léonard
Import upstream version 0.7.6
216
struct xen_v2d6_getdomaininfo {
217
    domid_t  domain;	/* the domain number */
218
    uint32_t flags;	/* flags, see before */
219
    uint64_t tot_pages ALIGN_64;	/* total number of pages used */
220
    uint64_t max_pages ALIGN_64;	/* maximum number of pages allowed */
221
    uint64_t shr_pages ALIGN_64;    /* number of shared pages */
222
    uint64_t shared_info_frame ALIGN_64; /* MFN of shared_info struct */
223
    uint64_t cpu_time ALIGN_64;  /* CPU time used */
224
    uint32_t nr_online_vcpus;  /* Number of VCPUs currently online. */
225
    uint32_t max_vcpu_id; /* Maximum VCPUID in use by this domain. */
226
    uint32_t ssidref;
227
    xen_domain_handle_t handle;
228
};
229
typedef struct xen_v2d6_getdomaininfo xen_v2d6_getdomaininfo;
230
0.4.1 by Guido Günther
Import upstream version 0.9.0~rc1
231
struct xen_v2d7_getdomaininfo {
232
    domid_t  domain;	/* the domain number */
233
    uint32_t flags;	/* flags, see before */
234
    uint64_t tot_pages ALIGN_64;	/* total number of pages used */
235
    uint64_t max_pages ALIGN_64;	/* maximum number of pages allowed */
236
    uint64_t shr_pages ALIGN_64;    /* number of shared pages */
237
    uint64_t shared_info_frame ALIGN_64; /* MFN of shared_info struct */
238
    uint64_t cpu_time ALIGN_64;  /* CPU time used */
239
    uint32_t nr_online_vcpus;  /* Number of VCPUs currently online. */
240
    uint32_t max_vcpu_id; /* Maximum VCPUID in use by this domain. */
241
    uint32_t ssidref;
242
    xen_domain_handle_t handle;
243
    uint32_t cpupool;
244
};
245
typedef struct xen_v2d7_getdomaininfo xen_v2d7_getdomaininfo;
246
1.2.13 by Chuck Short
Import upstream version 0.9.12
247
struct xen_v2d8_getdomaininfo {
248
    domid_t  domain;	/* the domain number */
249
    uint32_t flags;	/* flags, see before */
250
    uint64_t tot_pages ALIGN_64;	/* total number of pages used */
251
    uint64_t max_pages ALIGN_64;	/* maximum number of pages allowed */
252
    uint64_t shr_pages ALIGN_64;    /* number of shared pages */
253
    uint64_t paged_pages ALIGN_64;    /* number of paged pages */
254
    uint64_t shared_info_frame ALIGN_64; /* MFN of shared_info struct */
255
    uint64_t cpu_time ALIGN_64;  /* CPU time used */
256
    uint32_t nr_online_vcpus;  /* Number of VCPUs currently online. */
257
    uint32_t max_vcpu_id; /* Maximum VCPUID in use by this domain. */
258
    uint32_t ssidref;
259
    xen_domain_handle_t handle;
260
    uint32_t cpupool;
261
};
262
typedef struct xen_v2d8_getdomaininfo xen_v2d8_getdomaininfo;
263
0.2.1 by Guido Günther
Import upstream version 0.7.2
264
union xen_getdomaininfo {
265
    struct xen_v0_getdomaininfo v0;
266
    struct xen_v2_getdomaininfo v2;
267
    struct xen_v2d5_getdomaininfo v2d5;
0.2.4 by Laurent Léonard
Import upstream version 0.7.6
268
    struct xen_v2d6_getdomaininfo v2d6;
0.4.1 by Guido Günther
Import upstream version 0.9.0~rc1
269
    struct xen_v2d7_getdomaininfo v2d7;
1.2.13 by Chuck Short
Import upstream version 0.9.12
270
    struct xen_v2d8_getdomaininfo v2d8;
0.2.1 by Guido Günther
Import upstream version 0.7.2
271
};
272
typedef union xen_getdomaininfo xen_getdomaininfo;
273
274
union xen_getdomaininfolist {
275
    struct xen_v0_getdomaininfo *v0;
276
    struct xen_v2_getdomaininfo *v2;
277
    struct xen_v2d5_getdomaininfo *v2d5;
0.2.4 by Laurent Léonard
Import upstream version 0.7.6
278
    struct xen_v2d6_getdomaininfo *v2d6;
0.4.1 by Guido Günther
Import upstream version 0.9.0~rc1
279
    struct xen_v2d7_getdomaininfo *v2d7;
1.2.13 by Chuck Short
Import upstream version 0.9.12
280
    struct xen_v2d8_getdomaininfo *v2d8;
0.2.1 by Guido Günther
Import upstream version 0.7.2
281
};
282
typedef union xen_getdomaininfolist xen_getdomaininfolist;
283
284
285
struct xen_v2_getschedulerid {
286
    uint32_t sched_id; /* Get Scheduler ID from Xen */
287
};
288
typedef struct xen_v2_getschedulerid xen_v2_getschedulerid;
289
290
291
union xen_getschedulerid {
292
    struct xen_v2_getschedulerid *v2;
293
};
294
typedef union xen_getschedulerid xen_getschedulerid;
295
296
struct xen_v2s4_availheap {
297
    uint32_t min_bitwidth;  /* Smallest address width (zero if don't care). */
298
    uint32_t max_bitwidth;  /* Largest address width (zero if don't care). */
299
    int32_t  node;          /* NUMA node (-1 for sum across all nodes). */
300
    uint64_t avail_bytes;   /* Bytes available in the specified region. */
301
};
302
303
typedef struct xen_v2s4_availheap  xen_v2s4_availheap;
304
305
struct xen_v2s5_availheap {
306
    uint32_t min_bitwidth;  /* Smallest address width (zero if don't care). */
307
    uint32_t max_bitwidth;  /* Largest address width (zero if don't care). */
308
    int32_t  node;          /* NUMA node (-1 for sum across all nodes). */
309
    uint64_t avail_bytes ALIGN_64;   /* Bytes available in the specified region. */
310
};
311
312
typedef struct xen_v2s5_availheap  xen_v2s5_availheap;
313
314
315
#define XEN_GETDOMAININFOLIST_ALLOC(domlist, size)                      \
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
316
    (hv_versions.hypervisor < 2 ?                                       \
0.2.1 by Guido Günther
Import upstream version 0.7.2
317
     (VIR_ALLOC_N(domlist.v0, (size)) == 0) :                           \
1.2.13 by Chuck Short
Import upstream version 0.9.12
318
     (hv_versions.dom_interface >= 8 ?                                  \
319
      (VIR_ALLOC_N(domlist.v2d8, (size)) == 0) :                        \
320
     (hv_versions.dom_interface == 7 ?                                  \
0.4.1 by Guido Günther
Import upstream version 0.9.0~rc1
321
      (VIR_ALLOC_N(domlist.v2d7, (size)) == 0) :                        \
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
322
     (hv_versions.dom_interface == 6 ?                                  \
0.2.4 by Laurent Léonard
Import upstream version 0.7.6
323
      (VIR_ALLOC_N(domlist.v2d6, (size)) == 0) :                        \
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
324
     (hv_versions.dom_interface == 5 ?                                  \
0.2.4 by Laurent Léonard
Import upstream version 0.7.6
325
      (VIR_ALLOC_N(domlist.v2d5, (size)) == 0) :                        \
1.2.13 by Chuck Short
Import upstream version 0.9.12
326
      (VIR_ALLOC_N(domlist.v2, (size)) == 0))))))
0.2.1 by Guido Günther
Import upstream version 0.7.2
327
328
#define XEN_GETDOMAININFOLIST_FREE(domlist)            \
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
329
    (hv_versions.hypervisor < 2 ?                      \
0.2.1 by Guido Günther
Import upstream version 0.7.2
330
     VIR_FREE(domlist.v0) :                            \
1.2.13 by Chuck Short
Import upstream version 0.9.12
331
     (hv_versions.dom_interface >= 8 ?                 \
332
      VIR_FREE(domlist.v2d8) :                         \
333
     (hv_versions.dom_interface == 7 ?                 \
0.4.1 by Guido Günther
Import upstream version 0.9.0~rc1
334
      VIR_FREE(domlist.v2d7) :                         \
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
335
     (hv_versions.dom_interface == 6 ?                 \
0.2.4 by Laurent Léonard
Import upstream version 0.7.6
336
      VIR_FREE(domlist.v2d6) :                         \
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
337
     (hv_versions.dom_interface == 5 ?                 \
0.2.4 by Laurent Léonard
Import upstream version 0.7.6
338
      VIR_FREE(domlist.v2d5) :                         \
1.2.13 by Chuck Short
Import upstream version 0.9.12
339
      VIR_FREE(domlist.v2))))))
0.2.1 by Guido Günther
Import upstream version 0.7.2
340
341
#define XEN_GETDOMAININFOLIST_CLEAR(domlist, size)            \
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
342
    (hv_versions.hypervisor < 2 ?                             \
0.2.1 by Guido Günther
Import upstream version 0.7.2
343
     memset(domlist.v0, 0, sizeof(*domlist.v0) * size) :      \
1.2.13 by Chuck Short
Import upstream version 0.9.12
344
     (hv_versions.dom_interface >= 8 ?                        \
345
      memset(domlist.v2d8, 0, sizeof(*domlist.v2d8) * size) : \
346
     (hv_versions.dom_interface == 7 ?                        \
0.4.1 by Guido Günther
Import upstream version 0.9.0~rc1
347
      memset(domlist.v2d7, 0, sizeof(*domlist.v2d7) * size) : \
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
348
     (hv_versions.dom_interface == 6 ?                        \
0.2.4 by Laurent Léonard
Import upstream version 0.7.6
349
      memset(domlist.v2d6, 0, sizeof(*domlist.v2d6) * size) : \
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
350
     (hv_versions.dom_interface == 5 ?                        \
0.2.4 by Laurent Léonard
Import upstream version 0.7.6
351
      memset(domlist.v2d5, 0, sizeof(*domlist.v2d5) * size) : \
1.2.13 by Chuck Short
Import upstream version 0.9.12
352
      memset(domlist.v2, 0, sizeof(*domlist.v2) * size))))))
0.2.1 by Guido Günther
Import upstream version 0.7.2
353
354
#define XEN_GETDOMAININFOLIST_DOMAIN(domlist, n)    \
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
355
    (hv_versions.hypervisor < 2 ?                   \
0.2.1 by Guido Günther
Import upstream version 0.7.2
356
     domlist.v0[n].domain :                         \
1.2.13 by Chuck Short
Import upstream version 0.9.12
357
     (hv_versions.dom_interface >= 8 ?              \
358
      domlist.v2d8[n].domain :                      \
359
     (hv_versions.dom_interface == 7 ?              \
0.4.1 by Guido Günther
Import upstream version 0.9.0~rc1
360
      domlist.v2d7[n].domain :                      \
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
361
     (hv_versions.dom_interface == 6 ?              \
0.2.4 by Laurent Léonard
Import upstream version 0.7.6
362
      domlist.v2d6[n].domain :                      \
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
363
     (hv_versions.dom_interface == 5 ?              \
0.2.4 by Laurent Léonard
Import upstream version 0.7.6
364
      domlist.v2d5[n].domain :                      \
1.2.13 by Chuck Short
Import upstream version 0.9.12
365
      domlist.v2[n].domain)))))
0.2.1 by Guido Günther
Import upstream version 0.7.2
366
367
#define XEN_GETDOMAININFOLIST_UUID(domlist, n)      \
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
368
    (hv_versions.hypervisor < 2 ?                   \
0.2.1 by Guido Günther
Import upstream version 0.7.2
369
     domlist.v0[n].handle :                         \
1.2.13 by Chuck Short
Import upstream version 0.9.12
370
     (hv_versions.dom_interface >= 8 ?              \
371
      domlist.v2d8[n].handle :                      \
372
     (hv_versions.dom_interface == 7 ?              \
0.4.1 by Guido Günther
Import upstream version 0.9.0~rc1
373
      domlist.v2d7[n].handle :                      \
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
374
     (hv_versions.dom_interface == 6 ?              \
0.2.4 by Laurent Léonard
Import upstream version 0.7.6
375
      domlist.v2d6[n].handle :                      \
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
376
     (hv_versions.dom_interface == 5 ?              \
0.2.4 by Laurent Léonard
Import upstream version 0.7.6
377
      domlist.v2d5[n].handle :                      \
1.2.13 by Chuck Short
Import upstream version 0.9.12
378
      domlist.v2[n].handle)))))
0.2.1 by Guido Günther
Import upstream version 0.7.2
379
380
#define XEN_GETDOMAININFOLIST_DATA(domlist)        \
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
381
    (hv_versions.hypervisor < 2 ?                  \
0.2.1 by Guido Günther
Import upstream version 0.7.2
382
     (void*)(domlist->v0) :                        \
1.2.13 by Chuck Short
Import upstream version 0.9.12
383
     (hv_versions.dom_interface >= 8 ?             \
384
      (void*)(domlist->v2d8) :                     \
385
     (hv_versions.dom_interface == 7 ?             \
0.4.1 by Guido Günther
Import upstream version 0.9.0~rc1
386
      (void*)(domlist->v2d7) :                     \
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
387
     (hv_versions.dom_interface == 6 ?             \
0.2.4 by Laurent Léonard
Import upstream version 0.7.6
388
      (void*)(domlist->v2d6) :                     \
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
389
     (hv_versions.dom_interface == 5 ?             \
0.2.4 by Laurent Léonard
Import upstream version 0.7.6
390
      (void*)(domlist->v2d5) :                     \
1.2.13 by Chuck Short
Import upstream version 0.9.12
391
      (void*)(domlist->v2))))))
0.2.1 by Guido Günther
Import upstream version 0.7.2
392
393
#define XEN_GETDOMAININFO_SIZE                     \
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
394
    (hv_versions.hypervisor < 2 ?                  \
0.2.1 by Guido Günther
Import upstream version 0.7.2
395
     sizeof(xen_v0_getdomaininfo) :                \
1.2.13 by Chuck Short
Import upstream version 0.9.12
396
     (hv_versions.dom_interface >= 8 ?             \
397
      sizeof(xen_v2d8_getdomaininfo) :             \
398
     (hv_versions.dom_interface == 7 ?             \
0.4.1 by Guido Günther
Import upstream version 0.9.0~rc1
399
      sizeof(xen_v2d7_getdomaininfo) :             \
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
400
     (hv_versions.dom_interface == 6 ?             \
0.2.4 by Laurent Léonard
Import upstream version 0.7.6
401
      sizeof(xen_v2d6_getdomaininfo) :             \
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
402
     (hv_versions.dom_interface == 5 ?             \
0.2.4 by Laurent Léonard
Import upstream version 0.7.6
403
      sizeof(xen_v2d5_getdomaininfo) :             \
1.2.13 by Chuck Short
Import upstream version 0.9.12
404
      sizeof(xen_v2_getdomaininfo))))))
0.2.1 by Guido Günther
Import upstream version 0.7.2
405
406
#define XEN_GETDOMAININFO_CLEAR(dominfo)                           \
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
407
    (hv_versions.hypervisor < 2 ?                                  \
0.2.1 by Guido Günther
Import upstream version 0.7.2
408
     memset(&(dominfo.v0), 0, sizeof(xen_v0_getdomaininfo)) :      \
1.2.13 by Chuck Short
Import upstream version 0.9.12
409
     (hv_versions.dom_interface >= 8 ?                             \
410
      memset(&(dominfo.v2d8), 0, sizeof(xen_v2d8_getdomaininfo)) : \
411
     (hv_versions.dom_interface == 7 ?                             \
0.4.1 by Guido Günther
Import upstream version 0.9.0~rc1
412
      memset(&(dominfo.v2d7), 0, sizeof(xen_v2d7_getdomaininfo)) : \
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
413
     (hv_versions.dom_interface == 6 ?                             \
0.2.4 by Laurent Léonard
Import upstream version 0.7.6
414
      memset(&(dominfo.v2d6), 0, sizeof(xen_v2d6_getdomaininfo)) : \
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
415
     (hv_versions.dom_interface == 5 ?                             \
0.2.4 by Laurent Léonard
Import upstream version 0.7.6
416
      memset(&(dominfo.v2d5), 0, sizeof(xen_v2d5_getdomaininfo)) : \
1.2.13 by Chuck Short
Import upstream version 0.9.12
417
      memset(&(dominfo.v2), 0, sizeof(xen_v2_getdomaininfo)))))))
0.2.1 by Guido Günther
Import upstream version 0.7.2
418
419
#define XEN_GETDOMAININFO_DOMAIN(dominfo)       \
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
420
    (hv_versions.hypervisor < 2 ?               \
0.2.1 by Guido Günther
Import upstream version 0.7.2
421
     dominfo.v0.domain :                        \
1.2.13 by Chuck Short
Import upstream version 0.9.12
422
     (hv_versions.dom_interface >= 8 ?          \
423
      dominfo.v2d8.domain :                     \
424
     (hv_versions.dom_interface == 7 ?          \
0.4.1 by Guido Günther
Import upstream version 0.9.0~rc1
425
      dominfo.v2d7.domain :                     \
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
426
     (hv_versions.dom_interface == 6 ?          \
0.2.4 by Laurent Léonard
Import upstream version 0.7.6
427
      dominfo.v2d6.domain :                     \
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
428
     (hv_versions.dom_interface == 5 ?          \
0.2.4 by Laurent Léonard
Import upstream version 0.7.6
429
      dominfo.v2d5.domain :                     \
1.2.13 by Chuck Short
Import upstream version 0.9.12
430
      dominfo.v2.domain)))))
0.2.1 by Guido Günther
Import upstream version 0.7.2
431
432
#define XEN_GETDOMAININFO_CPUTIME(dominfo)      \
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
433
    (hv_versions.hypervisor < 2 ?               \
0.2.1 by Guido Günther
Import upstream version 0.7.2
434
     dominfo.v0.cpu_time :                      \
1.2.13 by Chuck Short
Import upstream version 0.9.12
435
     (hv_versions.dom_interface >= 8 ?          \
436
      dominfo.v2d8.cpu_time :                   \
437
     (hv_versions.dom_interface == 7 ?          \
0.4.1 by Guido Günther
Import upstream version 0.9.0~rc1
438
      dominfo.v2d7.cpu_time :                   \
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
439
     (hv_versions.dom_interface == 6 ?          \
0.2.4 by Laurent Léonard
Import upstream version 0.7.6
440
      dominfo.v2d6.cpu_time :                   \
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
441
     (hv_versions.dom_interface == 5 ?          \
0.2.4 by Laurent Léonard
Import upstream version 0.7.6
442
      dominfo.v2d5.cpu_time :                   \
1.2.13 by Chuck Short
Import upstream version 0.9.12
443
      dominfo.v2.cpu_time)))))
0.2.4 by Laurent Léonard
Import upstream version 0.7.6
444
0.2.1 by Guido Günther
Import upstream version 0.7.2
445
446
#define XEN_GETDOMAININFO_CPUCOUNT(dominfo)     \
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
447
    (hv_versions.hypervisor < 2 ?               \
0.2.1 by Guido Günther
Import upstream version 0.7.2
448
     dominfo.v0.nr_online_vcpus :               \
1.2.13 by Chuck Short
Import upstream version 0.9.12
449
     (hv_versions.dom_interface >= 8 ?          \
450
      dominfo.v2d8.nr_online_vcpus :            \
451
     (hv_versions.dom_interface == 7 ?          \
0.4.1 by Guido Günther
Import upstream version 0.9.0~rc1
452
      dominfo.v2d7.nr_online_vcpus :            \
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
453
     (hv_versions.dom_interface == 6 ?          \
0.2.4 by Laurent Léonard
Import upstream version 0.7.6
454
      dominfo.v2d6.nr_online_vcpus :            \
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
455
     (hv_versions.dom_interface == 5 ?          \
0.2.4 by Laurent Léonard
Import upstream version 0.7.6
456
      dominfo.v2d5.nr_online_vcpus :            \
1.2.13 by Chuck Short
Import upstream version 0.9.12
457
      dominfo.v2.nr_online_vcpus)))))
0.2.1 by Guido Günther
Import upstream version 0.7.2
458
1.2.13 by Chuck Short
Import upstream version 0.9.12
459
#define XEN_GETDOMAININFO_MAXCPUID(dominfo)     \
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
460
    (hv_versions.hypervisor < 2 ?               \
0.2.1 by Guido Günther
Import upstream version 0.7.2
461
     dominfo.v0.max_vcpu_id :                   \
1.2.13 by Chuck Short
Import upstream version 0.9.12
462
     (hv_versions.dom_interface >= 8 ?          \
463
      dominfo.v2d8.max_vcpu_id :                \
464
     (hv_versions.dom_interface == 7 ?          \
0.4.1 by Guido Günther
Import upstream version 0.9.0~rc1
465
      dominfo.v2d7.max_vcpu_id :                \
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
466
     (hv_versions.dom_interface == 6 ?          \
0.2.4 by Laurent Léonard
Import upstream version 0.7.6
467
      dominfo.v2d6.max_vcpu_id :                \
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
468
     (hv_versions.dom_interface == 5 ?          \
0.2.4 by Laurent Léonard
Import upstream version 0.7.6
469
      dominfo.v2d5.max_vcpu_id :                \
1.2.13 by Chuck Short
Import upstream version 0.9.12
470
      dominfo.v2.max_vcpu_id)))))
0.2.1 by Guido Günther
Import upstream version 0.7.2
471
472
#define XEN_GETDOMAININFO_FLAGS(dominfo)        \
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
473
    (hv_versions.hypervisor < 2 ?               \
0.2.1 by Guido Günther
Import upstream version 0.7.2
474
     dominfo.v0.flags :                         \
1.2.13 by Chuck Short
Import upstream version 0.9.12
475
     (hv_versions.dom_interface >= 8 ?          \
476
      dominfo.v2d8.flags :                      \
477
     (hv_versions.dom_interface == 7 ?          \
0.4.1 by Guido Günther
Import upstream version 0.9.0~rc1
478
      dominfo.v2d7.flags :                      \
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
479
     (hv_versions.dom_interface == 6 ?          \
0.2.4 by Laurent Léonard
Import upstream version 0.7.6
480
      dominfo.v2d6.flags :                      \
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
481
     (hv_versions.dom_interface == 5 ?          \
0.2.4 by Laurent Léonard
Import upstream version 0.7.6
482
      dominfo.v2d5.flags :                      \
1.2.13 by Chuck Short
Import upstream version 0.9.12
483
      dominfo.v2.flags)))))
0.2.1 by Guido Günther
Import upstream version 0.7.2
484
485
#define XEN_GETDOMAININFO_TOT_PAGES(dominfo)    \
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
486
    (hv_versions.hypervisor < 2 ?               \
0.2.1 by Guido Günther
Import upstream version 0.7.2
487
     dominfo.v0.tot_pages :                     \
1.2.13 by Chuck Short
Import upstream version 0.9.12
488
     (hv_versions.dom_interface >= 8 ?          \
489
      dominfo.v2d8.tot_pages :                  \
490
     (hv_versions.dom_interface == 7 ?          \
0.4.1 by Guido Günther
Import upstream version 0.9.0~rc1
491
      dominfo.v2d7.tot_pages :                  \
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
492
     (hv_versions.dom_interface == 6 ?          \
0.2.4 by Laurent Léonard
Import upstream version 0.7.6
493
      dominfo.v2d6.tot_pages :                  \
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
494
     (hv_versions.dom_interface == 5 ?          \
0.2.4 by Laurent Léonard
Import upstream version 0.7.6
495
      dominfo.v2d5.tot_pages :                  \
1.2.13 by Chuck Short
Import upstream version 0.9.12
496
      dominfo.v2.tot_pages)))))
0.2.1 by Guido Günther
Import upstream version 0.7.2
497
498
#define XEN_GETDOMAININFO_MAX_PAGES(dominfo)    \
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
499
    (hv_versions.hypervisor < 2 ?               \
0.2.1 by Guido Günther
Import upstream version 0.7.2
500
     dominfo.v0.max_pages :                     \
1.2.13 by Chuck Short
Import upstream version 0.9.12
501
     (hv_versions.dom_interface >= 8 ?          \
502
      dominfo.v2d8.max_pages :                  \
503
     (hv_versions.dom_interface == 7 ?          \
0.4.1 by Guido Günther
Import upstream version 0.9.0~rc1
504
      dominfo.v2d7.max_pages :                  \
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
505
     (hv_versions.dom_interface == 6 ?          \
0.2.4 by Laurent Léonard
Import upstream version 0.7.6
506
      dominfo.v2d6.max_pages :                  \
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
507
     (hv_versions.dom_interface == 5 ?          \
0.2.4 by Laurent Léonard
Import upstream version 0.7.6
508
      dominfo.v2d5.max_pages :                  \
1.2.13 by Chuck Short
Import upstream version 0.9.12
509
      dominfo.v2.max_pages)))))
0.2.1 by Guido Günther
Import upstream version 0.7.2
510
511
#define XEN_GETDOMAININFO_UUID(dominfo)         \
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
512
    (hv_versions.hypervisor < 2 ?               \
0.2.1 by Guido Günther
Import upstream version 0.7.2
513
     dominfo.v0.handle :                        \
1.2.13 by Chuck Short
Import upstream version 0.9.12
514
     (hv_versions.dom_interface >= 8 ?          \
515
      dominfo.v2d8.handle :                     \
516
     (hv_versions.dom_interface == 7 ?          \
0.4.1 by Guido Günther
Import upstream version 0.9.0~rc1
517
      dominfo.v2d7.handle :                     \
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
518
     (hv_versions.dom_interface == 6 ?          \
0.2.4 by Laurent Léonard
Import upstream version 0.7.6
519
      dominfo.v2d6.handle :                     \
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
520
     (hv_versions.dom_interface == 5 ?          \
0.2.4 by Laurent Léonard
Import upstream version 0.7.6
521
      dominfo.v2d5.handle :                     \
1.2.13 by Chuck Short
Import upstream version 0.9.12
522
      dominfo.v2.handle)))))
0.2.1 by Guido Günther
Import upstream version 0.7.2
523
524
525
static int
526
lock_pages(void *addr, size_t len)
527
{
528
#ifdef __linux__
1.2.13 by Chuck Short
Import upstream version 0.9.12
529
        return mlock(addr, len);
0.2.1 by Guido Günther
Import upstream version 0.7.2
530
#elif defined(__sun)
1.2.13 by Chuck Short
Import upstream version 0.9.12
531
        return 0;
0.2.1 by Guido Günther
Import upstream version 0.7.2
532
#endif
533
}
534
535
static int
536
unlock_pages(void *addr, size_t len)
537
{
538
#ifdef __linux__
1.2.13 by Chuck Short
Import upstream version 0.9.12
539
        return munlock(addr, len);
0.2.1 by Guido Günther
Import upstream version 0.7.2
540
#elif defined(__sun)
1.2.13 by Chuck Short
Import upstream version 0.9.12
541
        return 0;
0.2.1 by Guido Günther
Import upstream version 0.7.2
542
#endif
543
}
544
545
546
struct xen_v0_getdomaininfolistop {
547
    domid_t   first_domain;
548
    uint32_t  max_domains;
549
    struct xen_v0_getdomaininfo *buffer;
550
    uint32_t  num_domains;
551
};
552
typedef struct xen_v0_getdomaininfolistop xen_v0_getdomaininfolistop;
553
554
555
struct xen_v2_getdomaininfolistop {
556
    domid_t   first_domain;
557
    uint32_t  max_domains;
558
    struct xen_v2_getdomaininfo *buffer;
559
    uint32_t  num_domains;
560
};
561
typedef struct xen_v2_getdomaininfolistop xen_v2_getdomaininfolistop;
562
563
/* As of HV version 2, sysctl version 3 the *buffer pointer is 64-bit aligned */
564
struct xen_v2s3_getdomaininfolistop {
565
    domid_t   first_domain;
566
    uint32_t  max_domains;
567
#ifdef __BIG_ENDIAN__
568
    struct {
1.2.13 by Chuck Short
Import upstream version 0.9.12
569
        int __pad[(sizeof(long long) - sizeof(struct xen_v2d5_getdomaininfo *)) / sizeof(int)];
0.2.1 by Guido Günther
Import upstream version 0.7.2
570
        struct xen_v2d5_getdomaininfo *v;
571
    } buffer;
572
#else
573
    union {
574
        struct xen_v2d5_getdomaininfo *v;
575
        uint64_t pad ALIGN_64;
576
    } buffer;
577
#endif
578
    uint32_t  num_domains;
579
};
580
typedef struct xen_v2s3_getdomaininfolistop xen_v2s3_getdomaininfolistop;
581
582
583
584
struct xen_v0_domainop {
585
    domid_t   domain;
586
};
587
typedef struct xen_v0_domainop xen_v0_domainop;
588
589
/*
590
 * The information for a destroydomain system hypercall
591
 */
592
#define XEN_V0_OP_DESTROYDOMAIN	9
593
#define XEN_V1_OP_DESTROYDOMAIN	9
594
#define XEN_V2_OP_DESTROYDOMAIN	2
595
596
/*
597
 * The information for a pausedomain system hypercall
598
 */
599
#define XEN_V0_OP_PAUSEDOMAIN	10
600
#define XEN_V1_OP_PAUSEDOMAIN	10
601
#define XEN_V2_OP_PAUSEDOMAIN	3
602
603
/*
604
 * The information for an unpausedomain system hypercall
605
 */
606
#define XEN_V0_OP_UNPAUSEDOMAIN	11
607
#define XEN_V1_OP_UNPAUSEDOMAIN	11
608
#define XEN_V2_OP_UNPAUSEDOMAIN	4
609
610
/*
0.5.5 by Guido Günther
Import upstream version 0.9.8~rc2
611
 * The information for a setmaxmem system hypercall
0.2.1 by Guido Günther
Import upstream version 0.7.2
612
 */
613
#define XEN_V0_OP_SETMAXMEM	28
614
#define XEN_V1_OP_SETMAXMEM	28
615
#define XEN_V2_OP_SETMAXMEM	11
616
617
struct xen_v0_setmaxmem {
618
    domid_t	domain;
619
    uint64_t	maxmem;
620
};
621
typedef struct xen_v0_setmaxmem xen_v0_setmaxmem;
622
typedef struct xen_v0_setmaxmem xen_v1_setmaxmem;
623
624
struct xen_v2_setmaxmem {
625
    uint64_t	maxmem;
626
};
627
typedef struct xen_v2_setmaxmem xen_v2_setmaxmem;
628
629
struct xen_v2d5_setmaxmem {
630
    uint64_t	maxmem ALIGN_64;
631
};
632
typedef struct xen_v2d5_setmaxmem xen_v2d5_setmaxmem;
633
634
/*
0.5.5 by Guido Günther
Import upstream version 0.9.8~rc2
635
 * The information for a setmaxvcpu system hypercall
0.2.1 by Guido Günther
Import upstream version 0.7.2
636
 */
637
#define XEN_V0_OP_SETMAXVCPU	41
638
#define XEN_V1_OP_SETMAXVCPU	41
639
#define XEN_V2_OP_SETMAXVCPU	15
640
641
struct xen_v0_setmaxvcpu {
642
    domid_t	domain;
643
    uint32_t	maxvcpu;
644
};
645
typedef struct xen_v0_setmaxvcpu xen_v0_setmaxvcpu;
646
typedef struct xen_v0_setmaxvcpu xen_v1_setmaxvcpu;
647
648
struct xen_v2_setmaxvcpu {
649
    uint32_t	maxvcpu;
650
};
651
typedef struct xen_v2_setmaxvcpu xen_v2_setmaxvcpu;
652
653
/*
0.5.5 by Guido Günther
Import upstream version 0.9.8~rc2
654
 * The information for a setvcpumap system hypercall
0.2.1 by Guido Günther
Import upstream version 0.7.2
655
 * Note that between 1 and 2 the limitation to 64 physical CPU was lifted
656
 * hence the difference in structures
657
 */
658
#define XEN_V0_OP_SETVCPUMAP	20
659
#define XEN_V1_OP_SETVCPUMAP	20
660
#define XEN_V2_OP_SETVCPUMAP	9
661
662
struct xen_v0_setvcpumap {
663
    domid_t	domain;
664
    uint32_t	vcpu;
665
    cpumap_t    cpumap;
666
};
667
typedef struct xen_v0_setvcpumap xen_v0_setvcpumap;
668
typedef struct xen_v0_setvcpumap xen_v1_setvcpumap;
669
670
struct xen_v2_cpumap {
671
    uint8_t    *bitmap;
672
    uint32_t    nr_cpus;
673
};
674
struct xen_v2_setvcpumap {
675
    uint32_t	vcpu;
676
    struct xen_v2_cpumap cpumap;
677
};
678
typedef struct xen_v2_setvcpumap xen_v2_setvcpumap;
679
680
/* HV version 2, Dom version 5 requires 64-bit alignment */
681
struct xen_v2d5_cpumap {
682
#ifdef __BIG_ENDIAN__
683
    struct {
1.2.13 by Chuck Short
Import upstream version 0.9.12
684
        int __pad[(sizeof(long long) - sizeof(uint8_t *)) / sizeof(int)];
0.2.1 by Guido Günther
Import upstream version 0.7.2
685
        uint8_t *v;
686
    } bitmap;
687
#else
688
    union {
689
        uint8_t    *v;
690
        uint64_t   pad ALIGN_64;
691
    } bitmap;
692
#endif
693
    uint32_t    nr_cpus;
694
};
695
struct xen_v2d5_setvcpumap {
696
    uint32_t	vcpu;
697
    struct xen_v2d5_cpumap cpumap;
698
};
699
typedef struct xen_v2d5_setvcpumap xen_v2d5_setvcpumap;
700
701
/*
0.5.5 by Guido Günther
Import upstream version 0.9.8~rc2
702
 * The information for a vcpuinfo system hypercall
0.2.1 by Guido Günther
Import upstream version 0.7.2
703
 */
704
#define XEN_V0_OP_GETVCPUINFO   43
705
#define XEN_V1_OP_GETVCPUINFO	43
706
#define XEN_V2_OP_GETVCPUINFO   14
707
708
struct xen_v0_vcpuinfo {
709
    domid_t	domain;		/* owner's domain */
710
    uint32_t	vcpu;		/* the vcpu number */
711
    uint8_t	online;		/* seen as on line */
712
    uint8_t	blocked;	/* blocked on event */
713
    uint8_t	running;	/* scheduled on CPU */
714
    uint64_t    cpu_time;	/* nanosecond of CPU used */
715
    uint32_t	cpu;		/* current mapping */
716
    cpumap_t	cpumap;		/* deprecated in V2 */
717
};
718
typedef struct xen_v0_vcpuinfo xen_v0_vcpuinfo;
719
typedef struct xen_v0_vcpuinfo xen_v1_vcpuinfo;
720
721
struct xen_v2_vcpuinfo {
722
    uint32_t	vcpu;		/* the vcpu number */
723
    uint8_t	online;		/* seen as on line */
724
    uint8_t	blocked;	/* blocked on event */
725
    uint8_t	running;	/* scheduled on CPU */
726
    uint64_t    cpu_time;	/* nanosecond of CPU used */
727
    uint32_t	cpu;		/* current mapping */
728
};
729
typedef struct xen_v2_vcpuinfo xen_v2_vcpuinfo;
730
731
struct xen_v2d5_vcpuinfo {
732
    uint32_t	vcpu;		/* the vcpu number */
733
    uint8_t	online;		/* seen as on line */
734
    uint8_t	blocked;	/* blocked on event */
735
    uint8_t	running;	/* scheduled on CPU */
736
    uint64_t    cpu_time ALIGN_64; /* nanosecond of CPU used */
737
    uint32_t	cpu;		/* current mapping */
738
};
739
typedef struct xen_v2d5_vcpuinfo xen_v2d5_vcpuinfo;
740
741
/*
742
 * from V2 the pinning of a vcpu is read with a separate call
743
 */
744
#define XEN_V2_OP_GETVCPUMAP	25
745
typedef struct xen_v2_setvcpumap xen_v2_getvcpumap;
746
typedef struct xen_v2d5_setvcpumap xen_v2d5_getvcpumap;
747
748
/*
749
 * from V2 we get the scheduler information
750
 */
751
#define XEN_V2_OP_GETSCHEDULERID	4
752
753
/*
754
 * from V2 we get the available heap information
755
 */
0.3.4 by Laurent Léonard
Import upstream version 0.8.7
756
#define XEN_V2_OP_GETAVAILHEAP		9
0.2.1 by Guido Günther
Import upstream version 0.7.2
757
758
/*
759
 * from V2 we get the scheduler parameter
760
 */
761
#define XEN_V2_OP_SCHEDULER		16
762
/* Scheduler types. */
763
#define XEN_SCHEDULER_SEDF       4
764
#define XEN_SCHEDULER_CREDIT     5
765
/* get/set scheduler parameters */
766
#define XEN_DOMCTL_SCHEDOP_putinfo 0
767
#define XEN_DOMCTL_SCHEDOP_getinfo 1
768
769
struct xen_v2_setschedinfo {
770
    uint32_t sched_id;
771
    uint32_t cmd;
772
    union {
773
        struct xen_domctl_sched_sedf {
774
            uint64_t period ALIGN_64;
775
            uint64_t slice  ALIGN_64;
776
            uint64_t latency ALIGN_64;
777
            uint32_t extratime;
778
            uint32_t weight;
779
        } sedf;
780
        struct xen_domctl_sched_credit {
781
            uint16_t weight;
782
            uint16_t cap;
783
        } credit;
784
    } u;
785
};
786
typedef struct xen_v2_setschedinfo xen_v2_setschedinfo;
787
typedef struct xen_v2_setschedinfo xen_v2_getschedinfo;
788
789
790
/*
791
 * The hypercall operation structures also have changed on
792
 * changeset 86d26e6ec89b
793
 */
794
/* the old structure */
795
struct xen_op_v0 {
796
    uint32_t cmd;
797
    uint32_t interface_version;
798
    union {
799
        xen_v0_getdomaininfolistop getdomaininfolist;
800
        xen_v0_domainop          domain;
801
        xen_v0_setmaxmem         setmaxmem;
802
        xen_v0_setmaxvcpu        setmaxvcpu;
803
        xen_v0_setvcpumap        setvcpumap;
804
        xen_v0_vcpuinfo          getvcpuinfo;
805
        uint8_t padding[128];
806
    } u;
807
};
808
typedef struct xen_op_v0 xen_op_v0;
809
typedef struct xen_op_v0 xen_op_v1;
810
811
/* the new structure for systems operations */
812
struct xen_op_v2_sys {
813
    uint32_t cmd;
814
    uint32_t interface_version;
815
    union {
816
        xen_v2_getdomaininfolistop   getdomaininfolist;
817
        xen_v2s3_getdomaininfolistop getdomaininfolists3;
818
        xen_v2_getschedulerid        getschedulerid;
819
        xen_v2s4_availheap           availheap;
820
        xen_v2s5_availheap           availheap5;
821
        uint8_t padding[128];
822
    } u;
823
};
824
typedef struct xen_op_v2_sys xen_op_v2_sys;
825
826
/* the new structure for domains operation */
827
struct xen_op_v2_dom {
828
    uint32_t cmd;
829
    uint32_t interface_version;
830
    domid_t  domain;
831
    union {
832
        xen_v2_setmaxmem         setmaxmem;
833
        xen_v2d5_setmaxmem       setmaxmemd5;
834
        xen_v2_setmaxvcpu        setmaxvcpu;
835
        xen_v2_setvcpumap        setvcpumap;
836
        xen_v2d5_setvcpumap      setvcpumapd5;
837
        xen_v2_vcpuinfo          getvcpuinfo;
838
        xen_v2d5_vcpuinfo        getvcpuinfod5;
839
        xen_v2_getvcpumap        getvcpumap;
840
        xen_v2d5_getvcpumap      getvcpumapd5;
841
        xen_v2_setschedinfo      setschedinfo;
842
        xen_v2_getschedinfo      getschedinfo;
843
        uint8_t padding[128];
844
    } u;
845
};
846
typedef struct xen_op_v2_dom xen_op_v2_dom;
847
848
849
#ifdef __linux__
0.2.6 by Guido Günther
Import upstream version 0.8.0
850
# define XEN_HYPERVISOR_SOCKET	"/proc/xen/privcmd"
851
# define HYPERVISOR_CAPABILITIES	"/sys/hypervisor/properties/capabilities"
0.2.1 by Guido Günther
Import upstream version 0.7.2
852
#elif defined(__sun)
0.2.6 by Guido Günther
Import upstream version 0.8.0
853
# define XEN_HYPERVISOR_SOCKET	"/dev/xen/privcmd"
0.2.1 by Guido Günther
Import upstream version 0.7.2
854
#else
0.2.6 by Guido Günther
Import upstream version 0.8.0
855
# error "unsupported platform"
0.2.1 by Guido Günther
Import upstream version 0.7.2
856
#endif
857
1.2.13 by Chuck Short
Import upstream version 0.9.12
858
static unsigned long long xenHypervisorGetMaxMemory(virDomainPtr domain);
0.2.1 by Guido Günther
Import upstream version 0.7.2
859
860
struct xenUnifiedDriver xenHypervisorDriver = {
0.4.5 by Guido Günther
Import upstream version 0.9.4
861
    .xenClose = xenHypervisorClose,
862
    .xenVersion = xenHypervisorGetVersion,
863
    .xenDomainSuspend = xenHypervisorPauseDomain,
864
    .xenDomainResume = xenHypervisorResumeDomain,
865
    .xenDomainDestroyFlags = xenHypervisorDestroyDomainFlags,
866
    .xenDomainGetOSType = xenHypervisorDomainGetOSType,
867
    .xenDomainGetMaxMemory = xenHypervisorGetMaxMemory,
868
    .xenDomainSetMaxMemory = xenHypervisorSetMaxMemory,
869
    .xenDomainGetInfo = xenHypervisorGetDomainInfo,
870
    .xenDomainPinVcpu = xenHypervisorPinVcpu,
871
    .xenDomainGetVcpus = xenHypervisorGetVcpus,
872
    .xenDomainGetSchedulerType = xenHypervisorGetSchedulerType,
873
    .xenDomainGetSchedulerParameters = xenHypervisorGetSchedulerParameters,
874
    .xenDomainSetSchedulerParameters = xenHypervisorSetSchedulerParameters,
0.2.1 by Guido Günther
Import upstream version 0.7.2
875
};
876
0.2.6 by Guido Günther
Import upstream version 0.8.0
877
#define virXenError(code, ...)                                             \
878
        if (in_init == 0)                                                  \
0.3.7 by Guido Günther
Import upstream version 0.9.1
879
            virReportErrorHelper(VIR_FROM_XEN, code, __FILE__,             \
0.2.6 by Guido Günther
Import upstream version 0.8.0
880
                                 __FUNCTION__, __LINE__, __VA_ARGS__)
0.2.1 by Guido Günther
Import upstream version 0.7.2
881
882
/**
883
 * xenHypervisorDoV0Op:
884
 * @handle: the handle to the Xen hypervisor
885
 * @op: pointer to the hypervisor operation structure
886
 *
0.5.5 by Guido Günther
Import upstream version 0.9.8~rc2
887
 * Do a hypervisor operation though the old interface,
888
 * this leads to a hypervisor call through ioctl.
0.2.1 by Guido Günther
Import upstream version 0.7.2
889
 *
890
 * Returns 0 in case of success and -1 in case of error.
891
 */
892
static int
893
xenHypervisorDoV0Op(int handle, xen_op_v0 * op)
894
{
895
    int ret;
896
    v0_hypercall_t hc;
897
898
    memset(&hc, 0, sizeof(hc));
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
899
    op->interface_version = hv_versions.hv << 8;
0.2.1 by Guido Günther
Import upstream version 0.7.2
900
    hc.op = __HYPERVISOR_dom0_op;
901
    hc.arg[0] = (unsigned long) op;
902
903
    if (lock_pages(op, sizeof(dom0_op_t)) < 0) {
0.2.6 by Guido Günther
Import upstream version 0.8.0
904
        virXenError(VIR_ERR_XEN_CALL, " locking");
1.2.13 by Chuck Short
Import upstream version 0.9.12
905
        return -1;
0.2.1 by Guido Günther
Import upstream version 0.7.2
906
    }
907
908
    ret = ioctl(handle, xen_ioctl_hypercall_cmd, (unsigned long) &hc);
909
    if (ret < 0) {
0.2.6 by Guido Günther
Import upstream version 0.8.0
910
        virXenError(VIR_ERR_XEN_CALL, " ioctl %d",
0.2.1 by Guido Günther
Import upstream version 0.7.2
911
                    xen_ioctl_hypercall_cmd);
912
    }
913
914
    if (unlock_pages(op, sizeof(dom0_op_t)) < 0) {
0.2.6 by Guido Günther
Import upstream version 0.8.0
915
        virXenError(VIR_ERR_XEN_CALL, " releasing");
0.2.1 by Guido Günther
Import upstream version 0.7.2
916
        ret = -1;
917
    }
918
919
    if (ret < 0)
1.2.13 by Chuck Short
Import upstream version 0.9.12
920
        return -1;
0.2.1 by Guido Günther
Import upstream version 0.7.2
921
1.2.13 by Chuck Short
Import upstream version 0.9.12
922
    return 0;
0.2.1 by Guido Günther
Import upstream version 0.7.2
923
}
924
/**
925
 * xenHypervisorDoV1Op:
926
 * @handle: the handle to the Xen hypervisor
927
 * @op: pointer to the hypervisor operation structure
928
 *
0.5.5 by Guido Günther
Import upstream version 0.9.8~rc2
929
 * Do a hypervisor v1 operation, this leads to a hypervisor call through
0.2.1 by Guido Günther
Import upstream version 0.7.2
930
 * ioctl.
931
 *
932
 * Returns 0 in case of success and -1 in case of error.
933
 */
934
static int
935
xenHypervisorDoV1Op(int handle, xen_op_v1* op)
936
{
937
    int ret;
938
    hypercall_t hc;
939
940
    memset(&hc, 0, sizeof(hc));
941
    op->interface_version = DOM0_INTERFACE_VERSION;
942
    hc.op = __HYPERVISOR_dom0_op;
943
    hc.arg[0] = (unsigned long) op;
944
945
    if (lock_pages(op, sizeof(dom0_op_t)) < 0) {
0.2.6 by Guido Günther
Import upstream version 0.8.0
946
        virXenError(VIR_ERR_XEN_CALL, " locking");
1.2.13 by Chuck Short
Import upstream version 0.9.12
947
        return -1;
0.2.1 by Guido Günther
Import upstream version 0.7.2
948
    }
949
950
    ret = ioctl(handle, xen_ioctl_hypercall_cmd, (unsigned long) &hc);
951
    if (ret < 0) {
0.2.6 by Guido Günther
Import upstream version 0.8.0
952
        virXenError(VIR_ERR_XEN_CALL, " ioctl %d",
0.2.1 by Guido Günther
Import upstream version 0.7.2
953
                    xen_ioctl_hypercall_cmd);
954
    }
955
956
    if (unlock_pages(op, sizeof(dom0_op_t)) < 0) {
0.2.6 by Guido Günther
Import upstream version 0.8.0
957
        virXenError(VIR_ERR_XEN_CALL, " releasing");
0.2.1 by Guido Günther
Import upstream version 0.7.2
958
        ret = -1;
959
    }
960
961
    if (ret < 0)
1.2.13 by Chuck Short
Import upstream version 0.9.12
962
        return -1;
0.2.1 by Guido Günther
Import upstream version 0.7.2
963
1.2.13 by Chuck Short
Import upstream version 0.9.12
964
    return 0;
0.2.1 by Guido Günther
Import upstream version 0.7.2
965
}
966
967
/**
968
 * xenHypervisorDoV2Sys:
969
 * @handle: the handle to the Xen hypervisor
970
 * @op: pointer to the hypervisor operation structure
971
 *
0.5.5 by Guido Günther
Import upstream version 0.9.8~rc2
972
 * Do a hypervisor v2 system operation, this leads to a hypervisor
0.2.1 by Guido Günther
Import upstream version 0.7.2
973
 * call through ioctl.
974
 *
975
 * Returns 0 in case of success and -1 in case of error.
976
 */
977
static int
978
xenHypervisorDoV2Sys(int handle, xen_op_v2_sys* op)
979
{
980
    int ret;
981
    hypercall_t hc;
982
983
    memset(&hc, 0, sizeof(hc));
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
984
    op->interface_version = hv_versions.sys_interface;
0.2.1 by Guido Günther
Import upstream version 0.7.2
985
    hc.op = __HYPERVISOR_sysctl;
986
    hc.arg[0] = (unsigned long) op;
987
988
    if (lock_pages(op, sizeof(dom0_op_t)) < 0) {
0.2.6 by Guido Günther
Import upstream version 0.8.0
989
        virXenError(VIR_ERR_XEN_CALL, " locking");
1.2.13 by Chuck Short
Import upstream version 0.9.12
990
        return -1;
0.2.1 by Guido Günther
Import upstream version 0.7.2
991
    }
992
993
    ret = ioctl(handle, xen_ioctl_hypercall_cmd, (unsigned long) &hc);
994
    if (ret < 0) {
0.2.6 by Guido Günther
Import upstream version 0.8.0
995
        virXenError(VIR_ERR_XEN_CALL, " sys ioctl %d",
0.2.1 by Guido Günther
Import upstream version 0.7.2
996
                                            xen_ioctl_hypercall_cmd);
997
    }
998
999
    if (unlock_pages(op, sizeof(dom0_op_t)) < 0) {
0.2.6 by Guido Günther
Import upstream version 0.8.0
1000
        virXenError(VIR_ERR_XEN_CALL, " releasing");
0.2.1 by Guido Günther
Import upstream version 0.7.2
1001
        ret = -1;
1002
    }
1003
1004
    if (ret < 0)
1.2.13 by Chuck Short
Import upstream version 0.9.12
1005
        return -1;
0.2.1 by Guido Günther
Import upstream version 0.7.2
1006
1.2.13 by Chuck Short
Import upstream version 0.9.12
1007
    return 0;
0.2.1 by Guido Günther
Import upstream version 0.7.2
1008
}
1009
1010
/**
1011
 * xenHypervisorDoV2Dom:
1012
 * @handle: the handle to the Xen hypervisor
1013
 * @op: pointer to the hypervisor domain operation structure
1014
 *
0.5.5 by Guido Günther
Import upstream version 0.9.8~rc2
1015
 * Do a hypervisor v2 domain operation, this leads to a hypervisor
0.2.1 by Guido Günther
Import upstream version 0.7.2
1016
 * call through ioctl.
1017
 *
1018
 * Returns 0 in case of success and -1 in case of error.
1019
 */
1020
static int
1021
xenHypervisorDoV2Dom(int handle, xen_op_v2_dom* op)
1022
{
1023
    int ret;
1024
    hypercall_t hc;
1025
1026
    memset(&hc, 0, sizeof(hc));
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
1027
    op->interface_version = hv_versions.dom_interface;
0.2.1 by Guido Günther
Import upstream version 0.7.2
1028
    hc.op = __HYPERVISOR_domctl;
1029
    hc.arg[0] = (unsigned long) op;
1030
1031
    if (lock_pages(op, sizeof(dom0_op_t)) < 0) {
0.2.6 by Guido Günther
Import upstream version 0.8.0
1032
        virXenError(VIR_ERR_XEN_CALL, " locking");
1.2.13 by Chuck Short
Import upstream version 0.9.12
1033
        return -1;
0.2.1 by Guido Günther
Import upstream version 0.7.2
1034
    }
1035
1036
    ret = ioctl(handle, xen_ioctl_hypercall_cmd, (unsigned long) &hc);
1037
    if (ret < 0) {
0.2.6 by Guido Günther
Import upstream version 0.8.0
1038
        virXenError(VIR_ERR_XEN_CALL, " ioctl %d",
0.2.1 by Guido Günther
Import upstream version 0.7.2
1039
                    xen_ioctl_hypercall_cmd);
1040
    }
1041
1042
    if (unlock_pages(op, sizeof(dom0_op_t)) < 0) {
0.2.6 by Guido Günther
Import upstream version 0.8.0
1043
        virXenError(VIR_ERR_XEN_CALL, " releasing");
0.2.1 by Guido Günther
Import upstream version 0.7.2
1044
        ret = -1;
1045
    }
1046
1047
    if (ret < 0)
1.2.13 by Chuck Short
Import upstream version 0.9.12
1048
        return -1;
0.2.1 by Guido Günther
Import upstream version 0.7.2
1049
1.2.13 by Chuck Short
Import upstream version 0.9.12
1050
    return 0;
0.2.1 by Guido Günther
Import upstream version 0.7.2
1051
}
1052
1053
/**
1054
 * virXen_getdomaininfolist:
1055
 * @handle: the hypervisor handle
1056
 * @first_domain: first domain in the range
1057
 * @maxids: maximum number of domains to list
1058
 * @dominfos: output structures
1059
 *
1060
 * Do a low level hypercall to list existing domains information
1061
 *
1062
 * Returns the number of domains or -1 in case of failure
1063
 */
1064
static int
1065
virXen_getdomaininfolist(int handle, int first_domain, int maxids,
1066
                         xen_getdomaininfolist *dominfos)
1067
{
1068
    int ret = -1;
1069
1070
    if (lock_pages(XEN_GETDOMAININFOLIST_DATA(dominfos),
1071
              XEN_GETDOMAININFO_SIZE * maxids) < 0) {
0.2.6 by Guido Günther
Import upstream version 0.8.0
1072
        virXenError(VIR_ERR_XEN_CALL, " locking");
1.2.13 by Chuck Short
Import upstream version 0.9.12
1073
        return -1;
0.2.1 by Guido Günther
Import upstream version 0.7.2
1074
    }
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
1075
    if (hv_versions.hypervisor > 1) {
0.2.1 by Guido Günther
Import upstream version 0.7.2
1076
        xen_op_v2_sys op;
1077
1078
        memset(&op, 0, sizeof(op));
1079
        op.cmd = XEN_V2_OP_GETDOMAININFOLIST;
1080
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
1081
        if (hv_versions.sys_interface < 3) {
0.2.1 by Guido Günther
Import upstream version 0.7.2
1082
            op.u.getdomaininfolist.first_domain = (domid_t) first_domain;
1083
            op.u.getdomaininfolist.max_domains = maxids;
1084
            op.u.getdomaininfolist.buffer = dominfos->v2;
1085
            op.u.getdomaininfolist.num_domains = maxids;
1086
        } else {
1087
            op.u.getdomaininfolists3.first_domain = (domid_t) first_domain;
1088
            op.u.getdomaininfolists3.max_domains = maxids;
1089
            op.u.getdomaininfolists3.buffer.v = dominfos->v2d5;
1090
            op.u.getdomaininfolists3.num_domains = maxids;
1091
        }
1092
        ret = xenHypervisorDoV2Sys(handle, &op);
1093
1094
        if (ret == 0) {
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
1095
            if (hv_versions.sys_interface < 3)
0.2.1 by Guido Günther
Import upstream version 0.7.2
1096
                ret = op.u.getdomaininfolist.num_domains;
1097
            else
1098
                ret = op.u.getdomaininfolists3.num_domains;
1099
        }
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
1100
    } else if (hv_versions.hypervisor == 1) {
0.2.1 by Guido Günther
Import upstream version 0.7.2
1101
        xen_op_v1 op;
1102
1103
        memset(&op, 0, sizeof(op));
1104
        op.cmd = XEN_V1_OP_GETDOMAININFOLIST;
1105
        op.u.getdomaininfolist.first_domain = (domid_t) first_domain;
1106
        op.u.getdomaininfolist.max_domains = maxids;
1107
        op.u.getdomaininfolist.buffer = dominfos->v0;
1108
        op.u.getdomaininfolist.num_domains = maxids;
1109
        ret = xenHypervisorDoV1Op(handle, &op);
1110
        if (ret == 0)
1111
            ret = op.u.getdomaininfolist.num_domains;
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
1112
    } else if (hv_versions.hypervisor == 0) {
0.2.1 by Guido Günther
Import upstream version 0.7.2
1113
        xen_op_v0 op;
1114
1115
        memset(&op, 0, sizeof(op));
1116
        op.cmd = XEN_V0_OP_GETDOMAININFOLIST;
1117
        op.u.getdomaininfolist.first_domain = (domid_t) first_domain;
1118
        op.u.getdomaininfolist.max_domains = maxids;
1119
        op.u.getdomaininfolist.buffer = dominfos->v0;
1120
        op.u.getdomaininfolist.num_domains = maxids;
1121
        ret = xenHypervisorDoV0Op(handle, &op);
1122
        if (ret == 0)
1123
            ret = op.u.getdomaininfolist.num_domains;
1124
    }
1125
    if (unlock_pages(XEN_GETDOMAININFOLIST_DATA(dominfos),
1126
                XEN_GETDOMAININFO_SIZE * maxids) < 0) {
0.2.6 by Guido Günther
Import upstream version 0.8.0
1127
        virXenError(VIR_ERR_XEN_CALL, " release");
0.2.1 by Guido Günther
Import upstream version 0.7.2
1128
        ret = -1;
1129
    }
1.2.13 by Chuck Short
Import upstream version 0.9.12
1130
    return ret;
0.2.1 by Guido Günther
Import upstream version 0.7.2
1131
}
1132
1133
static int
1134
virXen_getdomaininfo(int handle, int first_domain,
1135
                     xen_getdomaininfo *dominfo) {
1136
    xen_getdomaininfolist dominfos;
1137
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
1138
    if (hv_versions.hypervisor < 2) {
0.2.1 by Guido Günther
Import upstream version 0.7.2
1139
        dominfos.v0 = &(dominfo->v0);
1140
    } else {
1141
        dominfos.v2 = &(dominfo->v2);
1142
    }
1143
1144
    return virXen_getdomaininfolist(handle, first_domain, 1, &dominfos);
1145
}
1146
1147
1148
/**
1149
 * xenHypervisorGetSchedulerType:
1150
 * @domain: pointer to the Xen Hypervisor block
1151
 * @nparams:give a number of scheduler parameters.
1152
 *
1153
 * Do a low level hypercall to get scheduler type
1154
 *
1155
 * Returns scheduler name or NULL in case of failure
1156
 */
1157
char *
1158
xenHypervisorGetSchedulerType(virDomainPtr domain, int *nparams)
1159
{
1160
    char *schedulertype = NULL;
1161
    xenUnifiedPrivatePtr priv;
1162
0.2.4 by Laurent Léonard
Import upstream version 0.7.6
1163
    if (domain->conn == NULL) {
1.2.13 by Chuck Short
Import upstream version 0.9.12
1164
        virXenError(VIR_ERR_INTERNAL_ERROR, "%s",
1165
                    _("domain or conn is NULL"));
0.2.1 by Guido Günther
Import upstream version 0.7.2
1166
        return NULL;
1167
    }
1168
1169
    priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
1170
    if (priv->handle < 0) {
1.2.13 by Chuck Short
Import upstream version 0.9.12
1171
        virXenError(VIR_ERR_INTERNAL_ERROR, "%s",
1172
                    _("priv->handle invalid"));
0.2.1 by Guido Günther
Import upstream version 0.7.2
1173
        return NULL;
1174
    }
1175
    if (domain->id < 0) {
0.2.6 by Guido Günther
Import upstream version 0.8.0
1176
        virXenError(VIR_ERR_OPERATION_INVALID,
0.2.1 by Guido Günther
Import upstream version 0.7.2
1177
                    "%s", _("domain is not running"));
1178
        return NULL;
1179
    }
1180
1181
    /*
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
1182
     * Support only hv_versions.dom_interface >=5
0.2.1 by Guido Günther
Import upstream version 0.7.2
1183
     * (Xen3.1.0 or later)
1184
     * TODO: check on Xen 3.0.3
1185
     */
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
1186
    if (hv_versions.dom_interface < 5) {
1.2.13 by Chuck Short
Import upstream version 0.9.12
1187
        virXenError(VIR_ERR_NO_XEN, "%s",
1188
                    _("unsupported in dom interface < 5"));
0.2.1 by Guido Günther
Import upstream version 0.7.2
1189
        return NULL;
1190
    }
1191
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
1192
    if (hv_versions.hypervisor > 1) {
0.2.1 by Guido Günther
Import upstream version 0.7.2
1193
        xen_op_v2_sys op;
1194
        int ret;
1195
1196
        memset(&op, 0, sizeof(op));
1197
        op.cmd = XEN_V2_OP_GETSCHEDULERID;
1198
        ret = xenHypervisorDoV2Sys(priv->handle, &op);
1199
        if (ret < 0)
1.2.13 by Chuck Short
Import upstream version 0.9.12
1200
            return NULL;
0.2.1 by Guido Günther
Import upstream version 0.7.2
1201
1202
        switch (op.u.getschedulerid.sched_id){
1203
            case XEN_SCHEDULER_SEDF:
1204
                schedulertype = strdup("sedf");
0.2.2 by Guido Günther
Import upstream version 0.7.4
1205
                if (schedulertype == NULL)
0.2.5 by Laurent Léonard
Import upstream version 0.7.7
1206
                    virReportOOMError();
0.2.1 by Guido Günther
Import upstream version 0.7.2
1207
                if (nparams)
0.3.8 by Guido Günther
Import upstream version 0.9.2
1208
                    *nparams = XEN_SCHED_SEDF_NPARAM;
0.2.1 by Guido Günther
Import upstream version 0.7.2
1209
                break;
1210
            case XEN_SCHEDULER_CREDIT:
1211
                schedulertype = strdup("credit");
0.2.2 by Guido Günther
Import upstream version 0.7.4
1212
                if (schedulertype == NULL)
0.2.5 by Laurent Léonard
Import upstream version 0.7.7
1213
                    virReportOOMError();
0.2.1 by Guido Günther
Import upstream version 0.7.2
1214
                if (nparams)
0.3.8 by Guido Günther
Import upstream version 0.9.2
1215
                    *nparams = XEN_SCHED_CRED_NPARAM;
0.2.1 by Guido Günther
Import upstream version 0.7.2
1216
                break;
1217
            default:
1218
                break;
1219
        }
1220
    }
1221
1222
    return schedulertype;
1223
}
1224
1225
/**
1226
 * xenHypervisorGetSchedulerParameters:
1227
 * @domain: pointer to the Xen Hypervisor block
1228
 * @params: pointer to scheduler parameters.
1229
 *     This memory area should be allocated before calling.
0.3.8 by Guido Günther
Import upstream version 0.9.2
1230
 * @nparams: this parameter must be at least as large as
1231
 *     the given number of scheduler parameters.
0.2.1 by Guido Günther
Import upstream version 0.7.2
1232
 *     from xenHypervisorGetSchedulerType().
1233
 *
1234
 * Do a low level hypercall to get scheduler parameters
1235
 *
1236
 * Returns 0 or -1 in case of failure
1237
 */
1238
int
1239
xenHypervisorGetSchedulerParameters(virDomainPtr domain,
0.3.8 by Guido Günther
Import upstream version 0.9.2
1240
                                    virTypedParameterPtr params, int *nparams)
0.2.1 by Guido Günther
Import upstream version 0.7.2
1241
{
1242
    xenUnifiedPrivatePtr priv;
1243
0.2.4 by Laurent Léonard
Import upstream version 0.7.6
1244
    if (domain->conn == NULL) {
1.2.13 by Chuck Short
Import upstream version 0.9.12
1245
        virXenError(VIR_ERR_INTERNAL_ERROR, "%s",
1246
                    _("domain or conn is NULL"));
0.2.1 by Guido Günther
Import upstream version 0.7.2
1247
        return -1;
1248
    }
1249
1250
    priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
1251
    if (priv->handle < 0) {
1.2.13 by Chuck Short
Import upstream version 0.9.12
1252
        virXenError(VIR_ERR_INTERNAL_ERROR, "%s",
1253
                    _("priv->handle invalid"));
0.2.1 by Guido Günther
Import upstream version 0.7.2
1254
        return -1;
1255
    }
1256
    if (domain->id < 0) {
0.2.6 by Guido Günther
Import upstream version 0.8.0
1257
        virXenError(VIR_ERR_OPERATION_INVALID,
0.2.1 by Guido Günther
Import upstream version 0.7.2
1258
                    "%s", _("domain is not running"));
1259
        return -1;
1260
    }
1261
1262
    /*
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
1263
     * Support only hv_versions.dom_interface >=5
0.2.1 by Guido Günther
Import upstream version 0.7.2
1264
     * (Xen3.1.0 or later)
1265
     * TODO: check on Xen 3.0.3
1266
     */
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
1267
    if (hv_versions.dom_interface < 5) {
1.2.13 by Chuck Short
Import upstream version 0.9.12
1268
        virXenError(VIR_ERR_NO_XEN, "%s",
1269
                    _("unsupported in dom interface < 5"));
0.2.1 by Guido Günther
Import upstream version 0.7.2
1270
        return -1;
1271
    }
1272
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
1273
    if (hv_versions.hypervisor > 1) {
0.2.1 by Guido Günther
Import upstream version 0.7.2
1274
        xen_op_v2_sys op_sys;
1275
        xen_op_v2_dom op_dom;
1276
        int ret;
1277
1278
        memset(&op_sys, 0, sizeof(op_sys));
1279
        op_sys.cmd = XEN_V2_OP_GETSCHEDULERID;
1280
        ret = xenHypervisorDoV2Sys(priv->handle, &op_sys);
1281
        if (ret < 0)
1282
            return -1;
1283
1284
        switch (op_sys.u.getschedulerid.sched_id){
1285
            case XEN_SCHEDULER_SEDF:
0.3.8 by Guido Günther
Import upstream version 0.9.2
1286
                if (*nparams < XEN_SCHED_SEDF_NPARAM) {
1287
                    virXenError(VIR_ERR_INVALID_ARG,
1288
                                "%s", _("Invalid parameter count"));
1289
                    return -1;
1290
                }
1291
0.2.1 by Guido Günther
Import upstream version 0.7.2
1292
                /* TODO: Implement for Xen/SEDF */
1293
                TODO
1.2.13 by Chuck Short
Import upstream version 0.9.12
1294
                return -1;
0.2.1 by Guido Günther
Import upstream version 0.7.2
1295
            case XEN_SCHEDULER_CREDIT:
1296
                memset(&op_dom, 0, sizeof(op_dom));
1297
                op_dom.cmd = XEN_V2_OP_SCHEDULER;
1298
                op_dom.domain = (domid_t) domain->id;
1299
                op_dom.u.getschedinfo.sched_id = XEN_SCHEDULER_CREDIT;
1300
                op_dom.u.getschedinfo.cmd = XEN_DOMCTL_SCHEDOP_getinfo;
1301
                ret = xenHypervisorDoV2Dom(priv->handle, &op_dom);
1302
                if (ret < 0)
1.2.13 by Chuck Short
Import upstream version 0.9.12
1303
                    return -1;
1304
1305
                if (virTypedParameterAssign(&params[0],
1306
                                            VIR_DOMAIN_SCHEDULER_WEIGHT,
1307
                                            VIR_TYPED_PARAM_UINT,
1308
                                            op_dom.u.getschedinfo.u.credit.weight) < 0)
1309
                    return -1;
1310
1311
                if (*nparams > 1 &&
1312
                    virTypedParameterAssign(&params[1],
1313
                                            VIR_DOMAIN_SCHEDULER_CAP,
1314
                                            VIR_TYPED_PARAM_UINT,
1315
                                            op_dom.u.getschedinfo.u.credit.cap) < 0)
0.5.2 by Guido Günther
Import upstream version 0.9.7~rc2
1316
                        return -1;
0.2.1 by Guido Günther
Import upstream version 0.7.2
1317
0.5.2 by Guido Günther
Import upstream version 0.9.7~rc2
1318
                if (*nparams > XEN_SCHED_CRED_NPARAM)
1319
                    *nparams = XEN_SCHED_CRED_NPARAM;
0.2.1 by Guido Günther
Import upstream version 0.7.2
1320
                break;
1321
            default:
1.2.13 by Chuck Short
Import upstream version 0.9.12
1322
                virXenError(VIR_ERR_INVALID_ARG,
1323
                            _("Unknown scheduler %d"),
1324
                            op_sys.u.getschedulerid.sched_id);
0.2.1 by Guido Günther
Import upstream version 0.7.2
1325
                return -1;
1326
        }
1327
    }
1328
1329
    return 0;
1330
}
1331
1332
/**
1333
 * xenHypervisorSetSchedulerParameters:
1334
 * @domain: pointer to the Xen Hypervisor block
1335
 * @nparams:give a number of scheduler setting parameters .
1336
 *
1337
 * Do a low level hypercall to set scheduler parameters
1338
 *
1339
 * Returns 0 or -1 in case of failure
1340
 */
1341
int
1342
xenHypervisorSetSchedulerParameters(virDomainPtr domain,
0.3.8 by Guido Günther
Import upstream version 0.9.2
1343
                                    virTypedParameterPtr params, int nparams)
0.2.1 by Guido Günther
Import upstream version 0.7.2
1344
{
1345
    int i;
1346
    unsigned int val;
1347
    xenUnifiedPrivatePtr priv;
1348
    char buf[256];
1349
0.2.4 by Laurent Léonard
Import upstream version 0.7.6
1350
    if (domain->conn == NULL) {
1.2.13 by Chuck Short
Import upstream version 0.9.12
1351
        virXenError(VIR_ERR_INTERNAL_ERROR, "%s",
1352
                    _("domain or conn is NULL"));
0.2.1 by Guido Günther
Import upstream version 0.7.2
1353
        return -1;
1354
    }
1355
0.3.8 by Guido Günther
Import upstream version 0.9.2
1356
    if (nparams == 0) {
1357
        /* nothing to do, exit early */
1358
        return 0;
0.2.1 by Guido Günther
Import upstream version 0.7.2
1359
    }
1360
1.2.13 by Chuck Short
Import upstream version 0.9.12
1361
    if (virTypedParameterArrayValidate(params, nparams,
1362
                                       VIR_DOMAIN_SCHEDULER_WEIGHT,
1363
                                       VIR_TYPED_PARAM_UINT,
1364
                                       VIR_DOMAIN_SCHEDULER_CAP,
1365
                                       VIR_TYPED_PARAM_UINT,
1366
                                       NULL) < 0)
1367
        return -1;
1368
0.2.1 by Guido Günther
Import upstream version 0.7.2
1369
    priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
1370
    if (priv->handle < 0) {
1.2.13 by Chuck Short
Import upstream version 0.9.12
1371
        virXenError(VIR_ERR_INTERNAL_ERROR, "%s",
1372
                    _("priv->handle invalid"));
0.2.1 by Guido Günther
Import upstream version 0.7.2
1373
        return -1;
1374
    }
1375
    if (domain->id < 0) {
0.2.6 by Guido Günther
Import upstream version 0.8.0
1376
        virXenError(VIR_ERR_OPERATION_INVALID,
0.2.1 by Guido Günther
Import upstream version 0.7.2
1377
                    "%s", _("domain is not running"));
1378
        return -1;
1379
    }
1380
1381
    /*
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
1382
     * Support only hv_versions.dom_interface >=5
0.2.1 by Guido Günther
Import upstream version 0.7.2
1383
     * (Xen3.1.0 or later)
1384
     * TODO: check on Xen 3.0.3
1385
     */
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
1386
    if (hv_versions.dom_interface < 5) {
1.2.13 by Chuck Short
Import upstream version 0.9.12
1387
        virXenError(VIR_ERR_NO_XEN, "%s",
1388
                    _("unsupported in dom interface < 5"));
0.2.1 by Guido Günther
Import upstream version 0.7.2
1389
        return -1;
1390
    }
1391
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
1392
    if (hv_versions.hypervisor > 1) {
0.2.1 by Guido Günther
Import upstream version 0.7.2
1393
        xen_op_v2_sys op_sys;
1394
        xen_op_v2_dom op_dom;
1395
        int ret;
1396
1397
        memset(&op_sys, 0, sizeof(op_sys));
1398
        op_sys.cmd = XEN_V2_OP_GETSCHEDULERID;
1399
        ret = xenHypervisorDoV2Sys(priv->handle, &op_sys);
1400
        if (ret == -1) return -1;
1401
1402
        switch (op_sys.u.getschedulerid.sched_id){
1403
        case XEN_SCHEDULER_SEDF:
1404
            /* TODO: Implement for Xen/SEDF */
1405
            TODO
1.2.13 by Chuck Short
Import upstream version 0.9.12
1406
            return -1;
0.2.1 by Guido Günther
Import upstream version 0.7.2
1407
        case XEN_SCHEDULER_CREDIT: {
1408
            memset(&op_dom, 0, sizeof(op_dom));
1409
            op_dom.cmd = XEN_V2_OP_SCHEDULER;
1410
            op_dom.domain = (domid_t) domain->id;
1411
            op_dom.u.getschedinfo.sched_id = XEN_SCHEDULER_CREDIT;
1412
            op_dom.u.getschedinfo.cmd = XEN_DOMCTL_SCHEDOP_putinfo;
1413
1414
            /*
1415
             * credit scheduler parameters
1416
             * following values do not change the parameters
1417
             */
1418
            op_dom.u.getschedinfo.u.credit.weight = 0;
1419
            op_dom.u.getschedinfo.u.credit.cap    = (uint16_t)~0U;
1420
1421
            for (i = 0; i < nparams; i++) {
1422
                memset(&buf, 0, sizeof(buf));
1.2.13 by Chuck Short
Import upstream version 0.9.12
1423
                if (STREQ(params[i].field, VIR_DOMAIN_SCHEDULER_WEIGHT)) {
0.2.1 by Guido Günther
Import upstream version 0.7.2
1424
                    val = params[i].value.ui;
1425
                    if ((val < 1) || (val > USHRT_MAX)) {
1.2.13 by Chuck Short
Import upstream version 0.9.12
1426
                        virXenError(VIR_ERR_INVALID_ARG,
1427
                                    _("Credit scheduler weight parameter (%d) "
1428
                                      "is out of range (1-65535)"), val);
1429
                        return -1;
0.2.1 by Guido Günther
Import upstream version 0.7.2
1430
                    }
1431
                    op_dom.u.getschedinfo.u.credit.weight = val;
1.2.13 by Chuck Short
Import upstream version 0.9.12
1432
                } else if (STREQ(params[i].field, VIR_DOMAIN_SCHEDULER_CAP)) {
0.2.1 by Guido Günther
Import upstream version 0.7.2
1433
                    val = params[i].value.ui;
0.3.1 by Guido Günther
Import upstream version 0.8.4
1434
                    if (val >= USHRT_MAX) {
1.2.13 by Chuck Short
Import upstream version 0.9.12
1435
                        virXenError(VIR_ERR_INVALID_ARG,
1436
                                    _("Credit scheduler cap parameter (%d) is "
1437
                                      "out of range (0-65534)"), val);
1438
                        return -1;
0.2.1 by Guido Günther
Import upstream version 0.7.2
1439
                    }
1440
                    op_dom.u.getschedinfo.u.credit.cap = val;
1441
                }
1442
            }
1443
1444
            ret = xenHypervisorDoV2Dom(priv->handle, &op_dom);
1445
            if (ret < 0)
1446
                return -1;
1447
            break;
1448
        }
1449
        default:
1.2.13 by Chuck Short
Import upstream version 0.9.12
1450
            virXenError(VIR_ERR_INVALID_ARG,
1451
                        _("Unknown scheduler %d"),
1452
                        op_sys.u.getschedulerid.sched_id);
0.2.1 by Guido Günther
Import upstream version 0.7.2
1453
            return -1;
1454
        }
1455
    }
1456
1457
    return 0;
1458
}
1459
1460
1461
int
1462
xenHypervisorDomainBlockStats (virDomainPtr dom,
1463
                               const char *path,
1464
                               struct _virDomainBlockStats *stats)
1465
{
0.3.3 by Laurent Léonard
Import upstream version 0.8.6
1466
#ifdef __linux__
0.2.1 by Guido Günther
Import upstream version 0.7.2
1467
    xenUnifiedPrivatePtr priv;
1468
    int ret;
1469
1470
    priv = (xenUnifiedPrivatePtr) dom->conn->privateData;
1471
    xenUnifiedLock(priv);
1472
    /* Need to lock because it hits the xenstore handle :-( */
1473
    ret = xenLinuxDomainBlockStats (priv, dom, path, stats);
1474
    xenUnifiedUnlock(priv);
1475
    return ret;
0.3.3 by Laurent Léonard
Import upstream version 0.8.6
1476
#else
1.2.13 by Chuck Short
Import upstream version 0.9.12
1477
    virXenError(VIR_ERR_OPERATION_INVALID, "%s",
1478
                _("block statistics not supported on this platform"));
0.2.1 by Guido Günther
Import upstream version 0.7.2
1479
    return -1;
0.3.3 by Laurent Léonard
Import upstream version 0.8.6
1480
#endif
0.2.1 by Guido Günther
Import upstream version 0.7.2
1481
}
1482
1483
/* Paths have the form vif<domid>.<n> (this interface checks that
1484
 * <domid> is the real domain ID and returns an error if not).
1485
 *
1486
 * In future we may allow you to query bridge stats (virbrX or
1487
 * xenbrX), but that will probably be through a separate
1488
 * virNetwork interface, as yet not decided.
1489
 */
1490
int
1491
xenHypervisorDomainInterfaceStats (virDomainPtr dom,
1492
                                   const char *path,
1493
                                   struct _virDomainInterfaceStats *stats)
1494
{
0.3.3 by Laurent Léonard
Import upstream version 0.8.6
1495
#ifdef __linux__
0.2.1 by Guido Günther
Import upstream version 0.7.2
1496
    int rqdomid, device;
1497
1498
    /* Verify that the vif requested is one belonging to the current
1499
     * domain.
1500
     */
1.2.13 by Chuck Short
Import upstream version 0.9.12
1501
    if (sscanf(path, "vif%d.%d", &rqdomid, &device) != 2) {
1502
        virXenError(VIR_ERR_INVALID_ARG, "%s",
1503
                    _("invalid path, should be vif<domid>.<n>."));
0.2.1 by Guido Günther
Import upstream version 0.7.2
1504
        return -1;
1505
    }
1506
    if (rqdomid != dom->id) {
1.2.13 by Chuck Short
Import upstream version 0.9.12
1507
        virXenError(VIR_ERR_INVALID_ARG, "%s",
1508
                    _("invalid path, vif<domid> should match this domain ID"));
0.2.1 by Guido Günther
Import upstream version 0.7.2
1509
        return -1;
1510
    }
1511
0.2.5 by Laurent Léonard
Import upstream version 0.7.7
1512
    return linuxDomainInterfaceStats(path, stats);
0.3.3 by Laurent Léonard
Import upstream version 0.8.6
1513
#else
1.2.13 by Chuck Short
Import upstream version 0.9.12
1514
    virXenError(VIR_ERR_OPERATION_INVALID, "%s",
1515
                _("/proc/net/dev: Interface not found"));
0.2.1 by Guido Günther
Import upstream version 0.7.2
1516
    return -1;
0.3.3 by Laurent Léonard
Import upstream version 0.8.6
1517
#endif
0.2.1 by Guido Günther
Import upstream version 0.7.2
1518
}
1519
1520
/**
1521
 * virXen_pausedomain:
1522
 * @handle: the hypervisor handle
1523
 * @id: the domain id
1524
 *
1525
 * Do a low level hypercall to pause the domain
1526
 *
1527
 * Returns 0 or -1 in case of failure
1528
 */
1529
static int
1530
virXen_pausedomain(int handle, int id)
1531
{
1532
    int ret = -1;
1533
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
1534
    if (hv_versions.hypervisor > 1) {
0.2.1 by Guido Günther
Import upstream version 0.7.2
1535
        xen_op_v2_dom op;
1536
1537
        memset(&op, 0, sizeof(op));
1538
        op.cmd = XEN_V2_OP_PAUSEDOMAIN;
1539
        op.domain = (domid_t) id;
1540
        ret = xenHypervisorDoV2Dom(handle, &op);
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
1541
    } else if (hv_versions.hypervisor == 1) {
0.2.1 by Guido Günther
Import upstream version 0.7.2
1542
        xen_op_v1 op;
1543
1544
        memset(&op, 0, sizeof(op));
1545
        op.cmd = XEN_V1_OP_PAUSEDOMAIN;
1546
        op.u.domain.domain = (domid_t) id;
1547
        ret = xenHypervisorDoV1Op(handle, &op);
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
1548
    } else if (hv_versions.hypervisor == 0) {
0.2.1 by Guido Günther
Import upstream version 0.7.2
1549
        xen_op_v0 op;
1550
1551
        memset(&op, 0, sizeof(op));
1552
        op.cmd = XEN_V0_OP_PAUSEDOMAIN;
1553
        op.u.domain.domain = (domid_t) id;
1554
        ret = xenHypervisorDoV0Op(handle, &op);
1555
    }
1.2.13 by Chuck Short
Import upstream version 0.9.12
1556
    return ret;
0.2.1 by Guido Günther
Import upstream version 0.7.2
1557
}
1558
1559
/**
1560
 * virXen_unpausedomain:
1561
 * @handle: the hypervisor handle
1562
 * @id: the domain id
1563
 *
1564
 * Do a low level hypercall to unpause the domain
1565
 *
1566
 * Returns 0 or -1 in case of failure
1567
 */
1568
static int
1569
virXen_unpausedomain(int handle, int id)
1570
{
1571
    int ret = -1;
1572
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
1573
    if (hv_versions.hypervisor > 1) {
0.2.1 by Guido Günther
Import upstream version 0.7.2
1574
        xen_op_v2_dom op;
1575
1576
        memset(&op, 0, sizeof(op));
1577
        op.cmd = XEN_V2_OP_UNPAUSEDOMAIN;
1578
        op.domain = (domid_t) id;
1579
        ret = xenHypervisorDoV2Dom(handle, &op);
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
1580
    } else if (hv_versions.hypervisor == 1) {
0.2.1 by Guido Günther
Import upstream version 0.7.2
1581
        xen_op_v1 op;
1582
1583
        memset(&op, 0, sizeof(op));
1584
        op.cmd = XEN_V1_OP_UNPAUSEDOMAIN;
1585
        op.u.domain.domain = (domid_t) id;
1586
        ret = xenHypervisorDoV1Op(handle, &op);
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
1587
    } else if (hv_versions.hypervisor == 0) {
0.2.1 by Guido Günther
Import upstream version 0.7.2
1588
        xen_op_v0 op;
1589
1590
        memset(&op, 0, sizeof(op));
1591
        op.cmd = XEN_V0_OP_UNPAUSEDOMAIN;
1592
        op.u.domain.domain = (domid_t) id;
1593
        ret = xenHypervisorDoV0Op(handle, &op);
1594
    }
1.2.13 by Chuck Short
Import upstream version 0.9.12
1595
    return ret;
0.2.1 by Guido Günther
Import upstream version 0.7.2
1596
}
1597
1598
/**
1599
 * virXen_destroydomain:
1600
 * @handle: the hypervisor handle
1601
 * @id: the domain id
1602
 *
1603
 * Do a low level hypercall to destroy the domain
1604
 *
1605
 * Returns 0 or -1 in case of failure
1606
 */
1607
static int
1608
virXen_destroydomain(int handle, int id)
1609
{
1610
    int ret = -1;
1611
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
1612
    if (hv_versions.hypervisor > 1) {
0.2.1 by Guido Günther
Import upstream version 0.7.2
1613
        xen_op_v2_dom op;
1614
1615
        memset(&op, 0, sizeof(op));
1616
        op.cmd = XEN_V2_OP_DESTROYDOMAIN;
1617
        op.domain = (domid_t) id;
1618
        ret = xenHypervisorDoV2Dom(handle, &op);
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
1619
    } else if (hv_versions.hypervisor == 1) {
0.2.1 by Guido Günther
Import upstream version 0.7.2
1620
        xen_op_v1 op;
1621
1622
        memset(&op, 0, sizeof(op));
1623
        op.cmd = XEN_V1_OP_DESTROYDOMAIN;
1624
        op.u.domain.domain = (domid_t) id;
1625
        ret = xenHypervisorDoV1Op(handle, &op);
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
1626
    } else if (hv_versions.hypervisor == 0) {
0.2.1 by Guido Günther
Import upstream version 0.7.2
1627
        xen_op_v0 op;
1628
1629
        memset(&op, 0, sizeof(op));
1630
        op.cmd = XEN_V0_OP_DESTROYDOMAIN;
1631
        op.u.domain.domain = (domid_t) id;
1632
        ret = xenHypervisorDoV0Op(handle, &op);
1633
    }
1.2.13 by Chuck Short
Import upstream version 0.9.12
1634
    return ret;
0.2.1 by Guido Günther
Import upstream version 0.7.2
1635
}
1636
1637
/**
1638
 * virXen_setmaxmem:
1639
 * @handle: the hypervisor handle
1640
 * @id: the domain id
1641
 * @memory: the amount of memory in kilobytes
1642
 *
1643
 * Do a low level hypercall to change the max memory amount
1644
 *
1645
 * Returns 0 or -1 in case of failure
1646
 */
1647
static int
1648
virXen_setmaxmem(int handle, int id, unsigned long memory)
1649
{
1650
    int ret = -1;
1651
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
1652
    if (hv_versions.hypervisor > 1) {
0.2.1 by Guido Günther
Import upstream version 0.7.2
1653
        xen_op_v2_dom op;
1654
1655
        memset(&op, 0, sizeof(op));
1656
        op.cmd = XEN_V2_OP_SETMAXMEM;
1657
        op.domain = (domid_t) id;
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
1658
        if (hv_versions.dom_interface < 5)
0.2.1 by Guido Günther
Import upstream version 0.7.2
1659
            op.u.setmaxmem.maxmem = memory;
1660
        else
1661
            op.u.setmaxmemd5.maxmem = memory;
1662
        ret = xenHypervisorDoV2Dom(handle, &op);
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
1663
    } else if (hv_versions.hypervisor == 1) {
0.2.1 by Guido Günther
Import upstream version 0.7.2
1664
        xen_op_v1 op;
1665
1666
        memset(&op, 0, sizeof(op));
1667
        op.cmd = XEN_V1_OP_SETMAXMEM;
1668
        op.u.setmaxmem.domain = (domid_t) id;
1669
        op.u.setmaxmem.maxmem = memory;
1670
        ret = xenHypervisorDoV1Op(handle, &op);
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
1671
    } else if (hv_versions.hypervisor == 0) {
0.2.1 by Guido Günther
Import upstream version 0.7.2
1672
        xen_op_v0 op;
1673
1674
        memset(&op, 0, sizeof(op));
1675
        op.cmd = XEN_V0_OP_SETMAXMEM;
1676
        op.u.setmaxmem.domain = (domid_t) id;
1677
        op.u.setmaxmem.maxmem = memory;
1678
        ret = xenHypervisorDoV0Op(handle, &op);
1679
    }
1.2.13 by Chuck Short
Import upstream version 0.9.12
1680
    return ret;
0.2.1 by Guido Günther
Import upstream version 0.7.2
1681
}
1682
1683
/**
1684
 * virXen_setmaxvcpus:
1685
 * @handle: the hypervisor handle
1686
 * @id: the domain id
1687
 * @vcpus: the numbers of vcpus
1688
 *
1689
 * Do a low level hypercall to change the max vcpus amount
1690
 *
1691
 * Returns 0 or -1 in case of failure
1692
 */
1693
static int
1694
virXen_setmaxvcpus(int handle, int id, unsigned int vcpus)
1695
{
1696
    int ret = -1;
1697
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
1698
    if (hv_versions.hypervisor > 1) {
0.2.1 by Guido Günther
Import upstream version 0.7.2
1699
        xen_op_v2_dom op;
1700
1701
        memset(&op, 0, sizeof(op));
1702
        op.cmd = XEN_V2_OP_SETMAXVCPU;
1703
        op.domain = (domid_t) id;
1704
        op.u.setmaxvcpu.maxvcpu = vcpus;
1705
        ret = xenHypervisorDoV2Dom(handle, &op);
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
1706
    } else if (hv_versions.hypervisor == 1) {
0.2.1 by Guido Günther
Import upstream version 0.7.2
1707
        xen_op_v1 op;
1708
1709
        memset(&op, 0, sizeof(op));
1710
        op.cmd = XEN_V1_OP_SETMAXVCPU;
1711
        op.u.setmaxvcpu.domain = (domid_t) id;
1712
        op.u.setmaxvcpu.maxvcpu = vcpus;
1713
        ret = xenHypervisorDoV1Op(handle, &op);
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
1714
    } else if (hv_versions.hypervisor == 0) {
0.2.1 by Guido Günther
Import upstream version 0.7.2
1715
        xen_op_v0 op;
1716
1717
        memset(&op, 0, sizeof(op));
1718
        op.cmd = XEN_V0_OP_SETMAXVCPU;
1719
        op.u.setmaxvcpu.domain = (domid_t) id;
1720
        op.u.setmaxvcpu.maxvcpu = vcpus;
1721
        ret = xenHypervisorDoV0Op(handle, &op);
1722
    }
1.2.13 by Chuck Short
Import upstream version 0.9.12
1723
    return ret;
0.2.1 by Guido Günther
Import upstream version 0.7.2
1724
}
1725
1726
/**
1727
 * virXen_setvcpumap:
1728
 * @handle: the hypervisor handle
1729
 * @id: the domain id
1730
 * @vcpu: the vcpu to map
1731
 * @cpumap: the bitmap for this vcpu
1732
 * @maplen: the size of the bitmap in bytes
1733
 *
1734
 * Do a low level hypercall to change the pinning for vcpu
1735
 *
1736
 * Returns 0 or -1 in case of failure
1737
 */
1738
static int
1739
virXen_setvcpumap(int handle, int id, unsigned int vcpu,
1740
                  unsigned char * cpumap, int maplen)
1741
{
1742
    int ret = -1;
1743
    unsigned char *new = NULL;
1744
    unsigned char *bitmap = NULL;
1745
    uint32_t nr_cpus;
1746
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
1747
    if (hv_versions.hypervisor > 1) {
0.2.1 by Guido Günther
Import upstream version 0.7.2
1748
        xen_op_v2_dom op;
1749
1750
        if (lock_pages(cpumap, maplen) < 0) {
0.2.6 by Guido Günther
Import upstream version 0.8.0
1751
            virXenError(VIR_ERR_XEN_CALL, " locking");
1.2.13 by Chuck Short
Import upstream version 0.9.12
1752
            return -1;
0.2.1 by Guido Günther
Import upstream version 0.7.2
1753
        }
1754
        memset(&op, 0, sizeof(op));
1755
        op.cmd = XEN_V2_OP_SETVCPUMAP;
1756
        op.domain = (domid_t) id;
1757
1758
        /* The allocated memory to cpumap must be 'sizeof(uint64_t)' byte *
1759
         * for Xen, and also nr_cpus must be 'sizeof(uint64_t) * 8'       */
1760
        if (maplen < 8) {
1761
            if (VIR_ALLOC_N(new, sizeof(uint64_t)) < 0) {
0.2.5 by Laurent Léonard
Import upstream version 0.7.7
1762
                virReportOOMError();
1.2.13 by Chuck Short
Import upstream version 0.9.12
1763
                return -1;
0.2.1 by Guido Günther
Import upstream version 0.7.2
1764
            }
1765
            memcpy(new, cpumap, maplen);
1766
            bitmap = new;
1767
            nr_cpus = sizeof(uint64_t) * 8;
1768
        } else {
1769
            bitmap = cpumap;
1770
            nr_cpus = maplen * 8;
1771
        }
1772
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
1773
        if (hv_versions.dom_interface < 5) {
0.2.1 by Guido Günther
Import upstream version 0.7.2
1774
            op.u.setvcpumap.vcpu = vcpu;
1775
            op.u.setvcpumap.cpumap.bitmap = bitmap;
1776
            op.u.setvcpumap.cpumap.nr_cpus = nr_cpus;
1777
        } else {
1778
            op.u.setvcpumapd5.vcpu = vcpu;
1779
            op.u.setvcpumapd5.cpumap.bitmap.v = bitmap;
1780
            op.u.setvcpumapd5.cpumap.nr_cpus = nr_cpus;
1781
        }
1782
        ret = xenHypervisorDoV2Dom(handle, &op);
1783
        VIR_FREE(new);
1784
1785
        if (unlock_pages(cpumap, maplen) < 0) {
0.2.6 by Guido Günther
Import upstream version 0.8.0
1786
            virXenError(VIR_ERR_XEN_CALL, " release");
0.2.1 by Guido Günther
Import upstream version 0.7.2
1787
            ret = -1;
1788
        }
1789
    } else {
1790
        cpumap_t xen_cpumap; /* limited to 64 CPUs in old hypervisors */
1791
        uint64_t *pm = &xen_cpumap;
1792
        int j;
1793
1794
        if ((maplen > (int)sizeof(cpumap_t)) || (sizeof(cpumap_t) & 7))
1.2.13 by Chuck Short
Import upstream version 0.9.12
1795
            return -1;
0.2.1 by Guido Günther
Import upstream version 0.7.2
1796
1797
        memset(pm, 0, sizeof(cpumap_t));
1798
        for (j = 0; j < maplen; j++)
1799
            *(pm + (j / 8)) |= cpumap[j] << (8 * (j & 7));
1800
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
1801
        if (hv_versions.hypervisor == 1) {
0.2.1 by Guido Günther
Import upstream version 0.7.2
1802
            xen_op_v1 op;
1803
1804
            memset(&op, 0, sizeof(op));
1805
            op.cmd = XEN_V1_OP_SETVCPUMAP;
1806
            op.u.setvcpumap.domain = (domid_t) id;
1807
            op.u.setvcpumap.vcpu = vcpu;
1808
            op.u.setvcpumap.cpumap = xen_cpumap;
1809
            ret = xenHypervisorDoV1Op(handle, &op);
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
1810
        } else if (hv_versions.hypervisor == 0) {
0.2.1 by Guido Günther
Import upstream version 0.7.2
1811
            xen_op_v0 op;
1812
1813
            memset(&op, 0, sizeof(op));
1814
            op.cmd = XEN_V0_OP_SETVCPUMAP;
1815
            op.u.setvcpumap.domain = (domid_t) id;
1816
            op.u.setvcpumap.vcpu = vcpu;
1817
            op.u.setvcpumap.cpumap = xen_cpumap;
1818
            ret = xenHypervisorDoV0Op(handle, &op);
1819
        }
1820
    }
1.2.13 by Chuck Short
Import upstream version 0.9.12
1821
    return ret;
0.2.1 by Guido Günther
Import upstream version 0.7.2
1822
}
0.3.3 by Laurent Léonard
Import upstream version 0.8.6
1823
0.2.1 by Guido Günther
Import upstream version 0.7.2
1824
1825
/**
1826
 * virXen_getvcpusinfo:
1827
 * @handle: the hypervisor handle
1828
 * @id: the domain id
1829
 * @vcpu: the vcpu to map
1830
 * @cpumap: the bitmap for this vcpu
1831
 * @maplen: the size of the bitmap in bytes
1832
 *
1833
 * Do a low level hypercall to change the pinning for vcpu
1834
 *
1835
 * Returns 0 or -1 in case of failure
1836
 */
1837
static int
1838
virXen_getvcpusinfo(int handle, int id, unsigned int vcpu, virVcpuInfoPtr ipt,
1839
                    unsigned char *cpumap, int maplen)
1840
{
1841
    int ret = -1;
1842
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
1843
    if (hv_versions.hypervisor > 1) {
0.2.1 by Guido Günther
Import upstream version 0.7.2
1844
        xen_op_v2_dom op;
1845
1846
        memset(&op, 0, sizeof(op));
1847
        op.cmd = XEN_V2_OP_GETVCPUINFO;
1848
        op.domain = (domid_t) id;
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
1849
        if (hv_versions.dom_interface < 5)
0.2.1 by Guido Günther
Import upstream version 0.7.2
1850
            op.u.getvcpuinfo.vcpu = (uint16_t) vcpu;
1851
        else
1852
            op.u.getvcpuinfod5.vcpu = (uint16_t) vcpu;
1853
        ret = xenHypervisorDoV2Dom(handle, &op);
1854
1855
        if (ret < 0)
1.2.13 by Chuck Short
Import upstream version 0.9.12
1856
            return -1;
0.2.1 by Guido Günther
Import upstream version 0.7.2
1857
        ipt->number = vcpu;
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
1858
        if (hv_versions.dom_interface < 5) {
0.2.1 by Guido Günther
Import upstream version 0.7.2
1859
            if (op.u.getvcpuinfo.online) {
1860
                if (op.u.getvcpuinfo.running)
1861
                    ipt->state = VIR_VCPU_RUNNING;
1862
                if (op.u.getvcpuinfo.blocked)
1863
                    ipt->state = VIR_VCPU_BLOCKED;
1864
            } else
1865
                ipt->state = VIR_VCPU_OFFLINE;
1866
1867
            ipt->cpuTime = op.u.getvcpuinfo.cpu_time;
1868
            ipt->cpu = op.u.getvcpuinfo.online ? (int)op.u.getvcpuinfo.cpu : -1;
1869
        } else {
1870
            if (op.u.getvcpuinfod5.online) {
1871
                if (op.u.getvcpuinfod5.running)
1872
                    ipt->state = VIR_VCPU_RUNNING;
1873
                if (op.u.getvcpuinfod5.blocked)
1874
                    ipt->state = VIR_VCPU_BLOCKED;
1875
            } else
1876
                ipt->state = VIR_VCPU_OFFLINE;
1877
1878
            ipt->cpuTime = op.u.getvcpuinfod5.cpu_time;
1879
            ipt->cpu = op.u.getvcpuinfod5.online ? (int)op.u.getvcpuinfod5.cpu : -1;
1880
        }
1881
        if ((cpumap != NULL) && (maplen > 0)) {
1882
            if (lock_pages(cpumap, maplen) < 0) {
0.2.6 by Guido Günther
Import upstream version 0.8.0
1883
                virXenError(VIR_ERR_XEN_CALL, " locking");
1.2.13 by Chuck Short
Import upstream version 0.9.12
1884
                return -1;
0.2.1 by Guido Günther
Import upstream version 0.7.2
1885
            }
1886
            memset(cpumap, 0, maplen);
1887
            memset(&op, 0, sizeof(op));
1888
            op.cmd = XEN_V2_OP_GETVCPUMAP;
1889
            op.domain = (domid_t) id;
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
1890
            if (hv_versions.dom_interface < 5) {
0.2.1 by Guido Günther
Import upstream version 0.7.2
1891
                op.u.getvcpumap.vcpu = vcpu;
1892
                op.u.getvcpumap.cpumap.bitmap = cpumap;
1893
                op.u.getvcpumap.cpumap.nr_cpus = maplen * 8;
1894
            } else {
1895
                op.u.getvcpumapd5.vcpu = vcpu;
1896
                op.u.getvcpumapd5.cpumap.bitmap.v = cpumap;
1897
                op.u.getvcpumapd5.cpumap.nr_cpus = maplen * 8;
1898
            }
1899
            ret = xenHypervisorDoV2Dom(handle, &op);
1900
            if (unlock_pages(cpumap, maplen) < 0) {
0.2.6 by Guido Günther
Import upstream version 0.8.0
1901
                virXenError(VIR_ERR_XEN_CALL, " release");
0.2.1 by Guido Günther
Import upstream version 0.7.2
1902
                ret = -1;
1903
            }
1904
        }
1905
    } else {
1906
        int mapl = maplen;
1907
        int cpu;
1908
1909
        if (maplen > (int)sizeof(cpumap_t))
1910
            mapl = (int)sizeof(cpumap_t);
1911
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
1912
        if (hv_versions.hypervisor == 1) {
0.2.1 by Guido Günther
Import upstream version 0.7.2
1913
            xen_op_v1 op;
1914
1915
            memset(&op, 0, sizeof(op));
1916
            op.cmd = XEN_V1_OP_GETVCPUINFO;
1917
            op.u.getvcpuinfo.domain = (domid_t) id;
1918
            op.u.getvcpuinfo.vcpu = vcpu;
1919
            ret = xenHypervisorDoV1Op(handle, &op);
1920
            if (ret < 0)
1.2.13 by Chuck Short
Import upstream version 0.9.12
1921
                return -1;
0.2.1 by Guido Günther
Import upstream version 0.7.2
1922
            ipt->number = vcpu;
1923
            if (op.u.getvcpuinfo.online) {
1924
                if (op.u.getvcpuinfo.running) ipt->state = VIR_VCPU_RUNNING;
1925
                if (op.u.getvcpuinfo.blocked) ipt->state = VIR_VCPU_BLOCKED;
1926
            }
1927
            else ipt->state = VIR_VCPU_OFFLINE;
1928
            ipt->cpuTime = op.u.getvcpuinfo.cpu_time;
1929
            ipt->cpu = op.u.getvcpuinfo.online ? (int)op.u.getvcpuinfo.cpu : -1;
1930
            if ((cpumap != NULL) && (maplen > 0)) {
1931
                for (cpu = 0; cpu < (mapl * 8); cpu++) {
1932
                    if (op.u.getvcpuinfo.cpumap & ((uint64_t)1<<cpu))
1933
                        VIR_USE_CPU(cpumap, cpu);
1934
                }
1935
            }
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
1936
        } else if (hv_versions.hypervisor == 0) {
0.2.1 by Guido Günther
Import upstream version 0.7.2
1937
            xen_op_v1 op;
1938
1939
            memset(&op, 0, sizeof(op));
1940
            op.cmd = XEN_V0_OP_GETVCPUINFO;
1941
            op.u.getvcpuinfo.domain = (domid_t) id;
1942
            op.u.getvcpuinfo.vcpu = vcpu;
1943
            ret = xenHypervisorDoV0Op(handle, &op);
1944
            if (ret < 0)
1.2.13 by Chuck Short
Import upstream version 0.9.12
1945
                return -1;
0.2.1 by Guido Günther
Import upstream version 0.7.2
1946
            ipt->number = vcpu;
1947
            if (op.u.getvcpuinfo.online) {
1948
                if (op.u.getvcpuinfo.running) ipt->state = VIR_VCPU_RUNNING;
1949
                if (op.u.getvcpuinfo.blocked) ipt->state = VIR_VCPU_BLOCKED;
1950
            }
1951
            else ipt->state = VIR_VCPU_OFFLINE;
1952
            ipt->cpuTime = op.u.getvcpuinfo.cpu_time;
1953
            ipt->cpu = op.u.getvcpuinfo.online ? (int)op.u.getvcpuinfo.cpu : -1;
1954
            if ((cpumap != NULL) && (maplen > 0)) {
1955
                for (cpu = 0; cpu < (mapl * 8); cpu++) {
1956
                    if (op.u.getvcpuinfo.cpumap & ((uint64_t)1<<cpu))
1957
                        VIR_USE_CPU(cpumap, cpu);
1958
                }
1959
            }
1960
        }
1961
    }
1.2.13 by Chuck Short
Import upstream version 0.9.12
1962
    return ret;
0.2.1 by Guido Günther
Import upstream version 0.7.2
1963
}
1964
1965
/**
1966
 * xenHypervisorInit:
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
1967
 * @override_versions: pointer to optional struct xenHypervisorVersions with
1968
 *     version information used instead of automatic version detection.
0.2.1 by Guido Günther
Import upstream version 0.7.2
1969
 *
1970
 * Initialize the hypervisor layer. Try to detect the kind of interface
1971
 * used i.e. pre or post changeset 10277
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
1972
 *
1973
 * Returns 0 or -1 in case of failure
0.2.1 by Guido Günther
Import upstream version 0.7.2
1974
 */
1975
int
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
1976
xenHypervisorInit(struct xenHypervisorVersions *override_versions)
0.2.1 by Guido Günther
Import upstream version 0.7.2
1977
{
1978
    int fd, ret, cmd, errcode;
1979
    hypercall_t hc;
1980
    v0_hypercall_t v0_hc;
1981
    xen_getdomaininfo info;
1982
    virVcpuInfoPtr ipt = NULL;
1983
1984
    if (initialized) {
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
1985
        if (hv_versions.hypervisor == -1)
1.2.13 by Chuck Short
Import upstream version 0.9.12
1986
            return -1;
1987
        return 0;
0.2.1 by Guido Günther
Import upstream version 0.7.2
1988
    }
1989
    initialized = 1;
1990
    in_init = 1;
1991
1992
    /* Compile regular expressions used by xenHypervisorGetCapabilities.
1993
     * Note that errors here are really internal errors since these
1994
     * regexps should never fail to compile.
1995
     */
1996
    errcode = regcomp (&flags_hvm_rec, flags_hvm_re, REG_EXTENDED);
1997
    if (errcode != 0) {
1998
        char error[100];
1.2.13 by Chuck Short
Import upstream version 0.9.12
1999
        regerror (errcode, &flags_hvm_rec, error, sizeof(error));
0.2.1 by Guido Günther
Import upstream version 0.7.2
2000
        regfree (&flags_hvm_rec);
0.2.6 by Guido Günther
Import upstream version 0.8.0
2001
        virXenError(VIR_ERR_INTERNAL_ERROR, "%s", error);
0.2.1 by Guido Günther
Import upstream version 0.7.2
2002
        in_init = 0;
2003
        return -1;
2004
    }
2005
    errcode = regcomp (&flags_pae_rec, flags_pae_re, REG_EXTENDED);
2006
    if (errcode != 0) {
2007
        char error[100];
1.2.13 by Chuck Short
Import upstream version 0.9.12
2008
        regerror (errcode, &flags_pae_rec, error, sizeof(error));
0.2.1 by Guido Günther
Import upstream version 0.7.2
2009
        regfree (&flags_pae_rec);
2010
        regfree (&flags_hvm_rec);
0.2.6 by Guido Günther
Import upstream version 0.8.0
2011
        virXenError(VIR_ERR_INTERNAL_ERROR, "%s", error);
0.2.1 by Guido Günther
Import upstream version 0.7.2
2012
        in_init = 0;
2013
        return -1;
2014
    }
2015
    errcode = regcomp (&xen_cap_rec, xen_cap_re, REG_EXTENDED);
2016
    if (errcode != 0) {
2017
        char error[100];
1.2.13 by Chuck Short
Import upstream version 0.9.12
2018
        regerror (errcode, &xen_cap_rec, error, sizeof(error));
0.2.1 by Guido Günther
Import upstream version 0.7.2
2019
        regfree (&xen_cap_rec);
2020
        regfree (&flags_pae_rec);
2021
        regfree (&flags_hvm_rec);
0.2.6 by Guido Günther
Import upstream version 0.8.0
2022
        virXenError(VIR_ERR_INTERNAL_ERROR, "%s", error);
0.2.1 by Guido Günther
Import upstream version 0.7.2
2023
        in_init = 0;
2024
        return -1;
2025
    }
2026
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
2027
    if (override_versions) {
2028
      hv_versions = *override_versions;
2029
      in_init = 0;
2030
      return 0;
2031
    }
2032
0.2.1 by Guido Günther
Import upstream version 0.7.2
2033
    /* Xen hypervisor version detection begins. */
2034
    ret = open(XEN_HYPERVISOR_SOCKET, O_RDWR);
2035
    if (ret < 0) {
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
2036
        hv_versions.hypervisor = -1;
223 by Stefan Bader
* Refresh fix-ubuntu-xen-qemu-dm-path.patch to only use executable
2037
        in_init = 0;
2038
        /* Missing socket may appear after xenfs is loaded as a module */
2039
        initialized = 0;
1.2.13 by Chuck Short
Import upstream version 0.9.12
2040
        return -1;
0.2.1 by Guido Günther
Import upstream version 0.7.2
2041
    }
2042
    fd = ret;
2043
2044
    /*
2045
     * The size of the hypervisor call block changed July 2006
2046
     * this detect if we are using the new or old hypercall_t structure
2047
     */
2048
    hc.op = __HYPERVISOR_xen_version;
2049
    hc.arg[0] = (unsigned long) XENVER_version;
2050
    hc.arg[1] = 0;
2051
2052
    cmd = IOCTL_PRIVCMD_HYPERCALL;
2053
    ret = ioctl(fd, cmd, (unsigned long) &hc);
2054
2055
    if ((ret != -1) && (ret != 0)) {
0.4.1 by Guido Günther
Import upstream version 0.9.0~rc1
2056
        VIR_DEBUG("Using new hypervisor call: %X", ret);
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
2057
        hv_versions.hv = ret;
0.2.1 by Guido Günther
Import upstream version 0.7.2
2058
        xen_ioctl_hypercall_cmd = cmd;
2059
        goto detect_v2;
2060
    }
2061
2062
#ifndef __sun
2063
    /*
2064
     * check if the old hypercall are actually working
2065
     */
2066
    v0_hc.op = __HYPERVISOR_xen_version;
2067
    v0_hc.arg[0] = (unsigned long) XENVER_version;
2068
    v0_hc.arg[1] = 0;
2069
    cmd = _IOC(_IOC_NONE, 'P', 0, sizeof(v0_hypercall_t));
2070
    ret = ioctl(fd, cmd, (unsigned long) &v0_hc);
2071
    if ((ret != -1) && (ret != 0)) {
0.4.1 by Guido Günther
Import upstream version 0.9.0~rc1
2072
        VIR_DEBUG("Using old hypervisor call: %X", ret);
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
2073
        hv_versions.hv = ret;
0.2.1 by Guido Günther
Import upstream version 0.7.2
2074
        xen_ioctl_hypercall_cmd = cmd;
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
2075
        hv_versions.hypervisor = 0;
0.2.1 by Guido Günther
Import upstream version 0.7.2
2076
        goto done;
2077
    }
2078
#endif
2079
2080
    /*
2081
     * we failed to make any hypercall
2082
     */
2083
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
2084
    hv_versions.hypervisor = -1;
0.2.6 by Guido Günther
Import upstream version 0.8.0
2085
    virXenError(VIR_ERR_XEN_CALL, " ioctl %lu",
0.2.1 by Guido Günther
Import upstream version 0.7.2
2086
                (unsigned long) IOCTL_PRIVCMD_HYPERCALL);
0.3.3 by Laurent Léonard
Import upstream version 0.8.6
2087
    VIR_FORCE_CLOSE(fd);
0.2.1 by Guido Günther
Import upstream version 0.7.2
2088
    in_init = 0;
1.2.13 by Chuck Short
Import upstream version 0.9.12
2089
    return -1;
0.2.1 by Guido Günther
Import upstream version 0.7.2
2090
2091
 detect_v2:
2092
    /*
2093
     * The hypercalls were refactored into 3 different section in August 2006
2094
     * Try to detect if we are running a version post 3.0.2 with the new ones
2095
     * or the old ones
2096
     */
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
2097
    hv_versions.hypervisor = 2;
0.2.1 by Guido Günther
Import upstream version 0.7.2
2098
2099
    if (VIR_ALLOC(ipt) < 0) {
0.2.5 by Laurent Léonard
Import upstream version 0.7.7
2100
        virReportOOMError();
1.2.13 by Chuck Short
Import upstream version 0.9.12
2101
        return -1;
0.2.1 by Guido Günther
Import upstream version 0.7.2
2102
    }
2103
    /* Currently consider RHEL5.0 Fedora7, xen-3.1, and xen-unstable */
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
2104
    hv_versions.sys_interface = 2; /* XEN_SYSCTL_INTERFACE_VERSION */
0.2.1 by Guido Günther
Import upstream version 0.7.2
2105
    if (virXen_getdomaininfo(fd, 0, &info) == 1) {
2106
        /* RHEL 5.0 */
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
2107
        hv_versions.dom_interface = 3; /* XEN_DOMCTL_INTERFACE_VERSION */
0.2.1 by Guido Günther
Import upstream version 0.7.2
2108
        if (virXen_getvcpusinfo(fd, 0, 0, ipt, NULL, 0) == 0){
0.3.8 by Guido Günther
Import upstream version 0.9.2
2109
            VIR_DEBUG("Using hypervisor call v2, sys ver2 dom ver3");
0.2.1 by Guido Günther
Import upstream version 0.7.2
2110
            goto done;
2111
        }
2112
        /* Fedora 7 */
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
2113
        hv_versions.dom_interface = 4; /* XEN_DOMCTL_INTERFACE_VERSION */
0.2.1 by Guido Günther
Import upstream version 0.7.2
2114
        if (virXen_getvcpusinfo(fd, 0, 0, ipt, NULL, 0) == 0){
0.3.8 by Guido Günther
Import upstream version 0.9.2
2115
            VIR_DEBUG("Using hypervisor call v2, sys ver2 dom ver4");
0.2.1 by Guido Günther
Import upstream version 0.7.2
2116
            goto done;
2117
        }
2118
    }
2119
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
2120
    hv_versions.sys_interface = 3; /* XEN_SYSCTL_INTERFACE_VERSION */
0.2.1 by Guido Günther
Import upstream version 0.7.2
2121
    if (virXen_getdomaininfo(fd, 0, &info) == 1) {
2122
        /* xen-3.1 */
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
2123
        hv_versions.dom_interface = 5; /* XEN_DOMCTL_INTERFACE_VERSION */
0.2.1 by Guido Günther
Import upstream version 0.7.2
2124
        if (virXen_getvcpusinfo(fd, 0, 0, ipt, NULL, 0) == 0){
0.3.8 by Guido Günther
Import upstream version 0.9.2
2125
            VIR_DEBUG("Using hypervisor call v2, sys ver3 dom ver5");
0.2.1 by Guido Günther
Import upstream version 0.7.2
2126
            goto done;
2127
        }
2128
    }
2129
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
2130
    hv_versions.sys_interface = 4; /* XEN_SYSCTL_INTERFACE_VERSION */
0.2.1 by Guido Günther
Import upstream version 0.7.2
2131
    if (virXen_getdomaininfo(fd, 0, &info) == 1) {
2132
        /* Fedora 8 */
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
2133
        hv_versions.dom_interface = 5; /* XEN_DOMCTL_INTERFACE_VERSION */
0.2.1 by Guido Günther
Import upstream version 0.7.2
2134
        if (virXen_getvcpusinfo(fd, 0, 0, ipt, NULL, 0) == 0){
0.3.8 by Guido Günther
Import upstream version 0.9.2
2135
            VIR_DEBUG("Using hypervisor call v2, sys ver4 dom ver5");
0.2.1 by Guido Günther
Import upstream version 0.7.2
2136
            goto done;
2137
        }
2138
    }
2139
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
2140
    hv_versions.sys_interface = 6; /* XEN_SYSCTL_INTERFACE_VERSION */
0.2.1 by Guido Günther
Import upstream version 0.7.2
2141
    if (virXen_getdomaininfo(fd, 0, &info) == 1) {
2142
        /* Xen 3.2, Fedora 9 */
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
2143
        hv_versions.dom_interface = 5; /* XEN_DOMCTL_INTERFACE_VERSION */
0.2.1 by Guido Günther
Import upstream version 0.7.2
2144
        if (virXen_getvcpusinfo(fd, 0, 0, ipt, NULL, 0) == 0){
0.3.8 by Guido Günther
Import upstream version 0.9.2
2145
            VIR_DEBUG("Using hypervisor call v2, sys ver6 dom ver5");
0.2.1 by Guido Günther
Import upstream version 0.7.2
2146
            goto done;
2147
        }
2148
    }
2149
0.2.4 by Laurent Léonard
Import upstream version 0.7.6
2150
    /* Xen 4.0 */
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
2151
    hv_versions.sys_interface = 7; /* XEN_SYSCTL_INTERFACE_VERSION */
0.2.4 by Laurent Léonard
Import upstream version 0.7.6
2152
    if (virXen_getdomaininfo(fd, 0, &info) == 1) {
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
2153
        hv_versions.dom_interface = 6; /* XEN_DOMCTL_INTERFACE_VERSION */
0.3.8 by Guido Günther
Import upstream version 0.9.2
2154
        VIR_DEBUG("Using hypervisor call v2, sys ver7 dom ver6");
0.4.1 by Guido Günther
Import upstream version 0.9.0~rc1
2155
        goto done;
2156
    }
2157
2158
    /* Xen 4.1
2159
     * sysctl version 8 -> xen-unstable c/s 21118:28e5409e3fb3
2160
     * domctl version 7 -> xen-unstable c/s 21212:de94884a669c
1.2.13 by Chuck Short
Import upstream version 0.9.12
2161
     * domctl version 8 -> xen-unstable c/s 23874:651aed73b39c
0.4.1 by Guido Günther
Import upstream version 0.9.0~rc1
2162
     */
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
2163
    hv_versions.sys_interface = 8; /* XEN_SYSCTL_INTERFACE_VERSION */
0.4.1 by Guido Günther
Import upstream version 0.9.0~rc1
2164
    if (virXen_getdomaininfo(fd, 0, &info) == 1) {
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
2165
        hv_versions.dom_interface = 7; /* XEN_DOMCTL_INTERFACE_VERSION */
1.2.13 by Chuck Short
Import upstream version 0.9.12
2166
        if (virXen_getvcpusinfo(fd, 0, 0, ipt, NULL, 0) == 0){
2167
            VIR_DEBUG("Using hypervisor call v2, sys ver8 dom ver7");
2168
            goto done;
2169
        }
2170
        hv_versions.dom_interface = 8; /* XEN_DOMCTL_INTERFACE_VERSION */
2171
        if (virXen_getvcpusinfo(fd, 0, 0, ipt, NULL, 0) == 0){
2172
            VIR_DEBUG("Using hypervisor call v2, sys ver8 dom ver8");
2173
            goto done;
2174
        }
0.2.4 by Laurent Léonard
Import upstream version 0.7.6
2175
    }
2176
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
2177
    hv_versions.hypervisor = 1;
2178
    hv_versions.sys_interface = -1;
0.2.1 by Guido Günther
Import upstream version 0.7.2
2179
    if (virXen_getdomaininfo(fd, 0, &info) == 1) {
0.3.8 by Guido Günther
Import upstream version 0.9.2
2180
        VIR_DEBUG("Using hypervisor call v1");
0.2.1 by Guido Günther
Import upstream version 0.7.2
2181
        goto done;
2182
    }
2183
2184
    /*
2185
     * we failed to make the getdomaininfolist hypercall
2186
     */
2187
0.3.8 by Guido Günther
Import upstream version 0.9.2
2188
    VIR_DEBUG("Failed to find any Xen hypervisor method");
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
2189
    hv_versions.hypervisor = -1;
0.2.6 by Guido Günther
Import upstream version 0.8.0
2190
    virXenError(VIR_ERR_XEN_CALL, " ioctl %lu",
0.2.1 by Guido Günther
Import upstream version 0.7.2
2191
                (unsigned long)IOCTL_PRIVCMD_HYPERCALL);
0.3.3 by Laurent Léonard
Import upstream version 0.8.6
2192
    VIR_FORCE_CLOSE(fd);
0.2.1 by Guido Günther
Import upstream version 0.7.2
2193
    in_init = 0;
2194
    VIR_FREE(ipt);
1.2.13 by Chuck Short
Import upstream version 0.9.12
2195
    return -1;
0.2.1 by Guido Günther
Import upstream version 0.7.2
2196
2197
 done:
0.3.3 by Laurent Léonard
Import upstream version 0.8.6
2198
    VIR_FORCE_CLOSE(fd);
0.2.1 by Guido Günther
Import upstream version 0.7.2
2199
    in_init = 0;
2200
    VIR_FREE(ipt);
1.2.13 by Chuck Short
Import upstream version 0.9.12
2201
    return 0;
0.2.1 by Guido Günther
Import upstream version 0.7.2
2202
}
2203
2204
/**
2205
 * xenHypervisorOpen:
2206
 * @conn: pointer to the connection block
2207
 * @name: URL for the target, NULL for local
2208
 * @flags: combination of virDrvOpenFlag(s)
2209
 *
2210
 * Connects to the Xen hypervisor.
2211
 *
2212
 * Returns 0 or -1 in case of error.
2213
 */
2214
virDrvOpenStatus
2215
xenHypervisorOpen(virConnectPtr conn,
2216
                  virConnectAuthPtr auth ATTRIBUTE_UNUSED,
0.4.4 by Guido Günther
Import upstream version 0.9.4~rc1
2217
                  unsigned int flags)
0.2.1 by Guido Günther
Import upstream version 0.7.2
2218
{
2219
    int ret;
2220
    xenUnifiedPrivatePtr priv = (xenUnifiedPrivatePtr) conn->privateData;
2221
0.4.4 by Guido Günther
Import upstream version 0.9.4~rc1
2222
    virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR);
2223
0.2.1 by Guido Günther
Import upstream version 0.7.2
2224
    if (initialized == 0)
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
2225
        if (xenHypervisorInit(NULL) == -1)
0.2.1 by Guido Günther
Import upstream version 0.7.2
2226
            return -1;
2227
2228
    priv->handle = -1;
2229
2230
    ret = open(XEN_HYPERVISOR_SOCKET, O_RDWR);
2231
    if (ret < 0) {
0.2.6 by Guido Günther
Import upstream version 0.8.0
2232
        virXenError(VIR_ERR_NO_XEN, "%s", XEN_HYPERVISOR_SOCKET);
1.2.13 by Chuck Short
Import upstream version 0.9.12
2233
        return -1;
0.2.1 by Guido Günther
Import upstream version 0.7.2
2234
    }
2235
2236
    priv->handle = ret;
2237
1.2.13 by Chuck Short
Import upstream version 0.9.12
2238
    return 0;
0.2.1 by Guido Günther
Import upstream version 0.7.2
2239
}
2240
2241
/**
2242
 * xenHypervisorClose:
2243
 * @conn: pointer to the connection block
2244
 *
2245
 * Close the connection to the Xen hypervisor.
2246
 *
2247
 * Returns 0 in case of success or -1 in case of error.
2248
 */
2249
int
2250
xenHypervisorClose(virConnectPtr conn)
2251
{
2252
    int ret;
2253
    xenUnifiedPrivatePtr priv;
2254
2255
    if (conn == NULL)
1.2.13 by Chuck Short
Import upstream version 0.9.12
2256
        return -1;
0.2.1 by Guido Günther
Import upstream version 0.7.2
2257
2258
    priv = (xenUnifiedPrivatePtr) conn->privateData;
2259
2260
    if (priv->handle < 0)
2261
        return -1;
2262
0.3.3 by Laurent Léonard
Import upstream version 0.8.6
2263
    ret = VIR_CLOSE(priv->handle);
0.2.1 by Guido Günther
Import upstream version 0.7.2
2264
    if (ret < 0)
1.2.13 by Chuck Short
Import upstream version 0.9.12
2265
        return -1;
0.2.1 by Guido Günther
Import upstream version 0.7.2
2266
1.2.13 by Chuck Short
Import upstream version 0.9.12
2267
    return 0;
0.2.1 by Guido Günther
Import upstream version 0.7.2
2268
}
2269
2270
2271
/**
2272
 * xenHypervisorGetVersion:
2273
 * @conn: pointer to the connection block
2274
 * @hvVer: where to store the version
2275
 *
2276
 * Call the hypervisor to extracts his own internal API version
2277
 *
2278
 * Returns 0 in case of success, -1 in case of error
2279
 */
2280
int
2281
xenHypervisorGetVersion(virConnectPtr conn, unsigned long *hvVer)
2282
{
2283
    xenUnifiedPrivatePtr priv;
2284
2285
    if (conn == NULL)
2286
        return -1;
2287
    priv = (xenUnifiedPrivatePtr) conn->privateData;
2288
    if (priv->handle < 0 || hvVer == NULL)
1.2.13 by Chuck Short
Import upstream version 0.9.12
2289
        return -1;
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
2290
    *hvVer = (hv_versions.hv >> 16) * 1000000 + (hv_versions.hv & 0xFFFF) * 1000;
1.2.13 by Chuck Short
Import upstream version 0.9.12
2291
    return 0;
0.2.1 by Guido Günther
Import upstream version 0.7.2
2292
}
2293
2294
struct guest_arch {
2295
    const char *model;
2296
    int bits;
2297
    int hvm;
2298
    int pae;
2299
    int nonpae;
2300
    int ia64_be;
2301
};
2302
2303
0.5.3 by Guido Günther
Import upstream version 0.9.7
2304
static int xenDefaultConsoleType(const char *ostype)
2305
{
2306
    if (STREQ(ostype, "hvm"))
2307
        return VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL;
2308
    else
2309
        return VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_XEN;
2310
}
2311
0.2.1 by Guido Günther
Import upstream version 0.7.2
2312
static virCapsPtr
2313
xenHypervisorBuildCapabilities(virConnectPtr conn,
2314
                               const char *hostmachine,
2315
                               int host_pae,
2316
                               const char *hvm_type,
2317
                               struct guest_arch *guest_archs,
2318
                               int nr_guest_archs) {
2319
    virCapsPtr caps;
2320
    int i;
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
2321
    int hv_major = hv_versions.hv >> 16;
2322
    int hv_minor = hv_versions.hv & 0xFFFF;
0.2.1 by Guido Günther
Import upstream version 0.7.2
2323
2324
    if ((caps = virCapabilitiesNew(hostmachine, 1, 1)) == NULL)
2325
        goto no_memory;
2326
2327
    virCapabilitiesSetMacPrefix(caps, (unsigned char[]){ 0x00, 0x16, 0x3e });
2328
2329
    if (hvm_type && STRNEQ(hvm_type, "") &&
2330
        virCapabilitiesAddHostFeature(caps, hvm_type) < 0)
2331
        goto no_memory;
2332
    if (host_pae &&
2333
        virCapabilitiesAddHostFeature(caps, "pae") < 0)
2334
        goto no_memory;
2335
2336
2337
    if (virCapabilitiesAddHostMigrateTransport(caps,
2338
                                               "xenmigr") < 0)
2339
        goto no_memory;
2340
2341
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
2342
    if (hv_versions.sys_interface >= SYS_IFACE_MIN_VERS_NUMA && conn != NULL) {
0.2.1 by Guido Günther
Import upstream version 0.7.2
2343
        if (xenDaemonNodeGetTopology(conn, caps) != 0) {
2344
            virCapabilitiesFree(caps);
2345
            return NULL;
2346
        }
2347
    }
2348
2349
    for (i = 0; i < nr_guest_archs; ++i) {
2350
        virCapsGuestPtr guest;
2351
        char const *const xen_machines[] = {guest_archs[i].hvm ? "xenfv" : "xenpv"};
2352
        virCapsGuestMachinePtr *machines;
2353
2354
        if ((machines = virCapabilitiesAllocMachines(xen_machines, 1)) == NULL)
2355
            goto no_memory;
2356
2357
        if ((guest = virCapabilitiesAddGuest(caps,
2358
                                             guest_archs[i].hvm ? "hvm" : "xen",
2359
                                             guest_archs[i].model,
2360
                                             guest_archs[i].bits,
2361
                                             (STREQ(hostmachine, "x86_64") ?
223 by Stefan Bader
* Refresh fix-ubuntu-xen-qemu-dm-path.patch to only use executable
2362
                                              "qemu-dm" :
2363
                                              "qemu-dm"),
0.2.1 by Guido Günther
Import upstream version 0.7.2
2364
                                             (guest_archs[i].hvm ?
223 by Stefan Bader
* Refresh fix-ubuntu-xen-qemu-dm-path.patch to only use executable
2365
                                              "hvmloader" :
0.2.1 by Guido Günther
Import upstream version 0.7.2
2366
                                              NULL),
2367
                                             1,
2368
                                             machines)) == NULL) {
2369
            virCapabilitiesFreeMachines(machines, 1);
2370
            goto no_memory;
2371
        }
2372
        machines = NULL;
2373
2374
        if (virCapabilitiesAddGuestDomain(guest,
2375
                                          "xen",
2376
                                          NULL,
2377
                                          NULL,
2378
                                          0,
2379
                                          NULL) == NULL)
2380
            goto no_memory;
2381
2382
        if (guest_archs[i].pae &&
2383
            virCapabilitiesAddGuestFeature(guest,
2384
                                           "pae",
2385
                                           1,
2386
                                           0) == NULL)
2387
            goto no_memory;
2388
2389
        if (guest_archs[i].nonpae &&
2390
            virCapabilitiesAddGuestFeature(guest,
2391
                                           "nonpae",
2392
                                           1,
2393
                                           0) == NULL)
2394
            goto no_memory;
2395
2396
        if (guest_archs[i].ia64_be &&
2397
            virCapabilitiesAddGuestFeature(guest,
2398
                                           "ia64_be",
2399
                                           1,
2400
                                           0) == NULL)
2401
            goto no_memory;
2402
2403
        if (guest_archs[i].hvm) {
2404
            if (virCapabilitiesAddGuestFeature(guest,
2405
                                               "acpi",
2406
                                               1, 1) == NULL)
2407
                goto no_memory;
2408
0.3.5 by Laurent Léonard
Import upstream version 0.8.8
2409
            /* In Xen 3.1.0, APIC is always on and can't be toggled */
0.2.1 by Guido Günther
Import upstream version 0.7.2
2410
            if (virCapabilitiesAddGuestFeature(guest,
2411
                                               "apic",
2412
                                               1,
2413
                                               (hv_major > 3 &&
2414
                                                hv_minor > 0 ?
2415
                                                0 : 1)) == NULL)
2416
                goto no_memory;
0.3.5 by Laurent Léonard
Import upstream version 0.8.8
2417
2418
            /* Xen 3.3.x and beyond supports enabling/disabling
2419
             * hardware assisted paging.  Default is off.
2420
             */
2421
            if ((hv_major == 3 && hv_minor >= 3) || (hv_major > 3))
2422
                if (virCapabilitiesAddGuestFeature(guest,
2423
                                                   "hap",
2424
                                                   0,
2425
                                                   1) == NULL)
2426
                    goto no_memory;
0.4.3 by Guido Günther
Import upstream version 0.9.3
2427
2428
            /* Xen 3.4.x and beyond supports the Viridian (Hyper-V)
2429
             * enlightenment interface.  Default is off.
2430
             */
2431
            if ((hv_major == 3 && hv_minor >= 4) || (hv_major > 3))
2432
                if (virCapabilitiesAddGuestFeature(guest,
2433
                                                   "viridian",
2434
                                                   0,
2435
                                                   1) == NULL)
2436
                    goto no_memory;
0.2.1 by Guido Günther
Import upstream version 0.7.2
2437
        }
0.4.3 by Guido Günther
Import upstream version 0.9.3
2438
0.2.1 by Guido Günther
Import upstream version 0.7.2
2439
    }
2440
0.5.3 by Guido Günther
Import upstream version 0.9.7
2441
    caps->defaultConsoleTargetType = xenDefaultConsoleType;
0.2.9 by Laurent Léonard
Import upstream version 0.8.3
2442
0.2.1 by Guido Günther
Import upstream version 0.7.2
2443
    return caps;
2444
2445
 no_memory:
2446
    virCapabilitiesFree(caps);
2447
    return NULL;
2448
}
2449
2450
#ifdef __sun
2451
2452
static int
2453
get_cpu_flags(virConnectPtr conn, const char **hvm, int *pae, int *longmode)
2454
{
2455
    struct {
2456
        uint32_t r_eax, r_ebx, r_ecx, r_edx;
2457
    } regs;
2458
2459
    char tmpbuf[20];
2460
    int ret = 0;
2461
    int fd;
2462
2463
    /* returns -1, errno 22 if in 32-bit mode */
2464
    *longmode = (sysinfo(SI_ARCHITECTURE_64, tmpbuf, sizeof(tmpbuf)) != -1);
2465
2466
    if ((fd = open("/dev/cpu/self/cpuid", O_RDONLY)) == -1 ||
2467
        pread(fd, &regs, sizeof(regs), 0) != sizeof(regs)) {
0.2.5 by Laurent Léonard
Import upstream version 0.7.7
2468
        virReportSystemError(errno, "%s", _("could not read CPU flags"));
0.2.1 by Guido Günther
Import upstream version 0.7.2
2469
        goto out;
2470
    }
2471
2472
    *pae = 0;
2473
    *hvm = "";
2474
2475
    if (STREQLEN((const char *)&regs.r_ebx, "AuthcAMDenti", 12)) {
1.2.13 by Chuck Short
Import upstream version 0.9.12
2476
        if (pread(fd, &regs, sizeof(regs), 0x80000001) == sizeof(regs)) {
0.2.1 by Guido Günther
Import upstream version 0.7.2
2477
            /* Read secure virtual machine bit (bit 2 of ECX feature ID) */
2478
            if ((regs.r_ecx >> 2) & 1) {
2479
                *hvm = "svm";
2480
            }
2481
            if ((regs.r_edx >> 6) & 1)
2482
                *pae = 1;
2483
        }
2484
    } else if (STREQLEN((const char *)&regs.r_ebx, "GenuntelineI", 12)) {
1.2.13 by Chuck Short
Import upstream version 0.9.12
2485
        if (pread(fd, &regs, sizeof(regs), 0x00000001) == sizeof(regs)) {
0.2.1 by Guido Günther
Import upstream version 0.7.2
2486
            /* Read VMXE feature bit (bit 5 of ECX feature ID) */
2487
            if ((regs.r_ecx >> 5) & 1)
2488
                *hvm = "vmx";
2489
            if ((regs.r_edx >> 6) & 1)
2490
                *pae = 1;
2491
        }
2492
    }
2493
2494
    ret = 1;
2495
2496
out:
0.3.3 by Laurent Léonard
Import upstream version 0.8.6
2497
    VIR_FORCE_CLOSE(fd);
0.2.1 by Guido Günther
Import upstream version 0.7.2
2498
    return ret;
2499
}
2500
2501
static virCapsPtr
2502
xenHypervisorMakeCapabilitiesSunOS(virConnectPtr conn)
2503
{
2504
    struct guest_arch guest_arches[32];
2505
    int i = 0;
2506
    virCapsPtr caps = NULL;
2507
    struct utsname utsname;
2508
    int pae, longmode;
2509
    const char *hvm;
2510
2511
    if (!get_cpu_flags(conn, &hvm, &pae, &longmode))
2512
        return NULL;
2513
2514
    /* Really, this never fails - look at the man-page. */
2515
    uname (&utsname);
2516
2517
    guest_arches[i].model = "i686";
2518
    guest_arches[i].bits = 32;
2519
    guest_arches[i].hvm = 0;
2520
    guest_arches[i].pae = pae;
2521
    guest_arches[i].nonpae = !pae;
2522
    guest_arches[i].ia64_be = 0;
2523
    i++;
2524
2525
    if (longmode) {
2526
        guest_arches[i].model = "x86_64";
2527
        guest_arches[i].bits = 64;
2528
        guest_arches[i].hvm = 0;
2529
        guest_arches[i].pae = 0;
2530
        guest_arches[i].nonpae = 0;
2531
        guest_arches[i].ia64_be = 0;
2532
        i++;
2533
    }
2534
2535
    if (hvm[0] != '\0') {
2536
        guest_arches[i].model = "i686";
2537
        guest_arches[i].bits = 32;
2538
        guest_arches[i].hvm = 1;
2539
        guest_arches[i].pae = pae;
2540
        guest_arches[i].nonpae = 1;
2541
        guest_arches[i].ia64_be = 0;
2542
        i++;
2543
2544
        if (longmode) {
2545
            guest_arches[i].model = "x86_64";
2546
            guest_arches[i].bits = 64;
2547
            guest_arches[i].hvm = 1;
2548
            guest_arches[i].pae = 0;
2549
            guest_arches[i].nonpae = 0;
2550
            guest_arches[i].ia64_be = 0;
2551
            i++;
2552
        }
2553
    }
2554
2555
    if ((caps = xenHypervisorBuildCapabilities(conn,
2556
                                               utsname.machine,
2557
                                               pae, hvm,
2558
                                               guest_arches, i)) == NULL)
0.2.5 by Laurent Léonard
Import upstream version 0.7.7
2559
        virReportOOMError();
0.2.1 by Guido Günther
Import upstream version 0.7.2
2560
2561
    return caps;
2562
}
2563
2564
#endif /* __sun */
2565
2566
/**
2567
 * xenHypervisorMakeCapabilitiesInternal:
2568
 * @conn: pointer to the connection block
2569
 * @cpuinfo: file handle containing /proc/cpuinfo data, or NULL
2570
 * @capabilities: file handle containing /sys/hypervisor/properties/capabilities data, or NULL
2571
 *
2572
 * Return the capabilities of this hypervisor.
2573
 */
2574
virCapsPtr
2575
xenHypervisorMakeCapabilitiesInternal(virConnectPtr conn,
2576
                                      const char *hostmachine,
2577
                                      FILE *cpuinfo, FILE *capabilities)
2578
{
2579
    char line[1024], *str, *token;
2580
    regmatch_t subs[4];
2581
    char *saveptr = NULL;
2582
    int i;
2583
2584
    char hvm_type[4] = ""; /* "vmx" or "svm" (or "" if not in CPU). */
2585
    int host_pae = 0;
2586
    struct guest_arch guest_archs[32];
2587
    int nr_guest_archs = 0;
2588
    virCapsPtr caps = NULL;
2589
2590
    memset(guest_archs, 0, sizeof(guest_archs));
2591
2592
    /* /proc/cpuinfo: flags: Intel calls HVM "vmx", AMD calls it "svm".
2593
     * It's not clear if this will work on IA64, let alone other
2594
     * architectures and non-Linux. (XXX)
2595
     */
2596
    if (cpuinfo) {
1.2.13 by Chuck Short
Import upstream version 0.9.12
2597
        while (fgets (line, sizeof(line), cpuinfo)) {
0.2.1 by Guido Günther
Import upstream version 0.7.2
2598
            if (regexec (&flags_hvm_rec, line, sizeof(subs)/sizeof(regmatch_t), subs, 0) == 0
2599
                && subs[0].rm_so != -1) {
2600
                if (virStrncpy(hvm_type,
2601
                               &line[subs[1].rm_so],
2602
                               subs[1].rm_eo-subs[1].rm_so,
2603
                               sizeof(hvm_type)) == NULL)
1.2.13 by Chuck Short
Import upstream version 0.9.12
2604
                    goto no_memory;
0.2.1 by Guido Günther
Import upstream version 0.7.2
2605
            } else if (regexec (&flags_pae_rec, line, 0, NULL, 0) == 0)
2606
                host_pae = 1;
2607
        }
2608
    }
2609
2610
    /* Most of the useful info is in /sys/hypervisor/properties/capabilities
2611
     * which is documented in the code in xen-unstable.hg/xen/arch/.../setup.c.
2612
     *
2613
     * It is a space-separated list of supported guest architectures.
2614
     *
2615
     * For x86:
2616
     *    TYP-VER-ARCH[p]
2617
     *    ^   ^   ^    ^
2618
     *    |   |   |    +-- PAE supported
2619
     *    |   |   +------- x86_32 or x86_64
2620
     *    |   +----------- the version of Xen, eg. "3.0"
2621
     *    +--------------- "xen" or "hvm" for para or full virt respectively
2622
     *
2623
     * For PPC this file appears to be always empty (?)
2624
     *
2625
     * For IA64:
2626
     *    TYP-VER-ARCH[be]
2627
     *    ^   ^   ^    ^
2628
     *    |   |   |    +-- Big-endian supported
2629
     *    |   |   +------- always "ia64"
2630
     *    |   +----------- the version of Xen, eg. "3.0"
2631
     *    +--------------- "xen" or "hvm" for para or full virt respectively
2632
     */
2633
2634
    /* Expecting one line in this file - ignore any more. */
1.2.13 by Chuck Short
Import upstream version 0.9.12
2635
    if ((capabilities) && (fgets (line, sizeof(line), capabilities))) {
0.2.1 by Guido Günther
Import upstream version 0.7.2
2636
        /* Split the line into tokens.  strtok_r is OK here because we "own"
2637
         * this buffer.  Parse out the features from each token.
2638
         */
2639
        for (str = line, nr_guest_archs = 0;
1.2.13 by Chuck Short
Import upstream version 0.9.12
2640
             nr_guest_archs < sizeof(guest_archs) / sizeof(guest_archs[0])
0.2.1 by Guido Günther
Import upstream version 0.7.2
2641
                 && (token = strtok_r (str, " ", &saveptr)) != NULL;
2642
             str = NULL) {
2643
1.2.13 by Chuck Short
Import upstream version 0.9.12
2644
            if (regexec (&xen_cap_rec, token, sizeof(subs) / sizeof(subs[0]),
0.2.1 by Guido Günther
Import upstream version 0.7.2
2645
                         subs, 0) == 0) {
2646
                int hvm = STRPREFIX(&token[subs[1].rm_so], "hvm");
2647
                const char *model;
2648
                int bits, pae = 0, nonpae = 0, ia64_be = 0;
2649
2650
                if (STRPREFIX(&token[subs[2].rm_so], "x86_32")) {
2651
                    model = "i686";
2652
                    bits = 32;
2653
                    if (subs[3].rm_so != -1 &&
2654
                        STRPREFIX(&token[subs[3].rm_so], "p"))
2655
                        pae = 1;
2656
                    else
2657
                        nonpae = 1;
2658
                }
2659
                else if (STRPREFIX(&token[subs[2].rm_so], "x86_64")) {
2660
                    model = "x86_64";
2661
                    bits = 64;
2662
                }
2663
                else if (STRPREFIX(&token[subs[2].rm_so], "ia64")) {
2664
                    model = "ia64";
2665
                    bits = 64;
2666
                    if (subs[3].rm_so != -1 &&
2667
                        STRPREFIX(&token[subs[3].rm_so], "be"))
2668
                        ia64_be = 1;
2669
                }
2670
                else if (STRPREFIX(&token[subs[2].rm_so], "powerpc64")) {
2671
                    model = "ppc64";
2672
                    bits = 64;
2673
                } else {
2674
                    /* XXX surely no other Xen archs exist  */
2675
                    continue;
2676
                }
2677
2678
                /* Search for existing matching (model,hvm) tuple */
2679
                for (i = 0 ; i < nr_guest_archs ; i++) {
2680
                    if (STREQ(guest_archs[i].model, model) &&
2681
                        guest_archs[i].hvm == hvm) {
2682
                        break;
2683
                    }
2684
                }
2685
2686
                /* Too many arch flavours - highly unlikely ! */
2687
                if (i >= ARRAY_CARDINALITY(guest_archs))
2688
                    continue;
2689
                /* Didn't find a match, so create a new one */
2690
                if (i == nr_guest_archs)
2691
                    nr_guest_archs++;
2692
2693
                guest_archs[i].model = model;
2694
                guest_archs[i].bits = bits;
2695
                guest_archs[i].hvm = hvm;
2696
2697
                /* Careful not to overwrite a previous positive
2698
                   setting with a negative one here - some archs
2699
                   can do both pae & non-pae, but Xen reports
2700
                   separately capabilities so we're merging archs */
2701
                if (pae)
2702
                    guest_archs[i].pae = pae;
2703
                if (nonpae)
2704
                    guest_archs[i].nonpae = nonpae;
2705
                if (ia64_be)
2706
                    guest_archs[i].ia64_be = ia64_be;
2707
            }
2708
        }
2709
    }
2710
2711
    if ((caps = xenHypervisorBuildCapabilities(conn,
2712
                                               hostmachine,
2713
                                               host_pae,
2714
                                               hvm_type,
2715
                                               guest_archs,
2716
                                               nr_guest_archs)) == NULL)
2717
        goto no_memory;
2718
2719
    return caps;
2720
2721
 no_memory:
0.2.5 by Laurent Léonard
Import upstream version 0.7.7
2722
    virReportOOMError();
0.2.1 by Guido Günther
Import upstream version 0.7.2
2723
    virCapabilitiesFree(caps);
2724
    return NULL;
2725
}
2726
2727
/**
2728
 * xenHypervisorMakeCapabilities:
2729
 *
2730
 * Return the capabilities of this hypervisor.
2731
 */
2732
virCapsPtr
2733
xenHypervisorMakeCapabilities(virConnectPtr conn)
2734
{
2735
#ifdef __sun
2736
    return xenHypervisorMakeCapabilitiesSunOS(conn);
2737
#else
1.2.13 by Chuck Short
Import upstream version 0.9.12
2738
    virCapsPtr caps = NULL;
0.2.1 by Guido Günther
Import upstream version 0.7.2
2739
    FILE *cpuinfo, *capabilities;
2740
    struct utsname utsname;
2741
2742
    /* Really, this never fails - look at the man-page. */
2743
    uname (&utsname);
2744
2745
    cpuinfo = fopen ("/proc/cpuinfo", "r");
2746
    if (cpuinfo == NULL) {
2747
        if (errno != ENOENT) {
0.2.5 by Laurent Léonard
Import upstream version 0.7.7
2748
            virReportSystemError(errno,
0.2.1 by Guido Günther
Import upstream version 0.7.2
2749
                                 _("cannot read file %s"),
2750
                                 "/proc/cpuinfo");
2751
            return NULL;
2752
        }
2753
    }
2754
2755
    capabilities = fopen ("/sys/hypervisor/properties/capabilities", "r");
2756
    if (capabilities == NULL) {
2757
        if (errno != ENOENT) {
0.3.3 by Laurent Léonard
Import upstream version 0.8.6
2758
            VIR_FORCE_FCLOSE(cpuinfo);
0.2.5 by Laurent Léonard
Import upstream version 0.7.7
2759
            virReportSystemError(errno,
0.2.1 by Guido Günther
Import upstream version 0.7.2
2760
                                 _("cannot read file %s"),
2761
                                 "/sys/hypervisor/properties/capabilities");
2762
            return NULL;
2763
        }
2764
    }
2765
2766
    caps = xenHypervisorMakeCapabilitiesInternal(conn,
2767
                                                 utsname.machine,
2768
                                                 cpuinfo,
2769
                                                 capabilities);
1.2.13 by Chuck Short
Import upstream version 0.9.12
2770
    if (caps == NULL)
2771
        goto cleanup;
0.2.1 by Guido Günther
Import upstream version 0.7.2
2772
0.5.4 by Guido Günther
Import upstream version 0.9.8~rc1
2773
    if (virNodeSuspendGetTargetMask(&caps->host.powerMgmt) < 0)
2774
        VIR_WARN("Failed to get host power management capabilities");
2775
1.2.13 by Chuck Short
Import upstream version 0.9.12
2776
cleanup:
0.3.3 by Laurent Léonard
Import upstream version 0.8.6
2777
    VIR_FORCE_FCLOSE(cpuinfo);
2778
    VIR_FORCE_FCLOSE(capabilities);
0.2.1 by Guido Günther
Import upstream version 0.7.2
2779
2780
    return caps;
2781
#endif /* __sun */
2782
}
2783
2784
2785
2786
/**
2787
 * xenHypervisorGetCapabilities:
2788
 * @conn: pointer to the connection block
2789
 *
2790
 * Return the capabilities of this hypervisor.
2791
 */
2792
char *
2793
xenHypervisorGetCapabilities (virConnectPtr conn)
2794
{
2795
    xenUnifiedPrivatePtr priv = (xenUnifiedPrivatePtr) conn->privateData;
2796
    char *xml;
2797
2798
    if (!(xml = virCapabilitiesFormatXML(priv->caps))) {
0.2.5 by Laurent Léonard
Import upstream version 0.7.7
2799
        virReportOOMError();
0.2.1 by Guido Günther
Import upstream version 0.7.2
2800
        return NULL;
2801
    }
2802
2803
    return xml;
2804
}
2805
2806
2807
/**
2808
 * xenHypervisorNumOfDomains:
2809
 * @conn: pointer to the connection block
2810
 *
2811
 * Provides the number of active domains.
2812
 *
2813
 * Returns the number of domain found or -1 in case of error
2814
 */
2815
int
2816
xenHypervisorNumOfDomains(virConnectPtr conn)
2817
{
2818
    xen_getdomaininfolist dominfos;
2819
    int ret, nbids;
2820
    static int last_maxids = 2;
2821
    int maxids = last_maxids;
2822
    xenUnifiedPrivatePtr priv;
2823
2824
    if (conn == NULL)
2825
        return -1;
2826
    priv = (xenUnifiedPrivatePtr) conn->privateData;
2827
    if (priv->handle < 0)
1.2.13 by Chuck Short
Import upstream version 0.9.12
2828
        return -1;
0.2.1 by Guido Günther
Import upstream version 0.7.2
2829
2830
 retry:
2831
    if (!(XEN_GETDOMAININFOLIST_ALLOC(dominfos, maxids))) {
0.2.5 by Laurent Léonard
Import upstream version 0.7.7
2832
        virReportOOMError();
1.2.13 by Chuck Short
Import upstream version 0.9.12
2833
        return -1;
0.2.1 by Guido Günther
Import upstream version 0.7.2
2834
    }
2835
2836
    XEN_GETDOMAININFOLIST_CLEAR(dominfos, maxids);
2837
2838
    ret = virXen_getdomaininfolist(priv->handle, 0, maxids, &dominfos);
2839
2840
    XEN_GETDOMAININFOLIST_FREE(dominfos);
2841
2842
    if (ret < 0)
1.2.13 by Chuck Short
Import upstream version 0.9.12
2843
        return -1;
0.2.1 by Guido Günther
Import upstream version 0.7.2
2844
2845
    nbids = ret;
2846
    /* Can't possibly have more than 65,000 concurrent guests
2847
     * so limit how many times we try, to avoid increasing
2848
     * without bound & thus allocating all of system memory !
2849
     * XXX I'll regret this comment in a few years time ;-)
2850
     */
2851
    if (nbids == maxids) {
2852
        if (maxids < 65000) {
2853
            last_maxids *= 2;
2854
            maxids *= 2;
2855
            goto retry;
2856
        }
2857
        nbids = -1;
2858
    }
2859
    if ((nbids < 0) || (nbids > maxids))
1.2.13 by Chuck Short
Import upstream version 0.9.12
2860
        return -1;
2861
    return nbids;
0.2.1 by Guido Günther
Import upstream version 0.7.2
2862
}
2863
2864
/**
2865
 * xenHypervisorListDomains:
2866
 * @conn: pointer to the connection block
2867
 * @ids: array to collect the list of IDs of active domains
2868
 * @maxids: size of @ids
2869
 *
2870
 * Collect the list of active domains, and store their ID in @maxids
2871
 *
2872
 * Returns the number of domain found or -1 in case of error
2873
 */
2874
int
2875
xenHypervisorListDomains(virConnectPtr conn, int *ids, int maxids)
2876
{
2877
    xen_getdomaininfolist dominfos;
2878
    int ret, nbids, i;
2879
    xenUnifiedPrivatePtr priv;
2880
2881
    if (conn == NULL)
2882
        return -1;
2883
2884
    priv = (xenUnifiedPrivatePtr) conn->privateData;
2885
    if (priv->handle < 0 ||
2886
        (ids == NULL) || (maxids < 0))
1.2.13 by Chuck Short
Import upstream version 0.9.12
2887
        return -1;
0.2.1 by Guido Günther
Import upstream version 0.7.2
2888
2889
    if (maxids == 0)
1.2.13 by Chuck Short
Import upstream version 0.9.12
2890
        return 0;
0.2.1 by Guido Günther
Import upstream version 0.7.2
2891
2892
    if (!(XEN_GETDOMAININFOLIST_ALLOC(dominfos, maxids))) {
0.2.5 by Laurent Léonard
Import upstream version 0.7.7
2893
        virReportOOMError();
1.2.13 by Chuck Short
Import upstream version 0.9.12
2894
        return -1;
0.2.1 by Guido Günther
Import upstream version 0.7.2
2895
    }
2896
2897
    XEN_GETDOMAININFOLIST_CLEAR(dominfos, maxids);
2898
    memset(ids, 0, maxids * sizeof(int));
2899
2900
    ret = virXen_getdomaininfolist(priv->handle, 0, maxids, &dominfos);
2901
2902
    if (ret < 0) {
2903
        XEN_GETDOMAININFOLIST_FREE(dominfos);
1.2.13 by Chuck Short
Import upstream version 0.9.12
2904
        return -1;
0.2.1 by Guido Günther
Import upstream version 0.7.2
2905
    }
2906
2907
    nbids = ret;
2908
    if ((nbids < 0) || (nbids > maxids)) {
2909
        XEN_GETDOMAININFOLIST_FREE(dominfos);
1.2.13 by Chuck Short
Import upstream version 0.9.12
2910
        return -1;
0.2.1 by Guido Günther
Import upstream version 0.7.2
2911
    }
2912
2913
    for (i = 0;i < nbids;i++) {
2914
        ids[i] = XEN_GETDOMAININFOLIST_DOMAIN(dominfos, i);
2915
    }
2916
2917
    XEN_GETDOMAININFOLIST_FREE(dominfos);
1.2.13 by Chuck Short
Import upstream version 0.9.12
2918
    return nbids;
0.2.1 by Guido Günther
Import upstream version 0.7.2
2919
}
2920
2921
2922
char *
2923
xenHypervisorDomainGetOSType (virDomainPtr dom)
2924
{
2925
    xenUnifiedPrivatePtr priv;
2926
    xen_getdomaininfo dominfo;
0.2.2 by Guido Günther
Import upstream version 0.7.4
2927
    char *ostype = NULL;
0.2.1 by Guido Günther
Import upstream version 0.7.2
2928
2929
    priv = (xenUnifiedPrivatePtr) dom->conn->privateData;
0.2.3 by Guido Günther
Import upstream version 0.7.5
2930
    if (priv->handle < 0) {
1.2.13 by Chuck Short
Import upstream version 0.9.12
2931
        virXenError(VIR_ERR_INTERNAL_ERROR, "%s",
2932
                    _("domain shut off or invalid"));
2933
        return NULL;
0.2.3 by Guido Günther
Import upstream version 0.7.5
2934
    }
0.2.1 by Guido Günther
Import upstream version 0.7.2
2935
2936
    /* HV's earlier than 3.1.0 don't include the HVM flags in guests status*/
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
2937
    if (hv_versions.hypervisor < 2 ||
2938
        hv_versions.dom_interface < 4) {
1.2.13 by Chuck Short
Import upstream version 0.9.12
2939
        virXenError(VIR_ERR_INTERNAL_ERROR, "%s",
2940
                    _("unsupported in dom interface < 4"));
2941
        return NULL;
0.2.3 by Guido Günther
Import upstream version 0.7.5
2942
    }
0.2.1 by Guido Günther
Import upstream version 0.7.2
2943
2944
    XEN_GETDOMAININFO_CLEAR(dominfo);
2945
0.2.3 by Guido Günther
Import upstream version 0.7.5
2946
    if (virXen_getdomaininfo(priv->handle, dom->id, &dominfo) < 0) {
1.2.13 by Chuck Short
Import upstream version 0.9.12
2947
        virXenError(VIR_ERR_INTERNAL_ERROR, "%s",
2948
                    _("cannot get domain details"));
2949
        return NULL;
0.2.3 by Guido Günther
Import upstream version 0.7.5
2950
    }
0.2.1 by Guido Günther
Import upstream version 0.7.2
2951
0.2.3 by Guido Günther
Import upstream version 0.7.5
2952
    if (XEN_GETDOMAININFO_DOMAIN(dominfo) != dom->id) {
1.2.13 by Chuck Short
Import upstream version 0.9.12
2953
        virXenError(VIR_ERR_INTERNAL_ERROR, "%s",
2954
                    _("cannot get domain details"));
2955
        return NULL;
0.2.3 by Guido Günther
Import upstream version 0.7.5
2956
    }
0.2.1 by Guido Günther
Import upstream version 0.7.2
2957
2958
    if (XEN_GETDOMAININFO_FLAGS(dominfo) & DOMFLAGS_HVM)
0.2.2 by Guido Günther
Import upstream version 0.7.4
2959
        ostype = strdup("hvm");
2960
    else
2961
        ostype = strdup("linux");
2962
2963
    if (ostype == NULL)
0.2.5 by Laurent Léonard
Import upstream version 0.7.7
2964
        virReportOOMError();
0.2.2 by Guido Günther
Import upstream version 0.7.4
2965
2966
    return ostype;
2967
}
2968
2969
int
2970
xenHypervisorHasDomain(virConnectPtr conn,
2971
                       int id)
2972
{
2973
    xenUnifiedPrivatePtr priv;
2974
    xen_getdomaininfo dominfo;
2975
2976
    priv = (xenUnifiedPrivatePtr) conn->privateData;
2977
    if (priv->handle < 0)
2978
        return 0;
2979
2980
    XEN_GETDOMAININFO_CLEAR(dominfo);
2981
2982
    if (virXen_getdomaininfo(priv->handle, id, &dominfo) < 0)
2983
        return 0;
2984
2985
    if (XEN_GETDOMAININFO_DOMAIN(dominfo) != id)
2986
        return 0;
2987
2988
    return 1;
0.2.1 by Guido Günther
Import upstream version 0.7.2
2989
}
2990
2991
virDomainPtr
2992
xenHypervisorLookupDomainByID(virConnectPtr conn,
2993
                              int id)
2994
{
2995
    xenUnifiedPrivatePtr priv;
2996
    xen_getdomaininfo dominfo;
2997
    virDomainPtr ret;
2998
    char *name;
2999
3000
    priv = (xenUnifiedPrivatePtr) conn->privateData;
3001
    if (priv->handle < 0)
1.2.13 by Chuck Short
Import upstream version 0.9.12
3002
        return NULL;
0.2.1 by Guido Günther
Import upstream version 0.7.2
3003
3004
    XEN_GETDOMAININFO_CLEAR(dominfo);
3005
3006
    if (virXen_getdomaininfo(priv->handle, id, &dominfo) < 0)
1.2.13 by Chuck Short
Import upstream version 0.9.12
3007
        return NULL;
0.2.1 by Guido Günther
Import upstream version 0.7.2
3008
3009
    if (XEN_GETDOMAININFO_DOMAIN(dominfo) != id)
1.2.13 by Chuck Short
Import upstream version 0.9.12
3010
        return NULL;
0.2.1 by Guido Günther
Import upstream version 0.7.2
3011
3012
    xenUnifiedLock(priv);
3013
    name = xenStoreDomainGetName(conn, id);
3014
    xenUnifiedUnlock(priv);
3015
    if (!name)
1.2.13 by Chuck Short
Import upstream version 0.9.12
3016
        return NULL;
0.2.1 by Guido Günther
Import upstream version 0.7.2
3017
3018
    ret = virGetDomain(conn, name, XEN_GETDOMAININFO_UUID(dominfo));
3019
    if (ret)
3020
        ret->id = id;
3021
    VIR_FREE(name);
3022
    return ret;
3023
}
3024
3025
3026
virDomainPtr
3027
xenHypervisorLookupDomainByUUID(virConnectPtr conn,
3028
                                const unsigned char *uuid)
3029
{
3030
    xen_getdomaininfolist dominfos;
3031
    xenUnifiedPrivatePtr priv;
3032
    virDomainPtr ret;
3033
    char *name;
3034
    int maxids = 100, nids, i, id;
3035
3036
    priv = (xenUnifiedPrivatePtr) conn->privateData;
3037
    if (priv->handle < 0)
1.2.13 by Chuck Short
Import upstream version 0.9.12
3038
        return NULL;
0.2.1 by Guido Günther
Import upstream version 0.7.2
3039
3040
 retry:
3041
    if (!(XEN_GETDOMAININFOLIST_ALLOC(dominfos, maxids))) {
0.2.5 by Laurent Léonard
Import upstream version 0.7.7
3042
        virReportOOMError();
1.2.13 by Chuck Short
Import upstream version 0.9.12
3043
        return NULL;
0.2.1 by Guido Günther
Import upstream version 0.7.2
3044
    }
3045
3046
    XEN_GETDOMAININFOLIST_CLEAR(dominfos, maxids);
3047
3048
    nids = virXen_getdomaininfolist(priv->handle, 0, maxids, &dominfos);
3049
3050
    if (nids < 0) {
3051
        XEN_GETDOMAININFOLIST_FREE(dominfos);
1.2.13 by Chuck Short
Import upstream version 0.9.12
3052
        return NULL;
0.2.1 by Guido Günther
Import upstream version 0.7.2
3053
    }
3054
3055
    /* Can't possibly have more than 65,000 concurrent guests
3056
     * so limit how many times we try, to avoid increasing
3057
     * without bound & thus allocating all of system memory !
3058
     * XXX I'll regret this comment in a few years time ;-)
3059
     */
3060
    if (nids == maxids) {
3061
        XEN_GETDOMAININFOLIST_FREE(dominfos);
3062
        if (maxids < 65000) {
3063
            maxids *= 2;
3064
            goto retry;
3065
        }
1.2.13 by Chuck Short
Import upstream version 0.9.12
3066
        return NULL;
0.2.1 by Guido Günther
Import upstream version 0.7.2
3067
    }
3068
3069
    id = -1;
3070
    for (i = 0 ; i < nids ; i++) {
3071
        if (memcmp(XEN_GETDOMAININFOLIST_UUID(dominfos, i), uuid, VIR_UUID_BUFLEN) == 0) {
3072
            id = XEN_GETDOMAININFOLIST_DOMAIN(dominfos, i);
3073
            break;
3074
        }
3075
    }
3076
    XEN_GETDOMAININFOLIST_FREE(dominfos);
3077
3078
    if (id == -1)
1.2.13 by Chuck Short
Import upstream version 0.9.12
3079
        return NULL;
0.2.1 by Guido Günther
Import upstream version 0.7.2
3080
3081
    xenUnifiedLock(priv);
3082
    name = xenStoreDomainGetName(conn, id);
3083
    xenUnifiedUnlock(priv);
3084
    if (!name)
1.2.13 by Chuck Short
Import upstream version 0.9.12
3085
        return NULL;
0.2.1 by Guido Günther
Import upstream version 0.7.2
3086
3087
    ret = virGetDomain(conn, name, uuid);
3088
    if (ret)
3089
        ret->id = id;
3090
    VIR_FREE(name);
3091
    return ret;
3092
}
3093
3094
/**
3095
 * xenHypervisorGetMaxVcpus:
3096
 *
3097
 * Returns the maximum of CPU defined by Xen.
3098
 */
3099
int
3100
xenHypervisorGetMaxVcpus(virConnectPtr conn,
3101
                         const char *type ATTRIBUTE_UNUSED)
3102
{
3103
    xenUnifiedPrivatePtr priv;
3104
3105
    if (conn == NULL)
3106
        return -1;
3107
    priv = (xenUnifiedPrivatePtr) conn->privateData;
3108
    if (priv->handle < 0)
1.2.13 by Chuck Short
Import upstream version 0.9.12
3109
        return -1;
0.2.1 by Guido Günther
Import upstream version 0.7.2
3110
3111
    return MAX_VIRT_CPUS;
3112
}
3113
3114
/**
3115
 * xenHypervisorGetDomMaxMemory:
3116
 * @conn: connection data
3117
 * @id: domain id
3118
 *
3119
 * Retrieve the maximum amount of physical memory allocated to a
3120
 * domain.
3121
 *
3122
 * Returns the memory size in kilobytes or 0 in case of error.
3123
 */
3124
unsigned long
3125
xenHypervisorGetDomMaxMemory(virConnectPtr conn, int id)
3126
{
3127
    xenUnifiedPrivatePtr priv;
3128
    xen_getdomaininfo dominfo;
3129
    int ret;
3130
3131
    if (conn == NULL)
3132
        return 0;
3133
3134
    priv = (xenUnifiedPrivatePtr) conn->privateData;
3135
    if (priv->handle < 0)
3136
        return 0;
3137
3138
    if (kb_per_pages == 0) {
3139
        kb_per_pages = sysconf(_SC_PAGESIZE) / 1024;
3140
        if (kb_per_pages <= 0)
3141
            kb_per_pages = 4;
3142
    }
3143
3144
    XEN_GETDOMAININFO_CLEAR(dominfo);
3145
3146
    ret = virXen_getdomaininfo(priv->handle, id, &dominfo);
3147
3148
    if ((ret < 0) || (XEN_GETDOMAININFO_DOMAIN(dominfo) != id))
1.2.13 by Chuck Short
Import upstream version 0.9.12
3149
        return 0;
0.2.1 by Guido Günther
Import upstream version 0.7.2
3150
1.2.13 by Chuck Short
Import upstream version 0.9.12
3151
    return (unsigned long) XEN_GETDOMAININFO_MAX_PAGES(dominfo) * kb_per_pages;
0.2.1 by Guido Günther
Import upstream version 0.7.2
3152
}
3153
3154
/**
3155
 * xenHypervisorGetMaxMemory:
3156
 * @domain: a domain object or NULL
3157
 *
3158
 * Retrieve the maximum amount of physical memory allocated to a
3159
 * domain. If domain is NULL, then this get the amount of memory reserved
3160
 * to Domain0 i.e. the domain where the application runs.
3161
 *
3162
 * Returns the memory size in kilobytes or 0 in case of error.
3163
 */
1.2.13 by Chuck Short
Import upstream version 0.9.12
3164
static unsigned long long ATTRIBUTE_NONNULL (1)
0.2.1 by Guido Günther
Import upstream version 0.7.2
3165
xenHypervisorGetMaxMemory(virDomainPtr domain)
3166
{
3167
    xenUnifiedPrivatePtr priv;
3168
0.2.4 by Laurent Léonard
Import upstream version 0.7.6
3169
    if (domain->conn == NULL)
0.2.1 by Guido Günther
Import upstream version 0.7.2
3170
        return 0;
3171
3172
    priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
3173
    if (priv->handle < 0 || domain->id < 0)
1.2.13 by Chuck Short
Import upstream version 0.9.12
3174
        return 0;
0.2.1 by Guido Günther
Import upstream version 0.7.2
3175
1.2.13 by Chuck Short
Import upstream version 0.9.12
3176
    return xenHypervisorGetDomMaxMemory(domain->conn, domain->id);
0.2.1 by Guido Günther
Import upstream version 0.7.2
3177
}
3178
3179
/**
3180
 * xenHypervisorGetDomInfo:
3181
 * @conn: connection data
3182
 * @id: the domain ID
3183
 * @info: the place where information should be stored
3184
 *
0.5.5 by Guido Günther
Import upstream version 0.9.8~rc2
3185
 * Do a hypervisor call to get the related set of domain information.
0.2.1 by Guido Günther
Import upstream version 0.7.2
3186
 *
3187
 * Returns 0 in case of success, -1 in case of error.
3188
 */
3189
int
3190
xenHypervisorGetDomInfo(virConnectPtr conn, int id, virDomainInfoPtr info)
3191
{
3192
    xenUnifiedPrivatePtr priv;
3193
    xen_getdomaininfo dominfo;
3194
    int ret;
3195
    uint32_t domain_flags, domain_state, domain_shutdown_cause;
3196
3197
    if (kb_per_pages == 0) {
3198
        kb_per_pages = sysconf(_SC_PAGESIZE) / 1024;
3199
        if (kb_per_pages <= 0)
3200
            kb_per_pages = 4;
3201
    }
3202
3203
    if (conn == NULL)
3204
        return -1;
3205
3206
    priv = (xenUnifiedPrivatePtr) conn->privateData;
3207
    if (priv->handle < 0 || info == NULL)
1.2.13 by Chuck Short
Import upstream version 0.9.12
3208
        return -1;
0.2.1 by Guido Günther
Import upstream version 0.7.2
3209
3210
    memset(info, 0, sizeof(virDomainInfo));
3211
    XEN_GETDOMAININFO_CLEAR(dominfo);
3212
3213
    ret = virXen_getdomaininfo(priv->handle, id, &dominfo);
3214
3215
    if ((ret < 0) || (XEN_GETDOMAININFO_DOMAIN(dominfo) != id))
1.2.13 by Chuck Short
Import upstream version 0.9.12
3216
        return -1;
0.2.1 by Guido Günther
Import upstream version 0.7.2
3217
3218
    domain_flags = XEN_GETDOMAININFO_FLAGS(dominfo);
3219
    domain_flags &= ~DOMFLAGS_HVM; /* Mask out HVM flags */
3220
    domain_state = domain_flags & 0xFF; /* Mask out high bits */
3221
    switch (domain_state) {
3222
        case DOMFLAGS_DYING:
3223
            info->state = VIR_DOMAIN_SHUTDOWN;
3224
            break;
3225
        case DOMFLAGS_SHUTDOWN:
3226
            /* The domain is shutdown.  Determine the cause. */
3227
            domain_shutdown_cause = domain_flags >> DOMFLAGS_SHUTDOWNSHIFT;
3228
            switch (domain_shutdown_cause) {
3229
                case SHUTDOWN_crash:
3230
                    info->state = VIR_DOMAIN_CRASHED;
3231
                    break;
3232
                default:
3233
                    info->state = VIR_DOMAIN_SHUTOFF;
3234
            }
3235
            break;
3236
        case DOMFLAGS_PAUSED:
3237
            info->state = VIR_DOMAIN_PAUSED;
3238
            break;
3239
        case DOMFLAGS_BLOCKED:
3240
            info->state = VIR_DOMAIN_BLOCKED;
3241
            break;
3242
        case DOMFLAGS_RUNNING:
3243
            info->state = VIR_DOMAIN_RUNNING;
3244
            break;
3245
        default:
3246
            info->state = VIR_DOMAIN_NOSTATE;
3247
    }
3248
3249
    /*
3250
     * the API brings back the cpu time in nanoseconds,
3251
     * convert to microseconds, same thing convert to
3252
     * kilobytes from page counts
3253
     */
3254
    info->cpuTime = XEN_GETDOMAININFO_CPUTIME(dominfo);
3255
    info->memory = XEN_GETDOMAININFO_TOT_PAGES(dominfo) * kb_per_pages;
3256
    info->maxMem = XEN_GETDOMAININFO_MAX_PAGES(dominfo);
3257
    if(info->maxMem != UINT_MAX)
3258
        info->maxMem *= kb_per_pages;
3259
    info->nrVirtCpu = XEN_GETDOMAININFO_CPUCOUNT(dominfo);
1.2.13 by Chuck Short
Import upstream version 0.9.12
3260
    return 0;
0.2.1 by Guido Günther
Import upstream version 0.7.2
3261
}
3262
3263
/**
3264
 * xenHypervisorGetDomainInfo:
3265
 * @domain: pointer to the domain block
3266
 * @info: the place where information should be stored
3267
 *
0.5.5 by Guido Günther
Import upstream version 0.9.8~rc2
3268
 * Do a hypervisor call to get the related set of domain information.
0.2.1 by Guido Günther
Import upstream version 0.7.2
3269
 *
3270
 * Returns 0 in case of success, -1 in case of error.
3271
 */
3272
int
3273
xenHypervisorGetDomainInfo(virDomainPtr domain, virDomainInfoPtr info)
3274
{
3275
    xenUnifiedPrivatePtr priv;
3276
0.2.4 by Laurent Léonard
Import upstream version 0.7.6
3277
    if (domain->conn == NULL)
0.2.1 by Guido Günther
Import upstream version 0.7.2
3278
        return -1;
3279
3280
    priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
3281
    if (priv->handle < 0 || info == NULL ||
3282
        (domain->id < 0))
1.2.13 by Chuck Short
Import upstream version 0.9.12
3283
        return -1;
0.2.1 by Guido Günther
Import upstream version 0.7.2
3284
1.2.13 by Chuck Short
Import upstream version 0.9.12
3285
    return xenHypervisorGetDomInfo(domain->conn, domain->id, info);
0.2.1 by Guido Günther
Import upstream version 0.7.2
3286
3287
}
3288
3289
/**
0.3.8 by Guido Günther
Import upstream version 0.9.2
3290
 * xenHypervisorGetDomainState:
3291
 * @domain: pointer to the domain block
3292
 * @state: returned state of the domain
3293
 * @reason: returned reason for the state
3294
 * @flags: additional flags, 0 for now
3295
 *
3296
 * Do a hypervisor call to get the related set of domain information.
3297
 *
3298
 * Returns 0 in case of success, -1 in case of error.
3299
 */
3300
int
3301
xenHypervisorGetDomainState(virDomainPtr domain,
3302
                            int *state,
3303
                            int *reason,
0.4.4 by Guido Günther
Import upstream version 0.9.4~rc1
3304
                            unsigned int flags)
0.3.8 by Guido Günther
Import upstream version 0.9.2
3305
{
3306
    xenUnifiedPrivatePtr priv = domain->conn->privateData;
3307
    virDomainInfo info;
3308
0.4.4 by Guido Günther
Import upstream version 0.9.4~rc1
3309
    virCheckFlags(0, -1);
3310
0.3.8 by Guido Günther
Import upstream version 0.9.2
3311
    if (domain->conn == NULL)
3312
        return -1;
3313
3314
    if (priv->handle < 0 || domain->id < 0)
3315
        return -1;
3316
3317
    if (xenHypervisorGetDomInfo(domain->conn, domain->id, &info) < 0)
3318
        return -1;
3319
3320
    *state = info.state;
3321
    if (reason)
3322
        *reason = 0;
3323
3324
    return 0;
3325
}
3326
3327
/**
0.2.1 by Guido Günther
Import upstream version 0.7.2
3328
 * xenHypervisorNodeGetCellsFreeMemory:
3329
 * @conn: pointer to the hypervisor connection
3330
 * @freeMems: pointer to the array of unsigned long long
3331
 * @startCell: index of first cell to return freeMems info on.
3332
 * @maxCells: Maximum number of cells for which freeMems information can
3333
 *            be returned.
3334
 *
3335
 * This call returns the amount of free memory in one or more NUMA cells.
3336
 * The @freeMems array must be allocated by the caller and will be filled
3337
 * with the amount of free memory in kilobytes for each cell requested,
3338
 * starting with startCell (in freeMems[0]), up to either
3339
 * (startCell + maxCells), or the number of additional cells in the node,
3340
 * whichever is smaller.
3341
 *
3342
 * Returns the number of entries filled in freeMems, or -1 in case of error.
3343
 */
3344
int
3345
xenHypervisorNodeGetCellsFreeMemory(virConnectPtr conn, unsigned long long *freeMems,
3346
                                    int startCell, int maxCells)
3347
{
3348
    xen_op_v2_sys op_sys;
3349
    int i, j, ret;
3350
    xenUnifiedPrivatePtr priv;
3351
3352
    if (conn == NULL) {
1.2.13 by Chuck Short
Import upstream version 0.9.12
3353
        virXenError(VIR_ERR_INVALID_ARG, "%s", _("invalid argument"));
0.2.1 by Guido Günther
Import upstream version 0.7.2
3354
        return -1;
3355
    }
3356
3357
    priv = conn->privateData;
3358
3359
    if (priv->nbNodeCells < 0) {
1.2.13 by Chuck Short
Import upstream version 0.9.12
3360
        virXenError(VIR_ERR_XEN_CALL, "%s",
3361
                    _("cannot determine actual number of cells"));
3362
        return -1;
0.2.1 by Guido Günther
Import upstream version 0.7.2
3363
    }
3364
3365
    if ((maxCells < 1) || (startCell >= priv->nbNodeCells)) {
1.2.13 by Chuck Short
Import upstream version 0.9.12
3366
        virXenError(VIR_ERR_INVALID_ARG, "%s",
3367
                    _("invalid argument"));
0.2.1 by Guido Günther
Import upstream version 0.7.2
3368
        return -1;
3369
    }
3370
3371
    /*
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
3372
     * Support only hv_versions.sys_interface >=4
0.2.1 by Guido Günther
Import upstream version 0.7.2
3373
     */
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
3374
    if (hv_versions.sys_interface < SYS_IFACE_MIN_VERS_NUMA) {
1.2.13 by Chuck Short
Import upstream version 0.9.12
3375
        virXenError(VIR_ERR_XEN_CALL, "%s",
3376
                    _("unsupported in sys interface < 4"));
0.2.1 by Guido Günther
Import upstream version 0.7.2
3377
        return -1;
3378
    }
3379
3380
    if (priv->handle < 0) {
1.2.13 by Chuck Short
Import upstream version 0.9.12
3381
        virXenError(VIR_ERR_INTERNAL_ERROR, "%s",
3382
                    _("priv->handle invalid"));
0.2.1 by Guido Günther
Import upstream version 0.7.2
3383
        return -1;
3384
    }
3385
3386
    memset(&op_sys, 0, sizeof(op_sys));
3387
    op_sys.cmd = XEN_V2_OP_GETAVAILHEAP;
3388
3389
    for (i = startCell, j = 0;(i < priv->nbNodeCells) && (j < maxCells);i++,j++) {
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
3390
        if (hv_versions.sys_interface >= 5)
0.2.1 by Guido Günther
Import upstream version 0.7.2
3391
            op_sys.u.availheap5.node = i;
3392
        else
3393
            op_sys.u.availheap.node = i;
3394
        ret = xenHypervisorDoV2Sys(priv->handle, &op_sys);
3395
        if (ret < 0) {
1.2.13 by Chuck Short
Import upstream version 0.9.12
3396
            return -1;
0.2.1 by Guido Günther
Import upstream version 0.7.2
3397
        }
0.5.1 by Guido Günther
Import upstream version 0.9.7~rc1
3398
        if (hv_versions.sys_interface >= 5)
0.2.1 by Guido Günther
Import upstream version 0.7.2
3399
            freeMems[j] = op_sys.u.availheap5.avail_bytes;
3400
        else
3401
            freeMems[j] = op_sys.u.availheap.avail_bytes;
3402
    }
1.2.13 by Chuck Short
Import upstream version 0.9.12
3403
    return j;
0.2.1 by Guido Günther
Import upstream version 0.7.2
3404
}
3405
3406
3407
/**
3408
 * xenHypervisorPauseDomain:
3409
 * @domain: pointer to the domain block
3410
 *
0.5.5 by Guido Günther
Import upstream version 0.9.8~rc2
3411
 * Do a hypervisor call to pause the given domain
0.2.1 by Guido Günther
Import upstream version 0.7.2
3412
 *
3413
 * Returns 0 in case of success, -1 in case of error.
3414
 */
3415
int
3416
xenHypervisorPauseDomain(virDomainPtr domain)
3417
{
3418
    int ret;
3419
    xenUnifiedPrivatePtr priv;
3420
0.2.4 by Laurent Léonard
Import upstream version 0.7.6
3421
    if (domain->conn == NULL)
0.2.1 by Guido Günther
Import upstream version 0.7.2
3422
        return -1;
3423
3424
    priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
3425
    if (priv->handle < 0 || domain->id < 0)
1.2.13 by Chuck Short
Import upstream version 0.9.12
3426
        return -1;
0.2.1 by Guido Günther
Import upstream version 0.7.2
3427
3428
    ret = virXen_pausedomain(priv->handle, domain->id);
3429
    if (ret < 0)
1.2.13 by Chuck Short
Import upstream version 0.9.12
3430
        return -1;
3431
    return 0;
0.2.1 by Guido Günther
Import upstream version 0.7.2
3432
}
3433
3434
/**
3435
 * xenHypervisorResumeDomain:
3436
 * @domain: pointer to the domain block
3437
 *
0.5.5 by Guido Günther
Import upstream version 0.9.8~rc2
3438
 * Do a hypervisor call to resume the given domain
0.2.1 by Guido Günther
Import upstream version 0.7.2
3439
 *
3440
 * Returns 0 in case of success, -1 in case of error.
3441
 */
3442
int
3443
xenHypervisorResumeDomain(virDomainPtr domain)
3444
{
3445
    int ret;
3446
    xenUnifiedPrivatePtr priv;
3447
0.2.4 by Laurent Léonard
Import upstream version 0.7.6
3448
    if (domain->conn == NULL)
0.2.1 by Guido Günther
Import upstream version 0.7.2
3449
        return -1;
3450
3451
    priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
3452
    if (priv->handle < 0 || domain->id < 0)
1.2.13 by Chuck Short
Import upstream version 0.9.12
3453
        return -1;
0.2.1 by Guido Günther
Import upstream version 0.7.2
3454
3455
    ret = virXen_unpausedomain(priv->handle, domain->id);
3456
    if (ret < 0)
1.2.13 by Chuck Short
Import upstream version 0.9.12
3457
        return -1;
3458
    return 0;
0.2.1 by Guido Günther
Import upstream version 0.7.2
3459
}
3460
3461
/**
0.4.4 by Guido Günther
Import upstream version 0.9.4~rc1
3462
 * xenHypervisorDestroyDomainFlags:
0.2.1 by Guido Günther
Import upstream version 0.7.2
3463
 * @domain: pointer to the domain block
0.4.4 by Guido Günther
Import upstream version 0.9.4~rc1
3464
 * @flags: an OR'ed set of virDomainDestroyFlagsValues
0.2.1 by Guido Günther
Import upstream version 0.7.2
3465
 *
0.5.5 by Guido Günther
Import upstream version 0.9.8~rc2
3466
 * Do a hypervisor call to destroy the given domain
1.2.10 by Chuck Short
Import upstream version 0.9.6
3467
 *
0.4.4 by Guido Günther
Import upstream version 0.9.4~rc1
3468
 * Calling this function with no @flags set (equal to zero)
3469
 * is equivalent to calling xenHypervisorDestroyDomain.
3470
 *
0.2.1 by Guido Günther
Import upstream version 0.7.2
3471
 * Returns 0 in case of success, -1 in case of error.
3472
 */
3473
int
0.4.4 by Guido Günther
Import upstream version 0.9.4~rc1
3474
xenHypervisorDestroyDomainFlags(virDomainPtr domain,
3475
                                unsigned int flags)
0.2.1 by Guido Günther
Import upstream version 0.7.2
3476
{
3477
    int ret;
3478
    xenUnifiedPrivatePtr priv;
3479
0.4.4 by Guido Günther
Import upstream version 0.9.4~rc1
3480
    virCheckFlags(0, -1);
3481
0.2.4 by Laurent Léonard
Import upstream version 0.7.6
3482
    if (domain->conn == NULL)
0.2.1 by Guido Günther
Import upstream version 0.7.2
3483
        return -1;
3484
3485
    priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
3486
    if (priv->handle < 0 || domain->id < 0)
1.2.13 by Chuck Short
Import upstream version 0.9.12
3487
        return -1;
0.2.1 by Guido Günther
Import upstream version 0.7.2
3488
3489
    ret = virXen_destroydomain(priv->handle, domain->id);
3490
    if (ret < 0)
1.2.13 by Chuck Short
Import upstream version 0.9.12
3491
        return -1;
3492
    return 0;
0.2.1 by Guido Günther
Import upstream version 0.7.2
3493
}
3494
3495
/**
3496
 * xenHypervisorSetMaxMemory:
3497
 * @domain: pointer to the domain block
3498
 * @memory: the max memory size in kilobytes.
3499
 *
0.5.5 by Guido Günther
Import upstream version 0.9.8~rc2
3500
 * Do a hypervisor call to change the maximum amount of memory used
0.2.1 by Guido Günther
Import upstream version 0.7.2
3501
 *
3502
 * Returns 0 in case of success, -1 in case of error.
3503
 */
3504
int
3505
xenHypervisorSetMaxMemory(virDomainPtr domain, unsigned long memory)
3506
{
3507
    int ret;
3508
    xenUnifiedPrivatePtr priv;
3509
0.2.4 by Laurent Léonard
Import upstream version 0.7.6
3510
    if (domain->conn == NULL)
0.2.1 by Guido Günther
Import upstream version 0.7.2
3511
        return -1;
3512
3513
    priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
3514
    if (priv->handle < 0 || domain->id < 0)
1.2.13 by Chuck Short
Import upstream version 0.9.12
3515
        return -1;
0.2.1 by Guido Günther
Import upstream version 0.7.2
3516
3517
    ret = virXen_setmaxmem(priv->handle, domain->id, memory);
3518
    if (ret < 0)
1.2.13 by Chuck Short
Import upstream version 0.9.12
3519
        return -1;
3520
    return 0;
0.2.1 by Guido Günther
Import upstream version 0.7.2
3521
}
0.3.3 by Laurent Léonard
Import upstream version 0.8.6
3522
3523
0.2.1 by Guido Günther
Import upstream version 0.7.2
3524
/**
3525
 * xenHypervisorSetVcpus:
3526
 * @domain: pointer to domain object
3527
 * @nvcpus: the new number of virtual CPUs for this domain
3528
 *
3529
 * Dynamically change the number of virtual CPUs used by the domain.
3530
 *
3531
 * Returns 0 in case of success, -1 in case of failure.
3532
 */
3533
3534
int
3535
xenHypervisorSetVcpus(virDomainPtr domain, unsigned int nvcpus)
3536
{
3537
    int ret;
3538
    xenUnifiedPrivatePtr priv;
3539
0.2.4 by Laurent Léonard
Import upstream version 0.7.6
3540
    if (domain->conn == NULL)
0.2.1 by Guido Günther
Import upstream version 0.7.2
3541
        return -1;
3542
3543
    priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
3544
    if (priv->handle < 0 || domain->id < 0 || nvcpus < 1)
1.2.13 by Chuck Short
Import upstream version 0.9.12
3545
        return -1;
0.2.1 by Guido Günther
Import upstream version 0.7.2
3546
3547
    ret = virXen_setmaxvcpus(priv->handle, domain->id, nvcpus);
3548
    if (ret < 0)
1.2.13 by Chuck Short
Import upstream version 0.9.12
3549
        return -1;
3550
    return 0;
0.2.1 by Guido Günther
Import upstream version 0.7.2
3551
}
3552
3553
/**
3554
 * xenHypervisorPinVcpu:
3555
 * @domain: pointer to domain object
3556
 * @vcpu: virtual CPU number
3557
 * @cpumap: pointer to a bit map of real CPUs (in 8-bit bytes)
3558
 * @maplen: length of cpumap in bytes
3559
 *
3560
 * Dynamically change the real CPUs which can be allocated to a virtual CPU.
3561
 *
3562
 * Returns 0 in case of success, -1 in case of failure.
3563
 */
3564
3565
int
3566
xenHypervisorPinVcpu(virDomainPtr domain, unsigned int vcpu,
3567
                     unsigned char *cpumap, int maplen)
3568
{
3569
    int ret;
3570
    xenUnifiedPrivatePtr priv;
3571
0.2.4 by Laurent Léonard
Import upstream version 0.7.6
3572
    if (domain->conn == NULL)
0.2.1 by Guido Günther
Import upstream version 0.7.2
3573
        return -1;
3574
3575
    priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
3576
    if (priv->handle < 0 || (domain->id < 0) ||
3577
        (cpumap == NULL) || (maplen < 1))
1.2.13 by Chuck Short
Import upstream version 0.9.12
3578
        return -1;
0.2.1 by Guido Günther
Import upstream version 0.7.2
3579
3580
    ret = virXen_setvcpumap(priv->handle, domain->id, vcpu,
3581
                            cpumap, maplen);
3582
    if (ret < 0)
1.2.13 by Chuck Short
Import upstream version 0.9.12
3583
        return -1;
3584
    return 0;
0.2.1 by Guido Günther
Import upstream version 0.7.2
3585
}
3586
3587
/**
3588
 * virDomainGetVcpus:
3589
 * @domain: pointer to domain object, or NULL for Domain0
3590
 * @info: pointer to an array of virVcpuInfo structures (OUT)
3591
 * @maxinfo: number of structures in info array
0.5.5 by Guido Günther
Import upstream version 0.9.8~rc2
3592
 * @cpumaps: pointer to a bit map of real CPUs for all vcpus of this domain (in 8-bit bytes) (OUT)
0.2.1 by Guido Günther
Import upstream version 0.7.2
3593
 *	If cpumaps is NULL, then no cpumap information is returned by the API.
3594
 *	It's assumed there is <maxinfo> cpumap in cpumaps array.
3595
 *	The memory allocated to cpumaps must be (maxinfo * maplen) bytes
3596
 *	(ie: calloc(maxinfo, maplen)).
3597
 *	One cpumap inside cpumaps has the format described in virDomainPinVcpu() API.
3598
 * @maplen: number of bytes in one cpumap, from 1 up to size of CPU map in
3599
 *	underlying virtualization system (Xen...).
3600
 *
3601
 * Extract information about virtual CPUs of domain, store it in info array
3602
 * and also in cpumaps if this pointer isn't NULL.
3603
 *
3604
 * Returns the number of info filled in case of success, -1 in case of failure.
3605
 */
3606
int
3607
xenHypervisorGetVcpus(virDomainPtr domain, virVcpuInfoPtr info, int maxinfo,
3608
                      unsigned char *cpumaps, int maplen)
3609
{
3610
    xen_getdomaininfo dominfo;
3611
    int ret;
3612
    xenUnifiedPrivatePtr priv;
3613
    virVcpuInfoPtr ipt;
3614
    int nbinfo, i;
3615
0.2.4 by Laurent Léonard
Import upstream version 0.7.6
3616
    if (domain->conn == NULL)
0.2.1 by Guido Günther
Import upstream version 0.7.2
3617
        return -1;
3618
3619
    priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
3620
    if (priv->handle < 0 || (domain->id < 0) ||
3621
        (info == NULL) || (maxinfo < 1) ||
0.2.3 by Guido Günther
Import upstream version 0.7.5
3622
        (sizeof(cpumap_t) & 7)) {
1.2.13 by Chuck Short
Import upstream version 0.9.12
3623
        virXenError(VIR_ERR_INTERNAL_ERROR, "%s",
3624
                    _("domain shut off or invalid"));
3625
        return -1;
0.2.3 by Guido Günther
Import upstream version 0.7.5
3626
    }
3627
    if ((cpumaps != NULL) && (maplen < 1)) {
1.2.13 by Chuck Short
Import upstream version 0.9.12
3628
        virXenError(VIR_ERR_INVALID_ARG, "%s",
3629
                    _("invalid argument"));
0.2.1 by Guido Günther
Import upstream version 0.7.2
3630
        return -1;
0.2.3 by Guido Günther
Import upstream version 0.7.5
3631
    }
0.2.1 by Guido Günther
Import upstream version 0.7.2
3632
    /* first get the number of virtual CPUs in this domain */
3633
    XEN_GETDOMAININFO_CLEAR(dominfo);
3634
    ret = virXen_getdomaininfo(priv->handle, domain->id,
3635
                               &dominfo);
3636
0.2.3 by Guido Günther
Import upstream version 0.7.5
3637
    if ((ret < 0) || (XEN_GETDOMAININFO_DOMAIN(dominfo) != domain->id)) {
1.2.13 by Chuck Short
Import upstream version 0.9.12
3638
        virXenError(VIR_ERR_INTERNAL_ERROR, "%s",
3639
                    _("cannot get domain details"));
3640
        return -1;
0.2.3 by Guido Günther
Import upstream version 0.7.5
3641
    }
0.2.1 by Guido Günther
Import upstream version 0.7.2
3642
    nbinfo = XEN_GETDOMAININFO_CPUCOUNT(dominfo) + 1;
3643
    if (nbinfo > maxinfo) nbinfo = maxinfo;
3644
3645
    if (cpumaps != NULL)
3646
        memset(cpumaps, 0, maxinfo * maplen);
3647
3648
    for (i = 0, ipt = info; i < nbinfo; i++, ipt++) {
3649
        if ((cpumaps != NULL) && (i < maxinfo)) {
3650
            ret = virXen_getvcpusinfo(priv->handle, domain->id, i,
3651
                                      ipt,
3652
                                      (unsigned char *)VIR_GET_CPUMAP(cpumaps, maplen, i),
3653
                                      maplen);
0.2.3 by Guido Günther
Import upstream version 0.7.5
3654
            if (ret < 0) {
1.2.13 by Chuck Short
Import upstream version 0.9.12
3655
                virXenError(VIR_ERR_INTERNAL_ERROR, "%s",
3656
                            _("cannot get VCPUs info"));
3657
                return -1;
0.2.3 by Guido Günther
Import upstream version 0.7.5
3658
            }
0.2.1 by Guido Günther
Import upstream version 0.7.2
3659
        } else {
3660
            ret = virXen_getvcpusinfo(priv->handle, domain->id, i,
3661
                                      ipt, NULL, 0);
0.2.3 by Guido Günther
Import upstream version 0.7.5
3662
            if (ret < 0) {
1.2.13 by Chuck Short
Import upstream version 0.9.12
3663
                virXenError(VIR_ERR_INTERNAL_ERROR, "%s",
3664
                            _("cannot get VCPUs info"));
3665
                return -1;
0.2.3 by Guido Günther
Import upstream version 0.7.5
3666
            }
0.2.1 by Guido Günther
Import upstream version 0.7.2
3667
        }
3668
    }
3669
    return nbinfo;
3670
}
3671
3672
/**
3673
 * xenHypervisorGetVcpuMax:
3674
 *
3675
 *  Returns the maximum number of virtual CPUs supported for
3676
 *  the guest VM. If the guest is inactive, this is the maximum
3677
 *  of CPU defined by Xen. If the guest is running this reflect
3678
 *  the maximum number of virtual CPUs the guest was booted with.
3679
 */
3680
int
3681
xenHypervisorGetVcpuMax(virDomainPtr domain)
3682
{
3683
    xen_getdomaininfo dominfo;
3684
    int ret;
3685
    int maxcpu;
3686
    xenUnifiedPrivatePtr priv;
3687
0.2.4 by Laurent Léonard
Import upstream version 0.7.6
3688
    if (domain->conn == NULL)
0.2.1 by Guido Günther
Import upstream version 0.7.2
3689
        return -1;
3690
3691
    priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
3692
    if (priv->handle < 0)
1.2.13 by Chuck Short
Import upstream version 0.9.12
3693
        return -1;
0.2.1 by Guido Günther
Import upstream version 0.7.2
3694
3695
    /* inactive domain */
3696
    if (domain->id < 0) {
3697
        maxcpu = MAX_VIRT_CPUS;
3698
    } else {
3699
        XEN_GETDOMAININFO_CLEAR(dominfo);
3700
        ret = virXen_getdomaininfo(priv->handle, domain->id,
3701
                                   &dominfo);
3702
3703
        if ((ret < 0) || (XEN_GETDOMAININFO_DOMAIN(dominfo) != domain->id))
1.2.13 by Chuck Short
Import upstream version 0.9.12
3704
            return -1;
0.2.1 by Guido Günther
Import upstream version 0.7.2
3705
        maxcpu = XEN_GETDOMAININFO_MAXCPUID(dominfo) + 1;
3706
    }
3707
3708
    return maxcpu;
3709
}
3710
3711
/**
3712
 * xenHavePrivilege()
3713
 *
3714
 * Return true if the current process should be able to connect to Xen.
3715
 */
3716
int
0.3.7 by Guido Günther
Import upstream version 0.9.1
3717
xenHavePrivilege(void)
0.2.1 by Guido Günther
Import upstream version 0.7.2
3718
{
3719
#ifdef __sun
3720
    return priv_ineffect (PRIV_XVM_CONTROL);
3721
#else
3722
    return access(XEN_HYPERVISOR_SOCKET, R_OK) == 0;
3723
#endif
3724
}