On Friday, 14 July 2017 15:39:26 CEST Richard W.M. Jones wrote: > +(* In order to examine subvolumes, quota and other things, the btrfs > + * filesystem has to be mounted. However we're passed a mountable > + * in these cases, so we must mount the filesystem. But we cannot > + * mount it under the sysroot, as something else might be mounted > + * there so this function mounts the filesystem on a temporary > + * directory and ensures it is always unmounted afterwards. > + *) > +let with_mounted mountable f = > + let tmpdir = sprintf "/tmp/%s" (String.random8 ()) in
let tmpdir = Mkdtemp.temp_dir ~base_dir:"/tmp" "btrfs." "" in
(or even without ~base_dir, I guess the default should be fine.)
This will also avoid the mkdir calls later on.
> + (* This is the cleanup function which is called to unmount and
> + * remove the temporary directory. This is called on error and
> + * ordinary exit paths.
> + *)
> + let finally () =
> + ignore (Sys.command (sprintf "umount %s" (quote tmpdir)));
> + rmdir tmpdir
> + in
> +
> + match mountable.m_type with
> + | MountablePath ->
> + (* This corner-case happens for Mountable_or_Path parameters, where
> + * a path was supplied by the caller. The path (the m_device
> + * field) is relative to the sysroot.
> + *)
> + f (Sysroot.sysroot () // mountable.m_device)
After using Mkdtemp.temp_dir above, "rmdir tmpdir" will be needed here.
> +
> + | MountableDevice ->
> + protect ~finally ~f:(
> + fun () ->
> + mkdir tmpdir 0o700;
> + ignore (command "mount" [mountable.m_device; tmpdir]);
> + f tmpdir
> + )
> +
> + | MountableBtrfsVol subvol ->
> + protect ~finally ~f:(
> + fun () ->
> + mkdir tmpdir 0o700;
> + ignore (command "mount" ["-o"; "subvol=" ^ subvol (* XXX quoting?
> *);
> + mountable.m_device; tmpdir]);
> + f tmpdir
> + )
> +
> +let re_btrfs_subvolume_list =
> + Str.regexp ("ID[ \t]+\\([0-9]+\\).*[ \t]" ^
> + "top level[ \t]+\\([0-9]+\\).*[ \t]" ^
> + "path[ \t]+\\(.*\\)")
Sigh, Str does not support simple character classes like \s :( No wonder
there are at least two or three "re" OCaml modules providing sane regular
expression engines (with a less awkward syntax for captures, etc).
> +let btrfs_subvolume_list mountable =
> + (* Execute 'btrfs subvolume list <fs>', and split the output into lines *)
> + let lines =
> + with_mounted mountable (
> + fun mp -> command "btrfs" ["subvolume"; "list"; mp]
> + ) in
> + let lines = String.nsplit "\n" lines in
If here we do:
let lines = List.filter ((<>) "") lines in
then later on we can use List.map instead of filter_map.
> diff --git a/daemon/btrfs.mli b/daemon/btrfs.mli
> new file mode 100644
> index 000000000..55a38e42d
> --- /dev/null
> +++ b/daemon/btrfs.mli
> @@ -0,0 +1,26 @@
> +(* guestfs-inspection
> + * Copyright (C) 2009-2017 Red Hat Inc.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License along
> + * with this program; if not, write to the Free Software Foundation, Inc.,
> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> + *)
> +
> +type btrfssubvolume = {
> + btrfssubvolume_id : int64;
> + btrfssubvolume_top_level_id : int64;
> + btrfssubvolume_path : string;
> +}
Is this needed? Could Structs.btrfssubvolume be used below?
--
Pino Toscano
signature.asc
Description: This is a digitally signed message part.
_______________________________________________ Libguestfs mailing list [email protected] https://www.redhat.com/mailman/listinfo/libguestfs
