On Thu, Jun 08, 2023 at 11:38:53AM +0100, Richard W.M. Jones wrote:
> From: Ravi Singh <ravi.si...@veritas.com>

First, thanks to various people who helped me to get Infoscale Storage
installed.

I have questions ...

>  appliance/hostfiles.in    |   4 ++
>  appliance/init            |   2 +
>  daemon/Makefile.am        |   7 +++
>  daemon/guestfsd.c         |   3 +
>  daemon/listfs.ml          |  17 ++++++
>  daemon/vm.ml              |  68 ++++++++++++++++++++++
>  daemon/vm.mli             |  24 ++++++++
>  daemon/vxfs.c             | 119 ++++++++++++++++++++++++++++++++++++++
>  daemon/vxvm_type.ml       |  17 ++++++
>  daemon/vxvm_type.mli      |  24 ++++++++
>  generator/actions_core.ml |  32 ++++++++++
>  generator/proc_nr.ml      |   3 +
>  lib/MAX_PROC_NR           |   2 +-
>  po/POTFILES               |   1 +
>  14 files changed, 322 insertions(+), 1 deletion(-)
> 
> diff --git a/appliance/hostfiles.in b/appliance/hostfiles.in
> index e78c79bd34..e519ad1787 100644
> --- a/appliance/hostfiles.in
> +++ b/appliance/hostfiles.in
> @@ -17,3 +17,7 @@ dnl   OPENMANDRIVA=1 For OpenMandriva.
>  /etc/ld.so.cache
>  /lib/lsb/*
>  /usr/share/augeas/lenses/*.aug
> +/etc/vx/vxfs
> +/etc/vx/veki
> +/etc/vx/vxvm-startup

These are executable configuration files which start various services.
Later on, do_vxfs_start will test if these files exist and then run
them to bring up the vxfs services inside the appliance.  However I'm
not exactly sure how that could possibly work as these scripts refer
to programs that are not copied into the appliance.

> +/opt/VRTS/bin/fstyp

This is a symlink to /usr/lib/fs/vxfs/fstyp which is a binary.  While
it's not impossible for hostfiles.in to be used for scripts (like the
ones above) and binaries, it's better to use packagelist.in to list
the packages (ie. RPMs) you actually want to copy in.  For example:

# rpm -qf /usr/lib/fs/vxfs/fstyp
VRTSvxfs-8.0.2.0000-RHEL9.x86_64
]# rpm -qf /etc/vx/vxfs
VRTSvxfs-8.0.2.0000-RHEL9.x86_64
# rpm -qf /etc/vx/veki 
VRTSveki-8.0.2.0000-RHEL9.x86_64
# rpm -qf /etc/vx/vxvm-startup 
VRTSvxvm-8.0.2.0000-RHEL9.x86_64

Simply listing VRTSvxvm in packagelist.in would copy the whole package
into the appliance, including all those files, and (if the RPMs are
set up correctly) all dependencies that they need to run.

I actually can't understand how this can work as written.

> diff --git a/appliance/init b/appliance/init
> index d410566597..535a3d6b19 100755
> --- a/appliance/init
> +++ b/appliance/init
> @@ -22,6 +22,8 @@ mount -t proc /proc /proc
>  mount -t sysfs /sys /sys
>  # devtmpfs is required since udev 176
>  mount -t devtmpfs /dev /dev
> +# Create dev directory for all VxVM device files.
> +mkdir -p /dev/vx
>  ln -s /proc/self/fd /dev/fd
>  
>  # Parse the kernel command line early (must be after /proc is mounted).
> diff --git a/daemon/Makefile.am b/daemon/Makefile.am
> index bb2e58d014..8d3d9c8255 100644
> --- a/daemon/Makefile.am
> +++ b/daemon/Makefile.am
> @@ -51,6 +51,8 @@ generator_built = \
>       link.mli \
>       listfs.mli \
>       lvm.mli \
> +     vm.mli \
> +     vxvm_type.mli \
>       lvm_dm.mli \
>       md.mli \
>       mount.mli \
> @@ -208,6 +210,7 @@ guestfsd_SOURCES = \
>       wc.c \
>       xattr.c \
>       xfs.c \
> +     vxfs.c \
>       yara.c \
>       zero.c \
>       zerofree.c
> @@ -294,6 +297,8 @@ SOURCES_MLI = \
>       link.mli \
>       listfs.mli \
>       lvm.mli \
> +     vm.mli \
> +     vxvm_type.mli \
>       lvm_dm.mli \
>       lvm_utils.mli \
>       md.mli \
> @@ -328,6 +333,8 @@ SOURCES_ML = \
>       ldm.ml \
>       link.ml \
>       lvm.ml \
> +     vm.ml \
> +     vxvm_type.ml \
>       lvm_utils.ml \
>       lvm_dm.ml \
>       findfs.ml \
> diff --git a/daemon/guestfsd.c b/daemon/guestfsd.c
> index 33c297de33..7b202ea53c 100644
> --- a/daemon/guestfsd.c
> +++ b/daemon/guestfsd.c
> @@ -273,6 +273,9 @@ main (int argc, char *argv[])
>     */
>    udev_settle ();
>  
> +  /* Start vxfs services */
> +  do_vxfs_start();
> +

