ia64/xen-unstable

annotate tools/python/xen/xend/XendDomain.py @ 10711:9ddc5be227c1

[XEND] Improve xm pause/unpause error reporting.
Signed-off-by: Masaki Kanno <kanno.masaki@jp.fujitsu.com>
author kfraser@localhost.localdomain
date Mon Jul 10 15:18:12 2006 +0100 (2006-07-10)
parents 800261a88275
children c45f1f3a926b
rev   line source
kaf24@6079 1 #============================================================================
kaf24@6079 2 # This library is free software; you can redistribute it and/or
kaf24@6079 3 # modify it under the terms of version 2.1 of the GNU Lesser General Public
kaf24@6079 4 # License as published by the Free Software Foundation.
kaf24@6079 5 #
kaf24@6079 6 # This library is distributed in the hope that it will be useful,
kaf24@6079 7 # but WITHOUT ANY WARRANTY; without even the implied warranty of
kaf24@6079 8 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
kaf24@6079 9 # Lesser General Public License for more details.
kaf24@6079 10 #
kaf24@6079 11 # You should have received a copy of the GNU Lesser General Public
kaf24@6079 12 # License along with this library; if not, write to the Free Software
kaf24@6079 13 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
kaf24@6079 14 #============================================================================
kaf24@6079 15 # Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com>
cl349@5124 16 # Copyright (C) 2005 Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
emellor@7006 17 # Copyright (C) 2005 XenSource Ltd
kaf24@6079 18 #============================================================================
mjw@1623 19
mjw@1623 20 """Handler for domain operations.
mjw@1623 21 Nothing here is persistent (across reboots).
mjw@1623 22 Needs to be persistent for one uptime.
mjw@1623 23 """
emellor@7414 24
emellor@7414 25 import logging
cl349@5144 26 import os
emellor@8144 27 import socket
emellor@7414 28 import sys
emellor@7151 29 import threading
mjw@1623 30
emellor@7026 31 import xen.lowlevel.xc
mjw@1623 32
emellor@7176 33 import XendDomainInfo
emellor@7176 34
emellor@7026 35 from xen.xend import XendRoot
cl349@5336 36 from xen.xend import XendCheckpoint
emellor@9530 37 from xen.xend.XendError import XendError, XendInvalidDomain
cl349@5336 38 from xen.xend.XendLogging import log
emellor@8190 39 from xen.xend.xenstore.xstransact import xstransact
emellor@7837 40 from xen.xend.xenstore.xswatch import xswatch
smh22@9836 41 from xen.util import security
mjw@1623 42
emellor@7026 43
emellor@7973 44 xc = xen.lowlevel.xc.xc()
emellor@7026 45 xroot = XendRoot.instance()
emellor@7026 46
emellor@7026 47
mjw@1623 48 __all__ = [ "XendDomain" ]
mjw@4580 49
emellor@7072 50 PRIV_DOMAIN = 0
emellor@8190 51 VMROOT = '/vm/'
emellor@8190 52
cl349@6922 53
mjw@1623 54 class XendDomain:
mjw@1623 55 """Index of all domains. Singleton.
mjw@1623 56 """
mjw@1673 57
emellor@7151 58 ## public:
mjw@1623 59
mjw@1623 60 def __init__(self):
emellor@7176 61 self.domains = {}
emellor@7348 62 self.domains_lock = threading.RLock()
emellor@7837 63
emellor@8144 64
emellor@8144 65 # This must be called only the once, by instance() below. It is separate
emellor@8144 66 # from the constructor because XendDomainInfo calls back into this class
emellor@8144 67 # in order to check the uniqueness of domain names. This means that
emellor@8144 68 # instance() must be able to return a valid instance of this class even
emellor@8144 69 # during this initialisation.
emellor@8144 70 def init(self):
emellor@8190 71 xstransact.Mkdir(VMROOT)
emellor@8190 72 xstransact.SetPermissions(VMROOT, { 'dom' : PRIV_DOMAIN })
emellor@8190 73
emellor@7176 74 self.domains_lock.acquire()
emellor@7176 75 try:
emellor@7414 76 self._add_domain(
emellor@7414 77 XendDomainInfo.recreate(self.xen_domains()[PRIV_DOMAIN],
emellor@7414 78 True))
emellor@7414 79 self.dom0_setup()
emellor@7861 80
emellor@7861 81 # This watch registration needs to be before the refresh call, so
emellor@7861 82 # that we're sure that we haven't missed any releases, but inside
emellor@7861 83 # the domains_lock, as we don't want the watch to fire until after
emellor@7861 84 # the refresh call has completed.
emellor@9466 85 xswatch("@introduceDomain", self.onChangeDomain)
emellor@9466 86 xswatch("@releaseDomain", self.onChangeDomain)
emellor@7861 87
emellor@7240 88 self.refresh(True)
emellor@7176 89 finally:
emellor@7176 90 self.domains_lock.release()
emellor@7176 91
mjw@1623 92
cl349@5017 93 def list(self):
cl349@5017 94 """Get list of domain objects.
cl349@5014 95
cl349@5017 96 @return: domain objects
cl349@5017 97 """
emellor@7176 98 self.domains_lock.acquire()
emellor@7176 99 try:
emellor@7176 100 self.refresh()
emellor@7176 101 return self.domains.values()
emellor@7176 102 finally:
emellor@7176 103 self.domains_lock.release()
emellor@7176 104
cl349@6585 105
cl349@6585 106 def list_sorted(self):
cl349@6585 107 """Get list of domain objects, sorted by name.
cl349@6585 108
cl349@6585 109 @return: domain objects
cl349@6585 110 """
cl349@6585 111 doms = self.list()
emellor@6943 112 doms.sort(lambda x, y: cmp(x.getName(), y.getName()))
cl349@6585 113 return doms
cl349@6585 114
cl349@6585 115 def list_names(self):
cl349@6585 116 """Get list of domain names.
cl349@6585 117
cl349@6585 118 @return: domain names
cl349@6585 119 """
cl349@6585 120 doms = self.list_sorted()
emellor@6943 121 return map(lambda x: x.getName(), doms)
cl349@6585 122
emellor@7151 123
emellor@7151 124 ## private:
emellor@7151 125
emellor@9466 126 def onChangeDomain(self, _):
emellor@7176 127 self.domains_lock.acquire()
emellor@7176 128 try:
emellor@7176 129 self.refresh()
emellor@7176 130 finally:
emellor@7176 131 self.domains_lock.release()
emellor@7837 132 return 1
cl349@6677 133
emellor@7208 134
mjw@4580 135 def xen_domains(self):
emellor@7208 136 """Get table of domains indexed by id from xc. Expects to be
emellor@7208 137 protected by the domains_lock.
mjw@1623 138 """
mjw@1623 139 domlist = xc.domain_getinfo()
mjw@1623 140 doms = {}
mjw@1623 141 for d in domlist:
cl349@5334 142 domid = d['dom']
mjw@1623 143 doms[domid] = d
mjw@4580 144 return doms
mjw@4580 145
emellor@7072 146
cl349@6922 147 def dom0_setup(self):
emellor@7208 148 """Expects to be protected by the domains_lock."""
emellor@7176 149 dom0 = self.domains[PRIV_DOMAIN]
emellor@7410 150
emellor@7410 151 # get max number of vcpus to use for dom0 from config
emellor@7410 152 target = int(xroot.get_dom0_vcpus())
emellor@7410 153 log.debug("number of vcpus to use is %d", target)
emellor@7410 154
emellor@7410 155 # target == 0 means use all processors
emellor@7410 156 if target > 0:
emellor@7426 157 dom0.setVCpuCount(target)
cl349@5911 158
mjw@1623 159
emellor@7208 160 def _add_domain(self, info):
emellor@7208 161 """Add the given domain entry to this instance's internal cache.
emellor@7208 162 Expects to be protected by the domains_lock.
mjw@1629 163 """
emellor@7025 164 self.domains[info.getDomid()] = info
emellor@7208 165
mjw@1623 166
emellor@7208 167 def _delete_domain(self, domid):
emellor@7208 168 """Remove the given domain from this instance's internal cache.
emellor@7208 169 Expects to be protected by the domains_lock.
mjw@1629 170 """
emellor@7084 171 info = self.domains.get(domid)
mjw@4580 172 if info:
emellor@7084 173 del self.domains[domid]
emellor@7151 174 info.cleanupDomain()
mjw@1623 175
mjw@1623 176
emellor@7240 177 def refresh(self, initialising = False):
emellor@7208 178 """Refresh domain list from Xen. Expects to be protected by the
emellor@7208 179 domains_lock.
emellor@7240 180
emellor@7240 181 @param initialising True if this is the first refresh after starting
emellor@7240 182 Xend. This does not change this method's behaviour, except for
emellor@7240 183 logging.
mjw@1623 184 """
emellor@7176 185 doms = self.xen_domains()
emellor@7176 186 for d in self.domains.values():
emellor@7176 187 info = doms.get(d.getDomid())
emellor@7176 188 if info:
emellor@7176 189 d.update(info)
emellor@7176 190 else:
emellor@7176 191 self._delete_domain(d.getDomid())
emellor@7176 192 for d in doms:
emellor@7239 193 if d not in self.domains:
emellor@7239 194 if doms[d]['dying']:
emellor@7240 195 log.log(initialising and logging.ERROR or logging.DEBUG,
emellor@7240 196 'Cannot recreate information for dying domain %d.'
emellor@7240 197 ' Xend will ignore this domain from now on.',
emellor@7240 198 doms[d]['dom'])
emellor@7414 199 elif d == PRIV_DOMAIN:
emellor@7414 200 log.fatal(
emellor@7414 201 "No record of privileged domain %d! Terminating.", d)
emellor@7414 202 sys.exit(1)
emellor@7239 203 else:
emellor@7239 204 try:
emellor@7414 205 self._add_domain(
emellor@7414 206 XendDomainInfo.recreate(doms[d], False))
emellor@7239 207 except:
emellor@7414 208 log.exception(
emellor@7414 209 "Failed to recreate information for domain "
emellor@7414 210 "%d. Destroying it in the hope of "
emellor@7414 211 "recovery.", d)
emellor@7414 212 try:
emellor@7973 213 xc.domain_destroy(d)
emellor@7414 214 except:
emellor@7414 215 log.exception('Destruction of %d failed.', d)
mjw@1623 216
emellor@7151 217
emellor@7151 218 ## public:
emellor@7151 219
mjw@1623 220 def domain_create(self, config):
mjw@1629 221 """Create a domain from a configuration.
mjw@1629 222
mjw@1729 223 @param config: configuration
mjw@4580 224 @return: domain
mjw@1629 225 """
emellor@7176 226 self.domains_lock.acquire()
emellor@7176 227 try:
emellor@7176 228 dominfo = XendDomainInfo.create(config)
emellor@7176 229 self._add_domain(dominfo)
emellor@7176 230 return dominfo
emellor@7176 231 finally:
emellor@7176 232 self.domains_lock.release()
emellor@7176 233
mjw@1744 234
emellor@7021 235 def domain_configure(self, config):
emellor@7151 236 """Configure an existing domain.
mjw@1744 237
mjw@2222 238 @param vmconfig: vm configuration
mjw@1744 239 """
emellor@7151 240 # !!!
emellor@7151 241 raise XendError("Unsupported")
cl349@5336 242
emellor@7084 243 def domain_restore(self, src):
mjw@1744 244 """Restore a domain from file.
mjw@1744 245
mjw@1744 246 @param src: source file
mjw@1744 247 """
cl349@5053 248
cl349@5145 249 try:
emellor@7213 250 fd = os.open(src, os.O_RDONLY)
emellor@7213 251 try:
emellor@7213 252 return self.domain_restore_fd(fd)
emellor@7213 253 finally:
emellor@7213 254 os.close(fd)
cl349@5145 255 except OSError, ex:
cl349@5145 256 raise XendError("can't read guest state file %s: %s" %
cl349@5145 257 (src, ex[1]))
cl349@5099 258
emellor@7181 259 def domain_restore_fd(self, fd):
emellor@7181 260 """Restore a domain from the given file descriptor."""
emellor@7181 261
emellor@7181 262 try:
emellor@7206 263 return XendCheckpoint.restore(self, fd)
emellor@7208 264 except:
emellor@7208 265 # I don't really want to log this exception here, but the error
emellor@7208 266 # handling in the relocation-socket handling code (relocate.py) is
emellor@7208 267 # poor, so we need to log this for debugging.
emellor@7181 268 log.exception("Restore failed")
smh22@9836 269 raise XendError("Restore failed")
emellor@7181 270
emellor@7181 271
emellor@7181 272 def restore_(self, config):
emellor@7181 273 """Create a domain as part of the restore process. This is called
emellor@7181 274 only from {@link XendCheckpoint}.
emellor@7181 275
emellor@7181 276 A restore request comes into XendDomain through {@link
emellor@7181 277 #domain_restore} or {@link #domain_restore_fd}. That request is
emellor@7181 278 forwarded immediately to XendCheckpoint which, when it is ready, will
emellor@7181 279 call this method. It is necessary to come through here rather than go
emellor@7181 280 directly to {@link XendDomainInfo.restore} because we need to
emellor@7181 281 serialise the domain creation process, but cannot lock
emellor@7181 282 domain_restore_fd as a whole, otherwise we will deadlock waiting for
emellor@7181 283 the old domain to die.
emellor@7181 284 """
emellor@7181 285 self.domains_lock.acquire()
emellor@7181 286 try:
smh22@9836 287 security.refresh_ssidref(config)
emellor@7181 288 dominfo = XendDomainInfo.restore(config)
emellor@7181 289 self._add_domain(dominfo)
emellor@7181 290 return dominfo
emellor@7181 291 finally:
emellor@7181 292 self.domains_lock.release()
emellor@7181 293
emellor@7006 294
emellor@7213 295 def domain_lookup(self, domid):
emellor@7176 296 self.domains_lock.acquire()
emellor@7176 297 try:
emellor@7176 298 self.refresh()
emellor@7213 299 return self.domains.get(domid)
emellor@7176 300 finally:
emellor@7176 301 self.domains_lock.release()
emellor@7176 302
emellor@7176 303
emellor@7213 304 def domain_lookup_nr(self, domid):
emellor@7176 305 self.domains_lock.acquire()
emellor@7176 306 try:
emellor@7213 307 return self.domains.get(domid)
emellor@7176 308 finally:
emellor@7176 309 self.domains_lock.release()
emellor@7176 310
emellor@7176 311
emellor@7176 312 def domain_lookup_by_name_or_id(self, name):
emellor@7176 313 self.domains_lock.acquire()
emellor@7176 314 try:
emellor@7176 315 self.refresh()
emellor@7176 316 return self.domain_lookup_by_name_or_id_nr(name)
emellor@7176 317 finally:
emellor@7176 318 self.domains_lock.release()
emellor@7176 319
cl349@5334 320
emellor@7176 321 def domain_lookup_by_name_or_id_nr(self, name):
emellor@7176 322 self.domains_lock.acquire()
emellor@7176 323 try:
emellor@7176 324 dominfo = self.domain_lookup_by_name_nr(name)
emellor@7176 325
emellor@7176 326 if dominfo:
emellor@7176 327 return dominfo
emellor@7176 328 else:
emellor@7176 329 try:
emellor@7176 330 return self.domains.get(int(name))
emellor@7176 331 except ValueError:
emellor@7176 332 return None
emellor@7176 333 finally:
emellor@7176 334 self.domains_lock.release()
emellor@7176 335
emellor@7176 336
emellor@7176 337 def domain_lookup_by_name_nr(self, name):
emellor@7176 338 self.domains_lock.acquire()
emellor@7176 339 try:
emellor@7381 340 matching = filter(lambda d: d.getName() == name,
emellor@7381 341 self.domains.values())
emellor@7176 342 n = len(matching)
emellor@7176 343 if n == 1:
emellor@7176 344 return matching[0]
emellor@7223 345 return None
emellor@7176 346 finally:
emellor@7176 347 self.domains_lock.release()
mjw@1975 348
emellor@7172 349
kfraser@10710 350 def domain_lookup_by_uuid_nr(self, uuid):
kfraser@10710 351 self.domains_lock.acquire()
kfraser@10710 352 try:
kfraser@10710 353 matching = filter(lambda d: d.getUuid() == uuid,
kfraser@10710 354 self.domains.values())
kfraser@10710 355 n = len(matching)
kfraser@10710 356 if n == 1:
kfraser@10710 357 return matching[0]
kfraser@10710 358 return None
kfraser@10710 359 finally:
kfraser@10710 360 self.domains_lock.release()
kfraser@10710 361
kfraser@10710 362
emellor@7172 363 def privilegedDomain(self):
emellor@7176 364 self.domains_lock.acquire()
emellor@7176 365 try:
emellor@7176 366 return self.domains[PRIV_DOMAIN]
emellor@7176 367 finally:
emellor@7176 368 self.domains_lock.release()
emellor@7172 369
emellor@7172 370
emellor@7213 371 def domain_unpause(self, domid):
emellor@7213 372 """Unpause domain execution."""
kfraser@10711 373
kfraser@10711 374 dominfo = self.domain_lookup_by_name_or_id_nr(domid)
kfraser@10711 375 if not dominfo:
kfraser@10711 376 raise XendInvalidDomain(str(domid))
kfraser@10711 377
kfraser@10711 378 if dominfo.getDomid() == PRIV_DOMAIN:
kfraser@10711 379 raise XendError("Cannot unpause privileged domain %s" % domid)
kfraser@10711 380
mjw@1985 381 try:
emellor@7215 382 log.info("Domain %s (%d) unpaused.", dominfo.getName(),
emellor@7215 383 dominfo.getDomid())
emellor@7433 384 return dominfo.unpause()
mjw@1985 385 except Exception, ex:
mjw@1985 386 raise XendError(str(ex))
emellor@7215 387
emellor@7215 388
emellor@7213 389 def domain_pause(self, domid):
emellor@7213 390 """Pause domain execution."""
kfraser@10711 391
kfraser@10711 392 dominfo = self.domain_lookup_by_name_or_id_nr(domid)
kfraser@10711 393 if not dominfo:
kfraser@10711 394 raise XendInvalidDomain(str(domid))
kfraser@10711 395
kfraser@10711 396 if dominfo.getDomid() == PRIV_DOMAIN:
kfraser@10711 397 raise XendError("Cannot pause privileged domain %s" % domid)
kfraser@10711 398
mjw@1985 399 try:
emellor@7215 400 log.info("Domain %s (%d) paused.", dominfo.getName(),
emellor@7215 401 dominfo.getDomid())
emellor@7433 402 return dominfo.pause()
mjw@1985 403 except Exception, ex:
mjw@1985 404 raise XendError(str(ex))
emellor@7072 405
emellor@7072 406
emellor@7173 407 def domain_destroy(self, domid):
emellor@7173 408 """Terminate domain immediately."""
emellor@7015 409
anthony@9421 410 dominfo = self.domain_lookup_by_name_or_id_nr(domid)
anthony@9421 411 if dominfo and dominfo.getDomid() == PRIV_DOMAIN:
anthony@9421 412 raise XendError("Cannot destroy privileged domain %s" % domid)
anthony@9421 413
cl349@6913 414 if dominfo:
cl349@6913 415 val = dominfo.destroy()
cl349@6913 416 else:
cl349@6913 417 try:
emellor@7973 418 val = xc.domain_destroy(domid)
cl349@6913 419 except Exception, ex:
cl349@6913 420 raise XendError(str(ex))
cl349@6913 421 return val
mjw@1673 422
vhanquez@8274 423 def domain_migrate(self, domid, dst, live=False, resource=0, port=0):
emellor@7213 424 """Start domain migration."""
mjw@1629 425
anthony@9421 426 dominfo = self.domain_lookup_by_name_or_id_nr(domid)
emellor@9530 427 if not dominfo:
emellor@9530 428 raise XendInvalidDomain(str(domid))
cl349@5155 429
emellor@8275 430 if dominfo.getDomid() == PRIV_DOMAIN:
emellor@8275 431 raise XendError("Cannot migrate privileged domain %i" % domid)
emellor@8275 432
emellor@9727 433 """ The following call may raise a XendError exception """
kaf24@10039 434 dominfo.testMigrateDevices(True, dst)
emellor@9727 435
vhanquez@8274 436 if port == 0:
vhanquez@8274 437 port = xroot.get_xend_relocation_port()
emellor@8144 438 try:
emellor@8144 439 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
emellor@8144 440 sock.connect((dst, port))
emellor@8144 441 except socket.error, err:
emellor@8144 442 raise XendError("can't connect: %s" % err[1])
cl349@5155 443
emellor@8144 444 sock.send("receive\n")
emellor@9727 445 sock.recv(80)
kaf24@10039 446 XendCheckpoint.save(sock.fileno(), dominfo, True, live, dst)
emellor@8144 447
mjw@1623 448
emellor@7213 449 def domain_save(self, domid, dst):
mjw@1744 450 """Start saving a domain to file.
mjw@1629 451
mjw@1729 452 @param dst: destination file
mjw@1623 453 """
cl349@5121 454
cl349@5121 455 try:
anthony@9421 456 dominfo = self.domain_lookup_by_name_or_id_nr(domid)
emellor@9530 457 if not dominfo:
emellor@9530 458 raise XendInvalidDomain(str(domid))
cl349@5121 459
emellor@8275 460 if dominfo.getDomid() == PRIV_DOMAIN:
emellor@8275 461 raise XendError("Cannot save privileged domain %i" % domid)
emellor@8275 462
cl349@5121 463 fd = os.open(dst, os.O_WRONLY | os.O_CREAT | os.O_TRUNC)
emellor@7213 464 try:
emellor@7213 465 # For now we don't support 'live checkpoint'
kaf24@10039 466 return XendCheckpoint.save(fd, dominfo, False, False, dst)
emellor@7213 467 finally:
emellor@7213 468 os.close(fd)
cl349@5145 469 except OSError, ex:
cl349@5145 470 raise XendError("can't write guest state file %s: %s" %
cl349@5145 471 (dst, ex[1]))
cl349@5121 472
emellor@7213 473 def domain_pincpu(self, domid, vcpu, cpumap):
cl349@4845 474 """Set which cpus vcpu can use
mjw@1623 475
kaf24@7483 476 @param cpumap: string repr of list of usable cpus
mjw@1629 477 """
anthony@9421 478 dominfo = self.domain_lookup_by_name_or_id_nr(domid)
emellor@9530 479 if not dominfo:
emellor@9530 480 raise XendInvalidDomain(str(domid))
emellor@9530 481
mjw@1985 482 try:
kaf24@8508 483 return xc.vcpu_setaffinity(dominfo.getDomid(), vcpu, cpumap)
mjw@1985 484 except Exception, ex:
mjw@1985 485 raise XendError(str(ex))
mjw@1623 486
emellor@7213 487 def domain_cpu_bvt_set(self, domid, mcuadv, warpback, warpvalue, warpl,
emellor@7213 488 warpu):
mjw@1629 489 """Set BVT (Borrowed Virtual Time) scheduler parameters for a domain.
mjw@1629 490 """
anthony@9421 491 dominfo = self.domain_lookup_by_name_or_id_nr(domid)
emellor@9530 492 if not dominfo:
emellor@9530 493 raise XendInvalidDomain(str(domid))
mjw@1985 494 try:
emellor@7025 495 return xc.bvtsched_domain_set(dom=dominfo.getDomid(),
emellor@6943 496 mcuadv=mcuadv,
emellor@6943 497 warpback=warpback,
emellor@6943 498 warpvalue=warpvalue,
gm281@2058 499 warpl=warpl, warpu=warpu)
mjw@1985 500 except Exception, ex:
mjw@1985 501 raise XendError(str(ex))
mjw@1623 502
emellor@7213 503 def domain_cpu_bvt_get(self, domid):
mjw@1629 504 """Get BVT (Borrowed Virtual Time) scheduler parameters for a domain.
mjw@1629 505 """
anthony@9421 506 dominfo = self.domain_lookup_by_name_or_id_nr(domid)
emellor@9530 507 if not dominfo:
emellor@9530 508 raise XendInvalidDomain(str(domid))
mjw@1985 509 try:
emellor@7025 510 return xc.bvtsched_domain_get(dominfo.getDomid())
mjw@1985 511 except Exception, ex:
mjw@1985 512 raise XendError(str(ex))
mjw@1623 513
sd386@3449 514
emellor@7213 515 def domain_cpu_sedf_set(self, domid, period, slice_, latency, extratime,
emellor@7213 516 weight):
sd386@3573 517 """Set Simple EDF scheduler parameters for a domain.
sd386@3449 518 """
anthony@9421 519 dominfo = self.domain_lookup_by_name_or_id_nr(domid)
emellor@9530 520 if not dominfo:
emellor@9530 521 raise XendInvalidDomain(str(domid))
sd386@3449 522 try:
emellor@7213 523 return xc.sedf_domain_set(dominfo.getDomid(), period, slice_,
emellor@6943 524 latency, extratime, weight)
sd386@3449 525 except Exception, ex:
sd386@3449 526 raise XendError(str(ex))
sd386@3449 527
emellor@7213 528 def domain_cpu_sedf_get(self, domid):
cl349@5334 529 """Get Simple EDF scheduler parameters for a domain.
sd386@3449 530 """
anthony@9421 531 dominfo = self.domain_lookup_by_name_or_id_nr(domid)
emellor@9530 532 if not dominfo:
emellor@9530 533 raise XendInvalidDomain(str(domid))
sd386@3449 534 try:
emellor@9217 535 sedf_info = xc.sedf_domain_get(dominfo.getDomid())
emellor@9217 536 # return sxpr
emellor@9217 537 return ['sedf',
emellor@9217 538 ['domain', sedf_info['domain']],
emellor@9217 539 ['period', sedf_info['period']],
emellor@9217 540 ['slice', sedf_info['slice']],
emellor@9217 541 ['latency', sedf_info['latency']],
emellor@9217 542 ['extratime', sedf_info['extratime']],
emellor@9217 543 ['weight', sedf_info['weight']]]
emellor@9217 544
sd386@3449 545 except Exception, ex:
sd386@3449 546 raise XendError(str(ex))
cl349@5304 547
kaf24@10206 548 def domain_sched_credit_get(self, domid):
ack@10188 549 """Get credit scheduler parameters for a domain.
ack@10188 550 """
ack@10188 551 dominfo = self.domain_lookup_by_name_or_id_nr(domid)
ack@10188 552 if not dominfo:
ack@10188 553 raise XendInvalidDomain(str(domid))
ack@10188 554 try:
kaf24@10206 555 return xc.sched_credit_domain_get(dominfo.getDomid())
ack@10188 556 except Exception, ex:
ack@10188 557 raise XendError(str(ex))
ack@10188 558
kaf24@10206 559 def domain_sched_credit_set(self, domid, weight, cap):
ack@10188 560 """Set credit scheduler parameters for a domain.
ack@10188 561 """
ack@10188 562 dominfo = self.domain_lookup_by_name_or_id_nr(domid)
ack@10188 563 if not dominfo:
ack@10188 564 raise XendInvalidDomain(str(domid))
ack@10188 565 try:
kaf24@10206 566 return xc.sched_credit_domain_set(dominfo.getDomid(), weight, cap)
ack@10188 567 except Exception, ex:
ack@10188 568 raise XendError(str(ex))
ack@10188 569
emellor@7213 570 def domain_maxmem_set(self, domid, mem):
mjw@1928 571 """Set the memory limit for a domain.
mjw@1928 572
emellor@7060 573 @param mem: memory limit (in MiB)
mjw@1928 574 @return: 0 on success, -1 on error
mjw@1928 575 """
anthony@9421 576 dominfo = self.domain_lookup_by_name_or_id_nr(domid)
emellor@9530 577 if not dominfo:
emellor@9530 578 raise XendInvalidDomain(str(domid))
mjw@1928 579 maxmem = int(mem) * 1024
mjw@1985 580 try:
emellor@8086 581 return xc.domain_setmaxmem(dominfo.getDomid(), maxmem)
mjw@1985 582 except Exception, ex:
mjw@1985 583 raise XendError(str(ex))
mjw@1928 584
kaf24@7642 585 def domain_ioport_range_enable(self, domid, first, last):
kaf24@7642 586 """Enable access to a range of IO ports for a domain
kaf24@7642 587
kaf24@7642 588 @param first: first IO port
kaf24@7642 589 @param last: last IO port
kaf24@7642 590 @return: 0 on success, -1 on error
kaf24@7642 591 """
anthony@9421 592 dominfo = self.domain_lookup_by_name_or_id_nr(domid)
emellor@9530 593 if not dominfo:
emellor@9530 594 raise XendInvalidDomain(str(domid))
kaf24@7642 595 nr_ports = last - first + 1
kaf24@7642 596 try:
kaf24@7642 597 return xc.domain_ioport_permission(dominfo.getDomid(),
kaf24@7642 598 first_port = first,
kaf24@7642 599 nr_ports = nr_ports,
kaf24@7642 600 allow_access = 1)
kaf24@7642 601 except Exception, ex:
kaf24@7642 602 raise XendError(str(ex))
kaf24@7642 603
kaf24@7642 604 def domain_ioport_range_disable(self, domid, first, last):
kaf24@7642 605 """Disable access to a range of IO ports for a domain
kaf24@7642 606
kaf24@7642 607 @param first: first IO port
kaf24@7642 608 @param last: last IO port
kaf24@7642 609 @return: 0 on success, -1 on error
kaf24@7642 610 """
anthony@9421 611 dominfo = self.domain_lookup_by_name_or_id_nr(domid)
emellor@9530 612 if not dominfo:
emellor@9530 613 raise XendInvalidDomain(str(domid))
kaf24@7642 614 nr_ports = last - first + 1
kaf24@7642 615 try:
kaf24@7642 616 return xc.domain_ioport_permission(dominfo.getDomid(),
kaf24@7642 617 first_port = first,
kaf24@7642 618 nr_ports = nr_ports,
kaf24@7642 619 allow_access = 0)
kaf24@7642 620 except Exception, ex:
kaf24@7642 621 raise XendError(str(ex))
kaf24@7642 622
emellor@7060 623
mjw@1623 624 def instance():
mjw@1629 625 """Singleton constructor. Use this instead of the class constructor.
mjw@1629 626 """
mjw@1623 627 global inst
mjw@1623 628 try:
mjw@1623 629 inst
mjw@1623 630 except:
mjw@1623 631 inst = XendDomain()
emellor@8144 632 inst.init()
mjw@1623 633 return inst