mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
Merge
This commit is contained in:
commit
dd60bc1ebc
10 files changed
+184
-51
No files matched your search
@@ -204,12 +204,14 @@ start()
|
||||
return;
|
||||
fi
|
||||
|
||||
saved_domains=" "
|
||||
if [ "$XENDOMAINS_RESTORE" = "true" ] &&
|
||||
contains_something "$XENDOMAINS_SAVE"
|
||||
then
|
||||
mkdir -p $(dirname "$LOCKFILE")
|
||||
touch $LOCKFILE
|
||||
echo -n "Restoring Xen domains:"
|
||||
saved_domains=`ls $XENDOMAINS_SAVE`
|
||||
for dom in $XENDOMAINS_SAVE/*; do
|
||||
echo -n " ${dom##*/}"
|
||||
xm restore $dom
|
||||
@@ -234,9 +236,14 @@ start()
|
||||
# Create all domains with config files in XENDOMAINS_AUTO.
|
||||
# TODO: We should record which domain name belongs
|
||||
# so we have the option to selectively shut down / migrate later
|
||||
# If a domain statefile from $XENDOMAINS_SAVE matches a domain name
|
||||
# in $XENDOMAINS_AUTO, do not try to start that domain; if it didn't
|
||||
# restore correctly it requires administrative attention.
|
||||
for dom in $XENDOMAINS_AUTO/*; do
|
||||
echo -n " ${dom##*/}"
|
||||
if is_running $dom; then
|
||||
shortdom=$(echo $dom | sed -n 's/^.*\/\(.*\)$/\1/p')
|
||||
echo $saved_domains | grep -w $shortdom > /dev/null
|
||||
if [ $? -eq 0 ] || is_running $dom; then
|
||||
echo -n "(skip)"
|
||||
else
|
||||
xm create --quiet --defconfig $dom
|
||||
|
||||
@@ -39,6 +39,7 @@ typedef struct USBMouseState {
|
||||
int x, y;
|
||||
int kind;
|
||||
int mouse_grabbed;
|
||||
int status_changed;
|
||||
} USBMouseState;
|
||||
|
||||
/* mostly the same values as the Bochs USB Mouse device */
|
||||
@@ -231,6 +232,7 @@ static void usb_mouse_event(void *opaque,
|
||||
s->dy += dy1;
|
||||
s->dz += dz1;
|
||||
s->buttons_state = buttons_state;
|
||||
s->status_changed = 1;
|
||||
}
|
||||
|
||||
static void usb_tablet_event(void *opaque,
|
||||
@@ -242,6 +244,7 @@ static void usb_tablet_event(void *opaque,
|
||||
s->y = y;
|
||||
s->dz += dz;
|
||||
s->buttons_state = buttons_state;
|
||||
s->status_changed = 1;
|
||||
}
|
||||
|
||||
static inline int int_clamp(int val, int vmin, int vmax)
|
||||
@@ -483,10 +486,16 @@ static int usb_mouse_handle_data(USBDevice *dev, int pid,
|
||||
switch(pid) {
|
||||
case USB_TOKEN_IN:
|
||||
if (devep == 1) {
|
||||
if (s->kind == USB_MOUSE)
|
||||
ret = usb_mouse_poll(s, data, len);
|
||||
else if (s->kind == USB_TABLET)
|
||||
ret = usb_tablet_poll(s, data, len);
|
||||
if (s->kind == USB_MOUSE)
|
||||
ret = usb_mouse_poll(s, data, len);
|
||||
else if (s->kind == USB_TABLET)
|
||||
ret = usb_tablet_poll(s, data, len);
|
||||
|
||||
if (!s->status_changed)
|
||||
ret = USB_RET_NAK;
|
||||
else
|
||||
s->status_changed = 0;
|
||||
|
||||
} else {
|
||||
goto fail;
|
||||
}
|
||||
@@ -523,6 +532,7 @@ USBDevice *usb_tablet_init(void)
|
||||
s->dev.handle_data = usb_mouse_handle_data;
|
||||
s->dev.handle_destroy = usb_mouse_handle_destroy;
|
||||
s->kind = USB_TABLET;
|
||||
s->status_changed = 0;
|
||||
|
||||
pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Tablet");
|
||||
|
||||
@@ -544,6 +554,7 @@ USBDevice *usb_mouse_init(void)
|
||||
s->dev.handle_data = usb_mouse_handle_data;
|
||||
s->dev.handle_destroy = usb_mouse_handle_destroy;
|
||||
s->kind = USB_MOUSE;
|
||||
s->status_changed = 0;
|
||||
|
||||
pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Mouse");
|
||||
|
||||
|
||||
+24
-12
@@ -424,12 +424,10 @@ static int uhci_handle_td(UHCIState *s, UHCI_TD *td, int *int_mask)
|
||||
uint8_t buf[2048];
|
||||
int len, max_len, err, ret;
|
||||
|
||||
if (td->ctrl & TD_CTRL_IOC) {
|
||||
*int_mask |= 0x01;
|
||||
if (!(td->ctrl & TD_CTRL_ACTIVE)){
|
||||
ret = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!(td->ctrl & TD_CTRL_ACTIVE))
|
||||
return 1;
|
||||
|
||||
/* TD is active */
|
||||
max_len = ((td->token >> 21) + 1) & 0x7ff;
|
||||
@@ -467,7 +465,8 @@ static int uhci_handle_td(UHCIState *s, UHCI_TD *td, int *int_mask)
|
||||
/* invalid pid : frame interrupted */
|
||||
s->status |= UHCI_STS_HCPERR;
|
||||
uhci_update_irq(s);
|
||||
return -1;
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
if (td->ctrl & TD_CTRL_IOS)
|
||||
td->ctrl &= ~TD_CTRL_ACTIVE;
|
||||
@@ -479,10 +478,12 @@ static int uhci_handle_td(UHCIState *s, UHCI_TD *td, int *int_mask)
|
||||
len < max_len) {
|
||||
*int_mask |= 0x02;
|
||||
/* short packet: do not update QH */
|
||||
return 1;
|
||||
ret = 1;
|
||||
goto out;
|
||||
} else {
|
||||
/* success */
|
||||
return 0;
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
switch(ret) {
|
||||
@@ -501,23 +502,34 @@ static int uhci_handle_td(UHCIState *s, UHCI_TD *td, int *int_mask)
|
||||
}
|
||||
td->ctrl = (td->ctrl & ~(3 << TD_CTRL_ERROR_SHIFT)) |
|
||||
(err << TD_CTRL_ERROR_SHIFT);
|
||||
return 1;
|
||||
ret = 1;
|
||||
goto out;
|
||||
case USB_RET_NAK:
|
||||
td->ctrl |= TD_CTRL_NAK;
|
||||
if (pid == USB_TOKEN_SETUP)
|
||||
goto do_timeout;
|
||||
return 1;
|
||||
ret = 1;
|
||||
goto out;
|
||||
case USB_RET_STALL:
|
||||
td->ctrl |= TD_CTRL_STALL;
|
||||
td->ctrl &= ~TD_CTRL_ACTIVE;
|
||||
return 1;
|
||||
ret = 1;
|
||||
goto out;
|
||||
case USB_RET_BABBLE:
|
||||
td->ctrl |= TD_CTRL_BABBLE | TD_CTRL_STALL;
|
||||
td->ctrl &= ~TD_CTRL_ACTIVE;
|
||||
/* frame interrupted */
|
||||
return -1;
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
/* If TD is inactive and IOC bit set to 1 then update int_mask */
|
||||
if ((td->ctrl & TD_CTRL_IOC) && (!(td->ctrl & TD_CTRL_ACTIVE))) {
|
||||
*int_mask |= 0x01;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void uhci_frame_timer(void *opaque)
|
||||
|
||||
@@ -264,7 +264,32 @@ class HttpServerRequest(http.HttpRequest):
|
||||
s += x + "/"
|
||||
self.write(' <a href="%s">%s</a>/' % (s, x))
|
||||
self.write("</h1>")
|
||||
|
||||
|
||||
class HttpServerClient:
|
||||
|
||||
def __init__(self, server, sock, addr):
|
||||
self.server = server
|
||||
self.sock = sock
|
||||
self.addr = addr
|
||||
|
||||
def process(self):
|
||||
thread = threading.Thread(target=self.doProcess)
|
||||
thread.setDaemon(True)
|
||||
thread.start()
|
||||
|
||||
def doProcess(self):
|
||||
try:
|
||||
rp = RequestProcessor(self.server, self.sock, self.addr)
|
||||
rp.process()
|
||||
except SystemExit:
|
||||
raise
|
||||
except Exception, ex:
|
||||
print 'HttpServer>processRequest> exception: ', ex
|
||||
try:
|
||||
self.sock.close()
|
||||
except:
|
||||
pass
|
||||
|
||||
class HttpServer:
|
||||
|
||||
backlog = 5
|
||||
@@ -286,8 +311,8 @@ class HttpServer:
|
||||
|
||||
while not self.closed:
|
||||
(sock, addr) = self.accept()
|
||||
self.processRequest(sock, addr)
|
||||
|
||||
cl = HttpServerClient(self, sock, addr)
|
||||
cl.process()
|
||||
|
||||
def stop(self):
|
||||
self.close()
|
||||
@@ -314,19 +339,6 @@ class HttpServer:
|
||||
except:
|
||||
pass
|
||||
|
||||
def processRequest(self, sock, addr):
|
||||
try:
|
||||
rp = RequestProcessor(self, sock, addr)
|
||||
rp.process()
|
||||
except SystemExit:
|
||||
raise
|
||||
except Exception, ex:
|
||||
print 'HttpServer>processRequest> exception: ', ex
|
||||
try:
|
||||
sock.close()
|
||||
except:
|
||||
pass
|
||||
|
||||
def getServerAddr(self):
|
||||
return (socket.gethostname(), self.port)
|
||||
|
||||
|
||||
@@ -42,6 +42,39 @@ def reverse_dict(adict):
|
||||
def bool0(v):
|
||||
return v != '0' and bool(v)
|
||||
|
||||
# Recursively copy a data struct, scrubbing out VNC passwords.
|
||||
# Will scrub any dict entry with a key of 'vncpasswd' or any
|
||||
# 2-element list whose first member is 'vncpasswd'. It will
|
||||
# also scrub a string matching '(vncpasswd XYZ)'. Everything
|
||||
# else is no-op passthrough
|
||||
def scrub_password(data):
|
||||
if type(data) == dict or type(data) == XendConfig:
|
||||
scrubbed = {}
|
||||
for key in data.keys():
|
||||
if key == "vncpasswd":
|
||||
scrubbed[key] = "XXXXXXXX"
|
||||
else:
|
||||
scrubbed[key] = scrub_password(data[key])
|
||||
return scrubbed
|
||||
elif type(data) == list:
|
||||
if len(data) == 2 and type(data[0]) == str and data[0] == 'vncpasswd':
|
||||
return ['vncpasswd', 'XXXXXXXX']
|
||||
else:
|
||||
scrubbed = []
|
||||
for entry in data:
|
||||
scrubbed.append(scrub_password(entry))
|
||||
return scrubbed
|
||||
elif type(data) == tuple:
|
||||
scrubbed = []
|
||||
for entry in data:
|
||||
scrubbed.append(scrub_password(entry))
|
||||
return tuple(scrubbed)
|
||||
elif type(data) == str:
|
||||
return re.sub(r'\(vncpasswd\s+[^\)]+\)','(vncpasswd XXXXXX)', data)
|
||||
else:
|
||||
return data
|
||||
|
||||
|
||||
# Mapping from XendConfig configuration keys to the old
|
||||
# legacy configuration keys that map directly.
|
||||
|
||||
@@ -269,7 +302,7 @@ class XendConfig(dict):
|
||||
# output from xc.domain_getinfo
|
||||
self._dominfo_to_xapi(dominfo)
|
||||
|
||||
log.debug('XendConfig.init: %s' % self)
|
||||
log.debug('XendConfig.init: %s' % scrub_password(self))
|
||||
|
||||
# validators go here
|
||||
self.validate()
|
||||
@@ -478,7 +511,7 @@ class XendConfig(dict):
|
||||
else:
|
||||
for opt, val in config[1:]:
|
||||
dev_info[opt] = val
|
||||
log.debug("XendConfig: reading device: %s" % dev_info)
|
||||
log.debug("XendConfig: reading device: %s" % scrub_password(dev_info))
|
||||
# create uuid if it doesn't
|
||||
dev_uuid = dev_info.get('uuid', uuid.createString())
|
||||
dev_info['uuid'] = dev_uuid
|
||||
|
||||
@@ -40,6 +40,7 @@ from xen.util import security
|
||||
from xen.xend import balloon, sxp, uuid, image, arch
|
||||
from xen.xend import XendRoot, XendNode, XendConfig
|
||||
|
||||
from xen.xend.XendConfig import scrub_password
|
||||
from xen.xend.XendBootloader import bootloader
|
||||
from xen.xend.XendError import XendError, VmError
|
||||
from xen.xend.XendDevices import XendDevices
|
||||
@@ -148,7 +149,7 @@ def create(config):
|
||||
@raise VmError: Invalid configuration or failure to start.
|
||||
"""
|
||||
|
||||
log.debug("XendDomainInfo.create(%s)", config)
|
||||
log.debug("XendDomainInfo.create(%s)", scrub_password(config))
|
||||
vm = XendDomainInfo(XendConfig.XendConfig(sxp_obj = config))
|
||||
try:
|
||||
vm.start()
|
||||
@@ -175,7 +176,7 @@ def recreate(info, priv):
|
||||
@raise XendError: Errors with configuration.
|
||||
"""
|
||||
|
||||
log.debug("XendDomainInfo.recreate(%s)", info)
|
||||
log.debug("XendDomainInfo.recreate(%s)", scrub_password(info))
|
||||
|
||||
assert not info['dying']
|
||||
|
||||
@@ -257,7 +258,7 @@ def restore(config):
|
||||
@raise XendError: Errors with configuration.
|
||||
"""
|
||||
|
||||
log.debug("XendDomainInfo.restore(%s)", config)
|
||||
log.debug("XendDomainInfo.restore(%s)", scrub_password(config))
|
||||
vm = XendDomainInfo(XendConfig.XendConfig(sxp_obj = config),
|
||||
resume = True)
|
||||
try:
|
||||
@@ -280,7 +281,7 @@ def createDormant(domconfig):
|
||||
@raise XendError: Errors with configuration.
|
||||
"""
|
||||
|
||||
log.debug("XendDomainInfo.createDormant(%s)", domconfig)
|
||||
log.debug("XendDomainInfo.createDormant(%s)", scrub_password(domconfig))
|
||||
|
||||
# domid does not make sense for non-running domains.
|
||||
domconfig.pop('domid', None)
|
||||
@@ -520,11 +521,11 @@ class XendDomainInfo:
|
||||
@param dev_config: device configuration
|
||||
@type dev_config: SXP object (parsed config)
|
||||
"""
|
||||
log.debug("XendDomainInfo.device_create: %s" % dev_config)
|
||||
log.debug("XendDomainInfo.device_create: %s" % scrub_password(dev_config))
|
||||
dev_type = sxp.name(dev_config)
|
||||
dev_uuid = self.info.device_add(dev_type, cfg_sxp = dev_config)
|
||||
dev_config_dict = self.info['devices'][dev_uuid][1]
|
||||
log.debug("XendDomainInfo.device_create: %s" % dev_config_dict)
|
||||
log.debug("XendDomainInfo.device_create: %s" % scrub_password(dev_config_dict))
|
||||
devid = self._createDevice(dev_type, dev_config_dict)
|
||||
self._waitForDevice(dev_type, devid)
|
||||
return self.getDeviceController(dev_type).sxpr(devid)
|
||||
@@ -746,7 +747,7 @@ class XendDomainInfo:
|
||||
|
||||
to_store.update(self._vcpuDomDetails())
|
||||
|
||||
log.debug("Storing domain details: %s", to_store)
|
||||
log.debug("Storing domain details: %s", scrub_password(to_store))
|
||||
|
||||
self._writeDom(to_store)
|
||||
|
||||
@@ -1188,7 +1189,7 @@ class XendDomainInfo:
|
||||
"""
|
||||
for (devclass, config) in self.info.get('devices', {}).values():
|
||||
if devclass in XendDevices.valid_devices():
|
||||
log.info("createDevice: %s : %s" % (devclass, config))
|
||||
log.info("createDevice: %s : %s" % (devclass, scrub_password(config)))
|
||||
self._createDevice(devclass, config)
|
||||
|
||||
if self.image:
|
||||
@@ -1667,7 +1668,7 @@ class XendDomainInfo:
|
||||
if not self._readVm('xend/restart_count'):
|
||||
to_store['xend/restart_count'] = str(0)
|
||||
|
||||
log.debug("Storing VM details: %s", to_store)
|
||||
log.debug("Storing VM details: %s", scrub_password(to_store))
|
||||
|
||||
self._writeVm(to_store)
|
||||
self._setVmPermissions()
|
||||
|
||||
@@ -21,6 +21,7 @@ from xen.web import http
|
||||
from xen.xend import sxp
|
||||
from xen.xend import XendDomain
|
||||
from xen.xend.Args import FormFn
|
||||
from xen.xend.XendLogging import log
|
||||
|
||||
from xen.web.SrvDir import SrvDir
|
||||
|
||||
@@ -63,6 +64,18 @@ class SrvDomain(SrvDir):
|
||||
self.acceptCommand(req)
|
||||
return self.dom.shutdown(req.args['reason'][0])
|
||||
|
||||
def op_delete(self, _, req):
|
||||
self.acceptCommand(req)
|
||||
return self.xd.domain_delete(self.dom.getName())
|
||||
|
||||
def op_start(self, _, req):
|
||||
self.acceptCommand(req)
|
||||
paused = False
|
||||
if 'paused' in req.args and req.args['paused'] == [1]:
|
||||
paused = True
|
||||
log.debug("Starting domain " + self.dom.getName() + " " + str(paused))
|
||||
return self.xd.domain_start(self.dom.getName(), paused)
|
||||
|
||||
def op_sysrq(self, _, req):
|
||||
self.acceptCommand(req)
|
||||
return self.dom.send_sysrq(int(req.args['key'][0]))
|
||||
|
||||
@@ -25,6 +25,8 @@ from xen.xend import XendDomain
|
||||
from xen.xend.XendDomainInfo import XendDomainInfo
|
||||
from xen.xend.Args import FormFn
|
||||
from xen.xend.XendError import XendError
|
||||
from xen.xend.XendLogging import log
|
||||
from xen.xend.XendConstants import DOM_STATE_RUNNING
|
||||
|
||||
from xen.web.SrvDir import SrvDir
|
||||
from SrvDomain import SrvDomain
|
||||
@@ -101,6 +103,35 @@ class SrvDomainDir(SrvDir):
|
||||
out.close()
|
||||
return val
|
||||
|
||||
def op_new(self, _, req):
|
||||
"""Define a new domain.
|
||||
Expects the domain config in request parameter 'config' in SXP format.
|
||||
"""
|
||||
ok = 0
|
||||
errmsg = ''
|
||||
try:
|
||||
configstring = req.args.get('config')[0]
|
||||
#print 'op_create>', 'config:', configstring
|
||||
pin = sxp.Parser()
|
||||
pin.input(configstring)
|
||||
pin.input_eof()
|
||||
config = pin.get_val()
|
||||
ok = 1
|
||||
except sxp.ParseError, ex:
|
||||
errmsg = 'Invalid configuration ' + str(ex)
|
||||
except Exception, ex:
|
||||
print 'op_create> Exception in config', ex
|
||||
traceback.print_exc()
|
||||
errmsg = 'Configuration error ' + str(ex)
|
||||
if not ok:
|
||||
raise XendError(errmsg)
|
||||
try:
|
||||
self.xd.domain_new(config)
|
||||
except Exception, ex:
|
||||
print 'op_create> Exception creating domain:'
|
||||
traceback.print_exc()
|
||||
raise XendError("Error creating domain: " + str(ex))
|
||||
|
||||
def op_restore(self, op, req):
|
||||
"""Restore a domain from file.
|
||||
|
||||
@@ -159,7 +190,11 @@ class SrvDomainDir(SrvDir):
|
||||
if detail:
|
||||
sxp.show(map(XendDomainInfo.sxpr, self.xd.list()), out=req)
|
||||
else:
|
||||
sxp.show(self.xd.list_names(), out=req)
|
||||
state = DOM_STATE_RUNNING
|
||||
if 'state' in req.args and len(req.args['state']) > 0:
|
||||
state = req.args['state'][0]
|
||||
log.debug("Listing domains in state " + str(state))
|
||||
sxp.show(self.xd.list_names(state), out=req)
|
||||
else:
|
||||
domains = self.xd.list_sorted()
|
||||
req.write('<ul>')
|
||||
|
||||
@@ -704,8 +704,10 @@ def configure_hvm(config_image, vals):
|
||||
config_image.append(['vncpasswd', vals.vncpasswd])
|
||||
|
||||
def run_bootloader(vals, config_image):
|
||||
if not os.access(vals.bootloader, os.F_OK):
|
||||
err("Bootloader '%s' does not exist" % vals.bootloader)
|
||||
if not os.access(vals.bootloader, os.X_OK):
|
||||
err("Bootloader isn't executable")
|
||||
err("Bootloader '%s' isn't executable" % vals.bootloader)
|
||||
if len(vals.disk) < 1:
|
||||
err("No disks configured and boot loader requested")
|
||||
(uname, dev, mode, backend) = vals.disk[0]
|
||||
|
||||
@@ -30,6 +30,7 @@ import socket
|
||||
import traceback
|
||||
import xmlrpclib
|
||||
import traceback
|
||||
import time
|
||||
import datetime
|
||||
from select import select
|
||||
import xml.dom.minidom
|
||||
@@ -626,7 +627,13 @@ def parse_doms_info(info):
|
||||
|
||||
def get_status(n, t, d):
|
||||
return DOM_STATES[t(sxp.child_value(info, n, d))]
|
||||
|
||||
|
||||
start_time = get_info('start_time', float, -1)
|
||||
if start_time == -1:
|
||||
up_time = float(-1)
|
||||
else:
|
||||
up_time = time.time() - start_time
|
||||
|
||||
return {
|
||||
'domid' : get_info('domid', str, ''),
|
||||
'name' : get_info('name', str, '??'),
|
||||
@@ -634,7 +641,7 @@ def parse_doms_info(info):
|
||||
'vcpus' : get_info('vcpus', int, 0),
|
||||
'state' : get_info('state', str, ''),
|
||||
'cpu_time' : get_info('cpu_time', float, 0),
|
||||
'up_time' : get_info('up_time', float, -1),
|
||||
'up_time' : up_time,
|
||||
'seclabel' : security.get_security_printlabel(info),
|
||||
}
|
||||
|
||||
@@ -1209,7 +1216,7 @@ def xm_uptime(args):
|
||||
|
||||
for dom in doms:
|
||||
d = parse_doms_info(dom)
|
||||
if d['domid'] > 0:
|
||||
if int(d['domid']) > 0:
|
||||
uptime = int(round(d['up_time']))
|
||||
else:
|
||||
f=open('/proc/uptime', 'r')
|
||||
@@ -1236,10 +1243,10 @@ def xm_uptime(args):
|
||||
if short_mode:
|
||||
now = datetime.datetime.now()
|
||||
upstring = now.strftime(" %H:%M:%S") + " up " + upstring
|
||||
upstring += ", " + d['name'] + " (" + str(d['domid']) + ")"
|
||||
upstring += ", " + d['name'] + " (" + d['domid'] + ")"
|
||||
else:
|
||||
upstring += ':%(seconds)02d' % vars()
|
||||
upstring = ("%(name)-32s %(domid)3d " % d) + upstring
|
||||
upstring = ("%(name)-32s %(domid)3s " % d) + upstring
|
||||
|
||||
print upstring
|
||||
|
||||
|
||||