remap-badblocks 0.8.1__tar.gz → 0.9__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. {remap_badblocks-0.8.1/remap_badblocks.egg-info → remap_badblocks-0.9}/PKG-INFO +3 -3
  2. {remap_badblocks-0.8.1 → remap_badblocks-0.9}/README.md +2 -2
  3. {remap_badblocks-0.8.1 → remap_badblocks-0.9}/pyproject.toml +1 -1
  4. {remap_badblocks-0.8.1 → remap_badblocks-0.9/remap_badblocks.egg-info}/PKG-INFO +3 -3
  5. {remap_badblocks-0.8.1 → remap_badblocks-0.9}/src/remap_badblocks/__init__.py +1 -1
  6. {remap_badblocks-0.8.1 → remap_badblocks-0.9}/src/remap_badblocks/cli/commands/update.py +8 -6
  7. {remap_badblocks-0.8.1 → remap_badblocks-0.9}/src/remap_badblocks/src/badblocks/_remap_badblocks.py +23 -23
  8. {remap_badblocks-0.8.1 → remap_badblocks-0.9}/src/remap_badblocks/src/mapping.py +5 -1
  9. {remap_badblocks-0.8.1 → remap_badblocks-0.9}/tests/test_remap_badblocks.py +85 -30
  10. {remap_badblocks-0.8.1 → remap_badblocks-0.9}/LICENSE +0 -0
  11. {remap_badblocks-0.8.1 → remap_badblocks-0.9}/remap_badblocks.egg-info/SOURCES.txt +0 -0
  12. {remap_badblocks-0.8.1 → remap_badblocks-0.9}/remap_badblocks.egg-info/dependency_links.txt +0 -0
  13. {remap_badblocks-0.8.1 → remap_badblocks-0.9}/remap_badblocks.egg-info/entry_points.txt +0 -0
  14. {remap_badblocks-0.8.1 → remap_badblocks-0.9}/remap_badblocks.egg-info/requires.txt +0 -0
  15. {remap_badblocks-0.8.1 → remap_badblocks-0.9}/remap_badblocks.egg-info/top_level.txt +0 -0
  16. {remap_badblocks-0.8.1 → remap_badblocks-0.9}/setup.cfg +0 -0
  17. {remap_badblocks-0.8.1 → remap_badblocks-0.9}/src/remap_badblocks/cli/__init__.py +0 -0
  18. {remap_badblocks-0.8.1 → remap_badblocks-0.9}/src/remap_badblocks/cli/__main__.py +0 -0
  19. {remap_badblocks-0.8.1 → remap_badblocks-0.9}/src/remap_badblocks/cli/commands/__init__.py +0 -0
  20. {remap_badblocks-0.8.1 → remap_badblocks-0.9}/src/remap_badblocks/cli/commands/add.py +0 -0
  21. {remap_badblocks-0.8.1 → remap_badblocks-0.9}/src/remap_badblocks/cli/commands/apply.py +0 -0
  22. {remap_badblocks-0.8.1 → remap_badblocks-0.9}/src/remap_badblocks/cli/commands/get.py +0 -0
  23. {remap_badblocks-0.8.1 → remap_badblocks-0.9}/src/remap_badblocks/cli/commands/remove.py +0 -0
  24. {remap_badblocks-0.8.1 → remap_badblocks-0.9}/src/remap_badblocks/cli/commands/version.py +0 -0
  25. {remap_badblocks-0.8.1 → remap_badblocks-0.9}/src/remap_badblocks/src/badblocks/_compute_good_ranges.py +0 -0
  26. {remap_badblocks-0.8.1 → remap_badblocks-0.9}/src/remap_badblocks/src/badblocks/_find_badblocks.py +0 -0
  27. {remap_badblocks-0.8.1 → remap_badblocks-0.9}/src/remap_badblocks/src/badblocks/_mapping_generation.py +0 -0
  28. {remap_badblocks-0.8.1 → remap_badblocks-0.9}/src/remap_badblocks/src/badblocks/badblocks.py +0 -0
  29. {remap_badblocks-0.8.1 → remap_badblocks-0.9}/src/remap_badblocks/src/devices/__init__.py +0 -0
  30. {remap_badblocks-0.8.1 → remap_badblocks-0.9}/src/remap_badblocks/src/devices/device_config.py +0 -0
  31. {remap_badblocks-0.8.1 → remap_badblocks-0.9}/src/remap_badblocks/src/devices/devices_config.py +0 -0
  32. {remap_badblocks-0.8.1 → remap_badblocks-0.9}/src/remap_badblocks/src/devices/exceptions.py +0 -0
  33. {remap_badblocks-0.8.1 → remap_badblocks-0.9}/src/remap_badblocks/src/devices_config_constants.py +0 -0
  34. {remap_badblocks-0.8.1 → remap_badblocks-0.9}/src/remap_badblocks/src/remappers/_check_applied_devices.py +0 -0
  35. {remap_badblocks-0.8.1 → remap_badblocks-0.9}/src/remap_badblocks/src/remappers/_generate_dm_table.py +0 -0
  36. {remap_badblocks-0.8.1 → remap_badblocks-0.9}/src/remap_badblocks/src/test_utils.py +0 -0
  37. {remap_badblocks-0.8.1 → remap_badblocks-0.9}/src/remap_badblocks/src/utils/__init__.py +0 -0
  38. {remap_badblocks-0.8.1 → remap_badblocks-0.9}/src/remap_badblocks/src/utils/_get_device_info.py +0 -0
  39. {remap_badblocks-0.8.1 → remap_badblocks-0.9}/src/remap_badblocks/src/utils/_iterable_bytes_converter.py +0 -0
  40. {remap_badblocks-0.8.1 → remap_badblocks-0.9}/src/remap_badblocks/src/utils/_parse_inputs.py +0 -0
  41. {remap_badblocks-0.8.1 → remap_badblocks-0.9}/src/remap_badblocks/src/utils/_run_command.py +0 -0
  42. {remap_badblocks-0.8.1 → remap_badblocks-0.9}/src/remap_badblocks/src/utils/_sort_devices.py +0 -0
  43. {remap_badblocks-0.8.1 → remap_badblocks-0.9}/tests/test_compute_good_ranges.py +0 -0
  44. {remap_badblocks-0.8.1 → remap_badblocks-0.9}/tests/test_devices_config.py +0 -0
  45. {remap_badblocks-0.8.1 → remap_badblocks-0.9}/tests/test_dm_table.py +0 -0
  46. {remap_badblocks-0.8.1 → remap_badblocks-0.9}/tests/test_find_badblocks.py +0 -0
  47. {remap_badblocks-0.8.1 → remap_badblocks-0.9}/tests/test_parse_inputs.py +0 -0
  48. {remap_badblocks-0.8.1 → remap_badblocks-0.9}/tests/test_pyproject_version.py +0 -0
  49. {remap_badblocks-0.8.1 → remap_badblocks-0.9}/tests/test_run_command.py +0 -0
  50. {remap_badblocks-0.8.1 → remap_badblocks-0.9}/tests/test_sort_devices.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: remap_badblocks
