- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在编写一个小内核模块,用于测量网络数据包退出节点所需的时间。这个模块是 netfilter 库中的一个钩子(Hook)。
对于它接收到的每个数据包,它都会计算一个哈希值,从 skbuff 获取 tstamp 和实际时间戳,并将所有这些数据保存在一个链表中。为了将此数据传递给用户空间,我创建了一个 proc 设备,当用户从该设备读取时,我发送链表的一个条目。
要更改列表(读和写),我有一个自旋锁。问题是有时当我在处理数据包时从 proc 设备读取时系统崩溃。
我认为问题出在函数“dump_data_to_proc”中,更具体地说是在尝试获取自旋锁时。我做了一些测试,它只在 tplink 路由器中运行时崩溃(软锁定)。当我在“普通”PC(单核)上运行该模块时,它不会崩溃,
#include /* Needed by all modules */
#include /* Needed for KERN_INFO */
#include /* Needed for the macros */
#include
#include
#include
#include
#include
#include
#include /* Necessary because of proc fs */
#include /* for copy_from_user */
#include "kmodule_measure_process_time.h"
#include "hash.c"
//DEBUG >=5 is very slow in the tplink
#define DEBUG 2
#define PROCFS_MAX_SIZE 64
#define PROCFS_NAME "measures"
#define MAXIMUM_SAMPLES 10000
static struct nf_hook_ops nfho;
unsigned int total_packets_processed= 0;
unsigned int total_packets_discarded=0;
int temp_counter=0;
struct values_list *HEAD;
spinlock_t list_lock ;
static int hello_proc(struct seq_file *m, void *v) {
seq_printf(m, " stats Mod initialized.\n");
trả về 0;
}
static int proc_open(struct inode *inode, struct file *file) {
return single_open(file, hello_proc, NULL);
}
ssize_t dump_data_to_proc(struct file *filp, char *buffer, size_t length, loff_t *offset){
int bytesRead = 0;
struct values_list *temp=NULL;
int bytesError=0;
char buff[PROCFS_MAX_SIZE];
spin_lock(&list_lock);
temp=HEAD;
if(temp!=NULL){
HEAD = temp->next;
}
spin_unlock(&list_lock);
if(temp!=NULL){
bytesRead = snprintf(buff, PROCFS_MAX_SIZE ,"%u|%llu|%llu\n", temp->hash,temp->arrival_timestap, temp->exit_timestap);
length = length - bytesRead+1;
kfree(temp);
temp_counter--;
}
bytesError= copy_to_user(buffer, buff, bytesRead);
if(bytesError!=0){
#if DEBUG >0
printk(KERN_INFO "Error: failed to copy to user");
#kết thúc nếu
}
return bytesRead;
}
static const struct file_operations proc_fops = {
.owner = THIS_MODULE,
.open = proc_open,
.read = dump_data_to_proc,
.llseek = seq_lseek,
.release = single_release,
};
static unsigned int hook_func(unsigned int hooknum, struct sk_buff *skb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *))
{
uint32_t hash=0;
ktime_t now_timeval;
struct timespec now;
u64 timestamp_arrival_time=0;
u64 timestamp_now=0;
struct ipv6hdr * ipheader;
struct values_list *node;
int number_of_samples=0;
spin_lock(&list_lock);
number_of_samples=temp_counter;
spin_unlock(&list_lock);
if(number_of_samples > MAXIMUM_SAMPLES){
#if DEBUG > 5
printk(KERN_INFO "Discarded one sample because the list is full.\n");
#kết thúc nếu
total_packets_discarded++; // probably this should be inside a spinlock
return NF_ACCEPT;
}
//calculate arrival time and actual time in ns
timestamp_arrival_time = ktime_to_ns(skb->tstamp);
getnstimeofday(&now);
now_timeval = timespec_to_ktime(now);
timestamp_now = ktime_to_ns(now_timeval);
//get Ipv6 addresses
ipheader = (struct ipv6hdr *)skb_network_header(skb);
hash=simple_hash((char *)&ipheader->saddr,sizeof(struct in6_addr)*2,hash);
total_packets_processed++;
node = (struct values_list *) kmalloc(sizeof(struct values_list),GFP_ATOMIC);
if(!node){
#if DEBUG >0
printk(KERN_INFO "Error cannot malloc\n");
#kết thúc nếu
return NF_ACCEPT;
}
node->hash=hash;
node->arrival_timestap=timestamp_arrival_time;
node->exit_timestap=timestamp_now;
spin_lock(&list_lock);
node->next=HEAD;
HEAD=node;
temp_counter++;
spin_unlock(&list_lock);
return NF_ACCEPT;
}
static int __init init_main(void)
{
nfho.hook = hook_func;
nfho.hooknum = NF_INET_POST_ROUTING;
nfho.pf = PF_INET6;
nfho.priority = NF_IP_PRI_FIRST;
nf_register_hook(&nfho);
#if DEBUG >0
printk(KERN_INFO " kernel module: Successfully inserted protocol module into kernel.\n");
#kết thúc nếu
proc_create(PROCFS_NAME, 0, NULL, &proc_fops);
spin_lock_init(&list_lock);
//Some distros/devices disable timestamping of packets
net_enable_timestamp();
trả về 0;
}
static void __exit cleanup_main(void)
{
struct values_list *temp;
nf_unregister_hook(&nfho);
#if DEBUG >0
printk(KERN_INFO " kernel module: Successfully unloaded protocol module.\n");
printk(KERN_INFO "Number of packets processed:%d\n",total_packets_processed);
printk(KERN_INFO "Number of packets discarded:%d\n",total_packets_discarded);
#kết thúc nếu
remove_proc_entry(PROCFS_NAME, NULL);
while(HEAD!=NULL){
temp=HEAD;
HEAD= HEAD->next;
kfree(temp);
}
}
module_init(init_main);
module_exit(cleanup_main);
/* * Declaring code as GPL. */
MODULE_LICENSE("GPLv3");
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
câu trả lời hay nhất
您的代码有两个问题:
为您的代码使用 Linux 内核宏。 http://makelinux.com/ldd3/chp-11-sect-5 .只需将 struct list_head
作为元素添加到您的 struct values_list
并使用 list_entry
、list_add
和其他
Netfilter hools 在软中断上下文中运行,因此您phảisử dụngspin_lock_irqsave
Vàspin_unlock_irqrestore
。这很可能是您的系统因软锁定而崩溃的原因。仔细阅读http://makelinux.com/ldd3/chp-5-sect-5
关于c - 了解 netfilter hook 中的自旋锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24814311/
Điều tôi muốn làm là làm cho JTextPane chiếm nhiều dung lượng nhất có thể trong JPanel. Đối với UpdateInfoPanel tôi đang sử dụng: public class UpdateInfoPanel mở rộng JP
Tôi có JTextArea trong JPanel và tôi muốn sử dụng nó với JScrollPane. Tôi đang sử dụng GridBagLayout. Khi tôi chạy nó, khung công tác dường như nhường chỗ cho JScrollPane, nhưng
Tôi muốn triển khai chức năng sau trong xcode. Tôi có Trình điều khiển xem. Trong UIViewController này, tôi có UITabBar. Bên dưới chúng là UIView. Thay đổi UITab
Có ai biết Firebird 2.5 có chức năng tương tự chức năng "STUFF" trong SQL không? Tôi có một bảng chứa các bản ghi người dùng gốc và một bảng khác chứa các bản ghi người dùng con liên quan đến cha mẹ. Tôi muốn có thể trích xuất một chuỗi "ROLES" được phân tách bằng dấu phẩy do người dùng sở hữu, trong khi
Tôi muốn sử dụng JSON làm đầu vào và đầu ra của kênh phản ánh, chẳng hạn như lưu thông tin chi tiết trong cơ sở dữ liệu hoặc tạo thông báo HL7. Nói tóm lại, đầu vào là JSON, phân tích cú pháp và xuất ra bất kỳ định dạng nào. Đối tượng trả lời tốt nhất
Thông thường tôi sẽ sử dụng R và thực hiện merge.by, nhưng tệp này có vẻ quá lớn để bất kỳ máy tính nào trong bộ phận có thể xử lý nó! (Thông tin bổ sung cho bất kỳ ai làm việc trong lĩnh vực di truyền học) Về cơ bản, việc quy định dường như sẽ bị xóa Sau khi nhận được số rs của ID snp, tôi chỉ có
Tôi có một câu hỏi có thể đã được hỏi trước đây nhưng tôi gặp khó khăn khi tìm mô tả chính xác. Tôi hy vọng ai đó có thể giúp tôi. Trong đoạn mã bên dưới, tôi đã thiết lập varprice và tôi muốn thêm biến javascript accu_id để tra cứu bản ghi trong cơ sở dữ liệu của mình thông qua Rails
Tôi có một tệp SVG đơn giản có thể xem tốt trong Firefox - nó có một số văn bản gói chứa một số HTML bằng cách sử dụng đối tượng nước ngoài - văn bản được gói trong một div:
Vì vậy, tôi đang viết một chương trình Ruby dành cho trường học để thay đổi giá trị bool thành true nếu giá trị là 1 hoặc 3 và thành false nếu nó là 0 hoặc 2. Vì tôi có nền tảng Java nên tôi nghĩ mã này sẽ hoạt động:
Những gì tôi đã làm: Tôi đã tạo VPC ngang hàng giữa các tài khoản này Cổng Internet cũng được kết nối với từng VPC Bảng định tuyến cũng được định cấu hình (để cho phép lưu lượng truy cập từ cả hai phía) Trường hợp 1: Khi hai VPC này nằm trong cùng một tài khoản Trong thời gian chờ đợi, tôi đã thử nghiệm thành công nó từ một La khác
Tôi có một bảng gọi là danh bạ: user_id contact_id 10294 10295 10294 10293 10293 10294 102
Tôi đang sử dụng mẫu mới trong Magento. Để tránh trùng lặp mã, tôi muốn sử dụng cùng một mẫu con cho mỗi bản xem trước sản phẩm. Cụ thể là tôi đã tạo một màn hình như thế này: $products = Mage::getModel('catalog/pro
"for" có luôn kiểm tra loại tham số đầu tiên trong mọi hàm được xác định trong giao thức không? Chỉnh sửa (viết lại): Khi một phương thức giao thức chỉ có một tham số, việc triển khai được tìm thấy dựa trên loại tham số đơn đó (trực tiếp hoặc tùy ý). Khi thỏa thuận (p
Tôi muốn gọi hàm JavaScript từ mã PHP của mình. Tôi đã đạt được điều này bằng cách sử dụng: echo ' drawChart($id); '; Điều này hoạt động tốt, nhưng tôi muốn lấy dữ liệu từ mã PHP của mình, tôi sử dụng
Câu hỏi này đã có câu trả lời: Sự kiện ràng buộc trên các phần tử được tạo động? (23 câu trả lời) Đã đóng 5 năm trước. Tôi có một biểu mẫu động mà tôi muốn nối thêm một số h
Tôi đang cố gắng tìm giải pháp sử dụng setState trên các mục được ánh xạ trong thành phầnDidMount. Tôi đang sử dụng GraphQL cùng với Gatsby để trả về nhiều mục dữ liệu nhưng yêu cầu điều đó trong một thao tác cụ thể
Tôi có Chế độ xem bên trong ScrollView. Tôi muốn gọi phương thức này cứ sau 80 mili giây miễn là người dùng giữ Chế độ xem. Đây là những gì tôi đã thực hiện: rung Runnable cuối cùng = Runnab mới
Tôi đã phát triển một ứng dụng Android bằng jni. Tôi nhận được một dvmabort trong dvmDecodeIndirectRef của GetStringUTFChars. Tôi chỉ phá thai một lần. Tại sao điều này lại xảy ra?
Khi tôi truy cập Hoạt động của mình, tôi gọi FragmentPagerAdapter để xử lý các tab khác nhau của mình. Trong một trong các tab của mình, tôi muốn hiển thị RecyclerView nhưng anh ấy không bao giờ xuất hiện, với một điểm ngắt mà tôi thấy
Khi tôi nhấn một nút trong Hoạt động, DialogFragment sẽ bật lên. Trong đoạn hộp thoại, có một RecyclerView trông giống như một ListView bình thường. Hành vi tôi muốn là khi
Tôi là một lập trình viên xuất sắc, rất giỏi!