]> www.infradead.org Git - users/dhowells/kafs-utils.git/commitdiff
Implement "vos examine"
authorDavid Howells <dhowells@redhat.com>
Mon, 6 Jul 2020 22:13:50 +0000 (23:13 +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/display.H
kafs/display_vol.C
kafs/vos_examine.C [new file with mode: 0644]

index 5dcad5669f3c46b97f4c370922028c798d2532cc..bde79f6fa71ba09f4939c41c0e8e15eac5aa795b 100644 (file)
@@ -32,6 +32,7 @@ PTS_SRCS := \
 
 VOS_SRCS := \
        vos.C \
+       vos_examine.C \
        vos_help.C \
        vos_listvldb.C \
        vos_status.C
index e76b9af4a84aa0eed94cc87b6eec091a95750109..8be7e61958277e7f781d96b76b0df73cd5bee4d6 100644 (file)
@@ -18,6 +18,7 @@ namespace kafs {
 
 struct Vldb_entry;
 struct Vldb_site;
+struct Volume_info;
 
 /*
  * display.C
@@ -40,6 +41,16 @@ extern bool kafs_display_error(Context *);
 extern std::string sprint_site(Context *, Vldb_site &);
 extern void display_vldb_site_list(Context *, Vldb_entry *, const char *);
 
+extern void display_vol_information(Context *, FS_site *,
+                                   Partition_spec &, Volume_info &);
+extern void display_vol_statistics(Context *, Volume_info &);
+extern void display_vol_mp_basic_information(Context *, FS_site *,
+                                            Partition_spec &, Volume_info &);
+extern void display_vol_mp_information(Context *, FS_site *,
+                                      Partition_spec &, Volume_info &);
+extern void display_vol_oneline_summary(Context *, FS_site *,
+                                       Partition_spec &, Volume_info &);
+
 } /* end namespace kafs */
 
 #endif /* DISPLAY_H */
index d38c05942e6d52274b457fdb6375458e734371b1..1825ac7edaba4e894e15bf2b6c9d457bd11d1380 100644 (file)
 #include <fmt/format.h>
 #include "kafs.H"
 #include "vlservice.H"
+#include "volservice.H"
 #include "afs_xg.H"
 #include "display.H"
 
 using rxrpc::ref;
 
+static const char *const statistics_time_ranges[] = {
+       "0-60 sec ",
+       "1-10 min ",
+       "10min-1hr",
+       "1hr-1day ",
+       "1day-1wk ",
+       "> 1wk    "
+};
+
+static std::string vol_type(const kafs::Volume_info &vi)
+{
+       switch (vi.type) {
+       case 0:  return "RW";
+       case 1:  return "RO";
+       case 2:  return "BK";
+       default: return fmt::format("0x{:02x}", vi.type);
+       }
+}
+
+static const char *vol_state(const kafs::Volume_info &vi)
+{
+        if (!vi.needs_salvage) {
+               if (vi.in_use)
+                       return "On-line";
+               else
+                       return "Off-line";
+       } else {
+               if (vi.in_use)
+                       return "On-line**needs salvage**";
+               else
+                       return "Off-line**needs salvage**";
+       }
+}
+
+static const char *vol_status(const kafs::Volume_info &vi)
+{
+       switch (vi.status) {
+       case kafs::afs::VOK:    return "OK";
+       case kafs::afs::VBUSY:  return "BUSY";
+       default:                return "UNATTACHABLE";
+       }
+}
+
+static const char *yes_or_no(bool x)
+{
+       return x ? "Y" : "N";
+}
+
 /*
  * Convert a volume site into a textual representation, possibly resolving it
  * to a DNS hostname.
@@ -94,3 +143,273 @@ void kafs::display_vldb_site_list(Context *ctx,
                        std::cout << indent << "Volume is locked for a dump/restore operation\n";
        }
 }
+
+/*
+ * Display a one-line volume summary
+ *
+ *       proj.foo                          536870957 RW   40475760 K On-line
+ *
+ */
+void kafs::display_vol_oneline_summary(Context *ctx,
+                                      FS_site *server,
+                                      Partition_spec &partition,
+                                      Volume_info &vi)
+{
+       fmt::print("{:<32s} {:10d} {:<2s} {:10d} K {}\n",
+                  vi.name,
+                  vi.volid,
+                  vol_type(vi),
+                  vi.size,
+                  vol_state(vi));
+}
+
+/*
+ * Display a volume information timestamp.
+ */
+static void display_vol_timestamp(const char *key, kafs::Time &t)
+{
+       fmt::print("{}{}\n", key, kafs::sprint_time_or_never(t));
+}
+
+/*
+ * Display volume information
+ *
+ *       proj.foo                          536870957 RW   40475760 K On-line
+ *           204.29.154.47 /vicepa
+ *           RWrite  536870957 ROnly  536870958 Backup          0
+ *           MaxQuota          0 K
+ *           Creation    Sat Aug 22 06:22:27 2009
+ *           Copy        Tue Oct 26 00:40:32 2010
+ *           Backup      Never
+ *           Last Access Tue Jan 28 23:20:37 2014
+ *           Last Update Mon Aug 05 21:15:32 2013
+ *           0 accesses in the past day (i.e., vnode references)
+ *       <blank>
+ *
+ */
+void kafs::display_vol_information(Context *ctx,
+                                  FS_site *site,
+                                  Partition_spec &partition,
+                                  Volume_info &vi)
+{
+       std::string addr = kafs::sprint_address(ctx, site->vs_addrs[0]);
+       std::string part = kafs::sprint_partition(partition);
+
+       display_vol_oneline_summary(ctx, site, partition, vi);
+       fmt::print("    {} {}\n", addr, part);
+       fmt::print("    RWrite {:10d} ROnly {:10d} Backup {:10d}\n",
+                  vi.parent_id, vi.clone_id, vi.backup_id);
+       fmt::print("    MaxQuota {:10d} K\n", vi.max_quota);
+
+       display_vol_timestamp("    Creation    ", vi.creation_date);
+       display_vol_timestamp("    Copy        ", vi.copy_date);
+       display_vol_timestamp("    Backup      ", vi.backup_date);
+       display_vol_timestamp("    Last Access ", vi.access_date);
+       display_vol_timestamp("    Last Update ", vi.update_date);
+       fmt::print("    {:d} accesses in the past day (i.e., vnode references)\n",
+                  vi.day_use);
+       fmt::print("\n");
+}
+
+/*
+ * Display volume access statistics
+ *
+ *                             Raw Read/Write Stats
+ *                 |-------------------------------------------|
+ *                 |    Same Network     |    Diff Network     |
+ *                 |----------|----------|----------|----------|
+ *                 |  Total   |   Auth   |   Total  |   Auth   |
+ *                 |----------|----------|----------|----------|
+ *       Reads     |        0 |        0 |        0 |        0 |
+ *       Writes    |        0 |        0 |        0 |        0 |
+ *                 |-------------------------------------------|
+ *       <blank>
+ *                          Writes Affecting Authorship
+ *                 |-------------------------------------------|
+ *                 |   File Authorship   | Directory Authorship|
+ *                 |----------|----------|----------|----------|
+ *                 |   Same   |   Diff   |    Same  |   Diff   |
+ *                 |----------|----------|----------|----------|
+ *       0-60 sec  |        0 |        0 |        0 |        0 |
+ *       1-10 min  |        0 |        0 |        0 |        0 |
+ *       10min-1hr |        0 |        0 |        0 |        0 |
+ *       1hr-1day  |        0 |        0 |        0 |        0 |
+ *       1day-1wk  |        0 |        0 |        0 |        0 |
+ *       > 1wk     |        0 |        0 |        0 |        0 |
+ *                 |-------------------------------------------|
+ *
+ */
+void kafs::display_vol_statistics(Context *ctx,
+                                 Volume_info &vi)
+{
+       int i;
+
+       printf("                      Raw Read/Write Stats\n");
+       printf("          |-------------------------------------------|\n");
+       printf("          |    Same Network     |    Diff Network     |\n");
+       printf("          |----------|----------|----------|----------|\n");
+       printf("          |  Total   |   Auth   |   Total  |   Auth   |\n");
+       printf("          |----------|----------|----------|----------|\n");
+       printf("Reads     |%9u |%9u |%9u |%9u |\n",
+              vi.stat_reads[0],
+              vi.stat_reads[1],
+              vi.stat_reads[2],
+              vi.stat_reads[3]);
+       printf("Writes    |%9u |%9u |%9u |%9u |\n",
+              vi.stat_writes[0],
+              vi.stat_writes[1],
+              vi.stat_writes[2],
+              vi.stat_writes[3]);
+       printf("          |-------------------------------------------|\n");
+
+       printf("\n");
+       printf("                   Writes Affecting Authorship\n");
+       printf("          |-------------------------------------------|\n");
+       printf("          |   File Authorship   | Directory Authorship|\n");
+       printf("          |----------|----------|----------|----------|\n");
+       printf("          |   Same   |   Diff   |    Same  |   Diff   |\n");
+       printf("          |----------|----------|----------|----------|\n");
+
+       for (i = 0; i < 5; i++) {
+               printf("%s |%9u |%9u |%9u |%9u |\n",
+                      statistics_time_ranges[i],
+                      vi.stat_fileSameAuthor[i],
+                      vi.stat_fileDiffAuthor[i],
+                      vi.stat_dirSameAuthor[i],
+                      vi.stat_dirDiffAuthor[i]);
+               printf("          |-------------------------------------------|\n");
+       }
+}
+
+/*
+ * Display machine-parseable form of volume record, but excluding certain info
+ *
+ *       name            proj.foo
+ *       id              536870957
+ *       serv            111.22.33.44   foo.abc.com
+ *       part            /vicepa
+ *       status          OK
+ *       backupID        0
+ *       parentID        536870957
+ *       cloneID         536870958
+ *       inUse           Y
+ *       needsSalvaged   N
+ *       destroyMe       N
+ *       type            RW
+ *       creationDate    1250918547      Sat Aug 22 06:22:27 2009
+ *       accessDate      1390951237      Tue Jan 28 23:20:37 2014
+ *       updateDate      1375733732      Mon Aug  5 21:15:32 2013
+ *       backupDate      0               Thu Jan  1 01:00:00 1970
+ *       copyDate        1288050032      Tue Oct 26 00:40:32 2010
+ *       flags           0       (Optional)
+ *       diskused        40475760
+ *       maxquota        0
+ *       minquota        0       (Optional)
+ *       filecount       327
+ *       dayUse          0
+ *
+ */
+void kafs::display_vol_mp_basic_information(Context *ctx,
+                                           FS_site *site,
+                                           Partition_spec &partition,
+                                           Volume_info &vi)
+{
+       char abuf[20];
+       unsigned int i;
+
+       abuf[0] = 0;
+       for (i = 0; i < site->vs_addrs.size(); i++) {
+               if (site->vs_addrs[i].transport.family != AF_INET)
+                       continue;
+               if (inet_ntop(AF_INET, &site->vs_addrs[i].transport.sin.sin_addr,
+                             abuf, sizeof(abuf)))
+                       break;
+       }
+
+       if (!abuf[0])
+               strcpy(abuf, "0.0.0.0");
+
+       std::string addr = kafs::sprint_address(ctx, site->vs_addrs[0]);
+       std::string part = kafs::sprint_partition(partition);
+
+       fmt::print("BEGIN_OF_ENTRY\n");
+       fmt::print("name\t\t{:s}\n", vi.name);
+       fmt::print("id\t\t{:d}\n", vi.volid);
+       fmt::print("serv\t\t{:<15s}\t{:s}\n", site->name, addr);
+       fmt::print("part\t\t{:s}\n", part);
+       fmt::print("status\t\t{:s}\n", vol_status(vi));
+       fmt::print("backupID\t{:d}\n", vi.backup_id);
+       fmt::print("parentID\t{:d}\n", vi.parent_id);
+       fmt::print("cloneID\t\t{:d}\n", vi.clone_id);
+       fmt::print("inUse\t\t{:s}\n", yes_or_no(vi.in_use));
+       if (vi.has_need_salvage) {
+               fmt::print("needsSalvaged\t{:s}\n", yes_or_no(vi.needs_salvage));
+               fmt::print("destroyMe\t{:s}\n", yes_or_no(vi.destroy_me));
+       }
+       fmt::print("type\t\t{:s}\n", vol_type(vi));
+       fmt::print("creationDate\t{:<10d}\t{:s}\n",
+                  vi.creation_date.seconds(), kafs::sprint_time(vi.creation_date));
+       fmt::print("accessDate\t{:<10d}\t{:s}\n",
+                  vi.access_date.seconds(), kafs::sprint_time(vi.access_date));
+       fmt::print("updateDate\t{:<10d}\t{:s}\n",
+                  vi.update_date.seconds(), kafs::sprint_time(vi.update_date));
+       fmt::print("backupData\t{:<10d}\t{:s}\n",
+                  vi.backup_date.seconds(), kafs::sprint_time(vi.backup_date));
+       fmt::print("copyDate\t{:<10d}\t{:s}\n",
+                  vi.copy_date.seconds(), kafs::sprint_time(vi.copy_date));
+       if (vi.has_flags)
+               fmt::print("flags\t\t{:<7d}\t(Optional)\n", vi.flags);
+       fmt::print("diskused\t{:d}\n", vi.size);
+       fmt::print("maxquota\t{:d}\n", vi.max_quota);
+       if (vi.has_min_quota)
+               fmt::print("minquota\t{:<7d}\t(Optional)\n", vi.min_quota);
+       fmt::print("filecount\t{:d}\n", vi.file_count);
+       fmt::print("dayUse\t\t{:d}\n", vi.day_use);
+}
+
+/*
+ *
+ * Display machine parseable form of volume record
+ *
+ *       name            proj.foo
+ *       id              536870957
+ *       serv            111.22.33.44   foo.abc.com
+ *       part            /vicepa
+ *       status          OK
+ *       backupID        0
+ *       parentID        536870957
+ *       cloneID         536870958
+ *       inUse           Y
+ *       needsSalvaged   N
+ *       destroyMe       N
+ *       type            RW
+ *       creationDate    1250918547      Sat Aug 22 06:22:27 2009
+ *       accessDate      1390951237      Tue Jan 28 23:20:37 2014
+ *       updateDate      1375733732      Mon Aug  5 21:15:32 2013
+ *       backupDate      0               Thu Jan  1 01:00:00 1970
+ *       copyDate        1288050032      Tue Oct 26 00:40:32 2010
+ *       flags           0       (Optional)
+ *       diskused        40475760
+ *       maxquota        0
+ *       minquota        0       (Optional)
+ *       filecount       327
+ *       dayUse          0
+ *       weekUse         0       (Optional)
+ *       spare2          21775   (Optional)
+ *       spare3          0       (Optional)
+ *
+ */
+void kafs::display_vol_mp_information(Context *ctx,
+                                     FS_site *site,
+                                     Partition_spec &partition,
+                                     Volume_info &vi)
+{
+       display_vol_mp_basic_information(ctx, site, partition, vi);
+
+       if (vi.nr_week_use > 0)
+               fmt::print("weekUse\t\t{:<7u}\t(Optional)\n", vi.week_use[0]);
+       if (vi.has_spare2)
+               fmt::print("spare2\t\t{:<7u}\t(Optional)\n", vi.spare2);
+       if (vi.has_spare3)
+               fmt::print("spare3\t\t{:<7u}\t(Optional)\n", vi.spare3);
+}
diff --git a/kafs/vos_examine.C b/kafs/vos_examine.C
new file mode 100644 (file)
index 0000000..51030ed
--- /dev/null
@@ -0,0 +1,144 @@
+/* The "vos examine" 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 <fmt/core.h>
+#include "kafs.H"
+#include "vlservice.H"
+#include "volservice.H"
+#include "afs_xg.H"
+#include "display.H"
+
+using rxrpc::ref;
+using kafs::afs::RWVOL;
+using kafs::afs::ROVOL;
+using kafs::afs::BACKVOL;
+using kafs::afs::VLSF_RWVOL;
+using kafs::afs::VLSF_ROVOL;
+using kafs::afs::VLSF_BACKVOL;
+
+static void display_vldb(kafs::Context *ctx,
+                        kafs::Vldb_entry *vldb)
+{
+       if (vldb->volume_id[RWVOL] != 0)
+               fmt::print("    RWrite: {:<10d}", vldb->volume_id[RWVOL]);
+       if (vldb->volume_id[ROVOL] != 0)
+               fmt::print("    ROnly: {:<10d}", vldb->volume_id[ROVOL]);
+       if (vldb->volume_id[BACKVOL] != 0)
+               fmt::print("    Backup: {:<10d}", vldb->volume_id[BACKVOL]);
+       fmt::print("\n");
+
+       kafs::display_vldb_site_list(ctx, vldb, "    ");
+}
+
+/***
+ * COMMAND: vos examine - Show volume header and VLDB entry information for a volume
+ * ARG: "-id <volume name or ID>"
+ * ARG: "[-extended]"
+ * ARG: "[-format]"
+ * ARG: "[-cell <cell name>]"
+ * ARG: "[-noauth]"                            - Auth
+ * ARG: "[-localauth]"                         - Auth
+ * ARG: "[-verbose]"
+ * ARG: "[-encrypt]"                           - Auth
+ * ARG: "[-noresolve]"
+ *
+ * Show volume header and VLDB entry information for a volume
+ */
+void COMMAND_vos_examine(
+       kafs::Context                   *ctx,
+       kafs::Volume_spec               &a_id,
+       bool                            a_extended,
+       bool                            a_format,
+       bool                            a_verbose,
+       bool                            a_noresolve)
+{
+       kafs::Vldb_entry_list vlist;
+       kafs::Volume_id volid;
+       unsigned int servflag = 0, i;
+
+       _enter("");
+
+       ctx->no_resolve = a_noresolve;
+
+       ref<kafs::VL_service> vlservice = new kafs::VL_service(ctx);
+
+       vlservice->look_up_volume_by_name(a_id, vlist);
+
+       kafs::Vldb_entry *vldb = vlist[0];
+       if (a_id.is_numeric) {
+               volid = a_id.number;
+               if (volid == vldb->volume_id[RWVOL])
+                       servflag = VLSF_RWVOL;
+               else if (volid == vldb->volume_id[ROVOL])
+                       servflag = VLSF_ROVOL;
+               else if (volid == vldb->volume_id[BACKVOL])
+                       servflag = VLSF_BACKVOL;
+               else
+                       throw std::runtime_error("Requested volume ID not in record for volume ID");
+       } else {
+               for (i = 0; i < vldb->sites.size(); i++)
+                       servflag |= vldb->sites[i].flags;
+               if (servflag & VLSF_RWVOL) {
+                       servflag = VLSF_RWVOL;
+                       volid = vldb->volume_id[RWVOL];
+               } else if (servflag & VLSF_ROVOL) {
+                       servflag = VLSF_ROVOL;
+                       volid = vldb->volume_id[ROVOL];
+               } else if (servflag & VLSF_BACKVOL) {
+                       servflag = VLSF_BACKVOL;
+                       volid = vldb->volume_id[BACKVOL];
+               } else {
+                       throw std::runtime_error("Requested volume does not exist on any server");
+               }
+       }
+
+       if (vldb->sites.size() == 0)
+               throw std::runtime_error("Couldn't examine requested volume");
+
+       for (i = 0; i < vldb->sites.size(); i++) {
+               kafs::Volume_info_list vi;
+               kafs::Vldb_site &site = vldb->sites[i];
+               kafs::FS_site *fs_site = site.fs_site;
+
+               if (!(site.flags & servflag))
+                       continue;
+
+               try {
+                       ref<kafs::Volserver> server = new kafs::Volserver(ctx, fs_site);
+                       server->query_volume_state(site.partition, volid, a_extended, vi);
+               } catch (const rxrpc::rx_abort &a) {
+                       std::cout << "aborted: " << a.what() << "\n";
+                       continue;
+               } catch (const std::system_error &e) {
+                       std::cout << "error: " << e.what() << "\n";
+                       continue;
+               } catch (const std::runtime_error &e) {
+                       std::cout << "error: " << e.what() << "\n";
+                       continue;
+               } catch (...) {
+                       continue;
+               }
+
+               if (vi.size()) {
+                       if (a_format && !a_extended) {
+                               display_vol_mp_information(ctx, fs_site, site.partition, vi[0]);
+                               fmt::print("\n");
+                       } else {
+                               display_vol_information(ctx, fs_site, site.partition, vi[0]);
+                               if (a_extended)
+                                       display_vol_statistics(ctx, vi[0]);
+                       }
+               }
+       }
+
+       display_vldb(ctx, vldb);
+}