qubes-storage.rst 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. :py:mod:`qubes.storage` -- Qubes data storage
  2. =============================================
  3. Qubes provide extensible API for domains data storage. Each domain have
  4. multiple storage volumes, for different purposes. Each volume is provided by
  5. some storage pool. Qubes support different storage pool drivers, and it's
  6. possible to register additional 3rd-party drivers.
  7. Domain's storage volumes:
  8. - `root` - this is where operating system is installed. The volume is
  9. available read-write to all domain classes. It could be made read-only for
  10. :py:class:`~qubes.vm.appvm.AppVM` and :py:class:`~qubes.vm.dispvm.DispVM` to
  11. implement an untrusted storage domain in the future, but doing so will cause
  12. such VMs to set up a device-mapper based copy-on-write layer that redirects
  13. writes to the `volatile` volume. Whose storage driver may already do CoW,
  14. leading to an inefficient CoW-on-CoW setup. For this reason, `root` is
  15. currently read-write in all cases.
  16. - `private` - this is where domain's data live. The volume is available
  17. read-write to all domain classes (including :py:class:`~qubes.vm.dispvm.DispVM`,
  18. but data written there is discarded on domain shutdown).
  19. - `volatile` - this is used for any data that do not to persist. This include
  20. swap, copy-on-write layer for a future read-only `root` volume etc.
  21. - `kernel` - domain boot files - operating system kernel, initial ramdisk,
  22. kernel modules etc. This volume is provided read-only and should be provided by
  23. a storage pool respecting :py:attr:`qubes.vm.qubesvm.QubesVM.kernel` property.
  24. Storage pool concept
  25. --------------------
  26. Storage pool is responsible for managing its volumes. Qubes have defined
  27. storage pool driver API, allowing to put domains storage in various places. By
  28. default three drivers are provided: :py:class:`qubes.storage.file.FilePool`
  29. (named `file`), :py:class:`qubes.storage.reflink.ReflinkPool` (named
  30. `file-reflink`), and :py:class:`qubes.storage.lvm.ThinPool` (named `lvm_thin`).
  31. But the API allow to implement variety of other drivers (like additionally
  32. encrypted storage, external disk, drivers using special features of some
  33. filesystems, etc).
  34. Most of storage API focus on storage volumes. Each volume have at least those
  35. properties:
  36. - :py:attr:`~qubes.storage.Volume.rw` - should the volume be available
  37. read-only or read-write to the domain
  38. - :py:attr:`~qubes.storage.Volume.snap_on_start` - should the domain start
  39. with its own state of the volume, or rather a snapshot of its template volume
  40. (pointed by a :py:attr:`~qubes.storage.Volume.source` property). This can be
  41. set to `True` only if a domain do have `template` property (AppVM and DispVM).
  42. If the domain's template is running already, the snapshot should be made out of
  43. the template's before its startup.
  44. - :py:attr:`~qubes.storage.Volume.save_on_stop` - should the volume state be
  45. saved or discarded on domain
  46. stop. In either case, while the domain is running, volume's current state
  47. should not be committed immediately. This is to allow creating snapshots of the
  48. volume's state from before domain start (see
  49. :py:attr:`~qubes.storage.Volume.snap_on_start`).
  50. - :py:attr:`~qubes.storage.Volume.revisions_to_keep` - number of volume
  51. revisions to keep. If greater than zero, at each domain stop (and if
  52. :py:attr:`~qubes.storage.Volume.save_on_stop` is `True`) new revision is saved
  53. and old ones exceeding :py:attr:`~qubes.storage.Volume.revisions_to_keep` limit
  54. are removed.
  55. - :py:attr:`~qubes.storage.Volume.source` - source volume for
  56. :py:attr:`~qubes.storage.Volume.snap_on_start` volumes
  57. - :py:attr:`~qubes.storage.Volume.vid` - pool specific volume identifier, must
  58. be unique inside given pool
  59. - :py:attr:`~qubes.storage.Volume.pool` - storage pool object owning this volume
  60. - :py:attr:`~qubes.storage.Volume.name` - name of the volume inside owning
  61. domain (like `root`, or `private`)
  62. - :py:attr:`~qubes.storage.Volume.size` - size of the volume, in bytes
  63. Storage pool driver may define additional properties.
  64. Storage pool driver API
  65. -----------------------
  66. Storage pool driver need to implement two classes:
  67. - pool class - inheriting from :py:class:`qubes.storage.Pool`
  68. - volume class - inheriting from :py:class:`qubes.storage.Volume`
  69. Pool class should be registered with `qubes.storage` entry_point, under the
  70. name of storage pool driver. Volume class instances should be returned by
  71. :py:meth:`qubes.storage.Pool.init_volume` method of pool class instance.
  72. Methods required to be implemented by the pool class:
  73. - :py:meth:`~qubes.storage.Pool.init_volume` - return instance of appropriate
  74. volume class; this method should not alter any persistent disk state, it is
  75. used to instantiate both existing volumes and create new ones
  76. - :py:meth:`~qubes.storage.Pool.setup` - setup new storage pool
  77. - :py:meth:`~qubes.storage.Pool.destroy` - destroy storage pool
  78. Methods and properties required to be implemented by the volume class:
  79. - :py:meth:`~qubes.storage.Volume.create` - create volume on disk
  80. - :py:meth:`~qubes.storage.Volume.remove` - remove volume from disk
  81. - :py:meth:`~qubes.storage.Volume.start` - prepare the volume for domain start;
  82. this include making a snapshot if
  83. :py:attr:`~qubes.storage.Volume.snap_on_start` is `True`
  84. - :py:meth:`~qubes.storage.Volume.stop` - cleanup after domain shutdown; this
  85. include committing changes to the volume if
  86. :py:attr:`~qubes.storage.Volume.save_on_stop` is `True`
  87. - :py:meth:`~qubes.storage.Volume.export` - return a path to be read to extract
  88. volume data; for complex formats, this can be a pipe (connected to some
  89. data-extracting process)
  90. - :py:meth:`~qubes.storage.Volume.export_end` - cleanup after exporting the
  91. data; this function is called when the path returned by
  92. :py:meth:`~qubes.storage.Volume.export` is not used anymore. This method
  93. optional - some storage drivers may not implement it if not needed.
  94. - :py:meth:`~qubes.storage.Volume.import_data` - return a path the data should
  95. be written to, to import volume data; for complex formats, this can be pipe
  96. (connected to some data-importing process)
  97. - :py:meth:`~qubes.storage.Volume.import_data_end` - finish data import
  98. operation (cleanup temporary files etc); this methods is called always after
  99. :py:meth:`~qubes.storage.Volume.import_data` regardless if operation was
  100. successful or not
  101. - :py:meth:`~qubes.storage.Volume.import_volume` - import data from another volume
  102. - :py:meth:`~qubes.storage.Volume.resize` - resize volume
  103. - :py:meth:`~qubes.storage.Volume.revert` - revert volume state to a given revision
  104. - :py:attr:`~qubes.storage.Volume.revisions` - collection of volume revisions (to use
  105. with :py:meth:`qubes.storage.Volume.revert`)
  106. - :py:meth:`~qubes.storage.Volume.is_dirty` - is volume properly committed
  107. after domain shutdown? Applies only to volumes with
  108. :py:attr:`~qubes.storage.Volume.save_on_stop` set to `True`
  109. - :py:meth:`~qubes.storage.Volume.is_outdated` - have the source volume started
  110. since domain startup? applies only to volumes with
  111. :py:attr:`~qubes.storage.Volume.snap_on_start` set to `True`
  112. - :py:attr:`~qubes.storage.Volume.config` - volume configuration, this should
  113. be enough to later reinstantiate the same volume object
  114. - :py:meth:`~qubes.storage.Volume.block_device` - return
  115. :py:class:`qubes.storage.BlockDevice` instance required to configure volume in
  116. libvirt
  117. Some storage pool drivers can provide limited functionality only - for example
  118. support only `volatile` volumes (those with
  119. :py:attr:`~qubes.storage.Volume.snap_on_start` is `False`,
  120. :py:attr:`~qubes.storage.Volume.save_on_stop` is `False`, and
  121. :py:attr:`~qubes.storage.Volume.rw` is `True`). In that case, it should raise
  122. :py:exc:`NotImplementedError` in :py:meth:`qubes.storage.Pool.init_volume` when
  123. trying to instantiate unsupported volume.
  124. Note that pool driver should be prepared to recover from power loss before
  125. stopping a domain - so, if volume have
  126. :py:attr:`~qubes.storage.Volume.save_on_stop` is `True`, and
  127. :py:meth:`qubes.storage.Volume.stop` wasn't called, next
  128. :py:meth:`~qubes.storage.Volume.start` should pick up previous (not committed)
  129. state.
  130. See specific methods documentation for details.
  131. Module contents
  132. ---------------
  133. .. automodule:: qubes.storage
  134. :members:
  135. :show-inheritance:
  136. .. vim: ts=3 sw=3 et