1 | #============================================================================ |
---|
2 | # This library is free software; you can redistribute it and/or |
---|
3 | # modify it under the terms of version 2.1 of the GNU Lesser General Public |
---|
4 | # License as published by the Free Software Foundation. |
---|
5 | # |
---|
6 | # This library is distributed in the hope that it will be useful, |
---|
7 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
8 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
---|
9 | # Lesser General Public License for more details. |
---|
10 | # |
---|
11 | # You should have received a copy of the GNU Lesser General Public |
---|
12 | # License along with this library; if not, write to the Free Software |
---|
13 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
---|
14 | #============================================================================ |
---|
15 | # Copyright (C) 2004 Mike Wray <mike.wray@hp.com> |
---|
16 | # Copyright (C) 2005 IBM Corporation |
---|
17 | # Author: Stefan Berger, stefanb@us.ibm.com |
---|
18 | # Copyright (C) 2005 XenSource Ltd |
---|
19 | #============================================================================ |
---|
20 | |
---|
21 | """Support for virtual TPM interfaces.""" |
---|
22 | |
---|
23 | from xen.xend import XendOptions |
---|
24 | from xen.xend.XendLogging import log |
---|
25 | from xen.xend.XendError import XendError |
---|
26 | from xen.xend.XendConstants import DEV_MIGRATE_TEST, VTPM_DELETE_SCRIPT |
---|
27 | from xen.xend.server.DevController import DevController |
---|
28 | |
---|
29 | import os |
---|
30 | import re |
---|
31 | |
---|
32 | xoptions = XendOptions.instance() |
---|
33 | |
---|
34 | def destroy_vtpmstate(name): |
---|
35 | if os.path.exists(VTPM_DELETE_SCRIPT): |
---|
36 | os.system(VTPM_DELETE_SCRIPT + " " + name) |
---|
37 | |
---|
38 | class TPMifController(DevController): |
---|
39 | """TPM interface controller. Handles all TPM devices for a domain. |
---|
40 | """ |
---|
41 | |
---|
42 | def __init__(self, vm): |
---|
43 | DevController.__init__(self, vm) |
---|
44 | |
---|
45 | |
---|
46 | def getDeviceDetails(self, config): |
---|
47 | """@see DevController.getDeviceDetails""" |
---|
48 | |
---|
49 | devid = self.allocateDeviceID() |
---|
50 | inst = int(config.get('pref_instance', -1)) |
---|
51 | if inst == -1: |
---|
52 | inst = int(config.get('instance', 0)) |
---|
53 | |
---|
54 | typ = config.get('type') |
---|
55 | uuid = config.get('uuid') |
---|
56 | |
---|
57 | log.info("The domain has a TPM with pref. instance %d and devid %d.", |
---|
58 | inst, devid) |
---|
59 | back = { 'pref_instance' : "%i" % inst, |
---|
60 | 'resume' : "%s" % (self.vm.getResume()) } |
---|
61 | if typ: |
---|
62 | back['type'] = typ |
---|
63 | if uuid: |
---|
64 | back['uuid'] = uuid |
---|
65 | |
---|
66 | front = { 'handle' : "%i" % devid } |
---|
67 | |
---|
68 | return (devid, back, front) |
---|
69 | |
---|
70 | def getDeviceConfiguration(self, devid): |
---|
71 | """Returns the configuration of a device""" |
---|
72 | result = DevController.getDeviceConfiguration(self, devid) |
---|
73 | |
---|
74 | (instance, uuid, type) = \ |
---|
75 | self.readBackend(devid, 'instance', |
---|
76 | 'uuid', |
---|
77 | 'type') |
---|
78 | |
---|
79 | if instance: |
---|
80 | result['instance'] = instance |
---|
81 | if uuid: |
---|
82 | result['uuid'] = uuid |
---|
83 | if type: |
---|
84 | result['type'] = type |
---|
85 | |
---|
86 | return result |
---|
87 | |
---|
88 | def migrate(self, deviceConfig, network, dst, step, domName): |
---|
89 | """@see DevContoller.migrate""" |
---|
90 | if network: |
---|
91 | tool = xoptions.get_external_migration_tool() |
---|
92 | if tool != '': |
---|
93 | log.info("Request to network-migrate device to %s. step=%d.", |
---|
94 | dst, step) |
---|
95 | |
---|
96 | if step == DEV_MIGRATE_TEST: |
---|
97 | """Assuming for now that everything is ok and migration |
---|
98 | with the given tool can proceed. |
---|
99 | """ |
---|
100 | return 0 |
---|
101 | else: |
---|
102 | fd = os.popen("%s -type vtpm -step %d -host %s -domname %s" % |
---|
103 | (tool, step, dst, domName), |
---|
104 | 'r') |
---|
105 | for line in fd.readlines(): |
---|
106 | mo = re.search('Error', line) |
---|
107 | if mo: |
---|
108 | raise XendError("vtpm: Fatal error in migration step %d: %s" % |
---|
109 | (step, line)) |
---|
110 | return 0 |
---|
111 | else: |
---|
112 | log.debug("External migration tool not in configuration.") |
---|
113 | return -1 |
---|
114 | return 0 |
---|
115 | |
---|
116 | def recover_migrate(self, deviceConfig, network, dst, step, domName): |
---|
117 | """@see DevContoller.recover_migrate""" |
---|
118 | if network: |
---|
119 | tool = xoptions.get_external_migration_tool() |
---|
120 | if tool != '': |
---|
121 | log.info("Request to recover network-migrated device. last good step=%d.", |
---|
122 | step) |
---|
123 | fd = os.popen("%s -type vtpm -step %d -host %s -domname %s -recover" % |
---|
124 | (tool, step, dst, domName), |
---|
125 | 'r') |
---|
126 | return 0 |
---|