]> www.infradead.org Git - users/dhowells/kafs-utils.git/commitdiff
Implement "vos listvol"
authorDavid Howells <dhowells@redhat.com>
Fri, 10 Jul 2020 07:40:08 +0000 (08:40 +0100)
committerDavid Howells <dhowells@redhat.com>
Fri, 5 May 2023 10:53:26 +0000 (11:53 +0100)
Signed-off-by: David Howells <dhowells@redhat.com>
kafs/Makefile
kafs/vol_query.C
kafs/volservice.H
kafs/vos_listvol.C [new file with mode: 0644]

index 504b93b19436553d8511feddc099231851cc0e18..6c0d3928e94e436b873a276cf11616557ce012bc 100644 (file)
@@ -36,6 +36,7 @@ VOS_SRCS := \
        vos_help.C \
        vos_listaddrs.C \
        vos_listvldb.C \
+       vos_listvol.C \
        vos_status.C
 
 CORE_OBJS := $(patsubst %.C,%.o,$(CORE_SRCS))
index 21d6277f470fa94d38f8347d50f5df2c36af6640..1ab47502033ec40ea1e30462934d956de9326235 100644 (file)
@@ -18,6 +18,8 @@ using kafs::Volserver;
 namespace kafs {
 static void volintinfo_to_volume_info(afs::volintInfo &info, Volume_info_list &vilist);
 static void xvolintinfo_to_volume_info(afs::xvolintInfo &xinfo, Volume_info_list &vilist);
+static void volintInfo64_to_volume_info(afs::volintInfo64 &info, afs::volintStats64 &stats,
+                                       Volume_info_list &vilist);
 }
 
 /**
@@ -152,6 +154,59 @@ static void kafs::xvolintinfo_to_volume_info(afs::xvolintInfo &xinfo,
        vi.nr_week_use          = 0;
 }
 
+/*
+ * Convert an xvolintInfo64 struct to a kafs_volume_info record.
+ */
+static void kafs::volintInfo64_to_volume_info(afs::volintInfo64 &info,
+                                             afs::volintStats64 &stats,
+                                             Volume_info_list &vilist)
+{
+       unsigned int index = vilist.size();
+       vilist.resize(index + 1);
+       Volume_info &vi = vilist[index];
+       int i;
+
+       vi.name                 = info.name;
+       vi.offline_msg          = info.offlineMessage;
+       vi.volid                = info.volId;
+       vi.type                 = info.type;
+       vi.backup_id            = info.backupId;
+       vi.parent_id            = info.parentId;
+       vi.clone_id             = info.cloneId;
+       vi.status               = info.status;
+       vi.flags                = info.flags;
+       vi.owner                = info.owner;
+
+       vi.creation_date        = info.creationDate;
+       vi.access_date          = info.accessDate;
+       vi.update_date          = info.updateDate;
+       vi.expiration_date      = info.expirationDate;
+       vi.backup_date          = info.backupDate;
+       vi.copy_date            = info.copyDate;
+
+       vi.max_quota            = info.maxquota;
+       vi.min_quota            = info.minquota;
+       vi.max_files            = info.maxfiles;
+       vi.disk_used            = info.diskused;
+       vi.file_count           = info.filecount;
+       vi.vol_update_counter   = info.volUpdateCounter;
+
+       vi.day_use_date         = info.dayUseDate;
+       vi.day_use              = info.dayUse;
+       for (i = 0; i < 7; i++)
+               vi.week_use[i]  = info.weekUse[i];
+
+       vi.has_day_use_date     = true;
+       vi.has_disk_used        = true;
+       vi.has_expiration_date  = true;
+       vi.has_flags            = true;
+       vi.has_max_files        = true;
+       vi.has_min_quota        = true;
+       vi.has_owner            = true;
+       vi.has_vol_update_counter = true;
+       vi.nr_week_use          = 7;
+}
+
 /**
  * Volserver::VOLSER_ListOneVolume - Get the ordinary state of an instance of a volume
  * @partition: The partition on which the volume resides
@@ -196,6 +251,27 @@ void Volserver::VOLSER_XListOneVolume(Partition_spec &partition,
        xvolintinfo_to_volume_info(xinfos[0], vi);
 }
 
+/**
+ * Volserver::YFSVOL_FetchVolumeInfo64 - Get the state of an instance of a volume
+ * @partition: The partition on which the volume resides
+ * @volid: The ID of the volume to query
+ * @vi: The record to load with the information retrieved
+ *
+ * Query the extended state of a volume on a volume server.  The information is
+ * stored into the supplied record.
+ */
+void Volserver::YFSVOL_FetchVolumeInfo64(Partition_spec &partition,
+                                        Volume_id volid,
+                                        Volume_info_list &vi)
+{
+       afs::volintInfo64 result_entry;
+       afs::volintStats64 result_stats;
+
+       afs::YFSVOL::FetchVolumeInfo64(&vs_params, partition.id, volid,
+                                      1, 1, result_entry, result_stats);
+       volintInfo64_to_volume_info(result_entry, result_stats, vi);
+}
+
 /**
  * Volserver::query_volume_state - Query the state of an instance of a volume
  * @partition: The partition on which the volume resides
@@ -217,6 +293,61 @@ void Volserver::query_volume_state(Partition_spec &partition,
                VOLSER_ListOneVolume(partition, volid, vi);
 }
 
+/**
+ * Volserver::VOLSER_ListVolumes - Get the ordinary states of volume instances on a partition
+ * @ctx: The cell and authentication context
+ * @server: The volume server to contact
+ * @partition: The partition on which the volumes reside
+ * @vilist: The record to load with the information retrieved
+ *
+ * Query the ordinary state of a volume on a volume server.  The information is
+ * stored into the supplied record.
+ */
+void Volserver::VOLSER_ListVolumes(Partition_spec &partition,
+                                  Volume_info_list &vilist)
+{
+       std::vector<afs::volintInfo> infos;
+
+       afs::VOLSER::ListVolumes(&vs_params, partition.id, 1, infos);
+       if (infos.size() == 0)
+               throw std::runtime_error("No volume information results returned");
+       volintinfo_to_volume_info(infos[0], vilist);
+}
+
+/*
+ * Query the extended state of a volume.
+ */
+void Volserver::VOLSER_XListVolumes(Partition_spec &partition,
+                                   Volume_info_list &vilist)
+{
+       std::vector<afs::xvolintInfo> xinfos;
+
+       afs::VOLSER::XListVolumes(&vs_params, partition.id, 1, xinfos);
+       if (xinfos.size() == 0)
+               throw std::runtime_error("No volume information results returned");
+       xvolintinfo_to_volume_info(xinfos[0], vilist);
+}
+
+/**
+ * Volserver::query_volume_states - Query the state of the volumes on a partition
+ * @partition: The partition to search
+ * @extended: Whether extended info is required
+ * @vilist: The list to add the returned record to
+ *
+ * Query the state of a volume residing in a particular partition on a
+ * particular volume server.  If successful, a record is allocated and
+ * added to the list.
+ */
+void Volserver::query_volume_states(Partition_spec &partition,
+                                   bool extended,
+                                   Volume_info_list &vilist)
+{
+       if (extended)
+               VOLSER_XListVolumes(partition, vilist);
+       else
+               VOLSER_ListVolumes(partition, vilist);
+}
+
 /**
  * Volserver::list_partitions - Get a list of partitions on a server.
  * @partitions: Where to store the list of partitions.
index 4eaf7dce2e9fad1900a7fb23348468d646136d60..2412c1f86e402d0c6d4df6859dddcf269c11888d 100644 (file)
@@ -144,10 +144,18 @@ public:
        void VOLSER_XListOneVolume(Partition_spec &partition,
                                   Volume_id volid,
                                   Volume_info_list &vi);
+       void YFSVOL_FetchVolumeInfo64(Partition_spec &partition,
+                                     Volume_id volid,
+                                     Volume_info_list &vi);
+       void VOLSER_ListVolumes(Partition_spec &partition,
+                               Volume_info_list &vilist);
+       void VOLSER_XListVolumes(Partition_spec &partition,
+                                Volume_info_list &vilist);
        void vol_monitor_transaction(Vol_transaction_info_list &);
        void list_partitions(Partition_list &);
        void query_volume_state(Partition_spec &, Volume_id, bool,
                                Volume_info_list &);
+       void query_volume_states(Partition_spec &, bool, Volume_info_list &);
 };
 
 } /* end namespace kafs */
