Skip to content

Commit 86c1ab0

Browse files
mmhalNipaLocal
authored andcommitted
vsock/test: Introduce get_transports()
Return a bitmap of registered vsock transports. As guesstimated by grepping /proc/kallsyms (CONFIG_KALLSYMS=y) for known symbols of type `struct vsock_transport`, or `struct virtio_transport` in case the vsock_transport is embedded within. Note that the way `enum transport` and `transport_ksyms[]` are defined triggers checkpatch.pl: util.h:11: ERROR: Macros with complex values should be enclosed in parentheses util.h:20: ERROR: Macros with complex values should be enclosed in parentheses util.h:20: WARNING: Argument 'symbol' is not used in function-like macro util.h:28: WARNING: Argument 'name' is not used in function-like macro While commit 15d4734 ("checkpatch: qualify do-while-0 advice") suggests it is known that the ERRORs heuristics are insufficient, I can not find many other places where preprocessor is used in this checkpatch-unhappy fashion. Notable exception being bcachefs, e.g. fs/bcachefs/alloc_background_format.h. WARNINGs regarding unused macro arguments seem more common, e.g. __ASM_SEL in arch/x86/include/asm/asm.h. In other words, this might be unnecessarily complex. The same can be achieved by just telling human to keep the order: enum transport { TRANSPORT_LOOPBACK = BIT(0), TRANSPORT_VIRTIO = BIT(1), TRANSPORT_VHOST = BIT(2), TRANSPORT_VMCI = BIT(3), TRANSPORT_HYPERV = BIT(4), TRANSPORT_NUM = 5, }; #define KSYM_ENTRY(sym) "d " sym "_transport" /* Keep `enum transport` order */ static const char * const transport_ksyms[] = { KSYM_ENTRY("loopback"), KSYM_ENTRY("virtio"), KSYM_ENTRY("vhost"), KSYM_ENTRY("vmci"), KSYM_ENTRY("vhs"), }; Suggested-by: Stefano Garzarella <[email protected]> Signed-off-by: Michal Luczaj <[email protected]> Tested-by: Luigi Leonardi <[email protected]> Reviewed-by: Luigi Leonardi <[email protected]> Reviewed-by: Stefano Garzarella <[email protected]> Signed-off-by: NipaLocal <nipa@local>
1 parent 26a7aed commit 86c1ab0

File tree

2 files changed

+85
-0
lines changed

2 files changed

+85
-0
lines changed

tools/testing/vsock/util.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
* Author: Stefan Hajnoczi <[email protected]>
88
*/
99

10+
#include <ctype.h>
1011
#include <errno.h>
1112
#include <stdio.h>
1213
#include <stdint.h>
@@ -23,6 +24,9 @@
2324
#include "control.h"
2425
#include "util.h"
2526

27+
#define KALLSYMS_PATH "/proc/kallsyms"
28+
#define KALLSYMS_LINE_LEN 512
29+
2630
/* Install signal handlers */
2731
void init_signals(void)
2832
{
@@ -854,3 +858,55 @@ void enable_so_linger(int fd, int timeout)
854858
exit(EXIT_FAILURE);
855859
}
856860
}
861+
862+
static int __get_transports(void)
863+
{
864+
char buf[KALLSYMS_LINE_LEN];
865+
const char *ksym;
866+
int ret = 0;
867+
FILE *f;
868+
869+
f = fopen(KALLSYMS_PATH, "r");
870+
if (!f) {
871+
perror("Can't open " KALLSYMS_PATH);
872+
exit(EXIT_FAILURE);
873+
}
874+
875+
while (fgets(buf, sizeof(buf), f)) {
876+
char *match;
877+
int i;
878+
879+
assert(buf[strlen(buf) - 1] == '\n');
880+
881+
for (i = 0; i < TRANSPORT_NUM; ++i) {
882+
if (ret & BIT(i))
883+
continue;
884+
885+
/* Match should be followed by '\t' or '\n'.
886+
* See kallsyms.c:s_show().
887+
*/
888+
ksym = transport_ksyms[i];
889+
match = strstr(buf, ksym);
890+
if (match && isspace(match[strlen(ksym)])) {
891+
ret |= BIT(i);
892+
break;
893+
}
894+
}
895+
}
896+
897+
fclose(f);
898+
return ret;
899+
}
900+
901+
/* Return integer with TRANSPORT_* bit set for every (known) registered vsock
902+
* transport.
903+
*/
904+
int get_transports(void)
905+
{
906+
static int tr = -1;
907+
908+
if (tr == -1)
909+
tr = __get_transports();
910+
911+
return tr;
912+
}

tools/testing/vsock/util.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,36 @@
33
#define UTIL_H
44

55
#include <sys/socket.h>
6+
#include <linux/bitops.h>
7+
#include <linux/kernel.h>
68
#include <linux/vm_sockets.h>
79

10+
/* All known vsock transports, see callers of vsock_core_register() */
11+
#define KNOWN_TRANSPORTS(x) \
12+
x(LOOPBACK, "loopback") \
13+
x(VIRTIO, "virtio") \
14+
x(VHOST, "vhost") \
15+
x(VMCI, "vmci") \
16+
x(HYPERV, "hvs")
17+
18+
enum transport {
19+
TRANSPORT_COUNTER_BASE = __COUNTER__ + 1,
20+
#define x(name, symbol) \
21+
TRANSPORT_##name = BIT(__COUNTER__ - TRANSPORT_COUNTER_BASE),
22+
KNOWN_TRANSPORTS(x)
23+
TRANSPORT_NUM = __COUNTER__ - TRANSPORT_COUNTER_BASE,
24+
#undef x
25+
};
26+
27+
static const char * const transport_ksyms[] = {
28+
#define x(name, symbol) "d " symbol "_transport",
29+
KNOWN_TRANSPORTS(x)
30+
#undef x
31+
};
32+
33+
static_assert(ARRAY_SIZE(transport_ksyms) == TRANSPORT_NUM);
34+
static_assert(BITS_PER_TYPE(int) >= TRANSPORT_NUM);
35+
836
/* Tests can either run as the client or the server */
937
enum test_mode {
1038
TEST_MODE_UNSET,
@@ -82,4 +110,5 @@ void setsockopt_timeval_check(int fd, int level, int optname,
82110
struct timeval val, char const *errmsg);
83111
void enable_so_zerocopy_check(int fd);
84112
void enable_so_linger(int fd, int timeout);
113+
int get_transports(void);
85114
#endif /* UTIL_H */

0 commit comments

Comments
 (0)