回到主战场INSMOD_MAIN!
1610 /* And open it. */
1611 if ((fp = gzf_open(filename, O_RDONLY)) == -1) {
1612 error("%s: %m", filename);
1613 return 1;
1614 }
1615 /* Try to prevent multiple simultaneous loads. */
1616 if (dolock)
1617 flock(fp, LOCK_EX);
gzf_open首先按压缩方式打开文件,然后在尝试非压缩方式。如果要求加锁,那就满足要求。
1618 if (!get_kernel_info(K_SYMBOLS))
1619 goto out;
函数get_kernel_info在./modutils-2.4.0/util/modstat.c中。
Insmod——get_kernel_info函数
409 int get_kernel_info(int type)
410 {
411 k_new_syscalls = !query_module(NULL, 0, NULL, 0, NULL);
412
413 #ifdef COMPAT_2_0
414 if (!k_new_syscalls)
415 return old_get_kernel_info(type);
416 #endif /* COMPAT_2_0 */
417
418 return new_get_kernel_info(type);
419 }
411行的作用是测试内核的版本,sys_query_module这个系统调用是在v2.1.x以后才加入的,如果版本比这个早,就会返回-NOSYS。new_get_kernel_info是这个函数的核心,它也在这个文件里。
Insmod——new_get_kernel_info函数
84 static int new_get_kernel_info(int type)
85 {
86 struct module_stat *modules;
87 struct module_stat *m;
88 struct module_symbol *syms;
89 struct module_symbol *s;
90 size_t ret;
91 size_t bufsize;
92 size_t nmod;
93 size_t nsyms;
94 size_t i;
95 size_t j;
96 char *module_names;
97 char *mn;
98
99 drop();
100
101 /*
102 * Collect the loaded modules
103 */
104 module_names = xmalloc(bufsize = 256);
105 while (query_module(NULL, QM_MODULES, module_names, bufsize, &ret)) {
106 if (errno != ENOSPC) {
107 error("QM_MODULES: %m/n");
108 return 0;
109 }
110 module_names = xrealloc(module_names, bufsize = ret);
111 }
112 module_name_list = module_names;
113 l_module_name_list = bufsize;
114 n_module_stat = nmod = ret;
115 module_stat = modules = xmalloc(nmod * sizeof(struct module_stat));
116 memset(modules, 0, nmod * sizeof(struct module_stat));
117
118 /* Collect the info from the modules */
119 for (i = 0, mn = module_names, m = modules;
120 i < nmod;
121 ++i, ++m, mn += strlen(mn) + 1) {
122 struct module_info info;
123
124 m->name = mn;
125 if (query_module(mn, QM_INFO, &info, sizeof(info), &ret)) {
126 if (errno == ENOENT) {
127 /* The module was removed out from underneath us. */
128 m->flags = NEW_MOD_DELETED;
129 continue;
130 }
131 /* else oops */
132 error("module %s: QM_INFO: %m", mn);
133 return 0;
134 }
135
136 m->addr = info.addr;
137
138 if (type & K_INFO) {
139 m->size = info.size;
140 m->flags = info.flags;
141 m->usecount = info.usecount;
142 m->modstruct = info.addr;
143 }
144
145 if (type & K_REFS) {
146 int mm;
147 char *mrefs;
148 char *mr;
149
150 mrefs = xmalloc(bufsize = 64);
151 while (query_module(mn, QM_REFS, mrefs, bufsize, &ret)) {
152 if (errno != ENOSPC) {
153 error("QM_REFS: %m");
154 return 1;
155 }
156 mrefs = xrealloc(mrefs, bufsize = ret);
157 }
158 for (j = 0, mr = mrefs;
159 j < ret;
160 ++j, mr += strlen(mr) + 1) {
161 for (mm = 0; mm < i; ++mm) {
162 if (strcmp(mr, module_stat[mm].name) == 0) {
163 m->nrefs += 1;
164 m->refs=xrealloc(m->refs, m->nrefs * sizeof(struct module_stat **));
165 m->refs[m->nrefs - 1] = module_stat + mm;
166 break;
167 }
168 }
169 }
170 free(mrefs);
171 }
172
173 if (type & K_SYMBOLS) { /* Want info about symbols */
174