

MacOS X El CapitanのiTerm2上でzshを起動し、そこから手でtmuxを起動しています。

そしてしばらく使っているといつのまにかtmuxのunixドメインソケット (以下「ソケット」) が消されてしまいます。

[code]

    /private/var/folders/<途中省略>/T/tmux-501/default
    
[/code]

にありますが、`tmux-501`
以下が消されてしまいます。消えるタイミングがまちまちで、おおむね数時間使っているといつの間にか消えている感じです。これが消えてしまうと `tmux ls`
などソケットを読み書きする機能を使ったとき

[code]

    error connecting to /private/var/folders/<途中省略>/T/tmux-501/default (No such file or directory)
    
[/code]

というエラーを報告してくるようになります。ソケットファイルが消えていることに気づくのはこのソケットを読み書きする機能を使った時であり、当然消えたタイミングではありません。つまりいつ消えたのかわかりません。このことから誰が消しているのか皆目見当がつかなくなっています。

ところでtmuxのmanを見ると、`SIGUSR1` をtmuxのプロセスに送るとソケットファイルを作りなおしてくれる
(ただし親ディレクトリがないと失敗する) との意味の記述があるので以下のようにやってみると復活できました。

[code]

    $ mkdir -m700 /private/var/folders/<途中省略>/T/tmux-501
    $ killall -SIGUSR1 tmux
    
[/code]

このあと `tmux ls` が正常に見えるようになります。

ディレクトリのパーミッションを700にしているのは、もともとtmuxが作ったディレクトリがそうだったのと、デフォルトの755のままだと作りなおしてくれなかったからであり、特に深い意味はありません。

実用上は作りなおせばいいので面倒なこと以外は問題ない気はします。が、誰が消しているのか気持ち悪くて仕方がありません。誰がいつ消しているのか特定できれば解決の糸口になる気がしています。特定する方法は何かありませんでしょうか?

### 2016/1/28 11:54追記

1秒毎にファイルが消えたかチェックして消えたら時刻を記録するシェルスクリプトを回していたところ消えた時刻を捕まえました。今日の11:42:56、コンソール.appでログを漁ってみるとこんなものが記録されていました。

[code]

    2016/01/28 11:42:56.581 sandboxd[132]: ([52708]) PluginProcess(52708) deny file-write-unlink /private/var/folders/<中略>/C/com.apple.sandbox
    2016/01/28 11:42:56.588 sandboxd[132]: ([52708]) PluginProcess(52708) deny file-write-unlink /private/var/folders/<中略>/C/com.apple.sandbox
    2016/01/28 11:42:56.597 sandboxd[132]: ([52708]) PluginProcess(52708) deny file-read-data /private/var/folders/<中略>/C/com.apple.sandbox
    2016/01/28 11:42:56.975 launchservicesd[79]: SecTaskLoadEntitlements failed error=22
    2016/01/28 11:42:56.981 launchservicesd[79]: SecTaskLoadEntitlements failed error=22
    2016/01/28 11:42:56.983 launchservicesd[79]: SecTaskLoadEntitlements failed error=22
    
[/code]

最初から3つまでのエントリにはそれぞれコンソール.appが詳細情報ありと言ってきていて、1番目のエントリについてそれを表示させると以下のようになります。

[code]

    PluginProcess(52708) deny file-write-unlink /private/var/folders/<中略>/C/com.apple.sandbox
    
    Process:         PluginProcess [52708]
    Path:            /System/Library/Frameworks/WebKit.framework/Versions/A/PluginProcess.app/Contents/MacOS/PluginProcess
    Load Address:    0x2000
    Identifier:      com.apple.WebKit.PluginProcess
    Version:         11601.4.4 (11601)
    Build Info:      1-WebKit2~7601004004000000
    Code Type:       i386 (Native)
    Parent Process:  Safari [331]
    
    Date/Time:       2016-01-28 11:42:56.401 +0900
    OS Version:      Mac OS X 10.11.3 (15D21)
    Report Version:  8
    
    <後略>
    
[/code]

