Fetch the repository succeeded.
This action will force synchronization from src-openEuler/oncn-bwm, which will overwrite any changes that you have made since you forked the repository, and can not be recovered!!!
Synchronous operation will process in the background and will refresh the page when finishing processing. Please be patient.
From ffe630818e3d5118ac0163e75e2f1ec774d3e4c9 Mon Sep 17 00:00:00 2001
From: JofDiamonds <kwb0523@163.com>
Date: Mon, 8 May 2023 10:04:42 +0800
Subject: [PATCH] add proc file interface
---
bwmcli.h | 6 +-
ko/Makefile | 16 ++
ko/bwm.c | 567 ++++++++++++++++++++++++++++++++++++++++++++++++++++
ko/bwm.h | 69 +++++++
4 files changed, 657 insertions(+), 1 deletion(-)
create mode 100644 ko/Makefile
create mode 100644 ko/bwm.c
create mode 100644 ko/bwm.h
diff --git a/bwmcli.h b/bwmcli.h
index f7d4c62..a319130 100644
--- a/bwmcli.h
+++ b/bwmcli.h
@@ -60,6 +60,10 @@ struct TcCmd {
#define BWM_LOG_DEBUG(fmt, args...) syslog(LOG_DEBUG, "[BWM_DEBUG]: " fmt, ## args)
#define BWM_LOG_ERR(fmt, args...) syslog(LOG_ERR, "[BWM]: " fmt, ## args)
-#define BWM_LOG_INFO(fmt, args...) ((void)printf(fmt, ## args))
+#define BWM_LOG_INFO(fmt, args...) \
+ do { \
+ (void)printf(fmt, ## args); \
+ syslog(LOG_INFO, "[BWM]: " fmt, ## args); \
+ } while (0)
#endif /* __BWMCLI_H__ */
diff --git a/ko/Makefile b/ko/Makefile
new file mode 100644
index 0000000..7eae5f5
--- /dev/null
+++ b/ko/Makefile
@@ -0,0 +1,16 @@
+CONFIG_MODULE_SIG=n
+
+obj-m := bwm.o
+
+KERNELDIR ?= /lib/modules/$(shell uname -r)/build
+PWD := $(shell pwd)
+
+LINUX_VER ?= $(shell ls /usr/src/ | grep linux)
+USERSRC ?= /usr/src/$(LINUX_VER)
+EXTRA_CFLAGS = -I$(USERSRC)
+
+all:
+ $(MAKE) -C $(KERNELDIR) M=$(PWD)
+clean:
+ @rm -rf *.o *.mod *.mod.c *.mod.o *.ko *.order *.symvers .*.cmd
+
diff --git a/ko/bwm.c b/ko/bwm.c
new file mode 100644
index 0000000..6be6cbe
--- /dev/null
+++ b/ko/bwm.c
@@ -0,0 +1,567 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2020-2022. All rights reserved.
+ * Description: Network bandwidth management tool
+ */
+#include "bwm.h"
+
+static char *envp[] = { "HOME=/", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
+
+static ssize_t proc_value_get(const char __user *buffer, unsigned long count, char *value)
+{
+ if (count == 0 || count >= MAX_BUF_SIZE) {
+ return -EINVAL;
+ }
+
+ if (copy_from_user(value, buffer, count)) {
+ return -EINVAL;
+ }
+
+ value[count - 1] = '\0';
+
+ return 0;
+}
+
+static int proc_net_qos_enable_open(struct seq_file *seq, void *offset)
+{
+ seq_printf(seq, "%s\n", net_qos_enable);
+ return 0;
+}
+
+static int proc_net_qos_enable_single_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, proc_net_qos_enable_open, NULL);
+}
+
+static int qos_cmd_upcall(char *cmd)
+{
+ int ret = 0;
+ char *argv[] = {
+ "/bin/bash",
+ "-c",
+ cmd,
+ NULL,
+ };
+
+ ret = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC);
+ if (ret) {
+ BWM_LOG_ERR("call_usermodehelper failed, ret = %d", ret);
+ }
+
+ return ret;
+}
+
+static ssize_t proc_net_qos_enable_write(struct file *file, const char __user *buffer,
+ unsigned long count, loff_t *ppos)
+{
+ int ret = 0;
+ char nspid[MAX_BUF_SIZE] = { 0 };
+ char cmd[MAX_CMD_LEN] = { 0 };
+
+ ret = proc_value_get(buffer, count, nspid);
+ if (ret != 0) {
+ BWM_LOG_ERR("proc_value_get failed");
+ return count;
+ }
+ BWM_LOG_DEBUG("get nspid %s", nspid);
+
+ ret = snprintf(cmd, MAX_CMD_LEN, "%s -n -t %s %s -e", NSENTER_PATH, nspid, BWMCLI_PATH);
+ if (ret < 0) {
+ BWM_LOG_ERR("failed to snprintf enable qos cmd");
+ return ret;
+ }
+ BWM_LOG_DEBUG("enable qos cmd:%s", cmd);
+
+ ret = qos_cmd_upcall(cmd);
+ if (ret != 0) {
+ BWM_LOG_ERR("qos_enable_upcall failed");
+ }
+
+ return count;
+}
+
+static int proc_net_qos_disable_open(struct seq_file *seq, void *offset)
+{
+ seq_printf(seq, "%s\n", net_qos_disable);
+ return 0;
+}
+
+static int proc_net_qos_disable_single_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, proc_net_qos_disable_open, NULL);
+}
+
+static ssize_t proc_net_qos_disable_write(struct file *file, const char __user *buffer,
+ unsigned long count, loff_t *ppos)
+{
+ int ret = 0;
+ char nspid[MAX_BUF_SIZE] = { 0 };
+ char cmd[MAX_CMD_LEN] = { 0 };
+
+ ret = proc_value_get(buffer, count, nspid);
+ if (ret != 0) {
+ BWM_LOG_ERR("proc_value_get failed");
+ return count;
+ }
+ BWM_LOG_DEBUG("get nspid %s.", nspid);
+
+ ret = snprintf(cmd, MAX_CMD_LEN, "%s -n -t %s %s -d", NSENTER_PATH, nspid, BWMCLI_PATH);
+ if (ret < 0) {
+ BWM_LOG_ERR("failed to snprintf disable qos cmd");
+ return ret;
+ }
+ BWM_LOG_DEBUG("disable qos cmd:%s", cmd);
+
+ ret = qos_cmd_upcall(cmd);
+ if (ret != 0) {
+ BWM_LOG_ERR("disable qos failed");
+ }
+
+ return count;
+}
+
+static int proc_net_qos_bandwidth_open(struct seq_file *seq, void *offset)
+{
+ seq_printf(seq, "%s\n", net_qos_bandwidth);
+ return 0;
+}
+
+static int proc_net_qos_bandwidth_single_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, proc_net_qos_bandwidth_open, NULL);
+}
+
+static ssize_t proc_net_qos_bandwidth_write(struct file *file, const char __user *buffer,
+ unsigned long count, loff_t *ppos)
+{
+ int ret = 0;
+ char bandwidth[MAX_BUF_SIZE] = { 0 };
+ char cmd[MAX_CMD_LEN] = { 0 };
+
+ ret = proc_value_get(buffer, count, bandwidth);
+ if (ret != 0) {
+ BWM_LOG_ERR("proc_value_get failed");
+ return count;
+ }
+ BWM_LOG_DEBUG("change net_qos_bandwidth to %s.", bandwidth);
+
+ ret = snprintf(cmd, MAX_CMD_LEN, "%s -s bandwidth %s", BWMCLI_PATH, bandwidth);
+ if (ret < 0) {
+ BWM_LOG_ERR("failed to snprintf bandwidth cmd");
+ return ret;
+ }
+ BWM_LOG_DEBUG("set bandwidth cmd : %s", cmd);
+
+ ret = qos_cmd_upcall(cmd);
+ if (ret != 0) {
+ BWM_LOG_ERR("set bandwidth failed");
+ return ret;
+ }
+
+ ret = snprintf(net_qos_bandwidth, MAX_BUF_SIZE, "%s", bandwidth);
+ if (ret < 0) {
+ BWM_LOG_ERR("failed to write net_qos_bandwidth");
+ return ret;
+ }
+
+ return count;
+}
+
+static int proc_net_qos_waterline_open(struct seq_file *seq, void *offset)
+{
+ seq_printf(seq, "%s\n", net_qos_waterline);
+ return 0;
+}
+
+static int proc_net_qos_waterline_single_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, proc_net_qos_waterline_open, NULL);
+}
+
+static ssize_t proc_net_qos_waterline_write(struct file *file, const char __user *buffer,
+ unsigned long count, loff_t *ppos)
+{
+ int ret = 0;
+ char waterline[MAX_BUF_SIZE] = { 0 };
+ char cmd[MAX_CMD_LEN] = { 0 };
+
+ ret = proc_value_get(buffer, count, waterline);
+ if (ret != 0) {
+ BWM_LOG_ERR("proc_value_get failed");
+ return count;
+ }
+ BWM_LOG_DEBUG("change net_qos_waterline to %s.", waterline);
+
+ ret = snprintf(cmd, MAX_CMD_LEN, "%s -s waterline %s", BWMCLI_PATH, waterline);
+ if (ret < 0) {
+ BWM_LOG_ERR("failed to snprintf waterline cmd");
+ return ret;
+ }
+ BWM_LOG_DEBUG("set waterline cmd : %s", cmd);
+
+ ret = qos_cmd_upcall(cmd);
+ if (ret != 0) {
+ BWM_LOG_ERR("set waterline failed");
+ return ret;
+ }
+
+ ret = snprintf(net_qos_waterline, MAX_BUF_SIZE, "%s", waterline);
+ if (ret < 0) {
+ BWM_LOG_ERR("failed to write net_qos_waterline");
+ return ret;
+ }
+
+ return count;
+}
+
+static int proc_net_qos_devs_open(struct seq_file *seq, void *offset)
+{
+ seq_printf(seq, "%s\n", net_qos_devs);
+ return 0;
+}
+
+static int proc_net_qos_devs_single_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, proc_net_qos_devs_open, NULL);
+}
+
+static ssize_t proc_net_qos_devs_write(struct file *file, const char __user *buffer,
+ unsigned long count, loff_t *ppos)
+{
+ int ret = 0;
+ char nspid[MAX_BUF_SIZE] = { 0 };
+ char cmd[MAX_CMD_LEN] = { 0 };
+
+ ret = proc_value_get(buffer, count, nspid);
+ if (ret != 0) {
+ BWM_LOG_ERR("proc_value_get failed");
+ return count;
+ }
+ BWM_LOG_DEBUG("write nspid:%s to net_qos_devs", nspid);
+
+ ret = snprintf(cmd, MAX_CMD_LEN, "%s -n -t %s %s -p devs > /proc/qos/net_qos_devstatus",
+ NSENTER_PATH, nspid, BWMCLI_PATH);
+ if (ret < 0) {
+ BWM_LOG_ERR("failed to snprintf devs status cmd");
+ return ret;
+ }
+ BWM_LOG_DEBUG("get devs status cmd:%s", cmd);
+
+ ret = qos_cmd_upcall(cmd);
+ if (ret != 0) {
+ BWM_LOG_ERR("write net_qos_devs failed");
+ }
+
+ return count;
+}
+
+static int proc_net_qos_devstatus_open(struct seq_file *seq, void *offset)
+{
+ seq_printf(seq, "%s\n", net_qos_devstatus);
+ return 0;
+}
+
+static int proc_net_qos_devstatus_single_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, proc_net_qos_devstatus_open, NULL);
+}
+
+static ssize_t proc_net_qos_devstatus_write(struct file *file, const char __user *buffer,
+ unsigned long count, loff_t *ppos)
+{
+ int ret = 0;
+ char data[MAX_BUF_SIZE] = { 0 };
+
+ ret = proc_value_get(buffer, count, data);
+ if (ret != 0) {
+ BWM_LOG_ERR("proc_value_get failed");
+ return count;
+ }
+
+ ret = snprintf(net_qos_devstatus, MAX_DATA_SIZE, "%s", data);
+ if (ret < 0) {
+ BWM_LOG_ERR("write net_qos_devstatus failed");
+ }
+
+ return count;
+}
+
+static atomic_t stats_flag = ATOMIC_INIT(0);
+
+static int proc_net_qos_stats_open(struct seq_file *seq, void *offset)
+{
+ seq_printf(seq, "%s\n", net_qos_stats);
+ return 0;
+}
+
+static int proc_net_qos_stats_single_open(struct inode *inode, struct file *file)
+{
+ int ret = 0;
+ char cmd[MAX_CMD_LEN] = { 0 };
+
+ if (atomic_read(&stats_flag) == 0) {
+ ret = snprintf(cmd, MAX_CMD_LEN, "%s -p stats > /proc/qos/net_qos_stats", BWMCLI_PATH);
+ if (ret < 0) {
+ BWM_LOG_ERR("failed to snprintf stats cmd");
+ return ret;
+ }
+ BWM_LOG_DEBUG("stats cmd:%s", cmd);
+
+ atomic_xchg(&stats_flag, 1);
+ ret = qos_cmd_upcall(cmd);
+ if (ret != 0) {
+ BWM_LOG_ERR("read net_qos_stats failed");
+ atomic_xchg(&stats_flag, 0);
+ return ret;
+ }
+ single_open(file, proc_net_qos_stats_open, NULL);
+ return 0;
+ }
+ atomic_xchg(&stats_flag, 0);
+ return single_open(file, proc_net_qos_stats_open, NULL);
+}
+
+static ssize_t proc_net_qos_stats_write(struct file *file, const char __user *buffer,
+ unsigned long count, loff_t *ppos)
+{
+ int ret = 0;
+ char stats[MAX_BUF_SIZE] = { 0 };
+
+ ret = proc_value_get(buffer, count, stats);
+ if (ret != 0) {
+ BWM_LOG_ERR("proc_value_get failed");
+ return count;
+ }
+
+ ret = snprintf(net_qos_stats, MAX_DATA_SIZE, "%s", stats);
+ if (ret < 0) {
+ BWM_LOG_ERR("write net_qos_stats failed");
+ }
+
+ return count;
+}
+
+static int proc_net_qos_version_open(struct seq_file *seq, void *offset)
+{
+ seq_printf(seq, "version:%s\n", net_qos_version);
+ return 0;
+}
+
+static int proc_net_qos_version_single_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, proc_net_qos_version_open, NULL);
+}
+
+static int proc_net_qos_debug_open(struct seq_file *seq, void *offset)
+{
+ seq_printf(seq, "%u\n", net_qos_debug);
+ return 0;
+}
+
+static int proc_net_qos_debug_single_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, proc_net_qos_debug_open, NULL);
+}
+
+static ssize_t proc_net_qos_debug_write(struct file *file, const char __user *buffer,
+ unsigned long count, loff_t *ppos)
+{
+ int ret = 0;
+ char debug_mode[MAX_BUF_SIZE] = { 0 };
+ unsigned int net_qos_debug_new = net_qos_debug;
+
+ ret = proc_value_get(buffer, count, debug_mode);
+ if (ret != 0) {
+ BWM_LOG_ERR("proc_value_get failed");
+ return count;
+ }
+
+ net_qos_debug_new = simple_strtoul(debug_mode, NULL, 0);
+ if (net_qos_debug_new != 0 && net_qos_debug_new != 1) {
+ BWM_LOG_ERR("invalid input of debug mode(%d), valid input: 0 or 1.", net_qos_debug_new);
+ return count;
+ }
+
+ BWM_LOG_INFO("change debug mode, old is %u, new is %u.", net_qos_debug, net_qos_debug_new);
+ net_qos_debug = net_qos_debug_new;
+
+ return count;
+}
+
+static struct proc_ops bwm_proc_net_qos_enable_ops = {
+ .proc_open = proc_net_qos_enable_single_open,
+ .proc_write = proc_net_qos_enable_write,
+ .proc_read = seq_read,
+ .proc_release = single_release,
+};
+
+static struct proc_ops bwm_proc_net_qos_disable_ops = {
+ .proc_open = proc_net_qos_disable_single_open,
+ .proc_write = proc_net_qos_disable_write,
+ .proc_read = seq_read,
+ .proc_release = single_release,
+};
+
+static struct proc_ops bwm_proc_net_qos_bandwidth_ops = {
+ .proc_open = proc_net_qos_bandwidth_single_open,
+ .proc_write = proc_net_qos_bandwidth_write,
+ .proc_read = seq_read,
+ .proc_release = single_release,
+};
+
+static struct proc_ops bwm_proc_net_qos_waterline_ops = {
+ .proc_open = proc_net_qos_waterline_single_open,
+ .proc_write = proc_net_qos_waterline_write,
+ .proc_read = seq_read,
+ .proc_release = single_release,
+};
+
+static struct proc_ops bwm_proc_net_qos_devs_ops = {
+ .proc_open = proc_net_qos_devs_single_open,
+ .proc_write = proc_net_qos_devs_write,
+ .proc_read = seq_read,
+ .proc_release = single_release,
+};
+
+static struct proc_ops bwm_proc_net_qos_devstatus_ops = {
+ .proc_open = proc_net_qos_devstatus_single_open,
+ .proc_write = proc_net_qos_devstatus_write,
+ .proc_read = seq_read,
+ .proc_release = single_release,
+};
+
+static struct proc_ops bwm_proc_net_qos_stats_ops = {
+ .proc_open = proc_net_qos_stats_single_open,
+ .proc_write = proc_net_qos_stats_write,
+ .proc_read = seq_read,
+ .proc_release = single_release,
+};
+
+static struct proc_ops bwm_proc_net_qos_version_ops = {
+ .proc_open = proc_net_qos_version_single_open,
+ .proc_read = seq_read,
+ .proc_release = single_release,
+};
+
+static struct proc_ops bwm_proc_net_qos_debug_ops = {
+ .proc_open = proc_net_qos_debug_single_open,
+ .proc_write = proc_net_qos_debug_write,
+ .proc_read = seq_read,
+ .proc_release = single_release,
+};
+
+static struct bwm_proc g_proc_table[] = {
+ {
+ .proc_name = "net_qos_enable",
+ .entry = NULL,
+ .ops = &bwm_proc_net_qos_enable_ops,
+ },
+ {
+ .proc_name = "net_qos_disable",
+ .entry = NULL,
+ .ops = &bwm_proc_net_qos_disable_ops,
+ },
+ {
+ .proc_name = "net_qos_bandwidth",
+ .entry = NULL,
+ .ops = &bwm_proc_net_qos_bandwidth_ops,
+ },
+ {
+ .proc_name = "net_qos_waterline",
+ .entry = NULL,
+ .ops = &bwm_proc_net_qos_waterline_ops,
+ },
+ {
+ .proc_name = "net_qos_devs",
+ .entry = NULL,
+ .ops = &bwm_proc_net_qos_devs_ops,
+ },
+ {
+ .proc_name = "net_qos_devstatus",
+ .entry = NULL,
+ .ops = &bwm_proc_net_qos_devstatus_ops,
+ },
+ {
+ .proc_name = "net_qos_stats",
+ .entry = NULL,
+ .ops = &bwm_proc_net_qos_stats_ops,
+ },
+ {
+ .proc_name = "net_qos_version",
+ .entry = NULL,
+ .ops = &bwm_proc_net_qos_version_ops,
+ },
+ {
+ .proc_name = "net_qos_debug",
+ .entry = NULL,
+ .ops = &bwm_proc_net_qos_debug_ops,
+ },
+};
+
+static int bwm_proc_init(void)
+{
+ unsigned int i;
+ int ret = 0;
+
+ bwm_proc_root_dir = proc_mkdir(BWM_PROC_ROOTDIR, NULL);
+ if (!bwm_proc_root_dir) {
+ BWM_LOG_ERR("can't create /proc/%s.", BWM_PROC_ROOTDIR);
+ return -EFAULT;
+ }
+
+ for (i = 0; i < sizeof(g_proc_table) / sizeof(struct bwm_proc); i++) {
+ g_proc_table[i].entry = proc_create_seq_data(g_proc_table[i].proc_name, BWM_CTL_PROC_PERM,
+ bwm_proc_root_dir, NULL, NULL);
+ if (!g_proc_table[i].entry) {
+ BWM_LOG_ERR("can't create file(%s).", g_proc_table[i].proc_name);
+ ret = -EFAULT;
+ break;
+ }
+ g_proc_table[i].entry->proc_ops = g_proc_table[i].ops;
+ }
+
+ if (ret != 0) {
+ BWM_LOG_ERR("bwm_proc_init failed");
+ }
+
+ return ret;
+}
+
+static void bwm_proc_clean(void)
+{
+ unsigned int i;
+
+ if (bwm_proc_root_dir) {
+ for (i = 0; i < sizeof(g_proc_table) / sizeof(struct bwm_proc); i++) {
+ if (g_proc_table[i].entry) {
+ remove_proc_entry(g_proc_table[i].proc_name, bwm_proc_root_dir);
+ g_proc_table[i].entry = NULL;
+ }
+ }
+ remove_proc_entry(BWM_PROC_ROOTDIR, NULL);
+ bwm_proc_root_dir = NULL;
+ }
+}
+
+static int __init bwm_init(void)
+{
+ int ret = 0;
+
+ ret = bwm_proc_init();
+ if (ret != 0) {
+ bwm_proc_clean();
+ return ret;
+ }
+
+ BWM_LOG_INFO("bwm loaded");
+ return ret;
+}
+
+static void __exit bwm_exit(void)
+{
+ bwm_proc_clean();
+ BWM_LOG_INFO("bwm unloaded");
+}
+
+module_init(bwm_init);
+module_exit(bwm_exit);
+MODULE_LICENSE("GPL");
diff --git a/ko/bwm.h b/ko/bwm.h
new file mode 100644
index 0000000..a977c0e
--- /dev/null
+++ b/ko/bwm.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2020-2022. All rights reserved.
+ * Description: Network bandwidth management tool
+ */
+#ifndef NET_BWM_H
+#define NET_BWM_H
+
+#include <asm/atomic.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/types.h>
+#include <fs/proc/internal.h>
+
+#define BWM_PROC_ROOTDIR "qos"
+#define BWM_CTL_PROC_PERM 0644
+
+#define NSENTER_PATH "/usr/bin/nsenter"
+#define BWMCLI_PATH "/usr/bin/bwmcli"
+
+#define MAX_BUF_SIZE 128
+#define MAX_CMD_LEN (256 + NAME_MAX)
+#define MAX_DATA_SIZE 1024
+
+static char net_qos_disable[] = "please write <nspid> to net_qos_disable to disable qos";
+static char net_qos_enable[] = "please write <nspid> to net_qos_enable to enable qos";
+static char net_qos_bandwidth[MAX_BUF_SIZE];
+static char net_qos_waterline[MAX_BUF_SIZE];
+static char net_qos_devs[] = "please write <nspid> to net_qos_devs and read dev status from net_qos_devstatus";
+static char net_qos_devstatus[MAX_DATA_SIZE];
+static char net_qos_stats[MAX_DATA_SIZE];
+static char net_qos_version[] = "1.1";
+static unsigned int net_qos_debug = 0;
+
+static struct proc_dir_entry *bwm_proc_root_dir = NULL;
+
+struct bwm_proc {
+ const char *proc_name;
+ struct proc_dir_entry *entry;
+ struct proc_ops *ops;
+};
+
+#define PFX "BWM"
+
+#define BWM_LOG_INFO(fmt, ...) \
+ do { \
+ printk(KERN_INFO "[" PFX "] INFO:" fmt "[%s():%u]\n", ##__VA_ARGS__, __FUNCTION__, __LINE__); \
+ } while (0)
+
+#define BWM_LOG_NOTICE(fmt, ...) \
+ do { \
+ printk(KERN_NOTICE "[" PFX "] NOTICE:" fmt, ##__VA_ARGS__); \
+ } while (0)
+
+#define BWM_LOG_ERR(fmt, ...) \
+ do { \
+ printk(KERN_ERR "[" PFX "] ERROR:" fmt "[%s():%u]\n", ##__VA_ARGS__, __FUNCTION__, __LINE__); \
+ } while (0)
+
+#define BWM_LOG_DEBUG(fmt, ...) \
+ do { \
+ if (net_qos_debug == 1) { \
+ printk(KERN_DEBUG "[" PFX "] DEBUG:" fmt "[%s():%u]\n", ##__VA_ARGS__, __FUNCTION__, __LINE__); \
+ } \
+ } while (0)
+
+#endif
--
2.33.0
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。