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);
}
/**
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
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
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.
--- /dev/null
+/* 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);
+ }
+}