1 | from xen.xend.server.DevController import DevController |
---|
2 | from xen.xend.XendLogging import log |
---|
3 | |
---|
4 | from xen.xend.XendError import VmError |
---|
5 | import xen.xend |
---|
6 | import os |
---|
7 | |
---|
8 | def spawn_detached(path, args, env): |
---|
9 | p = os.fork() |
---|
10 | if p == 0: |
---|
11 | os.spawnve(os.P_NOWAIT, path, args, env) |
---|
12 | os._exit(0) |
---|
13 | else: |
---|
14 | os.waitpid(p, 0) |
---|
15 | |
---|
16 | CONFIG_ENTRIES = ['type', 'vncdisplay', 'vnclisten', 'vncpasswd', 'vncunused', |
---|
17 | 'display', 'xauthority', 'keymap', |
---|
18 | 'uuid', 'location', 'protocol'] |
---|
19 | |
---|
20 | class VfbifController(DevController): |
---|
21 | """Virtual frame buffer controller. Handles all vfb devices for a domain. |
---|
22 | Note that we only support a single vfb per domain at the moment. |
---|
23 | """ |
---|
24 | |
---|
25 | def __init__(self, vm): |
---|
26 | DevController.__init__(self, vm) |
---|
27 | |
---|
28 | def getDeviceDetails(self, config): |
---|
29 | """@see DevController.getDeviceDetails""" |
---|
30 | |
---|
31 | back = dict([(k, str(config[k])) for k in CONFIG_ENTRIES |
---|
32 | if config.has_key(k)]) |
---|
33 | |
---|
34 | devid = 0 |
---|
35 | return (devid, back, {}) |
---|
36 | |
---|
37 | |
---|
38 | def getDeviceConfiguration(self, devid): |
---|
39 | result = DevController.getDeviceConfiguration(self, devid) |
---|
40 | |
---|
41 | devinfo = self.readBackend(devid, *CONFIG_ENTRIES) |
---|
42 | return dict([(CONFIG_ENTRIES[i], devinfo[i]) |
---|
43 | for i in range(len(CONFIG_ENTRIES)) |
---|
44 | if devinfo[i] is not None]) |
---|
45 | |
---|
46 | |
---|
47 | def createDevice(self, config): |
---|
48 | DevController.createDevice(self, config) |
---|
49 | if self.vm.info.is_hvm(): |
---|
50 | # is HVM, so qemu-dm will handle the vfb. |
---|
51 | return |
---|
52 | |
---|
53 | std_args = [ "--domid", "%d" % self.vm.getDomid(), |
---|
54 | "--title", self.vm.getName() ] |
---|
55 | t = config.get("type", None) |
---|
56 | if t == "vnc": |
---|
57 | passwd = None |
---|
58 | if config.has_key("vncpasswd"): |
---|
59 | passwd = config["vncpasswd"] |
---|
60 | else: |
---|
61 | passwd = xen.xend.XendOptions.instance().get_vncpasswd_default() |
---|
62 | if passwd: |
---|
63 | self.vm.storeVm("vncpasswd", passwd) |
---|
64 | log.debug("Stored a VNC password for vfb access") |
---|
65 | else: |
---|
66 | log.debug("No VNC passwd configured for vfb access") |
---|
67 | |
---|
68 | # Try to start the vnc backend |
---|
69 | args = [xen.util.auxbin.pathTo("xen-vncfb")] |
---|
70 | if config.has_key("vncunused"): |
---|
71 | args += ["--unused"] |
---|
72 | elif config.has_key("vncdisplay"): |
---|
73 | args += ["--vncport", "%d" % (5900 + int(config["vncdisplay"]))] |
---|
74 | vnclisten = config.get("vnclisten", |
---|
75 | xen.xend.XendOptions.instance().get_vnclisten_address()) |
---|
76 | args += [ "--listen", vnclisten ] |
---|
77 | if config.has_key("keymap"): |
---|
78 | args += ["-k", "%s" % config["keymap"]] |
---|
79 | spawn_detached(args[0], args + std_args, os.environ) |
---|
80 | elif t == "sdl": |
---|
81 | args = [xen.util.auxbin.pathTo("xen-sdlfb")] |
---|
82 | env = dict(os.environ) |
---|
83 | if config.has_key("display"): |
---|
84 | env['DISPLAY'] = config["display"] |
---|
85 | if config.has_key("xauthority"): |
---|
86 | env['XAUTHORITY'] = config["xauthority"] |
---|
87 | spawn_detached(args[0], args + std_args, env) |
---|
88 | else: |
---|
89 | raise VmError('Unknown vfb type %s (%s)' % (t, repr(config))) |
---|
90 | |
---|
91 | |
---|
92 | def waitForDevice(self, devid): |
---|
93 | if self.vm.info.get('HVM_boot_policy'): |
---|
94 | log.debug('skip waiting for HVM vfb') |
---|
95 | # is a qemu-dm managed device, don't wait for hotplug for these. |
---|
96 | return |
---|
97 | |
---|
98 | DevController.waitForDevice(self, devid) |
---|
99 | |
---|
100 | |
---|
101 | def reconfigureDevice(self, _, config): |
---|
102 | """ Only allow appending location information of vnc port into |
---|
103 | xenstore.""" |
---|
104 | |
---|
105 | if 'location' in config: |
---|
106 | (devid, back, front) = self.getDeviceDetails(config) |
---|
107 | self.writeBackend(devid, 'location', config['location']) |
---|
108 | return back.get('uuid') |
---|
109 | |
---|
110 | raise VmError('Refusing to reconfigure device vfb:%d' % devid) |
---|
111 | |
---|
112 | def destroyDevice(self, devid, force): |
---|
113 | if self.vm.info.get('HVM_boot_policy'): |
---|
114 | # remove the backend xenstore entries for HVM guests no matter |
---|
115 | # what |
---|
116 | DevController.destroyDevice(self, devid, True) |
---|
117 | else: |
---|
118 | DevController.destroyDevice(self, devid, force) |
---|
119 | |
---|
120 | |
---|
121 | def migrate(self, deviceConfig, network, dst, step, domName): |
---|
122 | if self.vm.info.get('HVM_boot_policy'): |
---|
123 | return 0 |
---|
124 | return DevController.migrate(self, deviceConfig, network, dst, step, |
---|
125 | domName) |
---|
126 | |
---|
127 | class VkbdifController(DevController): |
---|
128 | """Virtual keyboard controller. Handles all vkbd devices for a domain. |
---|
129 | """ |
---|
130 | |
---|
131 | def getDeviceDetails(self, config): |
---|
132 | """@see DevController.getDeviceDetails""" |
---|
133 | devid = 0 |
---|
134 | back = {} |
---|
135 | front = {} |
---|
136 | return (devid, back, front) |
---|
137 | |
---|
138 | def waitForDevice(self, config): |
---|
139 | if self.vm.info.get('HVM_boot_policy'): |
---|
140 | # is a qemu-dm managed device, don't wait for hotplug for these. |
---|
141 | return |
---|
142 | |
---|
143 | DevController.waitForDevice(self, config) |
---|
144 | |
---|
145 | def destroyDevice(self, devid, force): |
---|
146 | if self.vm.info.get('HVM_boot_policy'): |
---|
147 | # remove the backend xenstore entries for HVM guests no matter |
---|
148 | # what |
---|
149 | DevController.destroyDevice(self, devid, True) |
---|
150 | else: |
---|
151 | DevController.destroyDevice(self, devid, force) |
---|
152 | |
---|
153 | def migrate(self, deviceConfig, network, dst, step, domName): |
---|
154 | if self.vm.info.get('HVM_boot_policy'): |
---|
155 | return 0 |
---|
156 | return DevController.migrate(self, deviceConfig, network, dst, step, |
---|
157 | domName) |
---|