/proc/swaps


/proc/swapsはswap_info[]のswap_info_structからswap情報を表示します。なおswapon -aコマンドは/proc/swapsを参照することで実現しています。
[root@localhost kitamura]# cat /proc/swaps
Filename                                Type            Size    Used    Priority
/dev/dm-0                               partition       1671164 0       0

[root@localhost kitamura]# swapon -s
Filename                                Type            Size    Used    Priority
/dev/mapper/VolGroup-lv_swap            partition       1671164 0       0

[root@localhost kitamura]# ls -l /dev/mapper/VolGroup-lv_swap
lrwxrwxrwx 1 root root 7  2月  8 01:23 /dev/mapper/VolGroup-lv_swap -> ../dm-0
nr_swapfilesでswap_info[]内のif (!(si->flags & SWP_USED) || !si->swap_map)でないswap_info_structを取得します。nr_swapfilesはswapoffしてもがデクリメントされることはありません。(対応するswap_info[]のメモリも解放されません。ただし使用可能スロットのsi->swap_mapは解放されます。) その使用されなくなったswap_info_structは、新たなswapに再利用することで無駄なメモリ取得/解放を無くすような実装となっています。

PAGE_SHIFTは通常12で、1pageは4Kバイトで、PAGE_SHIFT - 10はpageをkバイト単位で表示するためで、上記Size/UsedはKバイトです。
static const struct seq_operations swaps_op = {
       .start =        swap_start,
       .next =         swap_next,
       .stop =         swap_stop,
       .show =         swap_show
};

static int swap_show(struct seq_file *swap, void *v)
{
       struct swap_info_struct *si = v;
       struct file *file;
       int len;

       if (si == SEQ_START_TOKEN) {
               seq_puts(swap,"Filename\t\t\t\tType\t\tSize\tUsed\tPriority\n");
               return 0;
       }

       file = si->swap_file;
       len = seq_path(swap, &file->f_path, " \t\n\\");
       seq_printf(swap, "%*s%s\t%u\t%u\t%d\n",
                       len < 40 ? 40 - len : 1, " ",
                       S_ISBLK(file->f_path.dentry->d_inode->i_mode) ?
                               "partition" : "file\t",
                       si->pages << (PAGE_SHIFT - 10),
                       si->inuse_pages << (PAGE_SHIFT - 10),
                       si->prio);
       return 0;
}

static void *swap_start(struct seq_file *swap, loff_t *pos)
{
       struct swap_info_struct *si;
       int type;
       loff_t l = *pos;

       mutex_lock(&swapon_mutex);

       if (!l)
               return SEQ_START_TOKEN;

       for (type = 0; type < nr_swapfiles; type++) {
               smp_rmb();      /* read nr_swapfiles before swap_info[type] */
               si = swap_info[type];
               if (!(si->flags & SWP_USED) || !si->swap_map)
                       continue;
               if (!--l)
                       return si;
       }

       return NULL;
}

static void *swap_next(struct seq_file *swap, void *v, loff_t *pos)
{
       struct swap_info_struct *si = v;
       int type;

       if (v == SEQ_START_TOKEN)
               type = 0;
       else
               type = si->type + 1;

       for (; type < nr_swapfiles; type++) {
               smp_rmb();      /* read nr_swapfiles before swap_info[type] */
               si = swap_info[type];
               if (!(si->flags & SWP_USED) || !si->swap_map)
                       continue;
               ++*pos;
               return si;
       }

       return NULL;
}

最終更新 2014/02/07 17:05:37 - north
(2014/02/07 17:05:37 作成)


検索

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