Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

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

#!/usr/bin/python 

# 

# Copyright (C) Citrix Systems Inc. 

# 

# This program is free software; you can redistribute it and/or modify  

# it under the terms of the GNU Lesser General Public License as published  

# by the Free Software Foundation; version 2.1 only. 

# 

# This program 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 program; if not, write to the Free Software Foundation, Inc., 

# 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA 

# 

# LUNperVDI: Generic Raw LUN handler, used by HBASR and ISCSISR 

# 

 

import os 

import VDI, util 

import scsiutil 

import xs_errors 

 

MAX_TIMEOUT = 15 

 

class RAWVDI(VDI.VDI): 

    def load(self, vdi_uuid): 

31        if not self.sr.attached: 

            raise xs_errors.XenError('SRUnavailable') 

 

        self.uuid = vdi_uuid 

        self.location = vdi_uuid 

        self.managed = False 

        try: 

            vdi_ref = self.sr.session.xenapi.VDI.get_by_uuid(vdi_uuid) 

            self.managed = self.sr.session.xenapi.VDI.get_managed(vdi_ref) 

            self.sm_config = self.sr.session.xenapi.VDI.get_sm_config(vdi_ref) 

            self.path = self.sr.mpathmodule.path(self.sm_config['SCSIid']) 

        except: 

            pass 

44        if self.sr.cmd == "vdi_introduce": 

            self.managed = True 

 

    def _query(self, path, id): 

        self.uuid = scsiutil.gen_uuid_from_string(scsiutil.getuniqueserial(path)) 

        self.location = self.uuid 

        self.vendor = scsiutil.getmanufacturer(path) 

        self.serial = scsiutil.getserial(path) 

        self.LUNid = id 

        self.size = scsiutil.getsize(path) 

        self.SCSIid = scsiutil.getSCSIid(path) 

        self.path = path 

        sm_config = util.default(self, "sm_config", lambda: {}) 

        sm_config['LUNid'] = str(self.LUNid) 

        sm_config['SCSIid'] = self.SCSIid 

        sm_config['backend-kind'] = 'vbd' 

        self.sm_config = sm_config 

 

    def introduce(self, sr_uuid, vdi_uuid): 

        self.sm_config = self.sr.srcmd.params['vdi_sm_config'] 

        vdi_path = self.sr._getLUNbySMconfig(self.sm_config) 

        self._query(vdi_path, self.sm_config['LUNid']) 

        vdi_uuid = self.uuid 

        self.sr.vdis[vdi_uuid] = self 

 

        try: 

            util._getVDI(self.sr, vdi_uuid) 

            self.sr.vdis[vdi_uuid]._db_update() 

            # For reasons I don't understand, VDI._db_update() doesn't set the 

            # managed flag, so we do that ourselves here. 

            vdi_ref = self.sr.session.xenapi.VDI.get_by_uuid(vdi_uuid) 

            self.sr.session.xenapi.VDI.set_managed(vdi_ref, self.managed) 

        except: 

            self.sr.vdis[vdi_uuid]._db_introduce() 

        return super(RAWVDI, self).get_params() 

 

    def create(self, sr_uuid, vdi_uuid, size): 

        VDIs = util._getVDIs(self.sr) 

        self.sr._loadvdis() 

        smallest = 0 

        for vdi in VDIs: 

            if not vdi['managed'] \ 

                   and long(vdi['virtual_size']) >= long(size) \ 

                   and self.sr.vdis.has_key(vdi['uuid']): 

                if not smallest: 

                    smallest = long(vdi['virtual_size']) 

                    v = vdi 

                elif long(vdi['virtual_size']) < smallest: 

                    smallest = long(vdi['virtual_size']) 

                    v = vdi 

        if smallest > 0: 

            self.managed = True 

            self.sr.session.xenapi.VDI.set_managed(v['vdi_ref'], self.managed) 

            return super(RAWVDI, self.sr.vdis[v['uuid']]).get_params() 

        raise xs_errors.XenError('SRNoSpace') 

 

    def delete(self, sr_uuid, vdi_uuid): 

        try: 

            vdi = util._getVDI(self.sr, vdi_uuid) 

            if not vdi['managed']: 

                return 

            sm_config = vdi['sm_config'] 

            self.sr.session.xenapi.VDI.set_managed(vdi['vdi_ref'], False) 

        except: 

            pass 

 

    def attach(self, sr_uuid, vdi_uuid): 

        self.sr._loadvdis() 

        if not self.sr.vdis.has_key(vdi_uuid): 

            raise xs_errors.XenError('VDIUnavailable') 

        if not util.pathexists(self.path): 

            self.sr.refresh() 

            if self.sm_config.has_key('SCSIid'): 

                if self.sr.mpath == 'true': 

                    self.sr.mpathmodule.refresh(self.sm_config['SCSIid'], 0) 

                devs = os.listdir("/dev/disk/by-scsid/%s" % self.sm_config['SCSIid']) 

                for dev in devs: 

                    realdev = os.path.realpath("/dev/disk/by-scsid/%s/%s" % (self.sm_config['SCSIid'], dev)) 

                    util.set_scheduler(realdev.split("/")[-1], "noop") 

            if not util.wait_for_path(self.path, MAX_TIMEOUT): 

                util.SMlog("Unable to detect LUN attached to host [%s]" % self.sr.path) 

                raise xs_errors.XenError('VDIUnavailable') 

        return super(RAWVDI, self).attach(sr_uuid, vdi_uuid) 

 

    def detach(self, sr_uuid, vdi_uuid): 

        self.sr._loadvdis() 

        if self.sm_config.has_key('SCSIid'): 

            self.sr.mpathmodule.reset(self.sm_config['SCSIid'], True) # explicitly unmap 

        if not self.sr.vdis.has_key(vdi_uuid): 

            raise xs_errors.XenError('VDIUnavailable') 

 

    def _set_managed(self, vdi_uuid, managed): 

        try: 

            vdi = util._getVDI(self.sr, vdi_uuid) 

            self.sr.session.xenapi.VDI.set_managed(vdi['vdi_ref'], managed) 

        except: 

            raise xs_errors.XenError('VDIUnavailable')