Hide keyboard shortcuts

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#!/usr/bin/env python3 

2# 

3# Copyright (C) 2020 Vates SAS 

4# 

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

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

7# the Free Software Foundation, either version 3 of the License, or 

8# (at your option) any later version. 

9# This program is distributed in the hope that it will be useful, 

10# but WITHOUT ANY WARRANTY; without even the implied warranty of 

11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

12# GNU General Public License for more details. 

13# 

14# You should have received a copy of the GNU General Public License 

15# along with this program. If not, see <https://www.gnu.org/licenses/>. 

16 

17import SR 

18import SRCommand 

19 

20import FileSR 

21 

22import util 

23import xs_errors 

24 

25CAPABILITIES = [ 

26 'SR_PROBE', 

27 'SR_UPDATE', 

28 'VDI_CREATE', 

29 'VDI_DELETE', 

30 'VDI_ATTACH', 

31 'VDI_DETACH', 

32 'VDI_CLONE', 

33 'VDI_SNAPSHOT', 

34 'VDI_RESIZE', 

35 'VDI_MIRROR', 

36 'VDI_GENERATE_CONFIG', 

37 'ATOMIC_PAUSE', 

38 'VDI_CONFIG_CBT', 

39 'VDI_ACTIVATE', 

40 'VDI_DEACTIVATE', 

41 'THIN_PROVISIONING' 

42] 

43 

44CONFIGURATION = [ 

45 ['location', 'local ZFS directory path (required)'] 

46] 

47 

48DRIVER_INFO = { 

49 'name': 'Local ZFS VHD', 

50 'description': 

51 'SR plugin which represents disks as VHD files stored on a ZFS disk', 

52 'vendor': 'Vates SAS', 

53 'copyright': '(C) 2020 Vates SAS', 

54 'driver_version': '1.0', 

55 'required_api_version': '1.0', 

56 'capabilities': CAPABILITIES, 

57 'configuration': CONFIGURATION 

58} 

59 

60 

61def is_zfs_available(): 

62 import distutils.spawn 

63 return distutils.spawn.find_executable('zfs') and \ 

64 util.pathexists('/sys/module/zfs/initstate') 

65 

66 

67def is_zfs_path(path): 

68 cmd = ['findmnt', '-o', 'FSTYPE', '-n', path] 

69 fs_type = util.pread2(cmd).split('\n')[0] 

70 return fs_type == 'zfs' 

71 

72 

73class ZFSSR(FileSR.FileSR): 

74 DRIVER_TYPE = 'zfs' 

75 

76 @staticmethod 

77 def handles(type): 

78 return type == ZFSSR.DRIVER_TYPE 

79 

80 def load(self, sr_uuid): 

81 if not is_zfs_available(): 

82 raise xs_errors.XenError( 

83 'SRUnavailable', 

84 opterr='zfs is not installed or module is not loaded' 

85 ) 

86 return super(ZFSSR, self).load(sr_uuid) 

87 

88 def create(self, sr_uuid, size): 

89 if not is_zfs_path(self.remotepath): 

90 raise xs_errors.XenError( 

91 'ZFSSRCreate', 

92 opterr='Cannot create SR, path is not a ZFS mountpoint' 

93 ) 

94 return super(ZFSSR, self).create(sr_uuid, size) 

95 

96 def delete(self, sr_uuid): 

97 if not self._checkmount(): 

98 raise xs_errors.XenError( 

99 'ZFSSRDelete', 

100 opterr='ZFS SR is not mounted or uses an invalid FS type' 

101 ) 

102 return super(ZFSSR, self).delete(sr_uuid) 

103 

104 def attach(self, sr_uuid): 

105 if not is_zfs_path(self.remotepath): 

106 raise xs_errors.XenError( 

107 'SRUnavailable', 

108 opterr='Invalid ZFS path' 

109 ) 

110 return super(ZFSSR, self).attach(sr_uuid) 

111 

112 def detach(self, sr_uuid): 

113 return super(ZFSSR, self).detach(sr_uuid) 

114 

115 def vdi(self, uuid, loadLocked=False): 

116 return ZFSFileVDI(self, uuid) 

117 

118 # Ensure _checkmount is overridden to prevent bad behaviors in FileSR. 

119 def _checkmount(self): 

120 return super(ZFSSR, self)._checkmount() and \ 

121 is_zfs_path(self.remotepath) 

122 

123 

124class ZFSFileVDI(FileSR.FileVDI): 

125 def attach(self, sr_uuid, vdi_uuid): 

126 if not hasattr(self, 'xenstore_data'): 

127 self.xenstore_data = {} 

128 

129 self.xenstore_data['storage-type'] = ZFSSR.DRIVER_TYPE 

130 

131 return super(ZFSFileVDI, self).attach(sr_uuid, vdi_uuid) 

132 

133 

134if __name__ == '__main__': 134 ↛ 135line 134 didn't jump to line 135, because the condition on line 134 was never true

135 SRCommand.run(ZFSSR, DRIVER_INFO) 

136else: 

137 SR.registerSR(ZFSSR)