--- /dev/null
+/* The "vos listaddrs" 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 <stdio.h>
+#include <string.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+#include "kafs.h"
+#include "vlservice.h"
+#include "arg_parse.h"
+#include "display.h"
+#include "afs_xg.h"
+
+static bool vos_listaddrs_one(struct kafs_context *ctx, bool a_printuuid,
+ struct kafs_fileserver *server)
+{
+ char buf[1024];
+ int i;
+
+ if (a_printuuid) {
+ uuid_unparse(server->uuid, buf);
+ printf("UUID: %s\n", buf);
+ }
+
+ for (i = 0; i < server->vs_nr_addrs; i++) {
+ kafs_sprint_address(ctx, &server->vs_addrs[i], buf, sizeof(buf));
+ printf("%s\n", buf);
+ }
+
+ if (a_printuuid)
+ printf("\n");
+ return true;
+}
+
+static bool vos_listaddrs_all(struct kafs_context *ctx, bool a_printuuid)
+{
+ struct kafs_fileserver *server;
+ struct VL_Callback vl_callback;
+ int32_t nentries;
+ uint32_t *blkaddr;
+ unsigned int blkaddr__nr, found;
+ bool ret;
+ int i;
+
+ if (!VL_GetAddrs(&ctx->vl_params, 0, 0, &vl_callback, &nentries,
+ &blkaddr, &blkaddr__nr, &ctx->result))
+ return false;
+
+#if 0
+ printf("nentries %u %u\n", nentries, blkaddr__nr);
+ for (i = 0; i < blkaddr__nr; i++)
+ printf("- %08x\n", blkaddr[i]);
+#endif
+
+ found = nentries;
+ for (i = 1; i < 65536; i++) {
+ server = kafs_look_up_fileserver_by_index(ctx, i);
+ if (!server) {
+ switch (ctx->result.source) {
+ case rxrpc_error_remote_abort:
+ switch (ctx->result.abort_code) {
+ case VL_NOENT:
+ continue;
+ case VL_INDEXERANGE:
+ goto stop;
+ default:
+ return false;
+ }
+ break;
+ default:
+ break;
+ }
+ return false;
+ }
+
+ ret = vos_listaddrs_one(ctx, a_printuuid, server);
+ put_kafs_fileserver(server);
+ if (!ret)
+ goto stop;
+
+ found--;
+ if (found <= 0)
+ break;
+ }
+
+stop:
+ free(blkaddr);
+ return true;
+}
+
+/***
+ * COMMAND: vos listaddrs - List all of the file server registrations.
+ * ARG: "[-uuid <uuid of server>]"
+ * ARG: "[-host <address of host>]"
+ * ARG: "[-printuuid]"
+ * ARG: "[-cell <cell name>]"
+ * ARG: "[-noauth]" - Auth
+ * ARG: "[-localauth]" - Auth
+ * ARG: "[-verbose]"
+ * ARG: "[-encrypt]" - Auth
+ * ARG: "[-noresolve]"
+ * NOCOMBINE: uuid, host
+ *
+ * Display a list of registered volume servers.
+ */
+bool COMMAND_vos_listaddrs(
+ struct kafs_context *ctx,
+ uuid_t *a_uuid,
+ struct kafs_fileserver_spec *a_host,
+ bool a_printuuid,
+ bool a_quiet,
+ bool a_nosort,
+ bool a_verbose,
+ bool a_noresolve)
+{
+ struct kafs_fileserver *server, *spec;
+ bool ret;
+
+ _enter("");
+
+ ctx->no_resolve = a_noresolve;
+
+ if (!kafs_probe_vl_service(ctx))
+ return false;
+
+ if (!kafs_open_vl_service(ctx))
+ return false;
+
+ if (!a_uuid && !a_host)
+ return vos_listaddrs_all(ctx, a_printuuid);
+
+ if (a_uuid) {
+ server = kafs_look_up_fileserver_by_uuid(ctx, a_uuid);
+ } else {
+ if (!kafs_resolve_fileserver_spec(ctx, a_host, &spec))
+ return false;
+ server = kafs_look_up_fileserver_by_addr(ctx, &spec->fs_addrs[0]);
+ put_kafs_fileserver(spec);
+ if (!server)
+ return false;
+ }
+
+ if (!server)
+ return false;
+ ret = vos_listaddrs_one(ctx, a_printuuid, server);
+ put_kafs_fileserver(server);
+ if (!ret)
+ return ret;
+ return true;
+}
+
+/***
+ * ALIAS: vos listfs - listaddrs
+ */