Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 我可以在不使用mmap的情况下防止文件页逐出吗?_Linux_Linux Kernel_Filesystems_Page Caching - Fatal编程技术网

Linux 我可以在不使用mmap的情况下防止文件页逐出吗?

Linux 我可以在不使用mmap的情况下防止文件页逐出吗?,linux,linux-kernel,filesystems,page-caching,Linux,Linux Kernel,Filesystems,Page Caching,我的理解是,我可以通过对文件执行mmap,然后对映射的内存调用mlock,将文件保存在内存中 有没有一种方法可以在不执行mmap的情况下将文件数据保留在页面缓存中?具体地说,我希望确保在向文件追加数据时,我要写入的页面永远不会被逐出 我意识到这是罕见的,但我相信在某些情况下会发生。例如,应用程序写入数据,等待的时间超过了脏写回的百分之几秒(之后页面变干净,可以被逐出),然后写入更多的数据。我相信您在理解这些数据时有点错误。它的预期用途是: 断言由于数据尚未从磁盘加载或交换出去(出于性能原因很有用

我的理解是,我可以通过对文件执行
mmap
,然后对映射的内存调用
mlock
,将文件保存在内存中

有没有一种方法可以在不执行mmap的情况下将文件数据保留在页面缓存中?具体地说,我希望确保在向文件追加数据时,我要写入的页面永远不会被逐出


我意识到这是罕见的,但我相信在某些情况下会发生。例如,应用程序写入数据,等待的时间超过了脏写回的百分之几秒(之后页面变干净,可以被逐出),然后写入更多的数据。

我相信您在理解这些数据时有点错误。它的预期用途是:

  • 断言由于数据尚未从磁盘加载或交换出去(出于性能原因很有用,在实时应用程序中很关键),所以从内存读取时不会有等待
  • 断言页面不会被交换出去(对于密码或明文私钥等私有数据至关重要)
  • 因此,它断言页面已加载到RAM中,并防止它们被调出。无法保证它可以防止从文件映射的脏页的写回(事实上,它没有,请参见下面的实验)

    要提示内核您将从fd进行一些读取,很快就会有了,所以

    可能会将文件的请求部分加载到页面缓存中


    我不能肯定这一点,但我认为目前实际上没有办法禁止为特定文件写回脏页。也许有什么方法可以暗示,但我也看不到


    mmap/mlock实验
    alexander@goblin~/tmp$cat mmap.c
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    #定义句柄错误(msg)\
    do{perror(msg);exit(exit_FAILURE);}while(0)
    int main(int argc,char*argv[]){
    char*addr;
    int-fd;
    结构统计某人;
    尺寸与长度;
    如果(argc!=2){
    fprintf(stderr,“%s文件\n”,argv[0]);
    退出(退出失败);
    }
    fd=开路(argv[1],O_RDWR);
    如果(fd==-1){
    处理错误(“打开”);
    }
    if(fstat(fd,&sb)=-1){/*获取文件大小*/
    处理错误(“fstat”);
    }
    长度=sb.st_尺寸;
    addr=mmap(空,长度,保护读取,保护写入,映射共享,fd,0);
    if(addr==MAP_失败){
    处理错误(“mmap”);
    }
    if(mlock(addr,length)/dev/null | hextump-C
    00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
    *
    00001000
    alexander@goblin~/tmp$gcc mmap.c
    alexander@goblin~/tmp$./a.out foo&
    [1] 26450
    alexander@goblin~/tmp$sudo hdparm--fibmap foo
    傅:
    文件系统块大小4096,从LBA 0开始;假设为512字节扇区。
    字节\u偏移开始\u LBA结束\u LBA扇区
    0  279061632  279061639          8
    alexander@goblin~/tmp$sudo dd if=/dev/mapper/vg_main-gentoo_home count=8 skip=279061632 iflag=nocache 2>/dev/null | hextdump-C
    00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
    *
    00001000
    alexander@goblin~/tmp$sleep 10
    alexander@goblin~/tmp$sudo hdparm--fibmap foo
    傅:
    文件系统块大小4096,从LBA 0开始;假设为512字节扇区。
    字节\u偏移开始\u LBA结束\u LBA扇区
    0  279061632  279061639          8
    alexander@goblin~/tmp$sudo dd if=/dev/mapper/vg_main-gentoo_home count=8 skip=279061632 iflag=nocache 2>/dev/null | hextdump-C
    00000000 68 65 6c 6c 6f 20 77 6f 72 6c 64 21 00 00 |你好世界|
    00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
    *
    00001000
    alexander@goblin~/tmp$fg
    /a.out-foo
    ^C
    
    我相信您在理解功能方面有点错误。它的预期用途是:

  • 断言由于数据尚未从磁盘加载或交换出去(出于性能原因很有用,在实时应用程序中很关键),所以从内存读取时不会有等待
  • 断言页面不会被交换出去(对于密码或明文私钥等私有数据至关重要)
  • 因此,它断言这些页面被加载到RAM中,并防止它们被调出。无法保证它会阻止从文件映射的脏页面的写回(事实上,它不会,请参见下面的实验)

    要提示内核您将从fd进行一些读取,很快就会有了,所以

    可能会将文件的请求部分加载到页面缓存中


    我不能肯定这一点,但我想目前实际上没有办法禁止为特定文件写回脏页。可能有某种方法可以暗示它,但我也看不到任何方法


    mmap/mlock实验
    alexander@goblin~/tmp$cat mmap.c
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    #定义句柄错误(msg)\
    do{perror(msg);exit(exit_FAILURE);}while(0)
    int main(int argc,char*argv[]){
    char*addr;
    int-fd;
    结构统计某人;
    尺寸与长度;
    如果(argc!=2){
    fprintf(stderr,“%s文件\n”,argv[0]);
    退出(退出失败);
    }
    fd=开路(argv[1],O_RDWR);
    如果(fd==-1){
    处理错误(“打开”);
    }
    if(fstat(fd,&sb)=-1){/*获取文件大小*/
    处理错误(“fstat”);
    }
    长度=sb.st_尺寸;
    addr=mmap(空,长度,保护读取,保护写入,映射共享,fd,0);
    if(addr==MAP_失败){
    处理错误(“mmap”);
    }
    if(mlock(addr,length)/dev/null | hextump-C
    00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
    *
    00001000
    alexander@goblin~/tmp$gcc mmap.c
    alexander@goblin~/tmp$./a.out foo&
    [1] 26450
    alexander@goblin~/tmp$sudo hdparm--fibmap foo
    傅:
    文件系统块大小4096,从LBA 0开始;假设为512字节
    
    posix_fadvise(fd, offset, len,  POSIX_FADV_RANDOM);
    
    alexander@goblin ~/tmp $ cat mmap.c
    #include <sys/mman.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    #define handle_error(msg) \
        do { perror(msg); exit(EXIT_FAILURE); } while (0)
    
    int main(int argc, char *argv[]) {
        char *addr;
        int fd;
        struct stat sb;
        size_t length;
    
        if (argc != 2) {
            fprintf(stderr, "%s file\n", argv[0]);
            exit(EXIT_FAILURE);
        }
    
        fd = open(argv[1], O_RDWR);
        if (fd == -1) {
            handle_error("open");
        }
        if (fstat(fd, &sb) == -1) {          /* To obtain file size */
            handle_error("fstat");
        }
    
        length = sb.st_size;
    
        addr = mmap(NULL, length , PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
        if (addr == MAP_FAILED) {
            handle_error("mmap");
        }
    
        if(mlock(addr, length)<0) {
            handle_error("mlock");
        }
    
        strcpy(addr, "hello world!");
    
        sleep(100);
    
        munmap(addr, length);
        close(fd);
    
        exit(EXIT_SUCCESS);
    }
    alexander@goblin ~/tmp $ grep . /proc/sys/vm/dirty_{expire,writeback}_centisecs
    /proc/sys/vm/dirty_expire_centisecs:1000
    /proc/sys/vm/dirty_writeback_centisecs:500
    alexander@goblin ~/tmp $ dd if=/dev/zero of=foo bs=4k count=1
    1+0 records in
    1+0 records out
    4096 bytes (4.1 kB, 4.0 KiB) copied, 8.1296e-05 s, 50.4 MB/s
    alexander@goblin ~/tmp $ fallocate -l 4096 foo
    alexander@goblin ~/tmp $ sync foo
    alexander@goblin ~/tmp $ sudo hdparm --fibmap foo
    
    foo:
     filesystem blocksize 4096, begins at LBA 0; assuming 512 byte sectors.
     byte_offset  begin_LBA    end_LBA    sectors
               0  279061632  279061639          8
    alexander@goblin ~/tmp $ sudo dd if=/dev/mapper/vg_main-gentoo_home count=8 skip=279061632 iflag=nocache 2>/dev/null | hexdump -C
    00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
    *
    00001000
    alexander@goblin ~/tmp $ gcc mmap.c
    alexander@goblin ~/tmp $ ./a.out foo &
    [1] 26450
    alexander@goblin ~/tmp $ sudo hdparm --fibmap foo
    
    foo:
     filesystem blocksize 4096, begins at LBA 0; assuming 512 byte sectors.
     byte_offset  begin_LBA    end_LBA    sectors
               0  279061632  279061639          8
    alexander@goblin ~/tmp $ sudo dd if=/dev/mapper/vg_main-gentoo_home count=8 skip=279061632 iflag=nocache 2>/dev/null | hexdump -C
    00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
    *
    00001000
    alexander@goblin ~/tmp $ sleep 10
    alexander@goblin ~/tmp $ sudo hdparm --fibmap foo
    
    foo:
     filesystem blocksize 4096, begins at LBA 0; assuming 512 byte sectors.
     byte_offset  begin_LBA    end_LBA    sectors
               0  279061632  279061639          8
    alexander@goblin ~/tmp $ sudo dd if=/dev/mapper/vg_main-gentoo_home count=8 skip=279061632 iflag=nocache 2>/dev/null | hexdump -C
    00000000  68 65 6c 6c 6f 20 77 6f  72 6c 64 21 00 00 00 00  |hello world!....|
    00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
    *
    00001000
    alexander@goblin ~/tmp $ fg
    ./a.out foo
    ^C