diff --git a/kafs/vos_listvol.C b/kafs/vos_listvol.C
new file mode 100644 (file)
index 0000000..7e92779
--- /dev/null
@@ -0,0 +1,227 @@
+/* The "vos listvol" command
+ *
+ * Copyright (C) 2020 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#include <iostream>
+#include <algorithm>
+#include <fmt/core.h>
+#include "kafs.H"
+#include "volservice.H"
+#include "arg_parse.H"
+#include "display.H"
+#include "afs_xg.H"
+
+using rxrpc::ref;
+using kafs::afs::VOK;
+using kafs::afs::VBUSY;
+
+static void display_fast(kafs::Context *ctx,
+                        kafs::FS_site *site,
+                        kafs::Partition_spec &part,
+                        kafs::Volume_info &vi)
+{
+       fmt::print("{:d}\n", vi.volid);
+}
+
+static void display_extended(kafs::Context *ctx,
+                            kafs::FS_site *site,
+                            kafs::Partition_spec &part,
+                            kafs::Volume_info &vi)
+{
+       kafs::display_vol_information(ctx, site, part, vi);
+       kafs::display_vol_statistics(ctx, vi);
+}
+
+static void display_format_normal(kafs::Context *ctx,
+                                 kafs::FS_site *site,
+                                 kafs::Partition_spec &part,
+                                 kafs::Volume_info &vi)
+{
+       kafs::display_vol_mp_information(ctx, site, part, vi);
+       fmt::print("END_OF_ENTRY\n");
+}
+
+static const char *const reads_labels[] = {
+       "reads_same_net",
+       "reads_same_net_auth",
+       "reads_diff_net",
+       "reads_diff_net_auth",
+};
+
+static const char *const writes_labels[] = {
+       "writes_same_net",
+       "writes_same_net_auth",
+       "writes_diff_net",
+       "writes_diff_net_auth",
+};
+
+static void display_format_extended(kafs::Context *ctx,
+                                   kafs::FS_site *site,
+                                   kafs::Partition_spec &part,
+                                   kafs::Volume_info &vi)
+{
+       int i;
+
+       if (vi.status != VOK) {
+               if (vi.status == VBUSY)
+                       fmt::print("VOLUME_BUSY\t{:d}\n", vi.volid);
+               else
+                       fmt::print("COULD_NOT_ATTACH_VOLUME\t{:d}\n", vi.volid);
+               return;
+       }
+
+       display_vol_mp_basic_information(ctx, site, part, vi);
+
+       for (i = 0; i < 4; i++)
+               fmt::print("{}\t{:8d}\n", reads_labels[i], vi.stat_reads[i]);
+       for (i = 0; i < 4; i++)
+               fmt::print("{}\t{:8d}\n", writes_labels[i], vi.stat_writes[i]);
+       for (i = 0; i < 6; i++) {
+               fmt::print("file_same_author_idx_{:d}\t{:8d}\n", i, vi.stat_fileSameAuthor[i]);
+               fmt::print("file_diff_author_idx_{:d}\t{:8d}\n", i, vi.stat_fileDiffAuthor[i]);
+               fmt::print("dir_same_author_idx_{:d}\t{:8d}\n", i, vi.stat_dirSameAuthor[i]);
+               fmt::print("dir_dif_author_idx_{:d}\t{:8d}\n", i, vi.stat_dirDiffAuthor[i]);
+       }
+
+       fmt::print("END_OF_ENTRY");
+}
+
+static bool compare_entries(const kafs::Volume_info &a, const kafs::Volume_info &b)
+{
+       return a.name.compare(b.name) < 0; //strcmp(a->name, b->name) < 0;
+}
+
+/*
+ * Display the records for a single partition in the appropriate format
+ */
+static void display_one_partition(kafs::Context *ctx,
+                                 kafs::FS_site *site,
+                                 kafs::Volserver *server,
+                                 kafs::Partition_spec &partition,
+                                 bool a_fast,
+                                 bool a_long,
+                                 bool a_quiet,
+                                 bool a_extended,
+                                 bool a_format)
+{
+       kafs::Volume_info_list vilist;
+       unsigned int n_online = 0, n_offline = 0, n_busy = 0, i;
+
+       void (*display_func)(kafs::Context *ctx,
+                            kafs::FS_site *site,
+                            kafs::Partition_spec &part,
+                            kafs::Volume_info &vi);
+
+       server->query_volume_states(partition, a_extended, vilist);
+
+       if (!a_quiet)
+               fmt::print("Total number of volumes on server {} partition {}: {:d}\n",
+                          site->name, kafs::sprint_partition(partition), vilist.size());
+
+       display_func = kafs::display_vol_oneline_summary;
+       if (a_fast)
+               display_func = display_fast;
+       else if (a_format && a_extended)
+               display_func = display_format_extended;
+       else if (a_format)
+               display_func = display_format_normal;
+       else if (a_extended)
+               display_func = display_extended;
+       else if (a_long)
+               display_func = kafs::display_vol_information;
+
+       std::sort(vilist.begin(), vilist.end(), compare_entries);
+
+       for (i = 0; i < vilist.size(); i++) {
+               kafs::Volume_info &vi = vilist[i];
+               if (vi.in_use)
+                       n_online += 1;
+               if (vi.status == VBUSY)
+                       n_busy += 1;
+               display_func(ctx, site, partition, vi);
+       }
+
+       if (!a_quiet) {
+               fmt::print("\n");
+               if (!a_fast && !a_format) {
+                       fmt::print("Total volumes onLine {:d}; Total volumes offLine {:d}; Total busy {:d}\n",
+                              n_online, n_offline, n_busy);
+                       fmt::print("\n");
+               } else if (a_format && a_extended) {
+                       fmt::print("VOLUMES_ONLINE  {:d}\n", n_online);
+                       fmt::print("VOLUMES_OFFLINE {:d}\n", n_offline);
+                       fmt::print("VOLUMES_BUSY    {:d}\n", n_busy);
+               }
+       }
+}
+
+/***
+ * COMMAND: vos listvol - Display information from a volume header
+ * ARG: "-server <machine name>"
+ * ARG: "[-partition <partition name>]"
+ * ARG: "[-fast]"
+ * ARG: "[-long]"
+ * ARG: "[-quiet]"
+ * ARG: "[-extended]"
+ * ARG: "[-format]"
+ * ARG: "[-cell <cell name>]"
+ * ARG: "[-noauth]"                            - Auth
+ * ARG: "[-localauth]"                         - Auth
+ * ARG: "[-verbose]"
+ * ARG: "[-encrypt]"                           - Auth
+ * ARG: "[-noresolve]"
+ * NOCOMBINE: fast, extended
+ *
+ * Display information from a volume header.
+ */
+void COMMAND_vos_listvol(
+       kafs::Context                   *ctx,
+       kafs::Volserver_spec            &a_server,
+       kafs::Partition_spec            &a_partition,
+       bool                            a_fast,
+       bool                            a_long,
+       bool                            a_quiet,
+       bool                            a_extended,
+       bool                            a_format,
+       bool                            a_verbose,
+       bool                            a_noresolve)
+{
+       kafs::Partition_list partitions;
+       ref<kafs::Volserver> server;
+       ref<kafs::FS_site> site;
+       unsigned int i;
+
+       _enter("");
+
+       ctx->no_resolve = a_noresolve;
+
+       site = kafs::resolve_server_spec(ctx, a_server);
+       server = new kafs::Volserver(ctx, site);
+
+       if (a_partition.specified) {
+               std::string part = kafs::sprint_partition(a_partition);
+               try {
+                       display_one_partition(ctx, site, server, a_partition,
+                                             a_fast, a_long, a_quiet, a_extended,
+                                             a_format);
+               } catch (const kafs::afs::VOLSER::AbortVOLSERILLEGAL_PARTITION &a) {
+                       throw std::runtime_error(
+                               fmt::format("vos : partition {} does not exist on the server",
+                                           part));
+               }
+       } else {
+               server->list_partitions(partitions);
+
+               for (i = 0; i < partitions.size(); i++)
+                       display_one_partition(ctx, site, server, partitions[i],
+                                             a_fast, a_long, a_quiet, a_extended,
+                                             a_format);
+       }
+}