symlinkの階層(procfs)


ブロックデバイスを有さないprocfsでは、シンボリックパス名をプロセスのnameidata.saved_names[MAX_NESTED_LINKS + 1]の設定による実装故に、シンボリックリンクは8階層までと思っていましたが、シンボリックパス名は、proc dentry毎のstruct proc_dir_entryのdata毎に動的にメモリを取得して設定されるようで、通常ファイルシステムと同じ40階層まででした。
enum { MAX_NESTED_LINKS = 8 };

struct nameidata {
      struct path     path;
      struct qstr     last;
      struct path     root;
      struct inode    *inode; /* path.dentry.d_inode */
      unsigned int    flags;
      unsigned        seq;
      int             last_type;
      unsigned        depth;
      char *saved_names[MAX_NESTED_LINKS + 1];

      /* Intent data */
      union {
              struct open_intent open;
      } intent;
};
[root@localhost lkm]# cat proc_babakaka.c
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>

static int babakaka_show(struct seq_file *m, void *none)
{
       seq_printf(m, "%s\n", "abcdefg");
       return 0;
}

static int babakaka_open(struct inode *inode, struct file *file)
{
       return single_open(file, babakaka_show, NULL);
}

static const struct file_operations babakaka_proc_fops = {
       .open           = babakaka_open,
       .read           = seq_read,
};

static int __init proc_babakaka_init(void)
{
       int     i;
       char    buf1[32], buf2[32];

       proc_create("babakaka0", 0, NULL, &babakaka_proc_fops);
       printk("link start\n");
       for (i = 0; i < 50; i++) {
               sprintf(buf1, "babakaka%d", i);
               sprintf(buf2, "babakaka%d", i + 1);
               if (!proc_symlink(buf2, NULL, buf1)) {
                       printk("link err\n");
               }
       }
       printk("link end\n");
       return 0;
}

static void __exit proc_babakaka_exit(void)
{
       int     i;
       char    buf1[32];

       for (i = 0; i < 51; i++) {
               sprintf(buf1, "babakaka%d", i);
               remove_proc_entry(buf1, NULL);
       }
}

module_init(proc_babakaka_init);
module_exit(proc_babakaka_exit);

[root@localhost lkm]# insmod proc_babakaka.ko
[root@localhost lkm]# dmesg
[ 5446.805708] link start
[ 5446.807411] link end
[root@localhost lkm]# cat /proc/babakaka0
abcdefg
[root@localhost lkm]# cat /proc/babakaka40
abcdefg
[root@localhost lkm]# cat /proc/babakaka41
cat: /proc/babakaka41: シンボリックリンクの階層が多すぎます

struct proc_dir_entry *proc_symlink(const char *name,
               struct proc_dir_entry *parent, const char *dest)
{
       struct proc_dir_entry *ent;

       ent = __proc_create(&parent, name,
                         (S_IFLNK | S_IRUGO | S_IWUGO | S_IXUGO),1);

       if (ent) {
               ent->data = kmalloc((ent->size=strlen(dest))+1, GFP_KERNEL);
               if (ent->data) {
                       strcpy((char*)ent->data,dest);
                       if (proc_register(parent, ent) < 0) {
                               kfree(ent->data);
                               kfree(ent);
                               ent = NULL;
                       }
               } else {
                       kfree(ent);
                       ent = NULL;
               }
       }
       return ent;
}
EXPORT_SYMBOL(proc_symlink);

最終更新 2017/01/29 14:26:06 - north
(2017/01/29 14:11:18 作成)


検索

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