• O_CLOEXEC

    默认情况下,一个文件描述符在execve之后,还是保持打开状态的. open一个文件的时候, 可以使用FD_CLOEXEC这个flag,改变这个初始值.

    在open的时候带上这个flag,就可以避免再次使用fcntl去设置,因为用fcntl设置的时候是线程不安全的, 可能在fork或者execve的时候出现问题.

    问题, execve是个什么问题? 为什么会牵扯到文件描述符? 问题2, 如果是整个函数退出(main函数退出), 文件描述符是关闭的吧?

    下午又了解了一下, 问题1的回答见O_CLOEXEC 2 问题2的回答应该是”是”, 在Unix环境高级编程第三章讲到.

  • Atom中在新tab打开文件

    自动升级到1.7.3之后,发现每次打开文件时候总是在当前tab,可是我有时候也需要在新的tab页打开.

    搜索了之后, 才知道现在atom多了smart tab功能, 也就是说如果文件没有被改动,打开下一个文件时, 就会覆盖当前的tab,否则在新tab打开.

    如果想强制在新tab打开, 只需要双击文件名就好了.

    隐藏的好深啊…

  • 问题 文件的物理结构是什么样的

    文件系统中, 文件的物理结构是什么样的呢? 文件系统中, 怎么定义的文件的存储呢? 先记下这个问题, 以后看.

    #include <fcntl.h>
    #include <unistd.h>
    #include <stdio.h>
    
    int main(){
        int f = open("blank",O_WRONLY);
        if (f<0){
            perror("open error");
        }
        printf("%d\n",f);
        write(f,"abcdefg",7);
        lseek(f,10000000,SEEK_CUR);
        write(f,"abcdefg\n",8);
        close(f);
    }
    

    写一个空洞文件.

    root@2d3967f5850a:/tmp/test# ll blank
    -rw-r--r-- 1 root root 10000015 May  6 03:56 blank
    root@2d3967f5850a:/tmp/test# du -sh blank
    104K    blank 
    

    文件在大概10M, 但实际占用的磁盘空间只有104K

    但读取文件时候, 是会读取10M字节的内容的, cat blank > blank2, 然后再du也可以佐证.

    那文件系统中, 文件的物理结构是什么样的呢? 文件系统中, 怎么定义的文件的存储呢? 先记下这个问题, 以后看.

  • 通过nc来远程跑命令

    公司服务器登陆用了OTP(one time password), 每次登陆服务器都要输入不同的token, 有些麻烦. 大家讨论有哪些办法可以绕过去. 我想到了nc.

    以下全部没有任何实际价值, 仅供娱乐!

    在服务器上面:

    tail -0f p | nc -k -l 8000 | bash >> p
    

    在自己机器上面:

    nc 172.17.0.3 8000
    

    甚至可以传文件!

    先在自己机器上通过nc在服务器运行

    nohup nc -l 8001 > /tmp/a &
    

    然后在自己机器:

    cat 1 | nc 172.17.0.3 8001
    
  • umask使用

    umask是shell里面内置的一个命令. 设置进程的文件模式创建屏蔽码, 这个屏蔽码会在open/mkdir/mkfifo/mknod等系统调用时使用, 用来关闭文件模式中对应位置的权限位.

    op1@5ef1a50fef8f:~$ umask
    0002
    op1@5ef1a50fef8f:~$ touch 1
    op1@5ef1a50fef8f:~$ ll
    total 24
    -rw-rw-r-- 1 op1  op1     0 May  2 02:10 1
    op1@5ef1a50fef8f:~$ umask 0077
    op1@5ef1a50fef8f:~$ umask
    0077
    op1@5ef1a50fef8f:~$ rm 1
    op1@5ef1a50fef8f:~$ touch 1
    op1@5ef1a50fef8f:~$ ll
    total 24
    -rw------- 1 op1  op1     0 May  2 02:11 1
    
  • git删除远端tag

    git push origin :tagname

    git push --delete origin tagname

  • 每次read时的buffer size如何影响性能2

    昨天的时候有个疑问, /proc/diskstats里面的第四列, 也就是reads completed是什么. 和iostat显示的tps对比之后, 确认了, read tps取的值和reads completed就是一个.

    那应该就是说, read(fd, 1024000)的时候, 未必是一次”I/O request to the device”. 具体系统怎么处理read的, 继续学习.

    下午更新:

    在高手的指点下, 想通了. 至少在读文件(而不是裸设备)的时候, read(fd, 1024000)不是一次IO请求. 下面具体说一下:

    如果文件系统的blocksize也是4096. readahead设置成16, 也就是16*512=8192字节, 2个block.

    我们假设文件是顺序的.

    我原来的想法

    因为文件在磁盘中顺序存放的, 所以read(fd, 1024000)的时候, 一次性取1024000字节, 可以极大的减少磁盘IO次数. 但和测试下来的结果不符合, 所以很困惑.

    现在的理解

    OS在执行read file的时候,可不知道文件在磁盘中是顺序存在的,它需要在分析文件当前的block之后才知道下一个block在磁盘的哪里.

    如果一次性读取1024000这么多字节, 非常有可能后面很多数据都浪费了. 所以每次IO操作时, OS还是按照readahead配置来读.

    read(fd, 1024000)的时候, 是250个block. 因为有readahead, 所以一次会读8192字节. 如果磁盘是顺序的, 那么就是需要1024000/8192=125次IO requests

  • 每次read时的buffer size如何影响性能

    磁盘IO是比较费时的操作. 操作系统在每次读取磁盘的时候, 会认为接下来的文件内容可能在接下来很快再次读取,所以会预先就先读到内存中.

    这样可以查看当前系统的read ahead的值, 单位是512 bytes.

    blockdev --getra /dev/sda1
    

    这样可以配置read ahead的值, 单位是512 bytes.

    blockdev --setra 1024 /dev/sda1
    

    简单的脚本测试一下:

    echo 3 > /proc/sys/vm/drop_caches
    
    read1=$(cat /proc/diskstats | grep sda1 | awk '{print $4}')
    dd if=test of=/dev/null ibs=$@
    read2=$(cat /proc/diskstats | grep sda1 | awk '{print $4}')
    echo $((read2-read1))
    

    运行结果:

    # blockdev --setra 256 /dev/sda1 
    # ./go.sh 4096
    4194
    #
    # blockdev --setra 128 /dev/sda1 
    # bash go.sh 4096
    8233
    

    关于/proc/diskstats的解释

    疑问1

    我是计算的 ‘reads completed’ 的差值.

    This is the total number of reads completed successfully.
    

    这个到底是指的什么?

    系统调用的次数? 看上面的测试结果应该不是.
    实际磁盘IO的次数? 也会有矛盾.

    疑问2

    如果readahead是16(512 bytes), 16*512=8192

    read(16384)的时候, 会有几次磁盘IO? 看reads completed的值, 8192和16384没有区别.

    非疑问

    st_blksize 是4096, 所以readahead一定要是8的位数.

  • docker内存限制不能用free来查看

    这样可以限制容器中所有进程使用的内存数量

    docker run -it -m 300M ubuntu:14.04 /bin/bash
    

    但它是用cgroup来实现的, 在窗口中用free看不出来.

  • TODO