files_structのpwdでカレントの移動


task_struct に作業ディレクトリ等を管理するために、fs_struct構造体がぶら下がっています。その中のpwdを設定することにより、カレントディレクトリを遷移させてみます。
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/fdtable.h>
#include <linux/fs.h>
#include <linux/nsproxy.h>
#include <linux/mnt_namespace.h>
#include <linux/namei.h>
#include <asm/pgtable.h>

#include <asm/uaccess.h>

#define PROC_NAME "hogehoge"
static struct proc_dir_entry *dirp;
static size_t proc_write( struct file *filp, const char __user *buff,
                        unsigned long len, void *data );

static int proc_init_module(void)
{
        dirp = (struct proc_dir_entry *)
                create_proc_entry(PROC_NAME, 0666, (struct proc_dir_entry *) 0);
        if (dirp == 0)
                return(-EINVAL);
        dirp->write_proc = (read_proc_t *) proc_write;

        return 0;
}

static void proc_cleanup_module(void)
{
        remove_proc_entry(PROC_NAME, (struct proc_dir_entry *) 0);
}

static	void	do_pwd(struct task_struct *process)
{
	int	err;

	struct nameidata nd;
	err = path_lookup("/var", LOOKUP_FOLLOW, &nd);
	if(err) {
		printk("err:%d\n", err);
		return err;
	}
	else {
		process->fs->pwd.dentry = nd.path.dentry;
	}
}

static size_t proc_write( struct file *filp, const char __user *buff,
                        unsigned long len, void *data )
{
	char	_buff[64];

	if (copy_from_user(_buff, buff, len )) {
    		return -EFAULT;
	}
	int	mypid = simple_strtol(_buff, NULL, 0);

	struct task_struct *process;
	process = find_task_by_vpid(mypid);
	if (process) { 
		do_pwd(process);
	}
	else {
		mypid = -1;
		printk("pid error:%d\n", mypid);
    		return -EFAULT;
	}
	return len;
}

module_init(proc_init_module);
module_exit(proc_cleanup_module);

モジュールの組み込みます。
[root@localhost test]# insmod files_struct.ko
カレントをルートにします。
[root@localhost test]# cd /
[root@localhost /]#
[root@localhost /]# pwd
/
[root@localhost /]# ls
bin   dev  home  lost+found  mnt  proc  sbin     srv  tmp  var
boot  etc  lib   media       opt  root  selinux  sys  usr
自bashのプロセスidを確認。
[root@localhost /]# ps
  PID TTY          TIME CMD
 1465 pts/0    00:00:02 bash
 2618 pts/0    00:00:00 ps
/proc/hogehogeに書き込む
[root@localhost /]# echo 1465 > /proc/hogehoge
pwdはbashのビルドインコマンドが実行されるのでダメ
[root@localhost /]# pwd
/
外部コマンドのpwdlおよびlsで確認すればOK.
[root@localhost /]# /bin/pwd
/var
[root@localhost /]# ls
account  db     ftp    gdm  local  log   named  opt       run    tmp  yp
cache    empty  games  lib  lock   mail  nis    preserve  spool  www

備忘

該当のファイル名のdentryを取得するため、path_lookupでnameidataを取得する。この中にはdentryが紐づいている。取得すればそれをtask_struct->fs_struct->pwd.dentryに設定すればよい。なおfs_structはルートディレクトリとかマウントしているファイルシステムの情報も保持している。chrootはたぶんここを設定していると・・・・思う。

最終更新 2010/01/10 17:03:24 - north
(2010/01/10 16:35:23 作成)


検索

アクセス数
3686200
最近のコメント
コアダンプファイル - sakaia
list_head構造体 - yocto_no_yomikata
勧告ロックと強制ロック - wataash
LKMからのファイル出力 - 重松 宏昌
kprobe - ななし
ksetの実装 - スーパーコピー
カーネルスレッドとは - ノース
カーネルスレッドとは - nbyst
asmlinkageってなに? - ノース
asmlinkageってなに? - よろしく
Adsense
広告情報が設定されていません。