kernels.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. #
  2. # The Qubes OS Project, http://www.qubes-os.org
  3. #
  4. # Copyright (C) 2010-2015 Joanna Rutkowska <joanna@invisiblethingslab.com>
  5. # Copyright (C) 2015 Wojtek Porczyk <woju@invisiblethingslab.com>
  6. # Copyright (C) 2016 Bahtiar `kalkin-` Gadimov <bahtiar@gadimov.de>
  7. #
  8. # This program is free software; you can redistribute it and/or modify
  9. # it under the terms of the GNU General Public License as published by
  10. # the Free Software Foundation; either version 2 of the License, or
  11. # (at your option) any later version.
  12. #
  13. # This program is distributed in the hope that it will be useful,
  14. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. # GNU General Public License for more details.
  17. #
  18. # You should have received a copy of the GNU General Public License along
  19. # with this program; if not, write to the Free Software Foundation, Inc.,
  20. # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  21. #
  22. ''' This module contains pool implementations for different OS kernels. '''
  23. import os
  24. from qubes.storage import Pool, StoragePoolException, Volume
  25. class LinuxModules(Volume):
  26. ''' A volume representing a ro linux kernel '''
  27. rw = False
  28. def __init__(self, target_dir, kernel_version, **kwargs):
  29. kwargs['vid'] = ''
  30. kwargs['source'] = self
  31. super(LinuxModules, self).__init__(**kwargs)
  32. self._kernel_version = kernel_version
  33. self.target_dir = target_dir
  34. @property
  35. def vid(self):
  36. if callable(self._kernel_version):
  37. return self._kernel_version()
  38. return self._kernel_version
  39. @vid.setter
  40. def vid(self, value):
  41. # ignore
  42. pass
  43. @property
  44. def kernels_dir(self):
  45. kernel_version = self.vid
  46. if kernel_version is None:
  47. return None
  48. return os.path.join(self.target_dir, kernel_version)
  49. @property
  50. def path(self):
  51. kernels_dir = self.kernels_dir
  52. if kernels_dir is None:
  53. return None
  54. return os.path.join(kernels_dir, 'modules.img')
  55. @property
  56. def vmlinuz(self):
  57. kernels_dir = self.kernels_dir
  58. if kernels_dir is None:
  59. return None
  60. return os.path.join(kernels_dir, 'vmlinuz')
  61. @property
  62. def initramfs(self):
  63. kernels_dir = self.kernels_dir
  64. if kernels_dir is None:
  65. return None
  66. return os.path.join(kernels_dir, 'initramfs')
  67. @property
  68. def revisions(self):
  69. return {}
  70. def block_device(self):
  71. if self.vid is not None:
  72. return super().block_device()
  73. class LinuxKernel(Pool):
  74. ''' Provides linux kernels '''
  75. driver = 'linux-kernel'
  76. def __init__(self, name=None, dir_path=None):
  77. assert dir_path, 'Missing dir_path'
  78. super(LinuxKernel, self).__init__(name=name)
  79. self.dir_path = dir_path
  80. def init_volume(self, vm, volume_config):
  81. assert not volume_config['rw']
  82. volume = LinuxModules(self.dir_path, lambda: vm.kernel, **volume_config)
  83. return volume
  84. def is_dirty(self, volume):
  85. return False
  86. def clone(self, source, target):
  87. return target
  88. def create(self, volume):
  89. return volume
  90. def commit(self, volume):
  91. return volume
  92. @property
  93. def config(self):
  94. return {
  95. 'name': self.name,
  96. 'dir_path': self.dir_path,
  97. 'driver': LinuxKernel.driver,
  98. }
  99. def destroy(self):
  100. pass
  101. def export(self, volume):
  102. return volume.path
  103. def import_volume(self, dst_pool, dst_volume, src_pool, src_volume):
  104. pass
  105. def is_outdated(self, volume):
  106. return False
  107. def remove(self, volume):
  108. pass
  109. def rename(self, volume, old_name, new_name):
  110. return volume
  111. def setup(self):
  112. pass
  113. def start(self, volume):
  114. path = volume.path
  115. if path and not os.path.exists(path):
  116. raise StoragePoolException('Missing kernel modules: %s' % path)
  117. return volume
  118. def stop(self, volume):
  119. pass
  120. def verify(self, volume):
  121. if volume.vid is not None:
  122. _check_path(volume.path)
  123. _check_path(volume.vmlinuz)
  124. _check_path(volume.initramfs)
  125. @property
  126. def volumes(self):
  127. ''' Return all known kernel volumes '''
  128. return [LinuxModules(self.dir_path,
  129. kernel_version,
  130. pool=self.name,
  131. name=kernel_version,
  132. internal=True,
  133. rw=False
  134. )
  135. for kernel_version in os.listdir(self.dir_path)]
  136. def _check_path(path):
  137. ''' Raise an :py:class:`qubes.storage.StoragePoolException` if ``path`` does
  138. not exist.
  139. '''
  140. if not os.path.exists(path):
  141. raise StoragePoolException('Missing file: %s' % path)