1
0
Fork
You've already forked pyparted
1

Strange disc.commit() behavior #73

Open
opened 2020年03月20日 11:27:10 +01:00 by marcel-behlau-elfin · 0 comments
marcel-behlau-elfin commented 2020年03月20日 11:27:10 +01:00 (Migrated from github.com)
Copy link

Hi,

i observed a strange behavior of the disc.commit() function.

I would expect, that i have to perform a commit after applying all necessary operations.

For reproducing, i created a simple test application:

#!/usr/bin/env python
#
# Requirements:
# - python
# - python-dev
# - pyparted
import parted
# Create a disk image then attach it to a loopback device (e.g. /dev/loop0)
'''
dd if=/dev/zero of=disk.img bs=512 count=2097152
losetup -f disk.img
'''
alwaysCommit = False
commitBeforeExtended = True
lengthModifier = 0
devicePath = '/dev/loop0'
device = parted.getDevice(devicePath)
disk = parted.freshDisk(device, "msdos")
# create partition 1
geometry1 = parted.Geometry(device=device, start=1, length=parted.sizeToSectors(16, 'MiB', device.sectorSize))
filesystem1 = parted.FileSystem(type='fat32', geometry=geometry1)
partition1 = parted.Partition(disk=disk,
 type=parted.PARTITION_NORMAL,
 fs=filesystem1,
 geometry=geometry1)
disk.addPartition(partition1, constraint=device.optimalAlignedConstraint)
if alwaysCommit:
 disk.commit()
# partition 2
geometry2 = parted.Geometry(device=device, start=partition1.geometry.end + 1,
 length=parted.sizeToSectors(512, 'MiB', device.sectorSize))
filesystem2 = parted.FileSystem(type='ext4', geometry=geometry2)
partition2 = parted.Partition(disk=disk,
 type=parted.PARTITION_NORMAL,
 fs=filesystem2,
 geometry=geometry2)
disk.addPartition(partition2, constraint=device.optimalAlignedConstraint)
if alwaysCommit:
 disk.commit()
# partition 3
geometry3 = parted.Geometry(device=device, start=partition2.geometry.end + 1,
 length=parted.sizeToSectors(512, 'MiB', device.sectorSize))
filesystem3 = parted.FileSystem(type='ext4', geometry=geometry3)
partition3 = parted.Partition(disk=disk,
 type=parted.PARTITION_NORMAL,
 fs=filesystem3,
 geometry=geometry3)
disk.addPartition(partition3, constraint=device.optimalAlignedConstraint)
if alwaysCommit or commitBeforeExtended:
 disk.commit()
# partition 4: Extended
geometry4 = parted.Geometry(device=device, start=partition3.geometry.end + 1,
 end=device.length-lengthModifier)
partition4 = parted.Partition(disk=disk,
 type=parted.PARTITION_EXTENDED,
 geometry=geometry4)
disk.addPartition(partition4, constraint=device.optimalAlignedConstraint)
if alwaysCommit:
 disk.commit()
# partition 5: Logical
geometry5 = parted.Geometry(device=device, start=partition4.geometry.start + 1,
 length=parted.sizeToSectors(256, 'MiB', device.sectorSize))
filesystem5 = parted.FileSystem(type='ext4', geometry=geometry5)
partition5 = parted.Partition(disk=disk,
 type=parted.PARTITION_LOGICAL,
 fs=filesystem5,
 geometry=geometry5)
disk.addPartition(partition5, constraint=device.optimalAlignedConstraint)
if alwaysCommit:
 disk.commit()
# partition 6: Logical
geometry6 = parted.Geometry(device=device, start=partition5.geometry.end + 1,
 length=parted.sizeToSectors(256, 'MiB', device.sectorSize))
filesystem6 = parted.FileSystem(type='ext4', geometry=geometry6)
partition6 = parted.Partition(disk=disk,
 type=parted.PARTITION_LOGICAL,
 fs=filesystem6,
 geometry=geometry6)