3
- Version: 0.8.1
3
+ Version: 0.9
4
4
  Summary: CLI tool for remapping bad sectors on Linux disks using device-mapper
5
5
  Author-email: Luigi Privitera <priviteraluigi98@gmail.com>
6
6
  License-Expression: GPL-3.0-only
@@ -89,11 +89,11 @@ ls /dev/mapper/
89
89
 
90
90
  We welcome feedback, bug reports, feature ideas, code contributions, and help shaping the roadmap — or even rethinking the project from the ground up.
91
91
 
92
- Start with [CONTRIBUTING.md](./CONTRIBUTING.md), then open an issue or submit a merge request to get involved.
92
+ Start with CONTRIBUTING.md, then open an issue or submit a merge request to get involved.
93
93
 
94
94
  ## License
95
95
 
96
- GPL v3 License — see [LICENSE](./LICENSE) for details.
96
+ GPL v3 License — see LICENSE for details.
97
97
 
98
98
  ## Community
99
99
 
@@ -68,11 +68,11 @@ ls /dev/mapper/
68
68
 
69
69
  We welcome feedback, bug reports, feature ideas, code contributions, and help shaping the roadmap — or even rethinking the project from the ground up.
70
70
 
71
- Start with [CONTRIBUTING.md](./CONTRIBUTING.md), then open an issue or submit a merge request to get involved.
71
+ Start with CONTRIBUTING.md, then open an issue or submit a merge request to get involved.
72
72
 
73
73
  ## License
74
74
 
75
- GPL v3 License — see [LICENSE](./LICENSE) for details.
75
+ GPL v3 License — see LICENSE for details.
76
76
 
77
77
  ## Community
78
78
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "remap_badblocks"
7
- version = "0.8.1"
7
+ version = "0.9"
8
8
  requires-python = ">= 3.10"
9
9
  description = "CLI tool for remapping bad sectors on Linux disks using device-mapper"
