dwipe 2.0.1__py3-none-any.whl → 2.0.2__py3-none-any.whl
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.
- dwipe/DeviceInfo.py +183 -52
- dwipe/DiskWipe.py +495 -180
- dwipe/DrivePreChecker.py +90 -0
- dwipe/FirmwareWipeTask.py +370 -0
- dwipe/LsblkMonitor.py +124 -0
- dwipe/PersistentState.py +26 -8
- dwipe/Prereqs.py +84 -0
- dwipe/StructuredLogger.py +643 -0
- dwipe/ToolManager.py +235 -254
- dwipe/Utils.py +108 -0
- dwipe/VerifyTask.py +410 -0
- dwipe/WipeJob.py +613 -165
- dwipe/WipeTask.py +148 -0
- dwipe/WriteTask.py +402 -0
- dwipe/main.py +14 -9
- {dwipe-2.0.1.dist-info → dwipe-2.0.2.dist-info}/METADATA +69 -33
- dwipe-2.0.2.dist-info/RECORD +21 -0
- dwipe/WipeJobFuture.py +0 -245
- dwipe-2.0.1.dist-info/RECORD +0 -14
- {dwipe-2.0.1.dist-info → dwipe-2.0.2.dist-info}/WHEEL +0 -0
- {dwipe-2.0.1.dist-info → dwipe-2.0.2.dist-info}/entry_points.txt +0 -0
- {dwipe-2.0.1.dist-info → dwipe-2.0.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dwipe
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.2
|
|
4
4
|
Summary: A tool to wipe disks and partitions for Linux
|
|
5
5
|
Keywords: disk,partition,wipe,clean,scrub
|
|
6
6
|
Author-email: Joe Defen <joedef@google.com>
|
|
@@ -10,7 +10,7 @@ Classifier: Programming Language :: Python :: 3
|
|
|
10
10
|
Classifier: License :: OSI Approved :: MIT License
|
|
11
11
|
Classifier: Operating System :: POSIX :: Linux
|
|
12
12
|
License-File: LICENSE
|
|
13
|
-
Requires-Dist: console-window == 1.
|
|
13
|
+
Requires-Dist: console-window == 1.4.2
|
|
14
14
|
Project-URL: Bug Tracker, https://github.com/joedefen/dwipe/issues
|
|
15
15
|
Project-URL: Homepage, https://github.com/joedefen/dwipe
|
|
16
16
|
|
|
@@ -25,7 +25,7 @@ Project-URL: Homepage, https://github.com/joedefen/dwipe
|
|
|
25
25
|
| Interactive TUI | ✓ | ✓ | ✗ | ✗ |
|
|
26
26
|
| Multiple simultaneous wipes | ✓ | ✗ | ✗ | ✗ |
|
|
27
27
|
| Hot-swap detection | ✓ | ✗ | ✗ | ✗ |
|
|
28
|
-
| Device/partition
|
|
28
|
+
| Device/partition blocking | ✓ | ✗ | ✗ | ✗ |
|
|
29
29
|
| Persistent wipe state | ✓ | ✗ | ✗ | ✗ |
|
|
30
30
|
| Resume interrupted wipes | ✓ | ✗ | ✗ | ✗ |
|
|
31
31
|
| Wipe operation logging | ✓ | ✗ | ✗ | ✗ |
|
|
@@ -38,6 +38,37 @@ Project-URL: Homepage, https://github.com/joedefen/dwipe
|
|
|
38
38
|
> * **Modern drives are reliably wiped with one pass of zeros**; just zero once in almost all cases for best, fastest results.
|
|
39
39
|
> * `dwipe` offers Multi-pass and Rand modes as "checkbox" features, but those provide no additional security on drives manufactured after 2001 (NIST SP 800-88).
|
|
40
40
|
|
|
41
|
+
## **V3 Features** (Partly in V2.x)
|
|
42
|
+
|
|
43
|
+
> Features added since initial V2 deployment (may not be in a demo until V3).
|
|
44
|
+
|
|
45
|
+
* **Port and Serial number**. Press `p` to control port and serial number; it adds another line per disk and you may want to use it selectively. You may choose "Off" (not shown), "On" (always shown), or the default "Auto" show if the disk is in a state allowed for wiping (e.g., no mounted partitions).
|
|
46
|
+
* **Fast SATA Release**. If you press `DEL` on a SATA drive in a hot-swap bay (and not mounted or otherwise busy):
|
|
47
|
+
* it will be removed from the OS managed devices,
|
|
48
|
+
* when gone from the `dwipe` screen, you can then pull out the device, and insert another one.
|
|
49
|
+
* So, replacing the drive can take just seconds, not minutes awaiting SATA timeouts.
|
|
50
|
+
* **Background device monitoring** - Faster and more efficient hot-swap detection with dedicated monitoring thread:
|
|
51
|
+
- Monitors `/sys/class/block` and `/proc/partitions` for device changes
|
|
52
|
+
- Runs `lsblk` only when changes detected (previously ran every refresh)
|
|
53
|
+
- Reduces CPU usage and improves responsiveness
|
|
54
|
+
- Faster detection of newly inserted or removed devices
|
|
55
|
+
* **Lock renamed Block** - To reduce confusion, the "lock" feature is renamed.
|
|
56
|
+
- "Blocking" a partition or disk is only effective within the running app.
|
|
57
|
+
- It prevents wiping w/o first unblocking even if unmounted or otherwise it a wipeable state.
|
|
58
|
+
- It does not system level lock of any type.
|
|
59
|
+
* **Hardware-based firmware wipes (EXPERIMENTAL/ALPHA)** - Full support for firmware-level secure erase operations:
|
|
60
|
+
- **⚠️ Requires `--firmware-wipes` flag to enable (disabled by default)**
|
|
61
|
+
- **NVMe Sanitize**: Crypto Erase, Block Erase, and Overwrite operations via `nvme-cli`
|
|
62
|
+
- **NVMe Format**: Secure format with optional crypto erase
|
|
63
|
+
- **SATA ATA Security Erase**: Normal and Enhanced erase modes via `hdparm`
|
|
64
|
+
- Automatic capability detection shows only supported methods for each drive
|
|
65
|
+
- Firmware wipes are much faster than software wipes (seconds to minutes vs hours)
|
|
66
|
+
- Same user interface - firmware options appear alongside Zero/Rand in wipe confirmation
|
|
67
|
+
- Progress tracking with "FW" indicator to show hardware operation in progress
|
|
68
|
+
- Persistent markers track firmware wipe completion and method used
|
|
69
|
+
- See [FIRMWARE_WIPES.md](FIRMWARE_WIPES.md) for technical details
|
|
70
|
+
- **Note**: This feature is experimental; software wipes are recommended for most users
|
|
71
|
+
|
|
41
72
|
## **V2 Features**
|
|
42
73
|
|
|
43
74
|
* **Statistical verification** - Automatic or on-demand verification with intelligent pattern detection:
|
|
@@ -51,23 +82,23 @@ Project-URL: Homepage, https://github.com/joedefen/dwipe
|
|
|
51
82
|
* **Configurable confirmation modes** - Choose your safety level: single keypress (Y/y), typed confirmation (YES/yes), or device name (cycle with **c** key)
|
|
52
83
|
* **Enhanced wipe history** - Detailed log viewer (**h** key) shows wipe history with UUIDs, filesystems, labels, and percentages for stopped wipes
|
|
53
84
|
* **Active wipe highlighting** - In-progress wipes displayed in bright cyan/blue with elapsed time, remaining time, and transfer speed (0-100% write, 101-200% verify)
|
|
54
|
-
* **Persistent user preferences** - Theme, wipe mode (Rand/Zero/Rand+V/Zero+V), confirmation mode, verification %, and
|
|
55
|
-
* **Individual partition
|
|
85
|
+
* **Persistent user preferences** - Theme, wipe mode (Rand/Zero/Rand+V/Zero+V), confirmation mode, verification %, and blocked devices persist across sessions (saved to `~/.config/dwipe/state.json`)
|
|
86
|
+
* **Individual partition blocking** - Block individual partitions to prevent accidental wiping (previously only whole disks could be blocked)
|
|
56
87
|
* **Full terminal color themes** - Complete themed color schemes with backgrounds, not just highlights (cycle with **t** key)
|
|
57
|
-
* **Visual feedback improvements** - Mounted and
|
|
88
|
+
* **Visual feedback improvements** - Mounted and blocked devices appear dimmed; active wipes are bright and prominent
|
|
58
89
|
* **Smart device identification** - Uses UUID/PARTUUID/serial numbers for stable device tracking across reconnections
|
|
59
90
|
* **Screen-based navigation** - Modern screen stack architecture with help screen (**?**) and history screen (**h**)
|
|
60
91
|
* **Direct I/O to Disk** - Wiping is done with direct I/O which is fast and avoid polluting your page cache. Writer threads are given lower than normal I/O priority to play nice with other apps. This makes stopping jobs fast and certain.
|
|
61
92
|
* **Improved Handling of Bad Disks.** Now detects (sometimes corrects) write failures, slowdowns, excessive no progress, and reports/aborts hopeless or hopelessly slow wipes.
|
|
62
93
|
|
|
63
|
-
## **V2.x Features**
|
|
64
|
-
Features added since V2 deployed (may not be in latest demo):
|
|
65
|
-
* **Port and Serial number**. Press `p` to toggle whether port and serial number is show; it adds another line per disk and you may want to use it selectively.
|
|
66
94
|
## Requirements
|
|
67
95
|
- **Linux operating system** (uses `/dev/`, `/sys/`, `/proc/` interfaces)
|
|
68
96
|
- **Python 3.8 or higher**
|
|
69
97
|
- **Root/sudo privileges** (automatically requested when you run the tool)
|
|
70
98
|
- **lsblk utility** (usually pre-installed on most Linux distributions)
|
|
99
|
+
- **Optional (for firmware wipes only):**
|
|
100
|
+
- `nvme-cli` - For NVMe Sanitize and Format operations
|
|
101
|
+
- `hdparm` - For SATA ATA Security Erase operations
|
|
71
102
|
|
|
72
103
|
## Installation
|
|
73
104
|
|
|
@@ -87,28 +118,37 @@ Features added since V2 deployed (may not be in latest demo):
|
|
|
87
118
|
`dwipe` provides comprehensive disk wiping capabilities with safety features:
|
|
88
119
|
|
|
89
120
|
* **Smart device display** - Shows disks and partitions with labels, sizes, types, and vendor/model information to help identify devices correctly
|
|
90
|
-
* **Safety protections** - Prevents wiping mounted devices, detects overlapping wipes, supports manual disk
|
|
121
|
+
* **Safety protections** - Prevents wiping mounted devices, detects overlapping wipes, supports manual disk blocking
|
|
91
122
|
* **Hot-swap detection** - Updates the device list when storage changes; newly added devices are marked with **^** to make them easy to spot
|
|
92
123
|
* **Multiple simultaneous wipes** - Start wipes on multiple devices at once, with individual progress tracking and completion states
|
|
93
124
|
* **Flexible wipe modes** - Choose between Rand, Zero, Rand+V (with auto-verify), or Zero+V (with auto-verify). Multi-pass modes alternate patterns for improved data destruction
|
|
94
125
|
* **Persistent state tracking** - Wipe status survives reboots; partially wiped (**s**) and completed (**W**) states are stored on the device
|
|
95
126
|
* **Device filtering** - Filter devices by name/pattern using regex in case of too many for one screen
|
|
96
127
|
* **Stop capability** - Stop individual wipes or all wipes in progress
|
|
97
|
-
* **Disk
|
|
98
|
-
* **Dry-run mode** - Practice using the interface without risk using `--dry-run`
|
|
128
|
+
* **Disk blocking** - Manually block disks to prevent accidental wipes (blocks hide all partitions)
|
|
99
129
|
|
|
100
130
|
|
|
101
131
|
> **Note:** `dwipe` shows file system labels, and if not available, the partition label. It is best practice to label partitions and file systems well to make selection easier.
|
|
102
|
-
|
|
132
|
+
|
|
103
133
|
## Usage
|
|
104
134
|
|
|
105
135
|
Simply run `dwipe` from the command line without arguments: `dwipe`
|
|
106
136
|
|
|
137
|
+
### Command-Line Options
|
|
138
|
+
|
|
139
|
+
- `--firmware-wipes` or `-F` - Enable experimental (alpha) firmware wipes
|
|
140
|
+
- Enables hardware-based secure erase operations (NVMe Sanitize/Format, SATA ATA Security Erase)
|
|
141
|
+
- Requires `nvme-cli` and `hdparm` tools to be installed
|
|
142
|
+
- Without this flag, only software wipes (Zero/Rand) are available
|
|
143
|
+
- **Warning**: This feature is experimental and should be used with caution
|
|
144
|
+
- `--dump-lsblk` - Dump parsed device information and exit (for debugging)
|
|
145
|
+
- `--help` - Show help message with all available options
|
|
146
|
+
|
|
107
147
|
### Color Legend
|
|
108
148
|
|
|
109
149
|
`dwipe` uses color coding to provide instant visual feedback about device and operation status:
|
|
110
150
|
|
|
111
|
-
- **Dimmed (gray)** - Mounted or
|
|
151
|
+
- **Dimmed (gray)** - Mounted or blocked devices (cannot be wiped)
|
|
112
152
|
- **Default (white)** - Ready to wipe, idle state, or previously wiped (before this session)
|
|
113
153
|
- **Bright cyan/blue + bold** - Active wipe or verification in progress (0-100% write, v0-v100% verify)
|
|
114
154
|
- **Bold yellow** - Stopped or partially completed wipe
|
|
@@ -156,8 +196,8 @@ The **STATE** column shows the current status of each device:
|
|
|
156
196
|
| **STOP** | Wipe or verification is being stopped |
|
|
157
197
|
| **s** | Wipe was stopped - device is partially wiped (can restart or verify) |
|
|
158
198
|
| **W** | Wipe was completed successfully (can wipe again or verify) |
|
|
159
|
-
| **
|
|
160
|
-
| **
|
|
199
|
+
| **Blk** | Disk is manually blocked - partitions are hidden and cannot be wiped |
|
|
200
|
+
| **Unbl** | Disk was just unblocked (transitory state) |
|
|
161
201
|
|
|
162
202
|
### Available Actions
|
|
163
203
|
|
|
@@ -169,42 +209,39 @@ The top line shows available actions. Some are context-sensitive (only available
|
|
|
169
209
|
| **v** | verify | Verify a wiped device or detect pattern on unmarked disk (context-sensitive) |
|
|
170
210
|
| **s** | stop | Stop the selected wipe in progress (context-sensitive) |
|
|
171
211
|
| **S** | Stop All | Stop all wipes in progress |
|
|
172
|
-
| **
|
|
212
|
+
| **b** | block/unblock | Block or unblock a disk to prevent accidental wiping |
|
|
173
213
|
| **q** or **x** | quit | Quit the application (stops all wipes first) |
|
|
174
214
|
| **?** | help | Show help screen with all actions and navigation keys |
|
|
175
215
|
| **h** | history | Show wipe history log |
|
|
176
216
|
| **/** | filter | Filter devices by regex pattern (shows matching devices + all active wipes) |
|
|
177
217
|
| **ESC** | clear filter | Clear the filter and jump to top of list |
|
|
178
|
-
| **
|
|
218
|
+
| **ESC** | back | Return to previous screen if on nested screen |
|
|
219
|
+
| **m** | mode | Cycle auto verify mode: +V (verify), -V (don't) [saved as preference] |
|
|
179
220
|
| **P** | passes | Cycle wipe passes: 1, 2, or 4 (saved as preference) |
|
|
180
221
|
| **V** | verify % | Cycle verification percentage: 0%, 2%, 5%, 10%, 25%, 50%, 100% (saved as preference) |
|
|
181
|
-
| **c** | confirmation | Cycle confirmation mode: Y, y, YES, yes, device name (saved as preference) |
|
|
182
|
-
| **d** | dirty limit | Cycle dirty page limit: 0, 500, 1000, 2000, 4000 MB (saved as preference) |
|
|
183
222
|
| **D** | dense | Toggle dense/spaced view (saved as preference) |
|
|
184
223
|
| **t** | themes | Open theme preview screen to view and change color themes |
|
|
185
224
|
|
|
186
|
-
### Wipe
|
|
225
|
+
### Wipe Types
|
|
187
226
|
|
|
188
|
-
`dwipe` supports
|
|
227
|
+
`dwipe` supports several wipe modes.
|
|
189
228
|
|
|
190
229
|
- **Zero** - Fills the device with zeros (multi-pass alternates random/zero patterns, ending on zeros)
|
|
191
|
-
- **Zero+V** - Same as Zero, but automatically verifies after wipe completes (if verify % > 0)
|
|
192
230
|
- **Rand** - Fills the device with random data (multi-pass alternates zero/random patterns, ending on random)
|
|
193
|
-
- **
|
|
231
|
+
- **Firmware wipes** - TBD
|
|
194
232
|
|
|
195
233
|
The `+V` suffix indicates automatic verification after wipe completion. Without `+V`, you can still manually verify by pressing **v** on a wiped device.
|
|
196
234
|
|
|
197
|
-
> **Note:** Multi-pass wipes (2 or 4 passes) alternate between zero and random patterns to ensure different bit patterns physically overwrite the disk, ending on your selected mode.
|
|
235
|
+
> **Note:** Multi-pass sofware (Zero and Rand) wipes (2 or 4 passes) alternate between zero and random patterns to ensure different bit patterns physically overwrite the disk, ending on your selected mode.
|
|
198
236
|
|
|
199
237
|
### Resuming Stopped Wipes
|
|
200
238
|
|
|
201
|
-
Stopped wipes (state **s**) can be resumed by pressing **w** on the device
|
|
239
|
+
Stopped wipes (state **s**) can be resumed by pressing **w** on the device. Choose the same type of wipe or it will start over at 0% complete.
|
|
202
240
|
|
|
203
241
|
**How Resume Works:**
|
|
204
242
|
- Preserves the original wipe mode (Rand or Zero) from when the wipe was started
|
|
205
243
|
- Uses the **current** passes setting to determine how much more to write
|
|
206
|
-
- Continues from the exact byte offset where it stopped (rounded to buffer boundary)
|
|
207
|
-
- Smart validation ensures interrupted wipes resume with correct pattern integrity
|
|
244
|
+
- Continues from the exact byte offset where it marked that stopped (rounded to buffer boundary). "Marks" are written about every 30s so for non-gracefully ended wipes, the position may be as much as 30s (or somewhat more) from the last wiped disk blocks.
|
|
208
245
|
|
|
209
246
|
**Resume Examples:**
|
|
210
247
|
|
|
@@ -259,7 +296,7 @@ Stopped wipes (state **s**) can be resumed by pressing **w** on the device:
|
|
|
259
296
|
|
|
260
297
|
### Progress Information
|
|
261
298
|
|
|
262
|
-
When wiping a device, `dwipe` displays:
|
|
299
|
+
When software wiping a device, `dwipe` displays:
|
|
263
300
|
- **Elapsed time** - Time since wipe started (e.g., 1m18s)
|
|
264
301
|
- **Remaining time** - Estimated time to completion (e.g., -3m6s)
|
|
265
302
|
- **Write rate** - Current throughput (e.g., "45.2MB/s")
|
|
@@ -317,7 +354,7 @@ Press **ESC** from the main screen to clear the filter and return to showing all
|
|
|
317
354
|
|
|
318
355
|
## Security Considerations
|
|
319
356
|
|
|
320
|
-
**Important limitations:**
|
|
357
|
+
**Important limitations of software wipes:**
|
|
321
358
|
|
|
322
359
|
- `dwipe` supports multi-pass wiping with alternating patterns, but does not implement specific DoD 5220.22-M or Gutmann certified pattern sequences
|
|
323
360
|
- More than adequate for **personal and business data** that doesn't require (antiquated) certified destruction
|
|
@@ -330,8 +367,7 @@ Press **ESC** from the main screen to clear the filter and return to showing all
|
|
|
330
367
|
|
|
331
368
|
**Best practices:**
|
|
332
369
|
- Verify device labels and sizes carefully before wiping
|
|
333
|
-
- Use the **
|
|
334
|
-
- Test with `--dry-run` first if unsure
|
|
370
|
+
- Use the **Block** feature to protect critical disks
|
|
335
371
|
- Consider encryption for sensitive data as the primary security measure
|
|
336
372
|
|
|
337
373
|
---
|
|
@@ -350,7 +386,7 @@ Press **ESC** from the main screen to clear the filter and return to showing all
|
|
|
350
386
|
### Wipe issues
|
|
351
387
|
- **Can't wipe a device** - Check the STATE column:
|
|
352
388
|
- **Mnt** - Unmount the partition first: `sudo umount /dev/sdXN`
|
|
353
|
-
- **
|
|
389
|
+
- **Blk** - Press **b** to unblock
|
|
354
390
|
- **Busy** - Another partition on the disk is being wiped
|
|
355
391
|
- **Wipe is very slow** - Normal for large drives; check write rate to verify progress
|
|
356
392
|
- **Wipe seems stuck** - Most likely due to bad disks; Direct I/O makes progress almost constant on good disks.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
dwipe/DeviceInfo.py,sha256=BMl591jzmmpaH3CeWv3iA65RhUkk_-PaefcxIQ7bNVo,31712
|
|
2
|
+
dwipe/DiskWipe.py,sha256=tCJ3Aw0DwbMV_tO7RLmlsu0Y5C8QBVinw21dznWmkQQ,53990
|
|
3
|
+
dwipe/DrivePreChecker.py,sha256=FKLHfYoXHwHVUbta4Jsq57I49bCFRm1dHzvG6BncH18,3422
|
|
4
|
+
dwipe/FirmwareWipeTask.py,sha256=Eu5nbT8pXlWC7Ln66_2aKD_evnmO8KB9_mnHTbEE_1U,12796
|
|
5
|
+
dwipe/LsblkMonitor.py,sha256=-Mya8yZjuLeDvzypgzHUmYSTK_atgw8jfpM9ZAnIA7U,4012
|
|
6
|
+
dwipe/PersistentState.py,sha256=p30kd2arMUIWdDf9L5TSfv8usNWNiSY_cO1h1lO2JKg,7363
|
|
7
|
+
dwipe/Prereqs.py,sha256=_O8-DV1mBIxK9OKKyFO7iBYOqBPjYDbCG8zyit7SFuY,2993
|
|
8
|
+
dwipe/StructuredLogger.py,sha256=K792eYnVsBIgkbd9hl4QzBLrhGOWNo5t2OooqlQcjHo,23623
|
|
9
|
+
dwipe/ToolManager.py,sha256=NuGLnZEEX-N9tDm-My_PpaAlkUUuoPjtPE68Az2oqo8,22890
|
|
10
|
+
dwipe/Utils.py,sha256=pb16IfIISnOu9hUb0JcegoblBxfw_RV2gB323GkhFeA,11263
|
|
11
|
+
dwipe/VerifyTask.py,sha256=WnOj5nY8wgKafIQFVWQ9-fNSE7bzLkXTzut5u_7QtkY,16925
|
|
12
|
+
dwipe/WipeJob.py,sha256=LCGHk2ZPAjyN3gSLSjRJLNEoep06fTb1P57FFD3-ySo,72767
|
|
13
|
+
dwipe/WipeTask.py,sha256=TvXADaBtNJDlyK8Rc3b4zklgkbyN_mdzp97o9RLrZZY,5382
|
|
14
|
+
dwipe/WriteTask.py,sha256=kXLmiT6BEhyNCQYHyinhdcgeSo8SaC2JQumpsyiBTJ8,16178
|
|
15
|
+
dwipe/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
16
|
+
dwipe/main.py,sha256=0vnTIRfrKMI8jw9uCmlkW-O1KzqfhqTTD2ETrGHno18,2051
|
|
17
|
+
dwipe-2.0.2.dist-info/entry_points.txt,sha256=SZHFezmse2c-jxG-BJ0TXy_TZ8vVFf0lPJWs0cdxz6Y,41
|
|
18
|
+
dwipe-2.0.2.dist-info/licenses/LICENSE,sha256=qB9OdnyyF6WYHiEIXVm0rOSdcf8e2ctorrtWs6CC5lU,1062
|
|
19
|
+
dwipe-2.0.2.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
|
|
20
|
+
dwipe-2.0.2.dist-info/METADATA,sha256=QuNSVa17wMNUM5YSjHKEpLRAPx0rqqnByaBerSb2MmE,24627
|
|
21
|
+
dwipe-2.0.2.dist-info/RECORD,,
|
dwipe/WipeJobFuture.py
DELETED
|
@@ -1,245 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Docstring for dwipe.WipeJobFuture. Probably, only winners here are:
|
|
3
|
-
- Detailed Status Dict - Returns structured status.
|
|
4
|
-
Low risk but not urgent since current status works fine.
|
|
5
|
-
- Custom Pattern Sequences - Adds 0xFF pattern support.
|
|
6
|
-
Low risk but adds complexity.
|
|
7
|
-
"""
|
|
8
|
-
|
|
9
|
-
class MaybeSomeDay:
|
|
10
|
-
def __init__(self, device_path, total_size, opts=None, resume_from=0, resume_mode=None):
|
|
11
|
-
""" Performance Throttling """
|
|
12
|
-
# ... existing initialization ...
|
|
13
|
-
|
|
14
|
-
# Performance throttling
|
|
15
|
-
self.max_speed_mbps = getattr(opts, 'max_speed_mbps', 0) # 0 = unlimited
|
|
16
|
-
self.min_speed_mbps = getattr(opts, 'min_speed_mbps', 0) # Minimum speed to trigger stall detection
|
|
17
|
-
|
|
18
|
-
# Stall detection and recovery
|
|
19
|
-
self.stall_timeout = getattr(opts, 'stall_timeout', 300) # Seconds before stall recovery (5 min)
|
|
20
|
-
self.last_progress_time = time.monotonic()
|
|
21
|
-
self.last_progress_bytes = resume_from
|
|
22
|
-
|
|
23
|
-
# Adaptive block sizing
|
|
24
|
-
self.adaptive_block_size = getattr(opts, 'adaptive_block_size', False)
|
|
25
|
-
self.current_write_size = WipeJob.WRITE_SIZE
|
|
26
|
-
|
|
27
|
-
# Temperature monitoring (for SSDs)
|
|
28
|
-
self.check_temperature = getattr(opts, 'check_temperature', False)
|
|
29
|
-
self.last_temp_check = 0
|
|
30
|
-
self.temp_check_interval = 60 # seconds
|
|
31
|
-
|
|
32
|
-
# Energy-efficient mode
|
|
33
|
-
self.energy_saver = getattr(opts, 'energy_saver', False)
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
def _throttle_write_speed(self, bytes_written, start_time):
|
|
39
|
-
"""Throttle write speed to specified maximum"""
|
|
40
|
-
if self.max_speed_mbps <= 0:
|
|
41
|
-
return
|
|
42
|
-
|
|
43
|
-
elapsed = time.monotonic() - start_time
|
|
44
|
-
if elapsed <= 0:
|
|
45
|
-
return
|
|
46
|
-
|
|
47
|
-
actual_speed_mbps = (bytes_written / (1024 * 1024)) / elapsed
|
|
48
|
-
if actual_speed_mbps > self.max_speed_mbps:
|
|
49
|
-
# Calculate how long to sleep to hit target speed
|
|
50
|
-
target_time = (bytes_written / (1024 * 1024)) / self.max_speed_mbps
|
|
51
|
-
sleep_time = target_time - elapsed
|
|
52
|
-
if sleep_time > 0:
|
|
53
|
-
time.sleep(sleep_time)
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
def _check_ssd_temperature(self):
|
|
58
|
-
"""Check SSD temperature and throttle if too hot"""
|
|
59
|
-
if not self.check_temperature:
|
|
60
|
-
return
|
|
61
|
-
|
|
62
|
-
now = time.monotonic()
|
|
63
|
-
if now - self.last_temp_check < self.temp_check_interval:
|
|
64
|
-
return
|
|
65
|
-
|
|
66
|
-
self.last_temp_check = now
|
|
67
|
-
|
|
68
|
-
try:
|
|
69
|
-
# Try to read temperature from SMART or sysfs
|
|
70
|
-
device_name = os.path.basename(self.device_path)
|
|
71
|
-
|
|
72
|
-
# Check sysfs for temperature
|
|
73
|
-
temp_paths = [
|
|
74
|
-
f"/sys/block/{device_name}/device/hwmon/hwmon*/temp1_input",
|
|
75
|
-
f"/sys/block/{device_name}/device/temperature",
|
|
76
|
-
]
|
|
77
|
-
|
|
78
|
-
for temp_path in temp_paths:
|
|
79
|
-
for path in glob.glob(temp_path):
|
|
80
|
-
try:
|
|
81
|
-
with open(path, 'r') as f:
|
|
82
|
-
temp_millic = int(f.read().strip())
|
|
83
|
-
temp_c = temp_millic // 1000
|
|
84
|
-
|
|
85
|
-
if temp_c > 70: # Throttle if >70°C
|
|
86
|
-
# Reduce speed by 50%
|
|
87
|
-
old_max = self.max_speed_mbps
|
|
88
|
-
self.max_speed_mbps = max(10, old_max // 2)
|
|
89
|
-
if old_max != self.max_speed_mbps:
|
|
90
|
-
print(f"Temperature {temp_c}°C: Throttling to {self.max_speed_mbps} MB/s")
|
|
91
|
-
elif temp_c < 60 and self.max_speed_mbps != getattr(self.opts, 'max_speed_mbps', 0):
|
|
92
|
-
# Restore speed if cooled down
|
|
93
|
-
self.max_speed_mbps = getattr(self.opts, 'max_speed_mbps', 0)
|
|
94
|
-
|
|
95
|
-
except (OSError, ValueError):
|
|
96
|
-
continue
|
|
97
|
-
|
|
98
|
-
except Exception:
|
|
99
|
-
pass
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
def _energy_saver_write(self, fd, chunk, is_random_pass):
|
|
107
|
-
"""Write with energy saving considerations"""
|
|
108
|
-
if not self.energy_saver:
|
|
109
|
-
return os.write(fd, chunk)
|
|
110
|
-
|
|
111
|
-
# For energy saving:
|
|
112
|
-
# 1. Group writes
|
|
113
|
-
# 2. Add small delays between writes
|
|
114
|
-
# 3. Use larger blocks when possible
|
|
115
|
-
|
|
116
|
-
bytes_written = 0
|
|
117
|
-
chunk_size = len(chunk)
|
|
118
|
-
|
|
119
|
-
while bytes_written < chunk_size:
|
|
120
|
-
write_size = min(self.current_write_size, chunk_size - bytes_written)
|
|
121
|
-
sub_chunk = chunk[bytes_written:bytes_written + write_size]
|
|
122
|
-
|
|
123
|
-
# Write the chunk
|
|
124
|
-
written = os.write(fd, sub_chunk)
|
|
125
|
-
bytes_written += written
|
|
126
|
-
|
|
127
|
-
# Small delay for energy saving
|
|
128
|
-
if bytes_written < chunk_size:
|
|
129
|
-
time.sleep(0.001) # 1ms delay
|
|
130
|
-
|
|
131
|
-
# Update progress
|
|
132
|
-
self.total_written += written
|
|
133
|
-
|
|
134
|
-
return bytes_written
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
def _adjust_block_size(self, write_success, write_time):
|
|
143
|
-
"""Dynamically adjust block size based on performance"""
|
|
144
|
-
if not self.adaptive_block_size:
|
|
145
|
-
return
|
|
146
|
-
|
|
147
|
-
if write_success:
|
|
148
|
-
# Successful write - consider increasing block size
|
|
149
|
-
speed_mbps = (self.current_write_size / (1024 * 1024)) / write_time if write_time > 0 else 0
|
|
150
|
-
|
|
151
|
-
if speed_mbps > 100: # Good speed, try larger blocks
|
|
152
|
-
new_size = min(WipeJob.WRITE_SIZE * 4, self.current_write_size * 2)
|
|
153
|
-
if new_size != self.current_write_size:
|
|
154
|
-
self.current_write_size = new_size
|
|
155
|
-
print(f"Increased block size to {new_size // 1024}KB")
|
|
156
|
-
else:
|
|
157
|
-
# Write failed or slow - reduce block size
|
|
158
|
-
new_size = max(WipeJob.BLOCK_SIZE, self.current_write_size // 2)
|
|
159
|
-
if new_size != self.current_write_size:
|
|
160
|
-
self.current_write_size = new_size
|
|
161
|
-
print(f"Reduced block size to {new_size // 1024}KB")
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
def get_detailed_status(self):
|
|
170
|
-
"""Get detailed status including speed, ETA, and health metrics"""
|
|
171
|
-
elapsed, pct_str, rate_str, eta_str = self.get_status()
|
|
172
|
-
|
|
173
|
-
status = {
|
|
174
|
-
'elapsed': elapsed,
|
|
175
|
-
'percentage': pct_str,
|
|
176
|
-
'rate': rate_str,
|
|
177
|
-
'eta': eta_str,
|
|
178
|
-
'bytes_written': self.total_written,
|
|
179
|
-
'total_bytes': self.total_size * self.passes,
|
|
180
|
-
'current_pass': self.current_pass + 1 if not self.verify_phase else 'Verifying',
|
|
181
|
-
'total_passes': self.passes,
|
|
182
|
-
'verify_phase': self.verify_phase,
|
|
183
|
-
'verify_result': self.verify_result if hasattr(self, 'verify_result') else None,
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
# Add adaptive block size info if enabled
|
|
187
|
-
if self.adaptive_block_size:
|
|
188
|
-
status['block_size_kb'] = self.current_write_size // 1024
|
|
189
|
-
|
|
190
|
-
# Add throttle info if enabled
|
|
191
|
-
if self.max_speed_mbps > 0:
|
|
192
|
-
status['max_speed_mbps'] = self.max_speed_mbps
|
|
193
|
-
|
|
194
|
-
return status
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
def get_custom_pattern(self, pass_number):
|
|
200
|
-
"""Get custom write pattern if specified"""
|
|
201
|
-
custom_patterns = getattr(self.opts, 'custom_patterns', None)
|
|
202
|
-
if custom_patterns and pass_number < len(custom_patterns):
|
|
203
|
-
pattern = custom_patterns[pass_number]
|
|
204
|
-
if pattern == 'random':
|
|
205
|
-
return True
|
|
206
|
-
elif pattern == 'zeros':
|
|
207
|
-
return False
|
|
208
|
-
elif pattern == 'ones':
|
|
209
|
-
# Special pattern: all ones (0xFF)
|
|
210
|
-
return 'ones'
|
|
211
|
-
|
|
212
|
-
# Fall back to standard pattern
|
|
213
|
-
mode_to_use = self.resume_mode if self.resume_mode else self.opts.wipe_mode.replace('+V', '')
|
|
214
|
-
return self.get_pass_pattern(pass_number, mode_to_use)
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
def run_benchmark(self, duration_seconds=30):
|
|
220
|
-
"""Run a benchmark to determine optimal settings"""
|
|
221
|
-
print(f"Running benchmark for {duration_seconds} seconds...")
|
|
222
|
-
|
|
223
|
-
benchmark_results = []
|
|
224
|
-
test_sizes = [4*1024, 64*1024, 512*1024, 1024*1024, 4*1024*1024] # 4KB to 4MB
|
|
225
|
-
|
|
226
|
-
for test_size in test_sizes:
|
|
227
|
-
self.current_write_size = test_size
|
|
228
|
-
start_time = time.monotonic()
|
|
229
|
-
bytes_written = 0
|
|
230
|
-
|
|
231
|
-
# Test write for duration_seconds
|
|
232
|
-
while time.monotonic() - start_time < duration_seconds:
|
|
233
|
-
# Perform test write
|
|
234
|
-
# ... benchmark logic ...
|
|
235
|
-
pass
|
|
236
|
-
|
|
237
|
-
speed_mbps = bytes_written / (1024 * 1024) / duration_seconds
|
|
238
|
-
benchmark_results.append((test_size, speed_mbps))
|
|
239
|
-
print(f" Block size {test_size//1024}KB: {speed_mbps:.2f} MB/s")
|
|
240
|
-
|
|
241
|
-
# Find optimal block size
|
|
242
|
-
optimal_size = max(benchmark_results, key=lambda x: x[1])[0]
|
|
243
|
-
print(f"Optimal block size: {optimal_size//1024}KB")
|
|
244
|
-
|
|
245
|
-
return optimal_size
|
dwipe-2.0.1.dist-info/RECORD
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
dwipe/DeviceInfo.py,sha256=7ZgtLDT1z5QwMWVwEb9Q3-wonvuPyAWgl7Xl5o14XbY,25777
|
|
2
|
-
dwipe/DiskWipe.py,sha256=SVfcGDMZccGBocpS5U8JXI-Y2UzRix3jAzzaYPVRCDc,40161
|
|
3
|
-
dwipe/PersistentState.py,sha256=FZydQs_-VYiq-Gw0hvcWPeuWOU5VFgI-FvrUsbT92RQ,6339
|
|
4
|
-
dwipe/ToolManager.py,sha256=EpG_588Q76IzFfjrTM5LSnhTUC1CoBeCUdqtR0duliY,23371
|
|
5
|
-
dwipe/Utils.py,sha256=Cuq8Usamrq1DWUk8EtjTuD6lSLXYGY0x-pDcoLJBR8M,7714
|
|
6
|
-
dwipe/WipeJob.py,sha256=bjv_hVuH5DBDgY5-y3Mv11URhsBu1t1iu8lx76dmAhE,54486
|
|
7
|
-
dwipe/WipeJobFuture.py,sha256=urkrASHtqELsKQ5c7OMc_LxpgIiYAIOeb1ZixQYmp74,8746
|
|
8
|
-
dwipe/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
|
-
dwipe/main.py,sha256=Zyw9LFBGqWYxga1H9qTdQGHLyCsxZUg3tm_Ylj20FG4,1841
|
|
10
|
-
dwipe-2.0.1.dist-info/entry_points.txt,sha256=SZHFezmse2c-jxG-BJ0TXy_TZ8vVFf0lPJWs0cdxz6Y,41
|
|
11
|
-
dwipe-2.0.1.dist-info/licenses/LICENSE,sha256=qB9OdnyyF6WYHiEIXVm0rOSdcf8e2ctorrtWs6CC5lU,1062
|
|
12
|
-
dwipe-2.0.1.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
|
|
13
|
-
dwipe-2.0.1.dist-info/METADATA,sha256=kcykkG3kr9kyZ0T6nUN_dGCxbC3E2fh26HovbCnqGD4,21957
|
|
14
|
-
dwipe-2.0.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|