This is added as a public API (see generator/actions_core.ml change
later).  But it seems like that wasn't intentional.  Do you intend
that programs using libguestfs would need to run 'guestfs_vxfs_start'
themselves?  And if so what would be the situation when that is
necessary?

If it's not necessary for this to be a public API then just make this
into a normal function.

>    /* Send the magic length message which indicates that
>     * userspace is up inside the guest.
>     */
> diff --git a/daemon/listfs.ml b/daemon/listfs.ml
> index 2376b61dbc..10e32d8c04 100644
> --- a/daemon/listfs.ml
> +++ b/daemon/listfs.ml
> @@ -25,6 +25,11 @@ open Std_utils
>   * contain filesystems, so we filter them out.
>   *)
>  let rec list_filesystems () =
> +
> +  (* Check if the vxvm services are available. As we are trying to read
> +   * vxvm disk layout
> +   *)
> +  let has_vxvm = Optgroups.vxvm_available () in
>    let has_lvm2 = Optgroups.lvm2_available () in
>    let has_ldm = Optgroups.ldm_available () in
>  
> @@ -53,6 +58,12 @@ let rec list_filesystems () =
>    let mds = List.filter is_not_partitioned_device mds in
>    List.iter (check_with_vfs_type ret) mds;
>  
> +  (* VxVM. *)
> +  if has_vxvm then (
> +    let vxvm_vol = Vm.vxvm () in
> +    List.iter (check_with_vxvmvol_type ret) vxvm_vol
> +  );
> +
>    (* LVM. *)
>    if has_lvm2 then (
>      let lvs = Lvm.lvs () in
> @@ -192,3 +203,9 @@ and check_with_vfs_type ret device =
>  
>    else
>      List.push_back ret (mountable, vfs_type)
> +
> +(* Check for the vxvm volume type *)
> +and check_with_vxvmvol_type ret device =
> +  let mountable = Mountable.of_device device in
> +  let vxvmvol_typ = Vxvm_type.vxvmvol_type mountable in
> +  List.push_back ret (mountable, vxvmvol_typ)
> diff --git a/daemon/vm.ml b/daemon/vm.ml
> new file mode 100644
> index 0000000000..d01b9e273d
> --- /dev/null
> +++ b/daemon/vm.ml
> @@ -0,0 +1,68 @@
> +open Unix
> +open Printf
> +
> +open Std_utils
> +open Str
> +open Utils
> +
> +let rec vxvm () =
> +  let a = command "vxdisk" ["-q"; "list"; "-p"; "-x"; "DG_NAME"] in
> +  let lines = String.nsplit "\n" a in
> +  let lines = List.map String.trim lines in
> +  let lines = List.filter ((<>) "") lines in
> +
> +  (* Create a list of list *)
> +  let lines = List.filter_map (
> +    fun line ->
> +      let s = Str.regexp "[ \t\r\n]" in
> +      let str = Str.bounded_split s line 2 in
> +      match str with
> +      | [ a; b ] ->
> +        Some (sprintf "%s" b)
> +      | _-> None
> +  ) lines in
> +
> +  (* Trim of all the whitespaces from each element of the list *)
> +  let lines = List.map String.trim lines in
> +
> +  (* Skip the lines with "-" *)
> +  let lines = List.filter ((<>) "-") lines in
> +  let lines = List.sort_uniq compare lines in
> +  let _ = List.iter (eprintf "%s") lines in
> +
> +  (* Import the disk group that is in the deported state *)
> +  let _ = List.map (
> +    fun x ->
> +      let r, out, err = commandr "vxdg" ["list"; x] in
> +      match r with
> +      | 0 -> None
> +      | _ ->
> +        Some (command "vxdg" ["-Cf"; "import"; x])
> +  ) lines in
> +
> +  let out = command "vxprint" [ "-s"; "-F"; "%{dg_name}/%{v_name}"; "-A"; 
> "-Q" ] in
> +  convert_vxvm_output ~prefix:"/dev/vx/dsk/" out
> +
> +and convert_vxvm_output ?prefix out =
> +  let lines = String.nsplit "\n" out in
> +
> +  (* Skip leading and trailing ("pvs", I'm looking at you) whitespace. *)
> +  let lines = List.map String.trim lines in
> +
> +  (* Skip empty lines. *)
> +  let lines = List.filter ((<>) "") lines in
> +
> +  (* Ignore "unknown device" message (RHBZ#1054761). *)
> +  let lines = List.filter ((<>) "unknown device") lines in
> +
> +  (* Remove Duplicate elements *)
> +  let lines = List.sort_uniq compare lines in
> +
> +  (* Add a prefix? *)
> +  let lines =
> +    match prefix with
> +    | None -> lines
> +    | Some prefix -> List.map ((^) prefix) lines in
> +
> +  (* Sort and return. *)
> +  List.sort compare lines
> diff --git a/daemon/vm.mli b/daemon/vm.mli
> new file mode 100644
> index 0000000000..98db6b4f9d
> --- /dev/null
> +++ b/daemon/vm.mli
> @@ -0,0 +1,24 @@
> +(* libguestfs generated file
> + * WARNING: THIS FILE IS GENERATED FROM THE FOLLOWING FILES:
> + *          generator/daemon.ml
> + *          and from the code in the generator/ subdirectory.
> + * ANY CHANGES YOU MAKE TO THIS FILE WILL BE LOST.

This file is generated so you don't need to include this file in the
patch.  The generator will recreate it correctly when libguestfs is
built.

> + * Copyright (C) 2009-2020 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.
> + *)
> +
> +val vxvm : unit -> string list
> diff --git a/daemon/vxfs.c b/daemon/vxfs.c
> new file mode 100644
> index 0000000000..75e18f9525
> --- /dev/null
> +++ b/daemon/vxfs.c
> @@ -0,0 +1,119 @@
> +#include <config.h>
> +
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <inttypes.h>
> +#include <string.h>
> +#include <unistd.h>
> +#include <fcntl.h>
> +#include <sys/stat.h>
> +#include <dirent.h>
> +
> +#include "daemon.h"
> +
> +/* This is used to check if we have the vxvm utility
> + * in place.
> + */
> +int
> +optgroup_vxvm_available (void)
> +{
> +
> +  CLEANUP_FREE char *err = NULL;
> +  int r;
> +
> +  r = commandr (NULL, &err, "vxdctl", "list",  NULL);
> +  
> +  return r == 0;
> +}
> +
> +int opt_servicefile_available (const char *path)

This function should be static.

> +{
> +  CLEANUP_FREE char *testpath;
> +  if (path == NULL) return 0;
> +  if (asprintf (&testpath, "%s/%s", "/etc/vx", path) == -1) return 0;
> +  if (access (testpath, X_OK) == 0)
> +      return 1;
> +
> +  /* Not found. */
> +  return 0;
> +}
> +
> +int
> +optgroup_vxfs_available (void)
> +{
> +  return filesystem_available ("vxfs");
> +}
> +
> +/* Starting Infoscale related services in the daemon which is
> + * required to read vxvm supported disk layout version, here we are
> + * first initialising the lisence then starting all the related
> + * services to read the files from vxvm disk layout
> + */
> +int
> +do_vxfs_start (void)
> +{
> +  CLEANUP_FREE char *err = NULL, *err2 = NULL,
> +   *err3 = NULL, *err4 = NULL, *err5 = NULL, *err6 = NULL;
> +  int r;
> +
> +  /**
> +   * Setup the license on the appliance to configure
> +   * Infoscale services.
> +   */
> +  r = commandr (NULL, &err, "vxkeyless", "--quiet", "set", "ENTERPRISE",  
> NULL);
> +  if (r == -1){
> +    reply_with_error ("vxkeyless set error:%s", err);
> +    return -1;
> +  }
> +
> +  /**
> +   * Start Veki service.
> +   */
> +  if (opt_servicefile_available("veki") == 0) return -1;
> +  r = commandr (NULL, &err2, "/etc/vx/veki", "start", NULL);
> +  if (r == -1){
> +    reply_with_error ("veki start error:%s", err2);
> +    return -1;
> +  }
> +
> +  /**
> +   * Start vxfs service.
> +   */
> +  if (opt_servicefile_available("vxfs") == 0) return -1;
> +  r = commandr (NULL, &err3, "/etc/vx/vxfs", "start", NULL);
> +  if (r == -1){
> +    reply_with_error ("vxfs start error:%s", err3);
> +    return -1;
> +  }
> +
> +  /**
> +   * Start vxvm related services.
> +   */
> +  if (opt_servicefile_available("vxvm-startup") == 0) return -1;
> +  r = commandr (NULL, &err4, "sh", "/etc/vx/vxvm-startup", NULL);
> +  if (r == -1){
> +    reply_with_error ("vxvm start error:%s", err4);
> +    return -1;
> +  }
> +
> +  /**
> +   * Trigger vxdctl init to generate volboot file
> +   */
> +  r = commandr (NULL, &err5, "vxdctl", "init", NULL);
> +  if (r == -1){
> +    reply_with_error ("vxdctl init error:%s", err5);
> +    return -1;
> +  }
> +
> +  /**
> +   * Enabling this would allow us to use vxvm related
> +   * commands
> +   */
> +  r = commandr (NULL, &err6, "vxdctl", "enable", NULL);
> +  if (r == -1){
> +    reply_with_error ("vxdctl enable error:%s", err6);
> +    return -1;
> +  }
> +
> +  return 0;
> +}
> diff --git a/daemon/vxvm_type.ml b/daemon/vxvm_type.ml
> new file mode 100644
> index 0000000000..9a01151ee3
> --- /dev/null
> +++ b/daemon/vxvm_type.ml
> @@ -0,0 +1,17 @@
> +open Std_utils
> +
> +open Utils
> +
> +(* Detrmine the VxVM volume type using the fstype command
> + * This would help us determine the vxfs specific volumes.
> + *)
> +let rec vxvmvol_type { Mountable.m_device=device }=
> +  Option.default "" (get_vxvmvol_type device)
> +
> +and get_vxvmvol_type device =
> +  let r, out, err =
> +    commandr "/opt/VRTS/bin/fstyp" [ device ] in
> +  match r with
> +  | 0 -> Some (String.chomp out)
> +  | 2 -> None
> +  | _ -> failwithf "fstyp: %s: %s" device err
> diff --git a/daemon/vxvm_type.mli b/daemon/vxvm_type.mli
> new file mode 100644
> index 0000000000..b1387454a6
> --- /dev/null
> +++ b/daemon/vxvm_type.mli
> @@ -0,0 +1,24 @@
> +(* libguestfs generated file
> + * WARNING: THIS FILE IS GENERATED FROM THE FOLLOWING FILES:
> + *          generator/daemon.ml
> + *          and from the code in the generator/ subdirectory.
> + * ANY CHANGES YOU MAKE TO THIS FILE WILL BE LOST.

Also generated, does not need to be included.

> + * Copyright (C) 2009-2020 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.
> + *)
> +
> +val vxvmvol_type : Mountable.t -> string
> diff --git a/generator/actions_core.ml b/generator/actions_core.ml
> index addbe4ec15..c1af43b3e6 100644
> --- a/generator/actions_core.ml
> +++ b/generator/actions_core.ml
> @@ -1808,6 +1808,38 @@ This returns a list of the logical volume device names
>  
>  See also C<guestfs_lvs_full>, C<guestfs_list_filesystems>." };
>  
> +{ defaults with
> +    name = "vxvm"; added = (0, 0, 1);
> +    style = RStringList (RDevice, "logvols"), [], [];
> +    impl = OCaml "Vm.vxvm";
> +    optional = Some "vxvm";
> +    shortdesc = "list the VxVM volumes (vxvm)";
> +    longdesc = "\
> +List all the VxVM volumes detected.  This is the equivalent
> +of the L<vxdisk list> command.
> +
> +This returns a list of the VxVM volume device names
> +(eg. F</dev/vx/dsk/DiskGroup/Volume>).
> +
> +See also C<guestfs_list_filesystems>." };


We're probably going to need to call this something like "list_vxvm".

> +{ defaults with
> +    name = "vxvmvol_type"; added = (0, 0, 1);
> +    style = RString (RPlainString, "fstype"), [String (Mountable, 
> "mountable")], [];
> +    impl = OCaml "Vxvm_type.vxvmvol_type";
> +    shortdesc = "get the VxVM Volume type corresponding to a mounted device";
> +    longdesc = "\
> +This command returns the filesystem type corresponding to
> +the filesystem on C<mountable>." };

OK.

> +{ defaults with
> +    name = "vxfs_start"; added = (0, 0, 1);
> +    style = RErr, [], [];
> +    shortdesc = "this command is used to start vxfs service";
> +    longdesc = "\
> +In order to start vxfs service in the guestfsd we use
> +this command" };

As discussed above, I don't think this should be a public API.

>    { defaults with
>      name = "pvs_full"; added = (0, 0, 4);
>      style = RStructList ("physvols", "lvm_pv"), [], [];
> diff --git a/generator/proc_nr.ml b/generator/proc_nr.ml
> index f71a849c98..9086f26c77 100644
> --- a/generator/proc_nr.ml
> +++ b/generator/proc_nr.ml
> @@ -516,6 +516,9 @@ let proc_nr = [
>  511, "internal_readdir";
>  512, "clevis_luks_unlock";
>  513, "inspect_get_build_id";
> +514, "vxvm";
> +515, "vxvmvol_type";
> +516, "vxfs_start"
>  ]
>  
>  (* End of list.  If adding a new entry, add it at the end of the list
> diff --git a/lib/MAX_PROC_NR b/lib/MAX_PROC_NR
> index 31cf34b8d0..1c599d4ff3 100644
> --- a/lib/MAX_PROC_NR
> +++ b/lib/MAX_PROC_NR
> @@ -1 +1 @@
> -513
> +516
> diff --git a/po/POTFILES b/po/POTFILES
> index 1facee0a3c..1989b17c8c 100644
> --- a/po/POTFILES
> +++ b/po/POTFILES
> @@ -144,6 +144,7 @@ daemon/uuids.c
>  daemon/wc.c
>  daemon/xattr.c
>  daemon/xfs.c
> +daemon/vxfs.c
>  daemon/yara.c
>  daemon/zero.c
>  daemon/zerofree.c

Do you have any suggestions about how to test the patch?

I'm able to create a vxfs filesystem and loop mount it, but what kind
of commands might I run to explore the filesystem and test things are
working?

Rich.

-- 
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
virt-builder quickly builds VMs from scratch
http://libguestfs.org/virt-builder.1.html
_______________________________________________
Libguestfs mailing list
Libguestfs@redhat.com
https://listman.redhat.com/mailman/listinfo/libguestfs

Reply via email to