Re: [PATCH net-next v3 2/3] vsock/test: Introduce get_transports()

2025-06-17 Thread Stefano Garzarella

On Wed, Jun 11, 2025 at 09:56:51PM +0200, Michal Luczaj wrote:

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 15d4734c7a58 ("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 
Signed-off-by: Michal Luczaj 
---
tools/testing/vsock/util.c | 56 ++
tools/testing/vsock/util.h | 29 
2 files changed, 85 insertions(+)


LGTM!

Reviewed-by: Stefano Garzarella 



diff --git a/tools/testing/vsock/util.c b/tools/testing/vsock/util.c
index 
b7b3fb2221c1682ecde58cf12e2f0b0ded1cff39..803f1e075b62228c25f9dffa1eff131b8072a06a
 100644
--- a/tools/testing/vsock/util.c
+++ b/tools/testing/vsock/util.c
@@ -7,6 +7,7 @@
 * Author: Stefan Hajnoczi 
 */

+#include 
#include 
#include 
#include 
@@ -23,6 +24,9 @@
#include "control.h"
#include "util.h"

+#define KALLSYMS_PATH  "/proc/kallsyms"
+#define KALLSYMS_LINE_LEN  512
+
/* Install signal handlers */
void init_signals(void)
{
@@ -854,3 +858,55 @@ void enable_so_linger(int fd, int timeout)
exit(EXIT_FAILURE);
}
}
+
+static int __get_transports(void)
+{
+   char buf[KALLSYMS_LINE_LEN];
+   const char *ksym;
+   int ret = 0;
+   FILE *f;
+
+   f = fopen(KALLSYMS_PATH, "r");
+   if (!f) {
+   perror("Can't open " KALLSYMS_PATH);
+   exit(EXIT_FAILURE);
+   }
+
+   while (fgets(buf, sizeof(buf), f)) {
+   char *match;
+   int i;
+
+   assert(buf[strlen(buf) - 1] == '\n');
+
+   for (i = 0; i < TRANSPORT_NUM; ++i) {
+   if (ret & BIT(i))
+   continue;
+
+   /* Match should be followed by '\t' or '\n'.
+* See kallsyms.c:s_show().
+*/
+   ksym = transport_ksyms[i];
+   match = strstr(buf, ksym);
+   if (match && isspace(match[strlen(ksym)])) {
+   ret |= BIT(i);
+   break;
+   }
+   }
+   }
+
+   fclose(f);
+   return ret;
+}
+
+/* Return integer with TRANSPORT_* bit set for every (known) registered vsock
+ * transport.
+ */
+int get_transports(void)
+{
+   static int tr = -1;
+
+   if (tr == -1)
+   tr = __get_transports();
+
+   return tr;
+}
diff --git a/tools/testing/vsock/util.h b/tools/testing/vsock/util.h
index 
0afe7cbae12e5194172c639ccfbeb8b81f7c25ac..71895192cc02313bf52784e2f77aa3b0c28a0c94
 100644
--- a/tools/testing/vsock/util.h
+++ b/tools/testing/vsock/util.h
@@ -3,8 +3,36 @@
#define UTIL_H

#include 
+#include 
+#include 
#include 

