]> www.infradead.org Git - users/dhowells/kafs-utils.git/commitdiff
cmd: Common display/formatting routines
authorDavid Howells <dhowells@redhat.com>
Thu, 9 Jul 2020 10:27:04 +0000 (11:27 +0100)
committerDavid Howells <dhowells@redhat.com>
Fri, 5 May 2023 09:05:31 +0000 (10:05 +0100)
Add some common display and output formatting routines.

Signed-off-by: David Howells <dhowells@redhat.com>
kafs/Makefile
kafs/display.c [new file with mode: 0644]
kafs/display.h
kafs/display_vol.c [new file with mode: 0644]

index 31fdcac59acc9c21fab34fc4214c2f72d19b638b..d1c5c99b70688c95cfee454edf0465bbe666077c 100644 (file)
@@ -7,7 +7,9 @@ CORE_SRCS := \
        kafs.c \
        arg_completion.c \
        arg_parse.c \
+       display.c \
        display_error.c \
+       display_vol.c \
        vl_fileservers.c \
        vl_probe.c \
        vl_volumes.c
diff --git a/kafs/display.c b/kafs/display.c
new file mode 100644 (file)
index 0000000..aa01bef
--- /dev/null
@@ -0,0 +1,136 @@
+/* Display
+ *
+ * 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 "afs_xg.h"
+#include "display.h"
+
+/**
+ * kafs_sprint_address - Convert/resolve an address into text
+ * @ctx: The cell and authentication context
+ * @addr: The address to convert
+ * @buf: The buffer to write into
+ * @buf_len: The size of the buffer
+ *
+ * Convert an address into a textual representation, possibly resolving it to a
+ * hostname via the DNS or other name resolution service.  The conversion is
+ * written into the buffer and truncated to the length given.
+ */
+void kafs_sprint_address(struct kafs_context *ctx,
+                        struct sockaddr_rxrpc *addr,
+                        char *buf, size_t buf_len)
+{
+       unsigned short port;
+       char service[64];
+       size_t len = 0;
+       int hint, ni;
+
+       hint = NI_DGRAM | NI_NUMERICSERV;
+
+       if (!ctx->no_resolve) {
+               hint |= NI_NAMEREQD;
+               ni = getnameinfo((struct sockaddr *)&addr[0].transport,
+                                addr[0].transport_len,
+                                buf, buf_len, service, sizeof(service), hint);
+               if (ni == EAI_MEMORY) {
+                       kafs_nomem(ctx);
+                       return;
+               }
+               if (ni == 0) {
+                       len = strlen(buf);
+                       if (len < buf_len - 2)
+                               snprintf(buf + len, buf_len - len, ":%s", service);
+                       return;
+               }
+       }
+
+       hint &= ~NI_NAMEREQD;
+       hint |= NI_NUMERICHOST;
+       ni = getnameinfo((struct sockaddr *)&addr[0].transport,
+                        addr[0].transport_len,
+                        buf, buf_len, service, sizeof(service), hint);
+       if (ni == EAI_MEMORY) {
+               kafs_nomem(ctx);
+               return;
+       }
+
+       len = strlen(buf);
+       if (strchr(buf, ':')) {
+               memmove(buf + 1, buf, len);
+               buf[0] = '[';
+               buf[len + 1] = ']';
+               buf[len + 2] = 0;
+               len += 2;
+       }
+
+       if (ni == 0) {
+               if (len < buf_len - 2)
+                       snprintf(buf + len, buf_len - len, ":%s", service);
+               return;
+       }
+
+       buf[0] = 0;
+       switch (addr[0].transport.sin.sin_family) {
+       case AF_INET:
+               inet_ntop(AF_INET, &addr[0].transport.sin.sin_addr, buf, buf_len);
+               port = ntohs(addr[0].transport.sin.sin_port);
+               break;
+       case AF_INET6:
+               buf[0] = '[';
+               inet_ntop(AF_INET6, &addr[0].transport.sin6.sin6_addr, buf + 1, buf_len - 1);
+               len = strlen(buf);
+               buf[len] = ']';
+               buf[len + 1] = 0;
+               port = ntohs(addr[0].transport.sin6.sin6_port);
+               break;
+       default:
+               snprintf(buf, buf_len, "<af-%u>", addr[0].transport.sin.sin_family);
+               return;
+       }
+
+       if (port == FS_PORT)
+               return;
+
+       len = strlen(buf);
+       if (len < buf_len - 3)
+               snprintf(buf + len, buf_len - len, "+%u", port);
+}
+
+/*
+ * kafs_sprint_address - Convert a numeric ID into a partition name string.
+ * @ctx: The cell and authentication context
+ * @partition: The partition specified to convert
+ * @buf: The buffer to write into
+ * @buf_len: The size of the buffer
+ *
+ * Render the numeric partition ID to the standard string representation and
+ * write it into the buffer.
+ */
+void kafs_sprint_partition(struct kafs_context *ctx,
+                          struct kafs_partition *partition,
+                          char *buf, size_t buf_len)
+{
+       unsigned int n = partition->id;
+
+       if (n < 26) {
+               snprintf(buf, buf_len, "/vicep%c", n + 97);
+       } else if (n <= 255) {
+               n -= 26;
+               snprintf(buf, buf_len, "/vicep%c%c", n / 26 + 97, n % 26 + 97);
+       } else {
+               snprintf(buf, buf_len, "/vicep?%u", n);
+       }
+}
index d9525b16ad688bc4ce4f53be197e28b094801725..40f450f143b807d97a59c8f8dc3ba2b3dd39406b 100644 (file)
 
 #include "kafs.h"
 
