this repo has no description

Unmount all datasets after use

We need to do this to flush the data to disk. We can end up in a position
where we snapshot before data is on disk and this breaks _everything_.

Changed files
+40 -39
src
vendor
+1 -1
src/lib/shelter/fetch.ml
···
let get_image ~dir ~proc image =
let container_id =
Eio.Process.parse_out proc Eio.Buf_read.take_all
-
[ "docker"; "run"; "-d"; image ]
+
[ "docker"; "create"; "--"; image ]
|> String.trim
in
let tar = replace_slash image ^ ".tar.gz" in
+2 -2
src/lib/shelter/runc.ml
···
"127.0.0.1 localhost builder";
let id = string_of_int !next_id in
incr next_id;
-
let cmd = [ "runc"; "--root"; "runc"; "run"; id ] in
+
let cmd = [ "runc"; "run"; id ] in
let stdout =
to_other_sink_as_well ~other:env#stdout
(log :> Eio.Flow.sink_ty Eio.Flow.sink)
in
-
Eio.Process.spawn ~sw ~stdout env#proc ~cwd:eio_tmp cmd
+
Eio.Process.spawn ~sw ~stdout ~stderr:env#stdout env#proc ~cwd:eio_tmp cmd
(*
Apache License
+1 -1
src/lib/shelter/shelter_main.ml
···
let start, res =
Switch.run @@ fun sw ->
let log =
-
Eio.Path.open_out ~sw ~create:(`If_missing 0o644)
+
Eio.Path.open_out ~sw ~create:(`Or_truncate 0o644)
Eio.Path.(fs / rootfs / "log")
in
let res = spawn sw log in
+32 -21
src/lib/shelter/store.ml
···
| Some _ -> ()
| None -> with_dataset ~typ t (dataset :> string) @@ fun d -> Zfs.mount d
+
let mount_snapshot ?(typ = Zfs.Types.snapshot) t (dataset : Datasets.snapshot) =
+
match Zfs.is_mounted t.zfs (dataset :> string) with
+
| Some _ -> ()
+
| None -> with_dataset ~typ t (dataset :> string) @@ fun d -> Zfs.mount d
+
let unmount_dataset t (dataset : Datasets.dataset) =
match Zfs.is_mounted t.zfs (dataset :> string) with
| None -> ()
| Some _ ->
with_dataset t (dataset :> string) @@ fun d ->
-
let _todo () = Zfs.unmount d in
+
let () = Zfs.unmount d in
()
let create_dataset t (dataset : Datasets.dataset) =
···
loop ()
in
loop ()
-
-
let diff t (data : Datasets.snapshot) (snap : Datasets.snapshot) output =
-
let data_fs =
-
String.sub (data :> string) 0 (String.index (data :> string) '@')
-
in
-
let zh = Zfs.open_ t.zfs data_fs Zfs.Types.filesystem in
-
let () =
-
try
-
Eio.Path.with_open_out ~create:(`If_missing 0o644) output
-
@@ fun flow_fd ->
-
let eio_fd = Eio_unix.Resource.fd_opt flow_fd in
-
Eio_unix.Fd.use_exn_opt "zfs-diff" eio_fd @@ function
-
| None -> Fmt.failwith "Output needs to have an FD"
-
| Some fd ->
-
Zfs.show_diff zh ~from_:(data :> string) ~to_:(snap :> string) fd
-
with Unix.Unix_error (Unix.EBADF, _, _) -> ()
-
in
-
Zfs.close zh;
-
let diff = Eio.Path.load output in
-
Diff.of_zfs diff
let cid s =
let hash =
···
Fun.protect ~finally:(fun () -> unmount_dataset t ds) @@ fun () ->
mount_dataset t ds;
fn ("/" ^ (ds :> string))
+
+
let diff t (data : Datasets.snapshot) (snap : Datasets.snapshot) output =
+
let data_fs =
+
String.sub (data :> string) 0 (String.index (data :> string) '@')
+
in
+
let snap_fs =
+
String.sub (snap :> string) 0 (String.index (snap :> string) '@')
+
in
+
if Option.is_none (Zfs.is_mounted t.zfs data_fs) then
+
with_dataset t data_fs Zfs.mount;
+
if Option.is_none (Zfs.is_mounted t.zfs snap_fs) then
+
with_dataset t snap_fs Zfs.mount;
+
with_dataset ~typ:Zfs.Types.filesystem t data_fs @@ fun zh ->
+
let () =
+
try
+
Eio.Path.with_open_out ~create:(`If_missing 0o644) output
+
@@ fun flow_fd ->
+
let eio_fd = Eio_unix.Resource.fd_opt flow_fd in
+
Eio_unix.Fd.use_exn_opt "zfs-diff" eio_fd @@ function
+
| None -> Fmt.failwith "Output needs to have an FD"
+
| Some fd ->
+
Zfs.show_diff zh ~from_:(data :> string) ~to_:(snap :> string) fd
+
with Unix.Unix_error (Unix.EBADF, _, _) -> ()
+
in
+
let diff = Eio.Path.load output in
+
Diff.of_zfs diff
let with_clone t ~src new_cid output fn =
let ds = Datasets.build t.pool (Cid.to_string src) in
+2 -2
vendor/zfs/src/function_description.ml
···
(Types.libzfs_handle_t @-> string @-> int @-> returning Types.zfs_handle_t)
let mount =
-
foreign "zfs_mount" (Types.zfs_handle_t @-> string @-> int @-> returning int)
+
foreign "zfs_mount" (Types.zfs_handle_t @-> string_opt @-> int @-> returning int)
let unmount =
foreign "zfs_unmount"
-
(Types.zfs_handle_t @-> string @-> int @-> returning int)
+
(Types.zfs_handle_t @-> string_opt @-> int @-> returning int)
let close = foreign "zfs_close" (Types.zfs_handle_t @-> returning void)
let get_type = foreign "zfs_get_type" (Types.zfs_handle_t @-> returning int)
+2 -12
vendor/zfs/src/zfs.ml
···
let null_string = Ctypes.(coerce (ptr void) (ptr char) null)
let mount ?mount_opts ?(mount_flags = 0) dataset =
-
let opts =
-
Option.value
-
~default:(Ctypes.string_from_ptr null_string ~length:0)
-
mount_opts
-
in
-
let res = C.Functions.mount dataset opts mount_flags in
+
let res = C.Functions.mount dataset mount_opts mount_flags in
if res <> 0 then invalid_arg "mounting dataset"
let unmount ?mount_opts ?(mount_flags = 0) dataset =
-
let opts =
-
Option.value
-
~default:(Ctypes.string_from_ptr null_string ~length:0)
-
mount_opts
-
in
-
let res = C.Functions.unmount dataset opts mount_flags in
+
let res = C.Functions.unmount dataset mount_opts mount_flags in
if res <> 0 then invalid_arg "unmounting dataset"
let show_diff ?to_ handle ~from_ (fd : Unix.file_descr) =