Re: kmod patch

Mikael Pettersson (mikpe@csd.uu.se)
Fri, 28 Aug 1998 02:03:46 +0200 (MET DST)


On Wed, 26 Aug 1998, Charles Anderson wrote:

> use_init_file_context's job is to change context to make
>it seem as if init started modprobe. First thing it does is close_fs(current)
>(why do the kernel_thread with CLONE_FS, if we're gonna close it?)

Precisely _because_ we're going to close it. If we didn't specify
CLONE_FS, fork() would allocate a copy of the fs struct. Now we just
increment and decrement the reference counter.

> then
>assigns current->fs with task_init->fs. This is the problem. task_init
>is #define'd as task[smp_num_cpus], smp_num_cpus on my box is 1, I don't
>know what task[1] is but it doesn't have fs->root or fs->pwd set to anything.

You mean they're NULL? That's bad.
task[0] to task[smp_num_cpus-1] hold the idle tasks ("swapper"),
one per CPU. task[smp_num_cpus] is (supposed to be) the task that
execve():s "init". The "init" task may also (if you're using initrd)
change its root at an early stage in the boot process. Hence, if
any task can define what the "system" root is, it's the "init" task.

>I'm not sure if this is because I have a dual processor MB with only one
>CPU or what. I changed this to init_task.fs and all is well.

Note: init_task does not run "init". It's the original hand-crafted
task from which all other tasks descend. init_task itself is in tasks[0],
and becomes the idle task for the first CPU after forking "init".

Could you try the patch below. It will make kmod emit some debugging
info about task[0], task[smp_num_cpus], and task[smp_num_cpus+1].
On a healthy single-CPU machine, you should see something like this
in the logs (duplicated many times):

kmod: task[0] == 0xc0106000, comm == swapper, fs == 0xc0194f04, fs->root == 0xc0293060, fs->pwd == 0xc0293060
kmod: task[1] == 0xc0288000, comm == init, fs == 0xc0194f04, fs->root == 0xc0293060, fs->pwd == 0xc0293060
kmod: task[2] == 0xc0096000, comm == kflushd, fs == 0xc0194f04, fs->root == 0xc0293060, fs->pwd == 0xc0293060

The actual addresses aren't important. What's important is that
task[smp_num_cpus] runs "init", and that it's fs, root, and pwd are
all non-NULL.

/Mikael

--- kernel/kmod.c.orig Wed Aug 26 19:04:57 1998
+++ kernel/kmod.c Fri Aug 28 01:07:40 1998
@@ -33,6 +33,28 @@
*/
#define task_init task[smp_num_cpus]

+static void
+check_task(unsigned i)
+{
+ int status = 1;
+ struct task_struct *p = task[i];
+ printk("kmod: task[%u] == %#lx", i, (long)p);
+ if( p == 0 )
+ goto out;
+ printk(", comm == %.16s, fs == %#lx", p->comm, (long)p->fs);
+ if( p->fs == 0 )
+ goto out;
+ printk(", fs->root == %#lx, fs->pwd == %#lx",
+ (long)p->fs->root, (long)p->fs->pwd);
+ if( p->fs->root == 0 || p->fs->pwd == 0 )
+ goto out;
+ status = 0;
+ out:
+ printk("\n");
+ if( status != 0 && i == smp_num_cpus )
+ printk("kmod: warning, task_init is broken\n");
+}
+
static inline void
use_init_file_context(void)
{
@@ -44,6 +66,10 @@
atomic_inc(&current->fs->count);

unlock_kernel();
+
+ check_task(0);
+ check_task(smp_num_cpus);
+ check_task(smp_num_cpus+1);
}

static int exec_modprobe(void * module_name)

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.altern.org/andrebalsa/doc/lkml-faq.html