+struct kafs_vldb_entry;
+struct kafs_vldb_site;
+
+/*
+ * display.c
+ */
+extern void kafs_sprint_address(struct kafs_context *, struct sockaddr_rxrpc *, char *, size_t);
+extern void kafs_sprint_partition(struct kafs_context *, struct kafs_partition *, char *, size_t);
+
 /*
  * display_error.c
  */
 extern bool kafs_display_error(struct kafs_context *);
 
+/*
+ * display_vol.c
+ */
+extern void kafs_sprint_site(struct kafs_context *, struct kafs_vldb_site *, char *, size_t);
+extern void kafs_display_vldb_site_list(struct kafs_context *, struct kafs_vldb_entry *,
+                                       const char *);
+
 #endif /* DISPLAY_H */
diff --git a/kafs/display_vol.c b/kafs/display_vol.c
new file mode 100644 (file)
index 0000000..e92ea9b
--- /dev/null
@@ -0,0 +1,102 @@
+/* Volume information display.
+ *
+ * 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 <assert.h>
+#include "kafs.h"
+#include "vlservice.h"
+#include "afs_xg.h"
+#include "display.h"
+
+
+/*
+ * Convert a volume site into a textual representation, possibly resolving it
+ * to a DNS hostname.
+ */
+void kafs_sprint_site(struct kafs_context *ctx,
+                     struct kafs_vldb_site *site,
+                     char *buf, size_t buf_len)
+{
+       struct kafs_fileserver *server = site->server;
+       struct sockaddr_rxrpc *addrs = server ? server->vs_addrs : NULL;
+       unsigned int nr_addrs = server ? server->vs_nr_addrs : 0;
+
+       if (buf_len < 64)
+               abort();
+
+       if (!addrs || nr_addrs == 0) {
+               if (site->has_uuid && buf_len > 40) {
+                       uuid_unparse(site->uuid, buf);
+                       return;
+               }
+               snprintf(buf, buf_len, "<no-addrs>");
+               return;
+       }
+
+       return kafs_sprint_address(ctx, &addrs[0], buf, buf_len);
+}
+
+/*
+ * Display the VLDB site list, looking something like:
+ *
+ *       number of sites -> 2
+ *          server fserver.abc.com partition /vicepa RW Site
+ *          server fserver.abc.com partition /vicepa RO Site
+ */
+void kafs_display_vldb_site_list(struct kafs_context *ctx,
+                                struct kafs_vldb_entry *vldb,
+                                const char *indent)
+{
+       const char *ptype;
+       unsigned int i;
+       char abuf[1024], pbuf[64];
+
+       printf("%snumber of sites -> %u\n", indent, vldb->nr_sites);
+       for (i = 0; i < vldb->nr_sites; i++) {
+               struct kafs_vldb_site *site = &vldb->sites[i];
+               unsigned int flags = site->flags;
+
+               kafs_sprint_site(ctx, site, abuf, sizeof(abuf));
+               kafs_sprint_partition(ctx, &site->partition, pbuf, sizeof(pbuf));
+
+               if (flags & VLSF_ROVOL)
+                       ptype = "RO";
+               else if (flags & VLSF_RWVOL)
+                       ptype = "RW";
+               else
+                       ptype = "Back";
+
+               printf("%s   server %s partition %s %s Site\n",
+                      indent, abuf, pbuf, ptype);
+       }
+
+       if (vldb->flags & (VLOP_MOVE |
+                         VLOP_RELEASE |
+                         VLOP_BACKUP |
+                         VLOP_DELETE |
+                         VLOP_DUMP)
+           ) {
+               printf("%sVolume is currently LOCKED", indent);
+               if (vldb->flags & VLOP_MOVE)
+                       printf("%sVolume is locked for a move operation", indent);
+               if (vldb->flags & VLOP_RELEASE)
+                       printf("%sVolume is locked for a release operation", indent);
+               if (vldb->flags & VLOP_BACKUP)
+                       printf("%sVolume is locked for a backup operation", indent);
+               if (vldb->flags & VLOP_DELETE)
+                       printf("%sVolume is locked for a delete/misc operation", indent);
+               if (vldb->flags & VLOP_DUMP)
+                       printf("%sVolume is locked for a dump/restore operation", indent);
+       }
+}