Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2590753
  • 博文数量: 351
  • 博客积分: 76
  • 博客等级: 上将
  • 技术积分: 3555
  • 用 户 组: 普通用户
  • 注册时间: 2004-11-13 21:27
文章分类

全部博文(351)

文章存档

2013年(1)

2012年(4)

2011年(7)

2010年(16)

2009年(34)

2008年(34)

2007年(34)

2006年(68)

2005年(82)

2004年(71)

分类: LINUX

2006-07-03 17:04:19

以前发现使用iptables时,系统所用的模块都会自动加载。比如说使用iptables -t nat -L
系统会自动加载ip_tables,ip_nat, iptables_nat等模块。看了源码(2.6.14),终于找到了原因。

当使用iptables进行配置的时候,内核会调用相应的match,
在net/ipv4/netfilter/ip_tables.c中调用了try_then_request_module()
702 static inline int
703 check_match(struct ipt_entry_match *m,
704             const char *name,
705             const struct ipt_ip *ip,
706             unsigned int hookmask,
707             unsigned int *i)
708 {
709         struct ipt_match *match;
710
711         match = try_then_request_module(find_match(m->u.user.name,
712                                                    m->u.user.revision),
713                                         "ipt_%s", m->u.user.name);
714 。。。。。。


try_then_request_module在include/linux/kmod.h中
 36
 37 #define try_then_request_module(x, mod...) ((x) ?: (request_module(mod), (x)))
 38

try_then_request_module先检查模块是否已经存在,如果不存在使用request_module(mod)加载mod.
request_module在kernel/kmod.c中。

 51
 52 /**
 53  * request_module - try to load a kernel module
 54  * @fmt:     printf style format string for the name of the module
 55  * @varargs: arguements as specified in the format string
 56  *
 57  * Load a module using the user mode module loader. The function returns
 58  * zero on success or a negative errno code on failure. Note that a
 59  * successful module load does not mean the module did not then unload
 60  * and exit on an error of its own. Callers must check that the service
 61  * they requested is now available not blindly invoke it.
 62  *
 63  * If module auto-loading support is disabled then this function
 64  * becomes a no-operation.
 65  */
 66 int request_module(const char *fmt, ...)
 67 {
 68         va_list args;
 69         char module_name[MODULE_NAME_LEN];
 70         unsigned int max_modprobes;
 71         int ret;
 72         char *argv[] = { modprobe_path, "-q", "--", module_name, NULL };
 73         static char *envp[] = { "HOME=/",
 74                                 "TERM=linux",
 75                                 "PATH=/sbin:/usr/sbin:/bin:/usr/bin",
 76                                 NULL };
 77         static atomic_t kmod_concurrent = ATOMIC_INIT(0);
 78 #define MAX_KMOD_CONCURRENT 50  /* Completely arbitrary value - KAO */
 79         static int kmod_loop_msg;
 80
 81         va_start(args, fmt);
 82         ret = vsnprintf(module_name, MODULE_NAME_LEN, fmt, args);
 83         va_end(args);
 84         if (ret >= MODULE_NAME_LEN)
 85                 return -ENAMETOOLONG;
 86
 87         /* If modprobe needs a service that is in a module, we get a recursive
 88          * loop.  Limit the number of running kmod threads to max_threads/2 or
 89          * MAX_KMOD_CONCURRENT, whichever is the smaller.  A cleaner method
 90          * would be to run the parents of this process, counting how many times
 91          * kmod was invoked.  That would mean accessing the internals of the
 92          * process tables to get the command line, proc_pid_cmdline is static
 93          * and it is not worth changing the proc code just to handle this case.
 94          * KAO.
 95          *
 96          * "trace the ppid" is simple, but will fail if someone's
 97          * parent exits.  I think this is as good as it gets. --RR
 98          */
 99         max_modprobes = min(max_threads/2, MAX_KMOD_CONCURRENT);
100         atomic_inc(&kmod_concurrent);
101         if (atomic_read(&kmod_concurrent) > max_modprobes) {
102                 /* We may be blaming an innocent here, but unlikely */
103                 if (kmod_loop_msg++ < 5)
104                         printk(KERN_ERR
105                                "request_module: runaway loop modprobe %s\n",
106                                module_name);
107                 atomic_dec(&kmod_concurrent);
108                 return -ENOMEM;
109         }
110
111         ret = call_usermodehelper(modprobe_path, argv, envp, 1);
112         atomic_dec(&kmod_concurrent);
113         return ret;
114 }
115 EXPORT_SYMBOL(request_module);
116 #endif /* CONFIG_KMOD */
117

阅读(5825) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~