2009年06月18日 request_module[net-pf-10]: waitpid(3788,...) failed, errno 1 (その6) [長年日記]
_ request_module[net-pf-10]: waitpid(3788,...) failed, errno 1 (その6)
request_module[net-pf-10]: waitpid(3788,...) failed, errno 1
の errno 1 は /usr/include/asm/errno.h より
#define EPERM 1 /* Operation not permitted */
を表していると思っていた。ところが /usr/src/linux/kernel/kmod.c より
178 int request_module(const char * module_name)
179 {
180 pid_t pid;
181 int waitpid_result;
182 sigset_t tmpsig;
183 int i;
184 static atomic_t kmod_concurrent = ATOMIC_INIT(0);
185 #define MAX_KMOD_CONCURRENT 50 /* Completely arbitrary value - KAO */
186 static int kmod_loop_msg;
187
188 /* Don't allow request_module() before the root fs is mounted! */
189 if ( ! current->fs->root ) {
190 printk(KERN_ERR "request_module[%s]: Root fs not mounted\n",
191 module_name);
192 return -EPERM;
193 }
194
195 /* If modprobe needs a service that is in a module, we get a recursive
196 * loop. Limit the number of running kmod threads to max_threads/2 or
197 * MAX_KMOD_CONCURRENT, whichever is the smaller. A cleaner method
198 * would be to run the parents of this process, counting how many times
199 * kmod was invoked. That would mean accessing the internals of the
200 * process tables to get the command line, proc_pid_cmdline is static
201 * and it is not worth changing the proc code just to handle this case.
202 * KAO.
203 */
204 i = max_threads/2;
205 if (i > MAX_KMOD_CONCURRENT)
206 i = MAX_KMOD_CONCURRENT;
207 atomic_inc(&kmod_concurrent);
208 if (atomic_read(&kmod_concurrent) > i) {
209 if (kmod_loop_msg++ < 5)
210 printk(KERN_ERR
211 "kmod: runaway modprobe loop assumed and stopped\n");
212 atomic_dec(&kmod_concurrent);
213 return -ENOMEM;
214 }
215
216 pid = kernel_thread(exec_modprobe, (void*) module_name, 0);
217 if (pid < 0) {
218 printk(KERN_ERR "request_module[%s]: fork failed, errno %d\n", module_name, -pid);
219 atomic_dec(&kmod_concurrent);
220 return pid;
221 }
222
223 /* Block everything but SIGKILL/SIGSTOP */
224 spin_lock_irq(¤t->sigmask_lock);
225 tmpsig = current->blocked;
226 siginitsetinv(¤t->blocked, sigmask(SIGKILL) | sigmask(SIGSTOP));
227 recalc_sigpending(current);
228 spin_unlock_irq(¤t->sigmask_lock);
229
230 waitpid_result = waitpid(pid, NULL, __WCLONE);
231 atomic_dec(&kmod_concurrent);
232
233 /* Allow signals again.. */
234 spin_lock_irq(¤t->sigmask_lock);
235 current->blocked = tmpsig;
236 recalc_sigpending(current);
237 spin_unlock_irq(¤t->sigmask_lock);
238
239 if (waitpid_result != pid) {
240 printk(KERN_ERR "request_module[%s]: waitpid(%d,...) failed, errno %d\n",
241 module_name, pid, -waitpid_result);
242 }
243 return 0;
244 }
240行〜241行が問題のエラーメッセージを出しているところなのだが、errnoに該当するのは -waitpid_result で、これは230行の waitpidのリターン値(-1)を符号反転したものに過ぎない。waitpidのリターン値が-1なのは単に「エラーで返ったよ」の印に過ぎず、真のエラーコードは errno に格納されているはず。なので、
239 if (waitpid_result != pid) {
240 #if 0
241 printk(KERN_ERR "request_module[%s]: waitpid(%d,...) failed, errno %d\n",
242 module_name, pid, -waitpid_result);
243 #else
244 printk(KERN_ERR "request_module[%s]: waitpid(%d,...) failed, errno %d realerrno %d\n",
245 module_name, pid, -waitpid_result, errno);
246 #endif
247 }
のようにして、カーネルをビルド中。
_ request_module[net-pf-10]: waitpid(3788,...) failed, errno 1 (その7)
本当の errno は
ECHILD 10 /* No child processes */
だった。
2.4系のスレッドの問題かもしれないが、はっきりとした事は言えない。とりあず
*** kernel/kmod.c.ORG 2009-06-18 01:09:00.000000000 +0900
--- kernel/kmod.c 2009-06-18 09:56:55.000000000 +0900
***************
*** 237,244 ****
--- 237,251 ----
spin_unlock_irq(¤t->sigmask_lock);
if (waitpid_result != pid) {
+ #if 0
printk(KERN_ERR "request_module[%s]: waitpid(%d,...) failed, errno %d\n",
module_name, pid, -waitpid_result);
+ #else
+ if (errno != ECHILD){
+ printk(KERN_ERR "request_module[%s]: waitpid(%d,...) failed, errno %d realerrno %d\n",
+ module_name, pid, -waitpid_result, errno);
+ }
+ #endif
}
return 0;
}
みたいにして、ECHILDの時はメッセージを出さないようにした。ビルド&再起動して様子をみているけれど、非常に場当たり的だが問題なさそう。
[ツッコミを入れる]