# 信号量残留<a name="ZH-CN_TOPIC_0184808212"></a>

使用devicemapper作为graphdriver时，强杀可能导致信号量残留。docker在操作dm的过程中会创建信号量，如果在释放信号量前，daemon被强杀，可能导致该信号量无法释放，一次强杀最多泄露一个信号量，泄露概率低。而linux系统有信号量上限限制，当信号量泄露次数达到上线值时将无法创建新的信号量，进而导致docker daemon启动失败。排查方法如下：

1.  首先查看系统上残留的信号量

    ```
    $ ipcs 
    ------ Message Queues -------- 
    key        msqid      owner      perms      used-bytes   messages 
    ------ Shared Memory Segments -------- 
    key        shmid      owner      perms      bytes      nattch     status 
    ------ Semaphore Arrays -------- 
    key        semid      owner      perms      nsems 
    0x0d4d3358 238977024  root       600        1 
    0x0d4d0ec9 270172161  root       600        1 
    0x0d4dc02e 281640962  root       600        1
    ```

2.  接着用dmsetup查看devicemapper创建的信号量，该信号量集合是上一步中查看到的系统信号量的子集

    ```
    $ dmsetup udevcookies 
    ```

3.  最后查看内核信号量设置上限，第四个值就是当前系统的信号量使用上限

    ```
    $ cat /proc/sys/kernel/sem 
    250     32000   32      128
    ```

    如果步骤1中残留的信号量数量与步骤3中看到的信号量上限相等，则是达到上限，此时docker daemon无法正常启动。可以使用下述命令增加信号量使用上限值来让docker恢复启动

    ```
    $ echo 250 32000  32  1024 > /proc/sys/kernel/sem
    ```

    也可以手动清理devicemapper残留的信号量（下面是清理一分钟以前申请的dm相关信号量）

    ```
    $ dmsetup udevcomplete_all 1 
    This operation will destroy all semaphores older than 1 minutes with keys that have a prefix 3405 (0xd4d). 
    Do you really want to continue? [y/n]: y 
    0 semaphores with keys prefixed by 3405 (0xd4d) destroyed. 0 skipped.
    ```


