aboutsummaryrefslogtreecommitdiffstats
path: root/tools/python/xen/xend/server/tpmif.py
blob: 23a10e9483c41b8844898a0a8b41dbd02fd06ffc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#============================================================================
# This library is free software; you can redistribute it and/or
# modify it under the terms of version 2.1 of the GNU Lesser General Public
# License as published by the Free Software Foundation.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#============================================================================
# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
# Copyright (C) 2005 IBM Corporation
#   Author: Stefan Berger, stefanb@us.ibm.com
# Copyright (C) 2005 XenSource Ltd
#============================================================================

"""Support for virtual TPM interfaces."""

from xen.xend import XendOptions
from xen.xend.XendLogging import log
from xen.xend.XendError import XendError
from xen.xend.XendConstants import DEV_MIGRATE_TEST, VTPM_DELETE_SCRIPT
from xen.xend.server.DevController import DevController

import os
import re

xoptions = XendOptions.instance()

def destroy_vtpmstate(uuids):
    if os.path.exists(VTPM_DELETE_SCRIPT):
        for uuid in uuids:
            os.system(VTPM_DELETE_SCRIPT + " " + uuid)

class TPMifController(DevController):
    """TPM interface controller. Handles all TPM devices for a domain.
    """

    def __init__(self, vm):
        DevController.__init__(self, vm)


    def getDeviceDetails(self, config):
        """@see DevController.getDeviceDetails"""

        devid = self.allocateDeviceID()
        inst = int(config.get('pref_instance', -1))
        if inst == -1:
            inst = int(config.get('instance', 0))

        typ    = config.get('type')
        uuid   = config.get('uuid')

        log.info("The domain has a TPM with pref. instance %d and devid %d.",
                 inst, devid)
        back  = { 'pref_instance' : "%i" % inst,
                  'resume'        : "%s" % (self.vm.getResume()) }
        if typ:
            back['type'] = typ
        if uuid:
            back['uuid'] = uuid

            data = self.vm.info['devices'].get(uuid)
            if data:
                other = data[1].get('other_config')
                if type(other) == dict:
                    for key, item in other.items():
                        back['oc_' + key] = item

        front = { 'handle' : "%i" % devid }

        return (devid, back, front)

    def getDeviceConfiguration(self, devid, transaction = None):
        """Returns the configuration of a device"""
        result = DevController.getDeviceConfiguration(self, devid, transaction)

        (instance, uuid, type) = \
                           self.readBackend(devid, 'instance',
                                                   'uuid',
                                                   'type')

        if instance:
            result['instance'] = instance
        if uuid:
            result['uuid'] = uuid
        if type:
            result['type'] = type

        if uuid:
            data = self.vm.info['devices'].get(uuid)
            if data:
                other = data[1].get('other_config')
                if other:
                    result['other_config'] = other

        return result

    def migrate(self, deviceConfig, network, dst, step, domName):
        """@see DevContoller.migrate"""
        if network:
            tool = xoptions.get_external_migration_tool()
            if tool != '':
                log.info("Request to network-migrate device to %s. step=%d.",
                         dst, step)

                if step == DEV_MIGRATE_TEST:
                    """Assuming for now that everything is ok and migration
                       with the given tool can proceed.
                    """
                    return 0
                else:
                    fd = os.popen("%s -type vtpm -step %d -host %s -domname %s" %
                                  (tool, step, dst, domName),
                                  'r')
                    for line in fd.readlines():
                        mo = re.search('Error', line)
                        if mo:
                            raise XendError("vtpm: Fatal error in migration step %d: %s" %
                                            (step, line))
                    return 0
            else:
                log.debug("External migration tool not in configuration.")
                return -1
        return 0

    def recover_migrate(self, deviceConfig, network, dst, step, domName):
        """@see DevContoller.recover_migrate"""
        if network:
            tool = xoptions.get_external_migration_tool()
            if tool != '':
                log.info("Request to recover network-migrated device. last good step=%d.",
                         step)
                fd = os.popen("%s -type vtpm -step %d -host %s -domname %s -recover" %
                              (tool, step, dst, domName),
                              'r')
        return 0