Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

CONNECTOR: add a proc entry to list connectors

I got a problem when I wanted to check if the kernel supports process
event connector, and It seems there's no way to do this check.

At best I can check if the kernel supports connector or not, by looking
into /proc/net/netlink, or maybe checking the return value of bind() to
see if it's ENOENT.

So it would be useful to add /proc/net/connector to list all supported
connectors:
# cat /proc/net/connector
Name ID
connector 4294967295:4294967295
cn_proc 1:1
w1 3:1

Changelog:
- fix memory leak: s/seq_release/single_release
- use spin_lock_bh instead of spin_lock_irqsave

Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
Acked-by: Evgeniy Polyakov <johnpol@2ka.mipt.ru>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Li Zefan and committed by
David S. Miller
a0a61a60 10b595af

+40
+40
drivers/connector/connector.c
··· 27 27 #include <linux/moduleparam.h> 28 28 #include <linux/connector.h> 29 29 #include <linux/mutex.h> 30 + #include <linux/proc_fs.h> 31 + #include <linux/spinlock.h> 30 32 31 33 #include <net/sock.h> 32 34 ··· 405 403 mutex_unlock(&notify_lock); 406 404 } 407 405 406 + static int cn_proc_show(struct seq_file *m, void *v) 407 + { 408 + struct cn_queue_dev *dev = cdev.cbdev; 409 + struct cn_callback_entry *cbq; 410 + 411 + seq_printf(m, "Name ID\n"); 412 + 413 + spin_lock_bh(&dev->queue_lock); 414 + 415 + list_for_each_entry(cbq, &dev->queue_list, callback_entry) { 416 + seq_printf(m, "%-15s %u:%u\n", 417 + cbq->id.name, 418 + cbq->id.id.idx, 419 + cbq->id.id.val); 420 + } 421 + 422 + spin_unlock_bh(&dev->queue_lock); 423 + 424 + return 0; 425 + } 426 + 427 + static int cn_proc_open(struct inode *inode, struct file *file) 428 + { 429 + return single_open(file, cn_proc_show, NULL); 430 + } 431 + 432 + static const struct file_operations cn_file_ops = { 433 + .owner = THIS_MODULE, 434 + .open = cn_proc_open, 435 + .read = seq_read, 436 + .llseek = seq_lseek, 437 + .release = single_release 438 + }; 439 + 408 440 static int __devinit cn_init(void) 409 441 { 410 442 struct cn_dev *dev = &cdev; ··· 470 434 return -EINVAL; 471 435 } 472 436 437 + proc_net_fops_create(&init_net, "connector", S_IRUGO, &cn_file_ops); 438 + 473 439 return 0; 474 440 } 475 441 ··· 480 442 struct cn_dev *dev = &cdev; 481 443 482 444 cn_already_initialized = 0; 445 + 446 + proc_net_remove(&init_net, "connector"); 483 447 484 448 cn_del_callback(&dev->id); 485 449 cn_queue_free_dev(dev->cbdev);