Ravi Singh
2023-Sep-15 11:37 UTC
[Libguestfs] [External] Re: [PATCH] VxFS Filesystem support to libguestfs
Hi Richard, I wanted to express my gratitude for taking the time to review the patch we submitted. We have made the suggested changes based on your feedback, and we have also included inline response to your comments for clarity. To ensure smooth review process, I have attached the updated patch, and a document on testing steps as a zip. Please let me know if you require any additional information or have specific questions, we can schedule a call. Thanks, Ravi / Gaurang -------------------------------------------- On Thu, Jun 08, 2023 at 11:38:53AM +0100, Richard W.M. Jones wrote:> From: Ravi Singh <ravi.singh at 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-startupThese 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/fstypThis 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>>> Fixed. Added VRTS* packages to packagelist.in and removed the above scripts from hostfiles.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.>>> The approach here we took to pass the package name as an extra parameter during libguestfs initial configure stage to eliminate our package dependencies. But as you suggested added to packagelist.in.e.g: ./configure --with-extra-packages="VRTSperl VRTSpython VRTSveki VRTSvlic VRTSvxfs VRTSvxvm"> 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.>>> Fixed. That was not intentional. Simple function works fine.> /* 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. Fixed. daemon/vm.mli is removed from patch.> + * 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.>> Done.> +{ > + 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.>> Fixed. daemon/vxvm_type.mli removed from patch.> + * 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".>>> Fixed.> +{ 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.>>> Fixed. Removed these lines of code.> { 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.cDo 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?>> Please find the attached zip file, contains latest patch and commands to create VxVM volumes and VxFS for testing this patch.________________________________ From: Richard W.M. Jones <rjones at redhat.com> Sent: Thursday, September 14, 2023 6:37 PM To: libguestfs at redhat.com <libguestfs at redhat.com> Cc: Ravi Singh <Ravi.Singh at veritas.com>; Aswad Kulkarni <aswad.kulkarni at veritas.com>; Shailesh Marathe <Shailesh.Marathe at veritas.com>; Sumit Dighe <Sumit.Dighe at veritas.com>; Mitul Kothari <Mitul.Kothari at veritas.com>; Brad Boyer <brad.boyer at veritas.com>; Saket Pusalkar <Saket.Pusalkar at veritas.com>; Gaurang Agnihotri <Gaurang.Agnihotri at veritas.com> Subject: [External] Re: [Libguestfs] [PATCH] VxFS Filesystem support to libguestfs CAUTION: This email originated from outside the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe. If you believe this is a phishing email, use the Report to Cybersecurity icon in Outlook. On Thu, Jun 08, 2023 at 11:38:53AM +0100, Richard W.M. Jones wrote:> From: Ravi Singh <ravi.singh at 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-startupThese 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/fstypThis 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.cDo 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 https://nam12.safelinks.protection.outlook.com/?url=http%3A%2F%2Fpeople.redhat.com%2F~rjones&data=05%7C01%7Cravi.singh%40veritas.com%7C0d0af6c56f12497f17b508dbb5238230%7Cfc8e13c0422c4c55b3eaca318e6cac32%7C0%7C0%7C638302936384477119%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=WLOkxzSzssVoOlTnXIUCC6bs1lGNK0NxEp06vaY2XnM%3D&reserved=0<http://people.redhat.com/~rjones> Read my programming and virtualization blog: https://nam12.safelinks.protection.outlook.com/?url=http%3A%2F%2Frwmj.wordpress.com%2F&data=05%7C01%7Cravi.singh%40veritas.com%7C0d0af6c56f12497f17b508dbb5238230%7Cfc8e13c0422c4c55b3eaca318e6cac32%7C0%7C0%7C638302936384477119%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=RfD1Sim9NrEgjL%2BGKXYwGdd9h0H22RBNwMgpP4HInxw%3D&reserved=0<http://rwmj.wordpress.com/> virt-builder quickly builds VMs from scratch https://nam12.safelinks.protection.outlook.com/?url=http%3A%2F%2Flibguestfs.org%2Fvirt-builder.1.html&data=05%7C01%7Cravi.singh%40veritas.com%7C0d0af6c56f12497f17b508dbb5238230%7Cfc8e13c0422c4c55b3eaca318e6cac32%7C0%7C0%7C638302936384477119%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=KnL10hys93sjbOTI6Q4UxlhUrfV2bOkD%2Bt%2BWJg27Q%2Fs%3D&reserved=0<http://libguestfs.org/virt-builder.1.html> -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://listman.redhat.com/archives/libguestfs/attachments/20230915/0ad2db34/attachment-0001.htm> -------------- next part -------------- A non-text attachment was scrubbed... Name: libguestfs_patch_15sept.zip Type: application/zip Size: 36425 bytes Desc: libguestfs_patch_15sept.zip URL: <http://listman.redhat.com/archives/libguestfs/attachments/20230915/0ad2db34/attachment-0001.zip>
Richard W.M. Jones
2023-Sep-19 10:18 UTC
[Libguestfs] [External] Re: [PATCH] VxFS Filesystem support to libguestfs
On Fri, Sep 15, 2023 at 11:37:32AM +0000, Ravi Singh wrote:> >>> Fixed. Added VRTS* packages to packagelist.in and removed the > above scripts from hostfiles.OK, that should work. I will test it out later. One issue we'll probably have is how to package this up for Fedora or RHEL as those require that the RPMs are available at build time (which is not possible as they are not open source). It may be that you will need to build a "libguestfs-vxfs" package yourself, built against your RPMs. It's fairly simple to do this but let's cross that bridge later.> >>> The approach here we took to pass the package name as an extra parameter > during libguestfs initial configure stage to eliminate our package > dependencies. But as you suggested added to packagelist.in. > > e.g: > ./configure --with-extra-packages="VRTSperl VRTSpython VRTSveki VRTSvlic > VRTSvxfs VRTSvxvm"I see. That would work, but including the package names in appliance/packagelist.in makes everything easier.> > + /* Start vxfs services */ > > + do_vxfs_start(); > > + > > >>> Fixed. That was not intentional. Simple function works fine.Good.> >> Please find the attached zip file, contains latest patch and commands to > create VxVM volumes and VxFS for testing this patch.Alright, I'll try this out soon. Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com virt-p2v converts physical machines to virtual machines. Boot with a live CD or over the network (PXE) and turn machines into KVM guests. http://libguestfs.org/virt-v2v
Richard W.M. Jones
2023-Sep-19 11:00 UTC
[Libguestfs] [External] Re: [PATCH] VxFS Filesystem support to libguestfs
A new patch is attached. This is only build tested so far. To build with this patch I had to do: ./configure --enable-werror \ --with-supermin-packager-config=$PWD/localyum.conf where localyum.conf contains: ---------------------------------------------------------------------- [local] name=local baseurl=file:///root/dvd1-redhatlinux/rhel9_x86_64/rpms/ enabled=1 gpgcheck=0 ---------------------------------------------------------------------- (adjust the path to point to the Veritas DVD mount point) I made various changes in this patch: - Add copyright and license notice to list_vxvm.ml & vxfs.c. Please ensure all files have copyright and license notices, and if necessary get them checked by your legal. - Change vm.ml{,i} -> list_vxvm.ml{,i} - In packagelist.in, move package names to their own section. - Remove perl/python packages as perl/python is not present in the appliance. - Fix commit message. - Line length under 80 columns in a few places. - Function names at start of line. - List SOURCES_MLI alphabetically. - daemon/listfs.ml: Remove comment about has_vxvm. - do_vxfs_start -> vxfs_start (since do_* is reserved prefix in daemon). - Skip vxfs_start if !vxdisk available, to save start up time. - Add a prototype for vxfs_start. - Don't use reply_with_error in vxfs_start, as we're not called during protocol context. - Use only one *err. - Add daemon/list_vxvm.mli & daemon/vxvm_type.mli to .gitignore vxfs_start has several issues which need to be addressed: - Why does it return if a service (eg. veki) is not available? That would prevent all further initialization. - I think this would be better done as part of appliance/init, and delete this function completely. Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com libguestfs lets you edit virtual machines. Supports shell scripting, bindings from many languages. http://libguestfs.org -------------- next part -------------->From 997cd736acf59432804aebb469fc1c6dbe56a9fd Mon Sep 17 00:00:00 2001From: "ravi.singh" <ravi.singh at veritas.com> Date: Fri, 15 Sep 2023 15:40:50 +0530 Subject: [PATCH] Add VxFS Filesystem support --- .gitignore | 2 + appliance/init | 2 + appliance/packagelist.in | 8 +++ daemon/Makefile.am | 9 ++- daemon/daemon.h | 3 + daemon/guestfsd.c | 3 + daemon/list_vxvm.ml | 78 ++++++++++++++++++++++++ daemon/listfs.ml | 13 ++++ daemon/vxfs.c | 122 ++++++++++++++++++++++++++++++++++++++ daemon/vxvm_type.ml | 17 ++++++ generator/actions_core.ml | 24 ++++++++ generator/proc_nr.ml | 2 + lib/MAX_PROC_NR | 2 +- po/POTFILES | 1 + 14 files changed, 284 insertions(+), 2 deletions(-) create mode 100644 daemon/list_vxvm.ml create mode 100644 daemon/vxfs.c create mode 100644 daemon/vxvm_type.ml diff --git a/.gitignore b/.gitignore index ee5ea74dd..28d327ea0 100644 --- a/.gitignore +++ b/.gitignore @@ -96,6 +96,7 @@ Makefile.in /daemon/ldm.mli /daemon/link.mli /daemon/listfs.mli +/daemon/list_vxvm.mli /daemon/lvm.mli /daemon/lvm_dm.mli /daemon/lvm-tokenization.c @@ -118,6 +119,7 @@ Makefile.in /daemon/stubs-?.c /daemon/stubs.h /daemon/types.ml +/daemon/vxvm_type.mli /depcomp /docs/guestfs-building.1 /docs/guestfs-faq.1 diff --git a/appliance/init b/appliance/init index d41056659..535a3d6b1 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/appliance/packagelist.in b/appliance/packagelist.in index 20b08c470..06d4aaf6d 100644 --- a/appliance/packagelist.in +++ b/appliance/packagelist.in @@ -271,5 +271,13 @@ exfat-utils exfatprogs fuse-exfat +dnl Proprietary Veritas packages for VxFS support +dnl VRTSperl +dnl VRTSpython +VRTSveki +VRTSvlic +VRTSvxfs +VRTSvxvm + dnl Define this by doing: ./configure --with-extra-packages="..." EXTRA_PACKAGES diff --git a/daemon/Makefile.am b/daemon/Makefile.am index bd1920c61..b251bebf4 100644 --- a/daemon/Makefile.am +++ b/daemon/Makefile.am @@ -51,6 +51,8 @@ generator_built = \ link.mli \ listfs.mli \ lvm.mli \ + list_vxvm.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 @@ -292,6 +295,7 @@ SOURCES_MLI = \ isoinfo.mli \ ldm.mli \ link.mli \ + list_vxvm.mli \ listfs.mli \ lvm.mli \ lvm_dm.mli \ @@ -307,7 +311,8 @@ SOURCES_MLI = \ statvfs.mli \ structs.mli \ sysroot.mli \ - utils.mli + utils.mli \ + vxvm_type.mli SOURCES_ML = \ $(CONFIGURE_GENERATED_ML) \ @@ -328,6 +333,8 @@ SOURCES_ML = \ ldm.ml \ link.ml \ lvm.ml \ + list_vxvm.ml \ + vxvm_type.ml \ lvm_utils.ml \ lvm_dm.ml \ findfs.ml \ diff --git a/daemon/daemon.h b/daemon/daemon.h index e050588ca..5b32da87d 100644 --- a/daemon/daemon.h +++ b/daemon/daemon.h @@ -289,6 +289,9 @@ extern int xfs_set_uuid_random (const char *device); extern int xfs_set_label (const char *device, const char *label); extern int64_t xfs_minimum_size (const char *path); +/* vxfs.c */ +extern void vxfs_start (void); + /* debug-bmap.c */ extern char *debug_bmap (const char *subcmd, size_t argc, char *const *const argv); extern char *debug_bmap_file (const char *subcmd, size_t argc, char *const *const argv); diff --git a/daemon/guestfsd.c b/daemon/guestfsd.c index 33c297de3..1f9db46d4 100644 --- a/daemon/guestfsd.c +++ b/daemon/guestfsd.c @@ -273,6 +273,9 @@ main (int argc, char *argv[]) */ udev_settle (); + /* Start vxfs services */ + vxfs_start(); + /* Send the magic length message which indicates that * userspace is up inside the guest. */ diff --git a/daemon/list_vxvm.ml b/daemon/list_vxvm.ml new file mode 100644 index 000000000..b491bdab2 --- /dev/null +++ b/daemon/list_vxvm.ml @@ -0,0 +1,78 @@ +(* guestfs-inspection + * Copyright (C) 2023 Veritas + * + * 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. + *) + +open Unix +open Printf + +open Std_utils +open Str +open Utils + +let rec list_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->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/listfs.ml b/daemon/listfs.ml index 2376b61db..e8487714d 100644 --- a/daemon/listfs.ml +++ b/daemon/listfs.ml @@ -27,6 +27,7 @@ open Std_utils let rec list_filesystems () let has_lvm2 = Optgroups.lvm2_available () in let has_ldm = Optgroups.ldm_available () in + let has_vxvm = Optgroups.vxvm_available () in let ret = ref [] in @@ -53,6 +54,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 = List_vxvm.list_vxvm () in + List.iter (check_with_vxvmvol_type ret) vxvm_vol + ); + (* LVM. *) if has_lvm2 then ( let lvs = Lvm.lvs () in @@ -192,3 +199,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/vxfs.c b/daemon/vxfs.c new file mode 100644 index 000000000..fb765fff7 --- /dev/null +++ b/daemon/vxfs.c @@ -0,0 +1,122 @@ +/* libguestfs - the guestfsd daemon + * Copyright (C) 2023 Veritas + * + * 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. + */ + +#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 <error.h> + +#include "daemon.h" + +/* This is used to check if we have the vxvm utility + * in place. + */ +int +optgroup_vxvm_available (void) +{ + return prog_exists ("vxdisk"); +} + +static int +opt_servicefile_available (const char *path) +{ + 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 license then starting all the related + * services to read the files from vxvm disk layout + */ +void +vxfs_start (void) +{ + CLEANUP_FREE char *err = NULL; + int r; + + if (!optgroup_vxvm_available ()) + return; + + /** + * Setup the license on the appliance to configure + * Infoscale services. + */ + r = commandr (NULL, &err, "vxkeyless", "--quiet", "set", "ENTERPRISE", + NULL); + if (r == -1) + error (EXIT_FAILURE, 0, "vxkeyless set error: %s", err); + + /** + * Start Veki service. + */ + if (opt_servicefile_available ("veki") == 0) return; + r = commandr (NULL, &err, "/etc/vx/veki", "start", NULL); + if (r == -1) + error (EXIT_FAILURE, 0, "veki start error: %s", err); + + /** + * Start vxfs service. + */ + if (opt_servicefile_available("vxfs") == 0) return; + r = commandr (NULL, &err, "/etc/vx/vxfs", "start", NULL); + if (r == -1) + error (EXIT_FAILURE, 0, "vxfs start error: %s", err); + + /** + * Start vxvm related services. + */ + if (opt_servicefile_available("vxvm-startup") == 0) return; + r = commandr (NULL, &err, "sh", "/etc/vx/vxvm-startup", NULL); + if (r == -1) + error (EXIT_FAILURE, 0, "vxvm start error: %s", err); + + /** + * Trigger vxdctl init to generate volboot file + */ + r = commandr (NULL, &err, "vxdctl", "init", NULL); + if (r == -1) + error (EXIT_FAILURE, 0, "vxdctl init error: %s", err); + + /** + * Enabling this would allow us to use vxvm related + * commands + */ + r = commandr (NULL, &err, "vxdctl", "enable", NULL); + if (r == -1) + error (EXIT_FAILURE, 0, "vxdctl enable error: %s", err); +} diff --git a/daemon/vxvm_type.ml b/daemon/vxvm_type.ml new file mode 100644 index 000000000..211a1832b --- /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.value ~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/generator/actions_core.ml b/generator/actions_core.ml index addbe4ec1..1ec18923a 100644 --- a/generator/actions_core.ml +++ b/generator/actions_core.ml @@ -1808,6 +1808,30 @@ This returns a list of the logical volume device names See also C<guestfs_lvs_full>, C<guestfs_list_filesystems>." }; +{ defaults with + name = "list_vxvm"; added = (0, 0, 1); + style = RStringList (RDevice, "logvols"), [], []; + impl = OCaml "List_vxvm.list_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>." }; + +{ 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>." }; + { 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 f71a849c9..75239cbdd 100644 --- a/generator/proc_nr.ml +++ b/generator/proc_nr.ml @@ -516,6 +516,8 @@ let proc_nr = [ 511, "internal_readdir"; 512, "clevis_luks_unlock"; 513, "inspect_get_build_id"; +514, "list_vxvm"; +515, "vxvmvol_type"; ] (* 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 31cf34b8d..3cda32fc2 100644 --- a/lib/MAX_PROC_NR +++ b/lib/MAX_PROC_NR @@ -1 +1 @@ -513 +515 diff --git a/po/POTFILES b/po/POTFILES index 1facee0a3..1989b17c8 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 -- 2.39.1