disk.addPartition(partition6, constraint=device.optimalAlignedConstraint)
disk.commit()

My first thought was to use the options as follows, but the operation fails

alwaysCommit = False
commitBeforeExtended = False
lengthModifier = 0
[marcel@elfin-behlau pat]$ sudo ./test.py 
Traceback (most recent call last):
 File "./test.py", line 67, in <module>
 disk.addPartition(partition4, constraint=device.optimalAlignedConstraint)
 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: Can't have a partition outside the disk!

This can be fixed by using an length modifier, but the "hack" fails with an assert.

alwaysCommit = False
commitBeforeExtended = False
lengthModifier = 1
Backtrace has 20 calls on stack:
 20: /usr/lib/libparted.so.2(ped_assert+0x46) [0x7fdc917e6476]
 19: /usr/lib/libparted.so.2(+0x259da) [0x7fdc917fd9da]
 18: /usr/lib/libparted.so.2(+0x1307a) [0x7fdc917eb07a]
 17: /usr/lib/libparted.so.2(ped_disk_add_partition+0x1ce) [0x7fdc917eb8fe]
 16: /usr/lib/python3.8/site-packages/_ped.cpython-38-x86_64-linux-gnu.so(py_ped_disk_add_partition+0xcc) [0x7fdc918c259c]
 15: /usr/lib/libpython3.8.so.1.0(+0x16eb07) [0x7fdc91dd1b07]
 14: /usr/lib/libpython3.8.so.1.0(_PyEval_EvalFrameDefault+0x7de) [0x7fdc91e520ce]
 13: /usr/lib/libpython3.8.so.1.0(_PyEval_EvalCodeWithName+0x3cb) [0x7fdc91e3ee3b]
 12: /usr/lib/libpython3.8.so.1.0(_PyFunction_Vectorcall+0x39b) [0x7fdc91e4024b]
 11: /usr/lib/libpython3.8.so.1.0(PyObject_Call+0x2f8) [0x7fdc91d91418]
 10: /usr/lib/libpython3.8.so.1.0(_PyEval_EvalFrameDefault+0x2413) [0x7fdc91e53d03]
 9: /usr/lib/libpython3.8.so.1.0(_PyEval_EvalCodeWithName+0x3cb) [0x7fdc91e3ee3b]
 8: /usr/lib/libpython3.8.so.1.0(+0x1dd892) [0x7fdc91e40892]
 7: /usr/lib/libpython3.8.so.1.0(_PyEval_EvalFrameDefault+0x11ac) [0x7fdc91e52a9c]
 6: /usr/lib/libpython3.8.so.1.0(_PyEval_EvalCodeWithName+0x3cb) [0x7fdc91e3ee3b]
 5: /usr/lib/libpython3.8.so.1.0(PyEval_EvalCode+0x23) [0x7fdc91ec83d3]
 4: /usr/lib/libpython3.8.so.1.0(+0x265428) [0x7fdc91ec8428]
 3: /usr/lib/libpython3.8.so.1.0(+0x269623) [0x7fdc91ecc623]
 2: /usr/lib/libpython3.8.so.1.0(PyRun_FileExFlags+0x97) [0x7fdc91d673e7]
 1: /usr/lib/libpython3.8.so.1.0(PyRun_SimpleFileExFlags+0x390) [0x7fdc91d71f4a]
Aborted

Committing after adding an partition, results in strange partition size ( loop0p2 is only 255M instead of 512M, /dev/loop0p3 is 510M)

alwaysCommit = True
commitBeforeExtended = False
lengthModifier = 0
Disk /dev/loop0: 4 GiB, 4294967296 bytes, 8388608 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xb80d081d
Device Boot Start End Sectors Size Id Type
/dev/loop0p1 1 32768 32768 16M b W95 FAT32
/dev/loop0p2 522240 1044479 522240 255M 83 Linux
/dev/loop0p3 1044480 2088959 1044480 510M 83 Linux
/dev/loop0p4 2088960 8355839 6266880 3G 5 Extended
/dev/loop0p5 2091008 2611199 520192 254M 83 Linux
/dev/loop0p6 2613248 3133439 520192 254M 83 Linux

