From 7f1ebe3803ab27c9178704a52044cc8e613e0c01 Mon Sep 17 00:00:00 2001 From: "ravi.singh" Date: Thu, 2 Nov 2023 23:01:56 +0530 Subject: [PATCH] Add VxFS Filesystem support --- appliance/init | 41 +++++++++++++++++++ appliance/packagelist.in | 8 ++++ daemon/Makefile.am | 9 ++++- daemon/list_vxvm.ml | 85 +++++++++++++++++++++++++++++++++++++++ daemon/listfs.ml | 13 ++++++ daemon/vxfs.c | 44 ++++++++++++++++++++ daemon/vxvm_type.ml | 34 ++++++++++++++++ generator/actions_core.ml | 24 +++++++++++ generator/proc_nr.ml | 2 + lib/MAX_PROC_NR | 2 +- po/POTFILES | 1 + 11 files changed, 261 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/appliance/init b/appliance/init index d41056659..b218495f8 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). @@ -204,6 +206,45 @@ if false; then echo quit >> /tmp/gdb-script cmd="gdb -batch -x /tmp/gdb-script --args $cmd" fi + +# Veritas VxFS support requires starting of a few specific services to bring +# the VxFS filesystem and VxVM volume manager up and running within appliance. +VXFS_STARTUP_DIR="/etc/vx" + +# Check if the VxFS/VxVM related startup script directory exists +if [ -d "$VXFS_STARTUP_DIR" ]; then + + mkdir -p /etc/vx/log/ + touch /etc/vx/log/cmdlog + + vxfs_startup() { + vxfs_exec_path=$1 + vxfs_cmd=$2 + # check if the script or bin file exists + [ -x "$vxfs_exec_path" ] && $vxfs_exec_path $vxfs_cmd + if [ $? -ne 0 ]; then + echo "Error: $vxfs_exec_path execution failed or file not found." + cmd=exit + fi + } + + # Setup the license within the appliance. + vxfs_startup /usr/sbin/vxkeyless "--quiet set ENTERPRISE"; + # Start Veki service. + vxfs_startup $VXFS_STARTUP_DIR/veki start; + # Start VxFS service. + vxfs_startup $VXFS_STARTUP_DIR/vxfs start; + # Start VxVM related services. + vxfs_startup $VXFS_STARTUP_DIR/vxvm-startup; + # Trigger vxdctl init to generate volboot file + vxfs_startup /usr/sbin/vxdctl init; + # Enabling this would allow us to use VxVM related commands + vxfs_startup /usr/sbin/vxdctl enable; +else + echo "VxFS/VxVM script directory '$VXFS_STARTUP_DIR' does not exist." + cmd=exit +fi + if ! test "$guestfs_rescue" = 1; then echo $cmd $cmd diff --git a/appliance/packagelist.in b/appliance/packagelist.in index d3a945792..8c63025d6 100644 --- a/appliance/packagelist.in +++ b/appliance/packagelist.in @@ -295,5 +295,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 01c0f6416..12da48977 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 @@ -293,6 +296,7 @@ SOURCES_MLI = \ isoinfo.mli \ ldm.mli \ link.mli \ + list_vxvm.mli \ listfs.mli \ lvm.mli \ lvm_dm.mli \ @@ -308,7 +312,8 @@ SOURCES_MLI = \ statvfs.mli \ structs.mli \ sysroot.mli \ - utils.mli + utils.mli \ + vxvm_type.mli SOURCES_ML = \ $(CONFIGURE_GENERATED_ML) \ @@ -330,6 +335,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/list_vxvm.ml b/daemon/list_vxvm.ml new file mode 100644 index 000000000..6df8aa6ec --- /dev/null +++ b/daemon/list_vxvm.ml @@ -0,0 +1,85 @@ +(* guestfs-inspection/* libguestfs - the guestfsd daemon + * Copyright (C) 2023 Veritas Technologies LLC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along + * with this program; if not, see https://www.gnu.org/licenses/lgpl-3.0.en.html + *) + +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 -> + 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/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..c931520d2 --- /dev/null +++ b/daemon/vxfs.c @@ -0,0 +1,44 @@ +/* libguestfs - the guestfsd daemon + * Copyright (C) 2023 Veritas Technologies LLC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along + * with this program; if not, see https://www.gnu.org/licenses/lgpl-3.0.en.html + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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; +} + + diff --git a/daemon/vxvm_type.ml b/daemon/vxvm_type.ml new file mode 100644 index 000000000..5ac06accc --- /dev/null +++ b/daemon/vxvm_type.ml @@ -0,0 +1,34 @@ +(* guestfs-inspection + * Copyright (C) 2023 Veritas Technologies LLC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along + * with this program; if not, see https://www.gnu.org/licenses/lgpl-3.0.en.html + *) + +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, C." }; +{ 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 command. + +This returns a list of the VxVM volume device names +(eg. F). + +See also C." }; + +{ 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." }; + { 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.31.1