summaryrefslogtreecommitdiff
path: root/fsmgr.hs
diff options
context:
space:
mode:
authorAndrew Cady <d@jerkface.net>2020-05-27 17:00:16 -0400
committerAndrew Cady <d@jerkface.net>2020-05-28 03:29:39 -0400
commita35b2f7ba9d18ac7fb89111e55924218042cbc4a (patch)
tree05a6aa47601ed25cfb6e8df886a9958dc6ce4b07 /fsmgr.hs
parent694309e7cae73b7f428238fc51242d1804c1cf4a (diff)
Begin support for "seeded images."
A seeded image keeps its parent image as a read-only "seed" device that joins the seeded image in a multi-device btrfs filesystem. That means that to mount such an image, the parent image must be made available as a block device (e.g. using losetup, or dd to an existing block device and run btfrs device scan). Such support had been added to the Samizdat Makefile, but more properly belongs here. This is the sequence of commands used by sami.git's Makefile to accomplish the effect: rm -f $@~tmp touch $@~tmp fallocate -l $(samizdat_btrfs_patch_size) $@~tmp test -d $@.mnt || mkdir $@.mnt ! mountpoint -q $@.mnt || umount $@.mnt mount -o compress,ro -t btrfs $< $@.mnt a=$(get_loop_dev); [ -z "$$a" ] || losetup -d $$a losetup -f $@~tmp btrfs device add $(get_loop_dev) $@.mnt mount -o compress,rw,remount $@.mnt The Makefile also defines: get_loop_dev="$$(sudo losetup -n -O name -j $@~tmp)" The same basic sequence is carried out here. The config file format is modified so that to get a seeded image you specify "seedme: <bytes>" where <bytes> is the size of the seeded image. This feature is complete enough to create a seeded image (i.e., to replace the Makefile), but children of a seeded image seem impossible to work because there is no code yet to run losetup on seed images of parents. Thus it can be expected that deriving from a parent with a seed will fail when fsmgr tries to mount the parent.
Diffstat (limited to 'fsmgr.hs')
-rw-r--r--fsmgr.hs42
1 files changed, 42 insertions, 0 deletions
diff --git a/fsmgr.hs b/fsmgr.hs
index ca80f8a..a2ee87d 100644
--- a/fsmgr.hs
+++ b/fsmgr.hs
@@ -34,6 +34,7 @@ import System.Posix.User (getEffectiveUserID)
34noParent :: BaseImageSpecification -> Bool 34noParent :: BaseImageSpecification -> Bool
35noParent (EmptyImageOfBytes _) = True 35noParent (EmptyImageOfBytes _) = True
36noParent (ParentImageConfigFile _) = False 36noParent (ParentImageConfigFile _) = False
37noParent (SeededImage _ _) = False
37 38
38dynamicNames :: FilePath -> FilePath 39dynamicNames :: FilePath -> FilePath
39dynamicNames = replace "$(karch)" uname . replace "$(debarch)" debarch 40dynamicNames = replace "$(karch)" uname . replace "$(debarch)" debarch
@@ -135,6 +136,20 @@ buildInitialImage DiskImageConfig{..} mountpoint out = do
135 cmd_ "btrfstune -f -S0" [out] 136 cmd_ "btrfstune -f -S0" [out]
136 cmd_ "mkdir -p" [mountpoint] 137 cmd_ "mkdir -p" [mountpoint]
137 cmd_ "mount -t btrfs" [out] mountpoint 138 cmd_ "mount -t btrfs" [out] mountpoint
139
140 SeededImage n f -> do
141 let parent = "_build" </> f -<.> "btrfs"
142 need [parent]
143
144 -- allocate new image file
145 cmd_ "rm -f" [out]
146 cmd_ "truncate -s" [show n, out]
147 cmd_ "fallocate -l" [show n, out]
148
149 idempotentMountImage parent mountpoint
150
151 addImageToBtrfs out mountpoint
152
138 EmptyImageOfBytes n -> do 153 EmptyImageOfBytes n -> do
139 cmd_ "truncate -s" [show n] [out] 154 cmd_ "truncate -s" [show n] [out]
140 cmd_ "mkfs.btrfs" [out] 155 cmd_ "mkfs.btrfs" [out]
@@ -150,6 +165,33 @@ buildInitialImage DiskImageConfig{..} mountpoint out = do
150 cmd_ (Cwd mountpoint) "mkdir -p var/cache/debconf" 165 cmd_ (Cwd mountpoint) "mkdir -p var/cache/debconf"
151 cmd_ (Cwd mountpoint) "btrfs subvolume create var/cache/apt/archives" 166 cmd_ (Cwd mountpoint) "btrfs subvolume create var/cache/apt/archives"
152 167
168idempotentSetupLoopDev :: FilePath -> Action (Maybe String)
169idempotentSetupLoopDev imageFile = do
170 deleteLoopDev imageFile
171 cmd_ "losetup -f" imageFile
172 getLoopDev imageFile
173 where
174 deleteLoopDev = getLoopDev >=> mapM_ (cmd_ "losetup -d")
175
176 getLoopDev :: FilePath -> Action (Maybe String)
177 getLoopDev x = do
178 Stdout r <- cmd "losetup -n -O name -j" x
179 return $ guard (r /= "") >> Just r
180
181idempotentMountImage :: FilePath -> FilePath -> Action ()
182idempotentMountImage imageFile mountPoint = do
183 cmd_ "mkdir -p" [mountPoint]
184 mounted <- cmd "mountpoint -q" [mountPoint] <&> (== ExitSuccess)
185 when mounted $ cmd_ "umount" [mountPoint]
186 cmd_ "mount -o compress,ro -t btrfs" [imageFile, mountPoint]
187
188addImageToBtrfs :: FilePath -> FilePath -> Action ()
189addImageToBtrfs imageFile mountPoint = do
190 blockDevice <- idempotentSetupLoopDev imageFile <&>
191 fromMaybe (error "failed to set up loop device for " ++ imageFile)
192 cmd_ "btrfs device add" blockDevice mountPoint
193 cmd_ "mount -o remount,rw,compress" mountPoint
194
153ignoreErrors' :: IO () -> IO () 195ignoreErrors' :: IO () -> IO ()
154ignoreErrors' = flip catch (\(SomeException _) -> return ()) 196ignoreErrors' = flip catch (\(SomeException _) -> return ())
155 197