後略以降はコールスタックが続いているようです。これを見る限り webkit に関連するファイルのようで deny や unlink
なんて出ていることから消すのに失敗したのでしょうか。その時に巻き込まれて tmux のソケットも消された? 全部推測ですけど。この時 safari
で何をやっていたかというとなんとも覚えてないですね。

ログに記録された文言でぐぐってみていますけど芳しい情報を見つけられないでいます。とりあえずこういう事実があったということだけ書いておきます。次はソケットを監視しつつ
safari をいじめてみることでしょうか。

### 2016/1/28 23:57追記

`(server-start)` で起動する Emacs サーバの unix
ドメインソケットも消されることがわかりました。同一犯による犯行なのかわかりませんが、ソケットを消しまくる奴がそんなにたくさんいるとは思えません。なんにしろ大変迷惑な話です。まいったな。こっちも
`M-x server-start` すりゃいいといえばいいんですがね…。


CC BY-SA 3.0
2016-01-23T07:50:46.673
21222
2016-01-29T23:56:25.873
2016-01-28T15:06:55.073
3413
3413
question
macos tmux
tmuxのunixドメインソケットを消している犯人を特定したい


実際に試してはいないのですが、この辺はどうでしょう？

> opensnoopコマンドは、特定のファイルやフォルダにアクセスしたプロセスをリストアプしてくれる便利なユーティリティです。

<http://yamaqblog.tokyo/?p=16811>

> launchdのWatchPathsによるファイル監視

<http://qiita.com/uraura/items/4bb0663e670fbaba1083>

「mac file audit」でぐぐるとけっこう見つかるようです。


CC BY-SA 3.0
2016-01-24T00:05:20.360
21242
2016-01-24T00:05:20.360
13882
21222
answer


# tmuxのソケットはどこにある？

netstatで確認。

[code]

    netstat -an | grep tmux
    40a70ef2516d600f stream      0      0 40a70ef2566b2197                0                0                0 /private/var/folders/j7/0w59t0zs7vs1j4r5x0tlywy80000gq/T/tmux-503/default
    
[/code]

statしてみる

[code]

    stat /private/var/folders/j7/0w59t0zs7vs1j4r5x0tlywy80000gq/T/tmux-503/default
    16777220 51632361 srwxrwx--- 1 knoguchi staff 0 0 "Jan 28 10:40:22 2016" "Jan 28 10:40:22 2016" "Jan 28 10:40:22 2016" "Jan 28 10:40:22 2016" 4096 0 0 /private/var/folders/j7/0w59t0zs7vs1j4r5x0tlywy80000gq/T/tmux-503/default
    
    stat -s /private/var/folders/j7/0w59t0zs7vs1j4r5x0tlywy80000gq/T/tmux-503/default
    st_dev=16777220 st_ino=51632361 st_mode=0140770 st_nlink=1 st_uid=503 st_gid=20 st_rdev=0 st_size=0 st_atime=1454006422 st_mtime=1454006422 st_ctime=1454006422 st_birthtime=1454006422 st_blksize=4096 st_blocks=0 st_flags=0
    
[/code]

# そもそも/var/foldersって何？

マニュアルによると、ユーザーごとの一時ファイルとキャッシュだそうです。/var/folders/ _/_
/Tならテンポラリ、Cならキャッシュという使い分けがされている様子。