10
10
  readme = "README.md"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: remap_badblocks
3
- Version: 0.8.1
3
+ Version: 0.9
4
4
  Summary: CLI tool for remapping bad sectors on Linux disks using device-mapper
5
5
  Author-email: Luigi Privitera <priviteraluigi98@gmail.com>
6
6
  License-Expression: GPL-3.0-only
@@ -89,11 +89,11 @@ ls /dev/mapper/
89
89
 
90
90
  We welcome feedback, bug reports, feature ideas, code contributions, and help shaping the roadmap — or even rethinking the project from the ground up.
91
91
 
92
- Start with [CONTRIBUTING.md](./CONTRIBUTING.md), then open an issue or submit a merge request to get involved.
92
+ Start with CONTRIBUTING.md, then open an issue or submit a merge request to get involved.
93
93
 
94
94
  ## License
95
95
 
96
- GPL v3 License — see [LICENSE](./LICENSE) for details.
96
+ GPL v3 License — see LICENSE for details.
97
97
 
98
98
  ## Community
99
99
 
@@ -1,3 +1,3 @@
1
1
  from packaging.version import Version
2
2
 
3
- __version__ = Version("0.8.1")
3
+ __version__ = Version("0.9")
@@ -9,7 +9,7 @@ from remap_badblocks.src.badblocks._find_badblocks import (
9
9
  get_all_badblocks, read_known_badblocks)
10
10
  from remap_badblocks.src.badblocks._mapping_generation import generate_mapping
11
11
  from remap_badblocks.src.badblocks._remap_badblocks import (
12
- count_used_spare_sectors, iter_all_spare_sectors, iter_free_spare_sectors,
12
+ filter_out_used_and_bad_spare_sectors, iter_all_spare_sectors,
13
13
  remap_badblocks, simplify_mapping)
14
14
  from remap_badblocks.src.devices.device_config import DeviceConfig
15
15
  from remap_badblocks.src.devices.devices_config import DevicesConfig
@@ -165,13 +165,15 @@ def update_mapping(
165
165
  good_ranges,
166
166
  )
167
167
  else:
168
+ badblocks_ = set(badblocks)
168
169
  spare_sectors = iter_all_spare_sectors(n_spare_sectors, device.logical_range[0])
169
- n_used_spare_sectors = count_used_spare_sectors(device.mapping, spare_sectors)
170
- current_mapping = map(lambda x: x.to_tuple(), device.mapping)
170
+ spare_sectors = filter_out_used_and_bad_spare_sectors(
171
+ spare_sectors, device.mapping, badblocks_
172
+ )
171
173
  new_mapping = remap_badblocks(
172
- current_mapping,
173
- badblocks,
174
- spare_sectors=iter_free_spare_sectors(spare_sectors, n_used_spare_sectors),
174
+ device.mapping,
175
+ badblocks_,
176
+ spare_sectors,
175
177
  )
176
178
 
177
179
  new_mapping = list(new_mapping)
@@ -1,13 +1,13 @@
1
- import itertools
2
- from typing import Iterable, Iterator, Optional, Union
1
+ from collections.abc import Container, Generator, Iterable, Iterator
2
+ from typing import Optional, Union
3
3
 
4
4
  from remap_badblocks.src.devices.devices_config import Mapping
5
5
 
6
6
 
7
7
  def remap_badblocks(
8
- mapping: Iterable[tuple[int, int, int]],
8
+ mapping: Union[Iterable[tuple[int, int, int]], Mapping],
9
9
  badblocks: Iterable[int],
10
- spare_sectors: Iterator[int],
10
+ usable_spare_sectors: Iterator[int],
11
11
  ) -> Iterable[tuple[int, int, int]]:
12
12
  sorted_badblocks = sorted(badblocks)
13
13
 