+/* All known vsock transports, see callers of vsock_core_register() */
+#define KNOWN_TRANSPORTS(x)\
+   x(LOOPBACK, "loopback")   \
+   x(VIRTIO, "virtio")   \
+   x(VHOST, "vhost") \
+   x(VMCI, "vmci")   \
+   x(HYPERV, "hvs")
+
+enum transport {
+   TRANSPORT_COUNTER_BASE = __COUNTER__ + 1,
+   #define x(name, symbol) \
+   TRANSPORT_##name = BIT(__COUNTER__ - TRANSPORT_COUNTER_BASE),
+   KNOWN_TRANSPORTS(x)
+   TRANSPORT_NUM = __COUNTER__ - TRANSPORT_COUNTER_BASE,
+   #undef x
+};
+
+static const char * const transport_ksyms[] = {
+   #define 

Re: [PATCH net-next v3 2/3] vsock/test: Introduce get_transports()

2025-06-13 Thread Luigi Leonardi

Hi Michal,

On Wed, Jun 11, 2025 at 09:56:51PM +0200, Michal Luczaj wrote:
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 15d4734c7a58 ("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 
Signed-off-by: Michal Luczaj 
---
tools/testing/vsock/util.c | 56 ++
tools/testing/vsock/util.h | 29 
2 files changed, 85 insertions(+)

diff --git a/tools/testing/vsock/util.c b/tools/testing/vsock/util.c
index 
b7b3fb2221c1682ecde58cf12e2f0b0ded1cff39..803f1e075b62228c25f9dffa1eff131b8072a06a
 100644
--- a/tools/testing/vsock/util.c
+++ b/tools/testing/vsock/util.c
@@ -7,6 +7,7 @@
 * Author: Stefan Hajnoczi 
 */

+#include 
#include 
#include 
#include 
@@ -23,6 +24,9 @@
#include "control.h"
#include "util.h"

+#define KALLSYMS_PATH  "/proc/kallsyms"
+#define KALLSYMS_LINE_LEN  512
+
/* Install signal handlers */
void init_signals(void)
{
@@ -854,3 +858,55 @@ void enable_so_linger(int fd, int timeout)
exit(EXIT_FAILURE);
}
}
+
+static int __get_transports(void)
+{
+   char buf[KALLSYMS_LINE_LEN];
+   const char *ksym;
+   int ret = 0;
+   FILE *f;
+
+   f = fopen(KALLSYMS_PATH, "r");
+   if (!f) {
+   perror("Can't open " KALLSYMS_PATH);
+   exit(EXIT_FAILURE);
+   }
+
+   while (fgets(buf, sizeof(buf), f)) {
+   char *match;
+   int i;
+
+   assert(buf[strlen(buf) - 1] == '\n');
+
+   for (i = 0; i < TRANSPORT_NUM; ++i) {
+   if (ret & BIT(i))
+   continue;
+
+   /* Match should be followed by '\t' or '\n'.
+* See kallsyms.c:s_show().
+*/
+   ksym = transport_ksyms[i];
+   match = strstr(buf, ksym);
+   if (match && isspace(match[strlen(ksym)])) {
+   ret |= BIT(i);
+   break;
+   }
+   }
+   }
+
+   fclose(f);
+   return ret;
+}
+
+/* Return integer with TRANSPORT_* bit set for every (known) registered vsock
+ * transport.
+ */
+int get_transports(void)
+{
+   static int tr = -1;
+
+   if (tr == -1)
+   tr = __get_transports();
+
+   return tr;
+}
diff --git a/tools/testing/vsock/util.h b/tools/testing/vsock/util.h
index 
0afe7cbae12e5194172c639ccfbeb8b81f7c25ac..71895192cc02313bf52784e2f77aa3b0c28a0c94
 100644
--- a/tools/testing/vsock/util.h
+++ b/tools/testing/vsock/util.h
@@ -3,8 +3,36 @@
#define UTIL_H

#include 
+#include 
+#include 
#include 

+/* All known vsock transports, see callers of vsock_core_register() */
+#define KNOWN_TRANSPORTS(x)\
+   x(LOOPBACK, "loopback")   \
+   x(VIRTIO, "virtio")   \
+   x(VHOST, "vhost") \
+   x(VMCI, "vmci")   \
+   x(HYPERV, "hvs")
+
+enum transport {
+   TRANSPORT_COUNTER_BASE = __COUNTER__ + 1,
+   #define x(name, symbol) \
+   TRANSPORT_##name = BIT(__COUNTER__ - TRANSPORT_COUNTER_BASE),
+   KNOWN_TRANSPORTS(x)
+   TRANSPORT_NUM = __COUNTER__ - TRANSPORT_COUNTER_BASE,
+   #undef x
+};
+
+static const char * const transport_ksyms[] = {
+   #define x(name, symbol) "d "