[code]

    $ man 7 hier
    
         /var/         multi-purpose log, temporary, transient, and spool files
    (中略）
                       folders/   per-user temporary files and caches
    
[/code]

# で、/var/foldersの関係者は誰？

Darwinのソースコードを`grep
/var/folders`すると、[launchctl](http://opensource.apple.com/source/launchd/launchd-842.92.1/support/launchctl.c)起動時に存在しなければ作成して権限など諸々セットするようです。

[code]

        { "/var/folders", 0, 0, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH, S_ISUID | S_ISGID, true },
    
[/code]

そして[dirhelper](http://www.opensource.apple.com/source/system_cmds/system_cmds-541/dirhelper.tproj/dirhelper.c)。これはは/System/Library/LaunchDaemons/com.apple.bsd.dirhelper.plistで指定されている環境変数を参照して、

[code]

        <key>EnvironmentVariables</key>
        <dict>
                <key>CLEAN_FILES_OLDER_THAN_DAYS</key>
                <string>3</string>
        </dict>
    
[/code]

古いファイルを消すことになっている。コイツは怪しい！

# dirhelperを追え

ソースコードで先の環境変数を参照しているところを探す。

[code]

    if (!args->machineBoot) {
            struct timeval now;
            long days = 3;
            const char* str = getenv("CLEAN_FILES_OLDER_THAN_DAYS");
            if (str) {
                days = strtol(str, NULL, 0);
            }
            (void)gettimeofday(&now, NULL);
            for (i = 0; args->dirs[i]; i++)
                asl_log(NULL, NULL, ASL_LEVEL_INFO, "Cleaning %s older than %ld days", args->dirs[i], days);
    
            when = now.tv_sec - (days * 60 * 60 * 24);
        }
    
[/code]

machineBootはdirhelperのコマンドラインに`-machineBoot`オプションを引き渡すとセットされる。起動時はこのオプションを指定するとwhen=0になり無条件削除になるようだ。

さらに見ていくと/var/folders/ _/_
/*ディレクトリを削除しようとしている。最初に書いたtmuxのソケットであれば/var/folders/j7/0w59t0zs7vs1j4r5x0tlywy80000gq/Tがclean_files_older_thanに引き渡されているようだ。コメントではレギュラーファイルだけを消すと書いてある。

[code]

    chdir("/");
    if ((d = opendir("/"))) {
        ...
        // /var/folders/*
        while ((e = readdir(d))) {
            ...
            // /var/folders/*/*
            while ((e2 = readdir(d2))) {
                ...
                for (i = 0; args->dirs[i]; i++) {
                            const char *name = args->dirs[i];
                            snprintf(dirbuf, sizeof(dirbuf),
                                 "%s/%s/%s", path, e2->d_name, name);
                            if (is_directory(dirbuf)) {
                                // at boot time we clean all files,
                                // otherwise only clean regular files.
                                clean_files_older_than(dirbuf, when);
                            }
                        }
    
[/code]

clean_files_older_thanを見てみるとまずディレクトリを開いて、逐次レギュラーファイルか確認して古ければ削除対象。S_ISREGがレギュラーファイルの確認マクロで/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/include/sys/stat.hここにある。

[code]

    fts = fts_open(path_argv, FTS_PHYSICAL | FTS_XDEV, NULL);
    ...
    while ((ent = fts_read(fts))) {
        switch(ent->fts_info) {
            ...
            case FTS_DEFAULT:
                if (S_ISREG(ent->fts_statp->st_mode) &&
                    (ent->fts_statp->st_birthtime < when) &&
                    (ent->fts_statp->st_atime < when)) {
                    ...
                    (void)unlink(ent->fts_path);
    
[/code]

ふむふむ、特に怪しい点はない...?
コマンドラインに`-cleanTemporaryItems`を引き渡すとmachineBootがfalseで実行されるので、試してみる。

[code]

    # atime, birth timeを1/1にセットして３日以上前に作ったことにする
    touch -t 201601010000 /private/var/folders/j7/0w59t0zs7vs1j4r5x0tlywy80000gq/T/tmux-503/default
    
    # dirhelper実行
    /usr/libexec/dirhelper -cleanTemporaryItems
    
    # statしてみる
    stat /private/var/folders/j7/0w59t0zs7vs1j4r5x0tlywy80000gq/T/tmux-503/default
    16777220 51632361 srw-rw---- 1 knoguchi staff 0 0 "Jan  1 00:00:00 2016" "Jan  1 00:00:00 2016" "Jan 29 14:48:47 2016" "Jan  1 00:00:00 2016" 4096 0 0 /private/var/folders/j7/0w59t0zs7vs1j4r5x0tlywy80000gq/T/tmux-503/default
    
[/code]

ちゃんと残ってる。というわけでdirhelperは犯人じゃなかった。スンマセン(^^;;;


CC BY-SA 3.0
2016-01-29T22:06:25.777
21492
2016-01-29T23:56:25.873
2016-01-29T23:56:25.873
7837
7837
21222
answer