summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/forum/imageBuiltFor_mount_points_not_automatically_created/comment_7_ad9ea2799890df2dfce4f0cc99e397e9/comment_1_68b3d9ca04283c2400f5b23e486bb4b7._comment62
-rw-r--r--src/Propellor/Property/Parted.hs23
2 files changed, 81 insertions, 4 deletions
diff --git a/doc/forum/imageBuiltFor_mount_points_not_automatically_created/comment_7_ad9ea2799890df2dfce4f0cc99e397e9/comment_1_68b3d9ca04283c2400f5b23e486bb4b7._comment b/doc/forum/imageBuiltFor_mount_points_not_automatically_created/comment_7_ad9ea2799890df2dfce4f0cc99e397e9/comment_1_68b3d9ca04283c2400f5b23e486bb4b7._comment
new file mode 100644
index 00000000..c7d7e384
--- /dev/null
+++ b/doc/forum/imageBuiltFor_mount_points_not_automatically_created/comment_7_ad9ea2799890df2dfce4f0cc99e397e9/comment_1_68b3d9ca04283c2400f5b23e486bb4b7._comment
@@ -0,0 +1,62 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 1"""
+ date="2017-12-21T19:44:45Z"
+ content="""
+Reproduced it with that information.
+
+ ghci> calcPartedParamsSize guexPartTable
+ (["mklabel","gpt","mkpart","primary","fat32","4194304B","16777215B","set","1","esp","on","mkpart","primary","ext2","16777216B","167772159B","mkpart","primary","ext4","167772160B","1660944383B"],1660944384)
+ joey@darkstar:~>dd if=/dev/zero of=test bs=1M count=1584
+ joey@darkstar:~>parted test
+ (parted) p
+ Model: (file)
+ Disk /home/joey/test: 1661MB
+ Sector size (logical/physical): 512B/512B
+ (parted) mklabel gpt
+ (parted) mkpart primary fat32 4194304B 16777215B
+ (parted) mkpart primary ext2 16777216B 167772159B
+ (parted) mkpart primary ext4 167772160B 1660944383B
+ Warning: You requested a partition from 168MB to 1661MB (sectors 327680..3244031).
+ The closest location we can manage is 168MB to 1661MB (sectors 327680..3243998).
+
+The problem only occurs with the gpt partition table. With "mklabel msdos",
+the mkpart command succeeds.
+
+So, gpt must have an additional restriction
+of some kind. I don't know what. The highest end position that parted
+will accept for that partition is 1660927487B; slightly smaller partitions
+are accepted. It's not a requirement that the position or size be divisible
+by anything in particular. Perhaps gpt needs some amount of reserved space
+at the end of the disk or something.
+
+Before 4MiB alignment was added, here's what
+propellor did for the same PartTable, which worked.
+
+ mkpart primary ext4 160MB 1649MB
+
+It would be good for propellor to not need to know about all the minutia of
+partition tables. Seems that the way it used to call parted gave it enough
+wiggle room that it avoided this kind of problem.
+
+To make parititions well aligned, propellor needs to precisely control where
+they begin (since parted does not have a way to configure modern
+alignment requirments). Perhaps propellor could precisely specify where a
+partition begins, but use the "MB" to leave wiggle room in where it ends
+so parted can pick a suitable end point.
+
+Let's see.. this works with the gpt example:
+
+ (parted) mkpart primary fat32 4194304B 16.777215MB
+ (parted) mkpart primary ext2 16777216B 167.772159MB
+ (parted) mkpart primary ext4 167772160B 660.944383MB
+
+That lets parted end the last partition right at the ideal 1660927487B.
+The previous two partitions end right where propellor expects.
+(Hopefully parted never rounds a MB value *up*!)
+
+Ok, I've convinced myself to make propellor use this wacky technique
+of B for the start position and fractional MB for the end position!
+I've implemented it, hopefully my analysis above is good to make
+this work with all the different kinds of partition tables.
+"""]]
diff --git a/src/Propellor/Property/Parted.hs b/src/Propellor/Property/Parted.hs
index 38c55b93..be12933d 100644
--- a/src/Propellor/Property/Parted.hs
+++ b/src/Propellor/Property/Parted.hs
@@ -85,8 +85,8 @@ calcPartedParamsSize (PartTable tabletype alignment parts) =
[ "mkpart"
, pval (partType p)
, pval (partFs p)
- , partpos startpos
- , partpos endpos
+ , partposexact startpos
+ , partposfuzzy endpos
] ++ case partName p of
Just n -> ["name", show partnum, n]
Nothing -> []
@@ -95,14 +95,29 @@ calcPartedParamsSize (PartTable tabletype alignment parts) =
in calcparts (partnum+1) endpos ps
(c ++ mkpart partnum startpos (endpos-1) p : map (mkflag partnum) (partFlags p))
calcparts _ endpos [] c = (c, endpos)
- partpos n
- | n > 0 = val n ++ "B"
+
+ -- Exact partition position value for parted.
+ -- For alignment to work, the start of a partition must be
+ -- specified exactly.
+ partposexact n
+ | n > 0 = show n ++ "B"
-- parted can't make partitions smaller than 1MB;
-- avoid failure in edge cases
| otherwise = "1MB"
+
+ -- Fuzzy partition position valie for parted.
+ -- This is used to specify the end of the partition,
+ -- parted takes the "MB" as license to slightly reduce the
+ -- partition size when something about the partition table
+ -- does not allow the partition to end exactly at the position.
+ partposfuzzy n
+ | n > 0 = show (fromIntegral n / 1000000) ++ "MB"
+ | otherwise = "1MB"
+
-- Location of the start of the first partition,
-- leaving space for the partition table, and aligning.
firstpos = align partitionTableOverhead
+
align = alignTo alignment
-- | Runs parted on a disk with the specified parameters.