Vanillaice
Vanillaice

Reputation: 55

What is the fastest way to overwrite everything on SD card with 0s

I have this class method that handles the writing of 0s to an SD card via dd:

    def run(self):
        try:
            print("[DEBUG] Starting zeroing process...")
            # Get the size of the device
            size_output = subprocess.check_output(['blockdev', '--getsize64', self.selected_device]).decode().strip()
            device_size = int(size_output)

            # Start the dd process
            dd_process = subprocess.Popen(
                ['dd', 'if=/dev/zero', f'of={self.selected_device}', 'bs=16M', 'status=progress'],
                stderr=subprocess.PIPE,
                universal_newlines=True
            )

            # Regex to capture progress information
            progress_pattern = re.compile(r'(\d+) bytes')

            for line in dd_process.stderr:
                print(f"[DEBUG] dd output: {line.strip()}")
                match = progress_pattern.search(line)
                if match:
                    bytes_written = int(match.group(1))
                    progress_value = min(int((bytes_written / device_size) * 100), 100)
                    print(f"[DEBUG] Zeroing progress: {progress_value}%")
                    self.zero_progress_update.emit(progress_value)

            # Wait for the dd process to finish
            dd_process.wait()

            # Check if the process completed successfully or with the expected "No space left on device" error
            dd_stderr_output = dd_process.stderr.read()
            if dd_process.returncode != 0:
                print("Returned an error code...")
                if "No space left on device" in dd_stderr_output:
                    print("[DEBUG] No space left on device, zeroing process completed successfully.")
                    self.zero_progress_update.emit(100)
                    self.finished.emit()
                else:
                    print("Passing error code into exception handler")
                    raise subprocess.CalledProcessError(dd_process.returncode, 'dd', output=dd_stderr_output)
            else:
                print("[DEBUG] Zeroing process completed successfully.")
                self.finished.emit()

        except subprocess.CalledProcessError as e:
            # Handle CalledProcessError properly
            error_output = e.output if e.output else str(e)
            if "No space left on device" in error_output:
                print("[DEBUG] Zeroing process completed successfully (device fully written).")
                self.zero_progress_update.emit(100)
                self.finished.emit()
            else:
                print(f"[ERROR] Exception occurred during zeroing (scenario 1): {error_output}")
                self.error_occurred.emit(error_output)
        except Exception as e:
            print(f"[ERROR] Exception occurred during zeroing (scenario 2): {str(e)}")
            self.error_occurred.emit(str(e))

Writing to the SD card until runs out of space is a pretty time consuming process though.

I initially was using bs=4M and tried bumping it up to bs=16m but I honestly don't think it made a difference.

I also tried adding these:

            # Start the dd process
            dd_process = subprocess.Popen(
                ['dd', 'if=/dev/zero', f'of={self.selected_device}', 'bs=16M', 'oflag=direct', 'conv=fdatasync', 'status=progress'],
                stderr=subprocess.PIPE,
                universal_newlines=True
            )

But I think it made things even slower somehow, or at the very least it made no noticeable improvements.

Is there anything that can be done or does this entirely depend on the actual SD card being used?

Upvotes: 2

Views: 71

Answers (0)

Related Questions