--- /dev/null
+/* VLDB query test
+ *
+ * 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 <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <kafs/cellserv.h>
+#include "rxrpc.h"
+#include "afs_xg.h"
+
+#define AFS_VL_PORT 7003 /* volume location service port */
+#define VL_SERVICE 52 /* RxRPC service ID for the Volume Location service */
+#define YFS_VL_SERVICE 2503 /* Service ID for AuriStor upgraded VL service */
+
+static void error_report(const char *fmt, ...)
+{
+ va_list va;
+
+ va_start(va, fmt);
+ vfprintf(stderr, fmt, va);
+ fputc('\n', stderr);
+ va_end(va);
+}
+
+static void verbose(const char *fmt, ...)
+{
+ va_list va;
+
+ va_start(va, fmt);
+ //printf("[V] ");
+ //vprintf(fmt, va);
+ //putchar('\n');
+ va_end(va);
+}
+
+int main(int argc, char *argv[])
+{
+ struct rxrpc_local_endpoint *endpoint;
+ struct kafs_server_addr *ad;
+ struct kafs_server_list *vll;
+ struct kafs_server *vl;
+ struct kafs_cell *cell;
+ struct uvldbentry entry;
+ struct rxrpc_result result;
+ struct rxrpc_call_params params;
+ int i;
+
+ struct kafs_lookup_context ctx = {
+ .report.error = error_report,
+ .report.verbose = verbose,
+ .report.verbose2 = verbose,
+ .want_ipv4_addrs = true,
+ .want_ipv6_addrs = true,
+ };
+
+ if (argc < 2) {
+ fprintf(stderr, "No cell specified\n");
+ exit(2);
+ }
+
+ if (kafs_init_lookup_context(&ctx) < 0)
+ exit(1);
+
+ if (kafs_read_config(NULL, &ctx.report) < 0)
+ exit(ctx.report.bad_config ? 3 : 1);
+
+ cell = kafs_lookup_cell(argv[1], &ctx);
+ if (!cell) {
+ fprintf(stderr, "%s: Unknown cell\n", argv[1]);
+ exit(1);
+ }
+
+ vll = cell->vlservers;
+ if (vll->nr_servers == 0) {
+ fprintf(stderr, "%s: No VL servers\n", argv[1]);
+ exit(1);
+ }
+
+ memset(¶ms, 0, sizeof(params));
+ params.peer.srx_family = AF_RXRPC;
+ params.peer.srx_service = VL_SERVICE;
+ params.peer.transport_type = SOCK_DGRAM;
+ params.peer_len = sizeof(params.peer);
+
+ for (i = 0; i < vll->nr_servers; i++) {
+ vl = &vll->servers[i];
+ printf("VL: %s %u\n", vl->name, vl->nr_addrs);
+ if (!vl->nr_addrs)
+ continue;
+
+ ad = &vl->addrs[0];
+ switch (ad->sin.sin_family) {
+ case AF_INET:
+ params.peer.transport_len = sizeof(params.peer.transport.sin);
+ memcpy(¶ms.peer.transport, &ad->sin, params.peer.transport_len);
+ if (!params.peer.transport.sin.sin_port)
+ params.peer.transport.sin.sin_port = htons(AFS_VL_PORT);
+ break;
+ case AF_INET6:
+ params.peer.transport_len = sizeof(params.peer.transport.sin6);
+ memcpy(¶ms.peer.transport, &ad->sin6, params.peer.transport_len);
+ if (!params.peer.transport.sin6.sin6_port)
+ params.peer.transport.sin6.sin6_port = htons(AFS_VL_PORT);
+ break;
+ default:
+ fprintf(stderr, "%s: Unsupported address family\n", argv[1]);
+ exit(1);
+ }
+ goto found;
+ }
+
+ fprintf(stderr, "%s: No VL addresses\n", argv[1]);
+ exit(1);
+found:
+
+ endpoint = rxrpc_new_local_endpoint(NULL, 0);
+ if (!endpoint) {
+ perror("Local endpoint");
+ exit(1);
+ }
+
+ params.endpoint = endpoint;
+ params.upgrade_service = true;
+ if (!VL_GetEntryByNameU(¶ms, "root.cell", &entry, &result)) {
+ fprintf(stderr, "VL_GetEntryByNameU failed (abort %d): %m\n",
+ result.abort_code);
+ exit(1);
+ }
+
+ printf("ENTRY: '%s'\n", entry.name);
+
+ rxrpc_free_local_endpoint(endpoint);
+ exit(0);
+}