@@ -37,10 +37,11 @@ def remap_badblocks(
37
37
  yield current_start_virtual, current_start_real, end_real - current_start_real + 1
38
38
  for virt_to_remap in sorted_to_remap_virtual:
39
39
  try:
40
- while (spare_sector := next(spare_sectors)) in badblocks:
41
- pass
40
+ spare_sector = next(usable_spare_sectors)
42
41
  except StopIteration:
43
- raise RuntimeError
42
+ raise RuntimeError(
43
+ "Not enough spare sectors to remap all new badblocks"
44
+ )
44
45
  # remap
45
46
  yield virt_to_remap, spare_sector, 1
46
47
 
@@ -93,22 +94,21 @@ def iter_all_spare_sectors(
93
94
  return iter(range(first_spare_sector, first_spare_sector + n_spare_sectors))
94
95
 
95
96
 
96
- def iter_free_spare_sectors(
97
- spare_sectors: Iterable[int], n_used_spare_sectors: int
98
- ) -> Iterator[int]:
99
- return itertools.islice(spare_sectors, n_used_spare_sectors, None)
100
-
101
-
102
- def count_used_spare_sectors(
103
- mapping: Union[Iterable[tuple[int, int, int]], Mapping],
104
- spare_sectors: Iterable[int],
105
- ) -> int:
106
- spare_sectors = set(spare_sectors)
107
- used = 0
97
+ def is_sector_used_in_mapping(
98
+ s: int, mapping: Union[Iterable[tuple[int, int, int]], Mapping]
99
+ ):
108
100
  for _, start, length in mapping:
109
101
  end = start + length
110
- for s in spare_sectors:
111
- if start <= s < end:
112
- used += 1
102
+ if start <= s < end:
103
+ return True
104
+ return False
113
105
 
114
- return used
106
+
107
+ def filter_out_used_and_bad_spare_sectors(
108
+ spare_sectors: Iterable[int],
109
+ current_mapping: Mapping,
110
+ badblocks: Container[int],
111
+ ) -> Generator[int]:
112
+ for s in spare_sectors:
113
+ if s not in badblocks and not is_sector_used_in_mapping(s, current_mapping):
114
+ yield s
@@ -1,6 +1,6 @@
1
1
  import sqlite3
2
2
  from dataclasses import dataclass
3
- from typing import Collection, Iterator
3
+ from typing import Collection, Iterable, Iterator
4
4
 
5
5
  from remap_badblocks.src.utils._iterable_bytes_converter import (
6
6
  iterable_from_bytes, iterable_to_bytes)
@@ -107,3 +107,7 @@ class Mapping:
107
107
 
108
108
  def __iter__(self) -> Iterator[MappingElement]:
109
109
  return iter(self.elements)
110
+
111
+ @classmethod
112
+ def from_tuples(cls, mapping_tuples: Iterable[tuple[int, int, int]]) -> "Mapping":
113
+ return cls(set(map(MappingElement.from_tuple, mapping_tuples)))
@@ -3,8 +3,9 @@ from typing import Iterable
3
3
  import pytest
4
4
 
5
5
  from remap_badblocks.src.badblocks._remap_badblocks import (
6
- count_used_spare_sectors, iter_all_spare_sectors, remap_badblocks,
7
- simplify_mapping)
6
+ filter_out_used_and_bad_spare_sectors, is_sector_used_in_mapping,
7
+ remap_badblocks, simplify_mapping)
8
+ from remap_badblocks.src.mapping import Mapping
8
9
 
9
10
 
10
11
  @pytest.mark.parametrize(
@@ -49,18 +50,21 @@ def test_simplify_mapping(
49
50
 
50
51
  @pytest.mark.parametrize("spare_sectors_n", [10, 20, 100])
51
52
  @pytest.mark.parametrize(
52
- "mapping, badblocks",
53
+ "_mapping, badblocks",
53
54
  [
54
55
  ([(0, 1024, 1024), (1024, 3000, 1000)], [0, 1025, 2050, 2800, 1026]),
55
56
  ([(0, 1024, 1024)], [1, 1024, 1025, 1026, 1027, 1028]),
56
57
  ],
57
58
  )
58
59
  def test_remap_badblocks__no_badblocks_in_output(
59
- mapping: Iterable[tuple[int, int, int]],
60
- badblocks: Iterable[int],
60
+ _mapping: Iterable[tuple[int, int, int]],
61
+ badblocks: list[int],
61
62
  spare_sectors_n: int,
62
63
  ):
63
- spare_sectors = iter(range(spare_sectors_n))
64
+ mapping = Mapping.from_tuples(_mapping)
65
+ spare_sectors = filter_out_used_and_bad_spare_sectors(
66
+ range(spare_sectors_n), mapping, badblocks
67
+ )
64
68
  remapped = list(remap_badblocks(mapping, badblocks, spare_sectors))
65
69
 
66
70
  for _, start, length in remapped:
@@ -91,8 +95,8 @@ def test_remap_badblocks__no_badblocks_in_output(
91
95
  ),
92
96
  [
93
97
  [(0, 1024, 1024)],
94
- list(range(10)) + [2047],
95
- 10,
98
+ [2047],
99
+ 0,
96
100
  False,
97
101
  ],
98
102
  [
@@ -157,28 +161,79 @@ def test_remap_badblocks__is_keeping_good_ranges_constant(
157
161
  assert old_maps_to_keep.issubset(new_maps)
158
162
 
159
163
 
164
+ # @pytest.mark.parametrize(
165
+ # "mapping, n_spare_sectors, answer",
166
+ # [
167
+ # (
168
+ # [(0, 10, 5), (5, 17, 8)],
169
+ # 10,
170
+ # 0,
171
+ # ),
172
+ # (
173
+ # [(0, 10, 5), (5, 0, 2), (7, 17, 8)],
174
+ # 10,
175
+ # 2,
176
+ # ),
177
+ # (
178
+ # [(0, 10, 5), (5, 0, 2), (7, 17, 8), (15, 2, 4)],
179
+ # 10,
180
+ # 6,
181
+ # ),
182
+ # ],
183
+ # )
184
+ # def test_count_used_spare_sectors(
185
+ # mapping: Iterable[tuple[int, int, int]], n_spare_sectors: int, answer: int
186
+ # ):
187
+ # spare_sectors = iter_all_spare_sectors(n_spare_sectors, 0)
188
+ # assert answer == count_used_spare_sectors(mapping, spare_sectors)
189
+
190
+
191
+ @pytest.mark.parametrize("mapping_elem_0", [v * 113 for v in range(100)])
160
192
  @pytest.mark.parametrize(
161
- "mapping, n_spare_sectors, answer",
162
- [
163
- (
164
- [(0, 10, 5), (5, 17, 8)],
165
- 10,
166
- 0,
167
- ),
168
- (
169
- [(0, 10, 5), (5, 0, 2), (7, 17, 8)],
170
- 10,
171
- 2,
172
- ),
173
- (
174
- [(0, 10, 5), (5, 0, 2), (7, 17, 8), (15, 2, 4)],
175
- 10,
176
- 6,
177
- ),
178
- ],
193
+ ("sector", "mapping_elem_1_2", "ground_truth"),
194
+ (
195
+ (1, [(0, 4)], True),
196
+ (0, [(0, 4)], True),
197
+ (0, [(1, 4)], False),
198
+ (4, [(0, 4)], False),
199
+ (5, [(0, 4), (5, 1)], True),
200
+ (5, [(0, 4), (6, 5)], False),
201
+ (1000, [(0, 4), (5, 6)], False),
202
+ ),
179
203
  )
180
- def test_count_used_spare_sectors(
181
- mapping: Iterable[tuple[int, int, int]], n_spare_sectors: int, answer: int
204
+ def test_is_sector_used_in_mapping(
205
+ mapping_elem_0: int,
206
+ sector: int,
207
+ mapping_elem_1_2: Iterable[tuple[int, int]],
208
+ ground_truth: bool,
209
+ ):
210
+ mapping = [
211
+ (mapping_elem_0, *_mapping_elem_1_2) for _mapping_elem_1_2 in mapping_elem_1_2
212
+ ]
213
+ assert is_sector_used_in_mapping(sector, mapping) == ground_truth
214
+
215
+
216
+ @pytest.mark.parametrize(
217
+ ("spare_sectors", "_current_mapping", "badblocks", "ground_truth"),
218
+ (
219
+ ([1, 3, 4, 5], [(0, 5, 2)], {0, 1, 10}, {3, 4}),
220
+ ([], [], [], []),
221
+ ([0, 1, 2], [], [], {0, 1, 2}),
222
+ ([0, 1, 2], [], {0, 1, 2}, []),
223
+ ([0, 1, 2], [(0, 0, 3)], [], []),
224
+ ([], [], {1, 2, 3}, []),
225
+ ([0, 1, 2], [(0, 0, 3)], {0, 1, 2}, []),
226
+ ),
227
+ )
228
+ def test_filter_out_used_and_bad_spare_sectors(
229
+ spare_sectors: Iterable[int],
230
+ _current_mapping: Iterable[tuple[int, int, int]],
231
+ badblocks: Iterable[int],
232
+ ground_truth: Iterable[int],
182
233
  ):
183
- spare_sectors = iter_all_spare_sectors(n_spare_sectors, 0)
184
- assert answer == count_used_spare_sectors(mapping, spare_sectors)
234
+ current_mapping = Mapping.from_tuples(_current_mapping)
235
+ assert set(
236
+ filter_out_used_and_bad_spare_sectors(
237
+ spare_sectors, current_mapping, set(badblocks)
238
+ )
239
+ ) == set(ground_truth)
File without changes
File without changes