Only if i commit before creating the extended partion, everything works as expected:

alwaysCommit = False
commitBeforeExtended = False
lengthModifier = 1
Disk /dev/loop0: 4 GiB, 4294967296 bytes, 8388608 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x265e0c9c
Device Boot Start End Sectors Size Id Type
/dev/loop0p1 1 32768 32768 16M b W95 FAT32
/dev/loop0p2 32769 1081344 1048576 512M 83 Linux
/dev/loop0p3 1081345 2129920 1048576 512M 83 Linux
/dev/loop0p4 2611200 8355839 5744640 2.8G 5 Extended
/dev/loop0p5 2613248 3133439 520192 254M 83 Linux
/dev/loop0p6 3135488 3655679 520192 254M 83 Linux
Hi, i observed a strange behavior of the disc.commit() function. I would expect, that i have to perform a commit after applying all necessary operations. For reproducing, i created a simple test application: ``` #!/usr/bin/env python # # Requirements: # - python # - python-dev # - pyparted import parted # Create a disk image then attach it to a loopback device (e.g. /dev/loop0) ''' dd if=/dev/zero of=disk.img bs=512 count=2097152 losetup -f disk.img ''' alwaysCommit = False commitBeforeExtended = True lengthModifier = 0 devicePath = '/dev/loop0' device = parted.getDevice(devicePath) disk = parted.freshDisk(device, "msdos") # create partition 1 geometry1 = parted.Geometry(device=device, start=1, length=parted.sizeToSectors(16, 'MiB', device.sectorSize)) filesystem1 = parted.FileSystem(type='fat32', geometry=geometry1) partition1 = parted.Partition(disk=disk, type=parted.PARTITION_NORMAL, fs=filesystem1, geometry=geometry1) disk.addPartition(partition1, constraint=device.optimalAlignedConstraint) if alwaysCommit: disk.commit() # partition 2 geometry2 = parted.Geometry(device=device, start=partition1.geometry.end + 1, length=parted.sizeToSectors(512, 'MiB', device.sectorSize)) filesystem2 = parted.FileSystem(type='ext4', geometry=geometry2) partition2 = parted.Partition(disk=disk, type=parted.PARTITION_NORMAL, fs=filesystem2, geometry=geometry2) disk.addPartition(partition2, constraint=device.optimalAlignedConstraint) if alwaysCommit: disk.commit() # partition 3 geometry3 = parted.Geometry(device=device, start=partition2.geometry.end + 1, length=parted.sizeToSectors(512, 'MiB', device.sectorSize)) filesystem3 = parted.FileSystem(type='ext4', geometry=geometry3) partition3 = parted.Partition(disk=disk, type=parted.PARTITION_NORMAL, fs=filesystem3, geometry=geometry3) disk.addPartition(partition3, constraint=device.optimalAlignedConstraint) if alwaysCommit or commitBeforeExtended: disk.commit() # partition 4: Extended geometry4 = parted.Geometry(device=device, start=partition3.geometry.end + 1, end=device.length-lengthModifier) partition4 = parted.Partition(disk=disk, type=parted.PARTITION_EXTENDED, geometry=geometry4) disk.addPartition(partition4, constraint=device.optimalAlignedConstraint) if alwaysCommit: disk.commit() # partition 5: Logical geometry5 = parted.Geometry(device=device, start=partition4.geometry.start + 1, length=parted.sizeToSectors(256, 'MiB', device.sectorSize)) filesystem5 = parted.FileSystem(type='ext4', geometry=geometry5) partition5 = parted.Partition(disk=disk, type=parted.PARTITION_LOGICAL, fs=filesystem5, geometry=geometry5) disk.addPartition(partition5, constraint=device.optimalAlignedConstraint) if alwaysCommit: disk.commit() # partition 6: Logical geometry6 = parted.Geometry(device=device, start=partition5.geometry.end + 1, length=parted.sizeToSectors(256, 'MiB', device.sectorSize)) filesystem6 = parted.FileSystem(type='ext4', geometry=geometry6) partition6 = parted.Partition(disk=disk, type=parted.PARTITION_LOGICAL, fs=filesystem6, geometry=geometry6) disk.addPartition(partition6, constraint=device.optimalAlignedConstraint) disk.commit() ``` My first thought was to use the options as follows, but the operation fails ``` alwaysCommit = False commitBeforeExtended = False lengthModifier = 0 ``` ``` [marcel@elfin-behlau pat]$ sudo ./test.py Traceback (most recent call last): File "./test.py", line 67, in <module> disk.addPartition(partition4, constraint=device.optimalAlignedConstraint) 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: Can't have a partition outside the disk! ``` This can be fixed by using an length modifier, but the "hack" fails with an assert. ``` alwaysCommit = False commitBeforeExtended = False lengthModifier = 1 ``` ``` Backtrace has 20 calls on stack: 20: /usr/lib/libparted.so.2(ped_assert+0x46) [0x7fdc917e6476] 19: /usr/lib/libparted.so.2(+0x259da) [0x7fdc917fd9da] 18: /usr/lib/libparted.so.2(+0x1307a) [0x7fdc917eb07a] 17: /usr/lib/libparted.so.2(ped_disk_add_partition+0x1ce) [0x7fdc917eb8fe] 16: /usr/lib/python3.8/site-packages/_ped.cpython-38-x86_64-linux-gnu.so(py_ped_disk_add_partition+0xcc) [0x7fdc918c259c] 15: /usr/lib/libpython3.8.so.1.0(+0x16eb07) [0x7fdc91dd1b07] 14: /usr/lib/libpython3.8.so.1.0(_PyEval_EvalFrameDefault+0x7de) [0x7fdc91e520ce] 13: /usr/lib/libpython3.8.so.1.0(_PyEval_EvalCodeWithName+0x3cb) [0x7fdc91e3ee3b] 12: /usr/lib/libpython3.8.so.1.0(_PyFunction_Vectorcall+0x39b) [0x7fdc91e4024b] 11: /usr/lib/libpython3.8.so.1.0(PyObject_Call+0x2f8) [0x7fdc91d91418] 10: /usr/lib/libpython3.8.so.1.0(_PyEval_EvalFrameDefault+0x2413) [0x7fdc91e53d03] 9: /usr/lib/libpython3.8.so.1.0(_PyEval_EvalCodeWithName+0x3cb) [0x7fdc91e3ee3b] 8: /usr/lib/libpython3.8.so.1.0(+0x1dd892) [0x7fdc91e40892] 7: /usr/lib/libpython3.8.so.1.0(_PyEval_EvalFrameDefault+0x11ac) [0x7fdc91e52a9c] 6: /usr/lib/libpython3.8.so.1.0(_PyEval_EvalCodeWithName+0x3cb) [0x7fdc91e3ee3b] 5: /usr/lib/libpython3.8.so.1.0(PyEval_EvalCode+0x23) [0x7fdc91ec83d3] 4: /usr/lib/libpython3.8.so.1.0(+0x265428) [0x7fdc91ec8428] 3: /usr/lib/libpython3.8.so.1.0(+0x269623) [0x7fdc91ecc623] 2: /usr/lib/libpython3.8.so.1.0(PyRun_FileExFlags+0x97) [0x7fdc91d673e7] 1: /usr/lib/libpython3.8.so.1.0(PyRun_SimpleFileExFlags+0x390) [0x7fdc91d71f4a] Aborted ``` Committing after adding an partition, results in strange partition size ( loop0p2 is only 255M instead of 512M, /dev/loop0p3 is 510M) ``` alwaysCommit = True commitBeforeExtended = False lengthModifier = 0 ``` ``` Disk /dev/loop0: 4 GiB, 4294967296 bytes, 8388608 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0xb80d081d Device Boot Start End Sectors Size Id Type /dev/loop0p1 1 32768 32768 16M b W95 FAT32 /dev/loop0p2 522240 1044479 522240 255M 83 Linux /dev/loop0p3 1044480 2088959 1044480 510M 83 Linux /dev/loop0p4 2088960 8355839 6266880 3G 5 Extended /dev/loop0p5 2091008 2611199 520192 254M 83 Linux /dev/loop0p6 2613248 3133439 520192 254M 83 Linux ``` Only if i commit before creating the extended partion, everything works as expected: ``` alwaysCommit = False commitBeforeExtended = False lengthModifier = 1 ``` ``` Disk /dev/loop0: 4 GiB, 4294967296 bytes, 8388608 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0x265e0c9c Device Boot Start End Sectors Size Id Type /dev/loop0p1 1 32768 32768 16M b W95 FAT32 /dev/loop0p2 32769 1081344 1048576 512M 83 Linux /dev/loop0p3 1081345 2129920 1048576 512M 83 Linux /dev/loop0p4 2611200 8355839 5744640 2.8G 5 Extended /dev/loop0p5 2613248 3133439 520192 254M 83 Linux /dev/loop0p6 3135488 3655679 520192 254M 83 Linux ```
Sign in to join this conversation.
No Branch/Tag specified
main
stable-3.9.x
master-distutils
master-staging
test-cases
v3.13.0
v3.12.0
v3.11.7
v3.11.6
v3.11.5
v3.11.4
v3.11.3
v3.11.2
v3.11.1
v3.11.0
v3.10.7
v3.10.6
v3.10.5
pyparted-3.10.4
pyparted-3.10.3
pyparted-3.10.2
pyparted-3.10.1
pyparted-3.10.0
pyparted-3.9.5
pyparted-3.9.4
pyparted-3.9.3
pyparted-3.9.2
pyparted-3.10
pyparted-3.10a1
v3.10a1
v3.10a0
hayseed
pyparted-3.9
pyparted-3.8
pyparted-3.7
pyparted-3.6
pyparted-3.5
pyparted-3.4
pyparted-3.3
pyparted-3.2
pyparted-3.1
pyparted-3.0
pyparted-2.5
pyparted-2.4
pyparted-2.3
pyparted-2.2
pyparted-2.1.2
pyparted-2.1.1
pyparted-2.1.0
pyparted-2.0.12
pyparted-2.0.11
pyparted-2.0.10
pyparted-2.0.9
pyparted-2.0.8
pyparted-2.0.7
pyparted-2.0.6
pyparted-2.0.5
pyparted-2.0.4
pyparted-2.0.3
pyparted-2.0.2
pyparted-2.0.1
pyparted-2.0.0
pyparted-1_8_9-1
start
pyparted-1.8.8-1
pyparted-1.8.7-1
pyparted-1.8.6-2
pyparted-1.8.6-1
pyparted-1.8.5-1
pyparted-1.8.4-1
pyparted-1.8.3-1
pyparted-1.8.2-1
pyparted-1.8.1-1
pyparted-1.8.0-1
pyparted-1.7.3-1
pyparted-1.6.9-1
pyparted-1.6.7-1
pyparted-1.6.6-2
pyparted-1.6.6-1
pyparted-1.6.10-1
Milestone
Clear milestone
No items
No milestone
Projects
Clear projects
No items
No project
Assignees
Clear assignees
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
dcantrell/pyparted#73
Reference in a new issue
dcantrell/pyparted
No description provided.
Delete branch "%!s()"

Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?