dcantrell / pyparted

Python bindings for GNU parted (libparted)
GNU General Public License v2.0
85 stars 42 forks source link

Trouble formatting an SD card #104

Open cmcquinn opened 11 months ago

cmcquinn commented 11 months ago

I am trying to use pyparted to automatically format and mount a MicroSD card when it is inserted into an embedded linux system. I basically copied the make_one_primary_partition.py example script, but it does not seem to detect the size of my MicroSD card correctly. Here is the output from my script:

DEBUG - created parted.Device instance --
   model:   path: /dev/mmcblk1  type: 5
   sectorSize: 512  physicalSectorSize:  512
   length: 2  openCount: 0  readOnly: False
   externalMode: False  dirty: False  bootDirty: False
   host: 127  did: 0  busy: False
   hardwareGeometry: (0, 4, 32)  biosGeometry: (0, 4, 32)
   PedDevice: <_ped.Device object at 0x7f93dfedc0>
 DEBUG - created parted.Disk instance --
   type: msdos  primaryPartitionCount: 0
   lastPartitionNumber: -1  maxPrimaryPartitionCount: 4
   partitions: []
   device: <parted.device.Device object at 0x7f93dbd520>
   PedDisk: <_ped.Disk object at 0x7f93dc2980>
 DEBUG - created parted.Geometry instance --
   start: 0  end: 1  length: 2
   device: <parted.device.Device object at 0x7f93dbd700>  PedGeometry: <_ped.Geometry object at 0x7f93dbd490>
 DEBUG - created parted.FileSystem instance --
   type: fat32  geometry: <parted.geometry.Geometry object at 0x7f93dbd6a0>  checked: False
   PedFileSystem: <_ped.FileSystem object at 0x7f93dc29c0>
 DEBUG - created parted.Partition instance --
   disk: <parted.disk.Disk object at 0x7f93dbd3a0>  fileSystem: <parted.filesystem.FileSystem object at 0x7f93dbd790>
   number: -1  path: /dev/mmcblk1p-1  type: 0
   name: None  active: True  busy: False
   geometry: <parted.geometry.Geometry object at 0x7f93dbd6a0>  PedPartition: <_ped.Partition object at 0x7f93dd76d0>
 Traceback (most recent call last):
   File "/usr/bin/sdcard-formatter", line 11, in <module>
     load_entry_point('disk-formatter==1.0', 'console_scripts', 'sdcard-formatter')()
   File "/usr/lib/python3.8/site-packages/disk_formatter/sdcard_formatter.py", line 88, in main
     mount_sdcard(args.devnode)
   File "/usr/lib/python3.8/site-packages/disk_formatter/sdcard_formatter.py", line 43, in mount_sdcard
     if not disk.partition():
   File "/usr/lib/python3.8/site-packages/disk_formatter/disk_formatter.py", line 106, in partition
     disk.addPartition(
   File "/usr/lib/python3.8/site-packages/parted/decorators.py", line 42, in new
     ret = fn(*args, **kwds)
   File "/usr/lib/python3.8/site-packages/parted/disk.py", line 244, in addPartition
     result = self.__disk.add_partition(partition.getPedPartition(),
 _ped.PartitionException: Unable to satisfy all constraints on the partition.

The code for the function that is failing:

 def partition(self):
        """
        Create a partition table on the block device.
        """
        self.logger.info("creating primary partition")
        device = parted.getDevice(self.path)
        self.logger.debug("created %s", device)

        if self.filesystem is Filesystem.EXT4:
            disk = parted.freshDisk(device, "gpt")
        elif self.filesystem is Filesystem.FAT32:
            disk = parted.freshDisk(device, "msdos")

        self.logger.debug("created %s", disk)
        disk.commit()

        geometry = disk.getFreeSpaceRegions()[-1]
        self.logger.debug("created %s", geometry)

        filesystem = parted.FileSystem(
            type=self.filesystem.name.lower(), geometry=geometry
        )

        self.logger.debug("created %s", filesystem)
        partition = parted.Partition(
            disk=disk, type=parted.PARTITION_NORMAL, fs=filesystem, geometry=geometry
        )
        self.logger.debug("created %s", partition)
        disk.addPartition(
            partition=partition, constraint=device.optimalAlignedConstraint
        )
        disk.commit()

        if not self._wait_for_partition():
            return False

        # create filesystem
        try:
            subprocess.run(
                f"mkfs.{self.filesystem.name.lower()} {self.partition_path}".split(),
                check=True,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                encoding="UTF-8",
            )
            self.logger.debug(
                "Created %s fs on %s", self.filesystem.name.lower(), self.partition_path
            )
            return True
        except subprocess.CalledProcessError as error:
            self.logger.error(
                "mkfs.%s failed: %s", self.filesystem.name.lower(), error.stderr
            )
            return False

I am using PyParted commit 481510c10866851844b19f3d2ffcdaa37efc0cf8 (3.11.3) and parted 3.3.