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_UPDATE', 

27 'VDI_CREATE', 

28 'VDI_DELETE', 

29 'VDI_ATTACH', 

30 'VDI_DETACH', 

31 'VDI_CLONE', 

32 'VDI_SNAPSHOT', 

33 'VDI_RESIZE', 

34 'VDI_MIRROR', 

35 'VDI_GENERATE_CONFIG', 

36 'ATOMIC_PAUSE', 

37 'VDI_CONFIG_CBT', 

38 'VDI_ACTIVATE', 

39 'VDI_DEACTIVATE', 

40 'THIN_PROVISIONING' 

41] 

42 

43CONFIGURATION = [ 

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

45] 

46 

47DRIVER_INFO = { 

48 'name': 'Local ZFS VHD', 

49 'description': 

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

51 'vendor': 'Vates SAS', 

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

53 'driver_version': '1.0', 

54 'required_api_version': '1.0', 

55 'capabilities': CAPABILITIES, 

56 'configuration': CONFIGURATION 

57} 

58 

59 

60def is_zfs_available(): 

61 import distutils.spawn 

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

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

64 

65 

66def is_zfs_path(path): 

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

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

69 return fs_type == 'zfs' 

70 

71 

72class ZFSSR(FileSR.FileSR): 

73 DRIVER_TYPE = 'zfs' 

74 

75 @staticmethod 

76 def handles(type): 

77 return type == ZFSSR.DRIVER_TYPE 

78 

79 def load(self, sr_uuid): 

80 if not is_zfs_available(): 

81 raise xs_errors.XenError( 

82 'SRUnavailable', 

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

84 ) 

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

86 

87 def create(self, sr_uuid, size): 

88 if not is_zfs_path(self.remotepath): 

89 raise xs_errors.XenError( 

90 'ZFSSRCreate', 

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

92 ) 

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

94 

95 def delete(self, sr_uuid): 

96 if not self._checkmount(): 

97 raise xs_errors.XenError( 

98 'ZFSSRDelete', 

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

100 ) 

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

102 

103 def attach(self, sr_uuid): 

104 if not is_zfs_path(self.remotepath): 

105 raise xs_errors.XenError( 

106 'SRUnavailable', 

107 opterr='Invalid ZFS path' 

108 ) 

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

110 

111 def detach(self, sr_uuid): 

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

113 

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

115 return ZFSFileVDI(self, uuid) 

116 

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

118 def _checkmount(self): 

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

120 is_zfs_path(self.remotepath) 

121 

122 

123class ZFSFileVDI(FileSR.FileVDI): 

124 def attach(self, sr_uuid, vdi_uuid): 

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

126 self.xenstore_data = {} 

127 

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

129 

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

131 

132 

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

134 SRCommand.run(ZFSSR, DRIVER_INFO) 

135else: 

136 SR.registerSR(ZFSSR)