夏キャンプ①

はじめに

子どもたちが夏休みに突入しました。パパにとっても忙しい季節ですね。今年はすでに日帰りを含めてキャンプの予定が3つ入っています。最初のキャンプの記録です。

最初のキャンプは家族だけの二泊三日のキャンプでした。

1日目

目的地は、山梨県北杜市です。すんなり行けば2時間半程度の距離ですが、中央道が混むかもと思って、余裕を持って朝9時前に出発。この時点でGoogleマップでは多少の渋滞の情報がでていました。

あきる野ICを過ぎるあたりから、明らかに渋滞に入ってしまった感じがありました。しかし、迂回路もよくわからないので、我慢して進むと八王子JCTに近づくに連れ、どんどん動かなくなります。これはやばい。ほとんど動いているのかいないのかわからないような感じになりました。もう歩くのと変わらないんじゃ?という状況でした。高速に乗る前にトイレは済ましていたものの、3時間近く乗り続けていたため、さすがに限界が近づきつつある状況に。なんとか八王子JCTを過ぎた後、次のPAに入れる気がしなかったので、相模湖東ICでいったん高速を降りることに。

高速を降りてすぐの道(国道20号)も山梨方面はすごく混んでいたので、いちど逆方向に進み、とりあえず最初に見つけたお店に駆け込みました。

トイレの後に、おまんじゅうと野沢菜を買いました。お腹が空いていたこともあり、おまんじゅうを美味しくいただきました。その後、顔はめしていたら、道行く車のドライバーたちに微笑ましく見られて照れました。

ついでにお昼を近くのお蕎麦屋さんでいただいて、気を取り直し出発。相模湖ICから中央道に戻りました。渋滞ではあるものの、八王子付近のような状況ではなく、それなりに進み上野原ICを抜けた後くらいからは割とスムーズに進めるようになりました。良かった。結局予定よりも大幅に遅い16時ころ、宿泊予定のキャンプ場に到着しました。無事に着いて良かったです。

キャンプ場はこちらです。

山の斜面にあるキャンプ場で、とてもすばらしい見晴らしを楽しめました。以前は、ヤギもいたみたいなのですが、今はいなくなってしまったようです。残念。スタッフの方(特におじいさんとおばあさん)がとても親切で、素敵なところでしたよ。夜、炊事場の水がでなくなったのですが、おじいさんがポンプを何かしてくれたらしく、割とすぐに出るようになりました。ありがとうございました。後で伺った話では、サントリーの南アルプスの天然水と同じ井戸水を汲み上げているとのことでした。

オートキャンプ牧場チロルの看板

下の写真は、キャンプ場からの眺めです。残念ながら、雲に隠れていますが、甲斐駒ヶ岳の姿を見ることができます。もう15年ほど前に旅行で行った、スイスのアイガー、メンヒ、ユングフラウを観たときと同じような印象でした。南アルプスと呼ばれる理由が少し分かった気がします。雄大さを感じました。昔の人が山に何か神聖なものを感じたのも分かる気がします。(気がするだけかもですが。。)

キャンプ場からの眺望

この日は、夜ごはんをいただいて、ゆっくり眠りました。

2日目

2日目は川遊びです!キャンプ場のおじいさんに、「精進ヶ滝」に向かう遊歩道にある「一の滝」を紹介してもらいました。道を聞いていても若干心細くなるような道を進むこと15分、駐車場に到着です。そこから、遊歩道を10分ほど歩くと「一の滝」に到着です。途中、フォッサマグナの案内などもあったのですが、子どもたちは興味ないようで、残念ながらスルーしました。

一の滝

写真では小さく見えますが、滝つぼに近づくと結構な圧がありました。滝行って見た目よりツライかもと感じました。水がたいへん透き通るようにきれいで、あまり魚は見つけられませんでした。せっかく来たので、石をいくつか拾ってみたのですが、種類はあまり多くなくて、似たような石ばかりでした。事前に下調べして来るべきでしたが、仕事が忙しかったため、あまり下調べできず残念でした。小さい石を少しいただいて帰ったので、後で調べてみようと思います。

お昼を食べに町に下りて、道の駅でランチにしました。遅い時間だったにもかかわらず結構混んでいました。「おざら」という地域の麺料理をいただこうと思ったのですが、品切れらしく、甲斐駒ヶ岳天丼をいただきました。野菜がとても美味しかったです。

夕飯の食材を買ったり、温泉に入ったりして、キャンプ場に戻りました。2日目の夕飯はパエリアとミネストローネでした。焼き肉よりも落ち着いて食べることができました。

3日目

最終日は、朝起きてテントの撤去などをしました。9時過ぎにキャンプ場を後にしました。とても素敵なところだったので、ちょっと名残惜しい気持ちもありました。

うちでは「アルプスの少女ハイジ」ブームが来ていることもあり、ハイジの村に向かいました。

駐車場が結構混んでいたのですが、敷地が広いこともあり、中はゆったりとしていました。ロッテンマイヤーズカフェで、カップを持って帰ることができるヤギのミルクのアイスクリームを食べてから、ハイジの村の中を散策しました。ヤギにえさをあげたり、おんじの山小屋を観たり。遊具のコーナーで少し遊んで、お昼を食べにペーター館へ向かいました。2日目に食べそこねた「おざら」をいただくことができたので、満足でした。おざらは武蔵野うどんとよく似ていて、地理的にも遠くないのだな、と感じることができました。

帰りは高速もそれほどの渋滞はなく、割とスムーズに進み、予定どおりくらいで帰宅できました。夕飯はハイジの村で買った「白パン」でした。美味しかったです。

まとめ

山梨県は感染対策もしっかりしていて、うちもしっかり気をつけて過ごしました。安心と安全の中でのキャンプを過ごすことができ、楽しい思い出をありがとうございました。山梨県北杜市のみなさんと家族に感謝です。

ちなみに、買って帰ったソーセージが美味しかったので、ふるさと納税しました!

Linuxのメモリ使用状況を把握したい

はじめに

仕事で、担当しているシステムがハングアップしたような事象が起こりました。その際、sarコマンドの結果を見て、「メモリが枯渇している」という説明を受けたのに対して違和感を感じました。

freeでの使用状況は枯渇していないことを示していますし、スワップ使用量が増えるようなこともありませんでした。一方で、自分の説明に説得力をもたせることができなかったので、ソースコードを調べて観ました。

誤り等見つけたらご指摘いただけるとありがたいです。

対象サーバ

Redhat Enterprise Linux 7.7

freeコマンド

freeはRHEL6系とRHEL7系で出力結果が変わって、7系では使用量にキャッシュ等は含まない、その時点で利用可能なメモリ量をavailable で示してくれるようになったと理解しています。

今回確認したソースコードは以下のURLからとってきました。後から気づいたのですが、サーバのfreeのバージョンを調べて該当のソースを読むべきでした。
https://gitlab.com/procps-ng/procps

ざっくりとした構造

freeはコマンドなので、main関数が起点ですね。なので、そこから読みました。

今回、freeをオプション等なしで実行したパターンを想定したので、オプション解析などはすべてスキップします。そのため、重要なのは326行目からのdo while ループです。
見ると分かりますが、353行目以降は、出力のためのコードで、メモリの値を取り出しているのは349行目の meminfo() だけと推測しました。

meminfo関数

定義は、同じディレクトリのsysinfo.c に書かれていました。細かいことは省くと、おそらく754行目からのforループが/proc/meminfo の情報をmemtableの各変数にセットしているように思いました。

  for(;;){
    tail = strchr(head, ':');
    if(!tail) break;
    *tail = '\0';
    if(strlen(head) >= sizeof(namebuf)){
      head = tail+1;
      goto nextline;
    }
    strcpy(namebuf,head);
    found = bsearch(&findme, mem_table, mem_table_count,
        sizeof(mem_table_struct), compare_mem_table_structs
    );
    head = tail+1;
    if(!found) goto nextline;
    *(found->slot) = (unsigned long)strtoull(head,&tail,10);
nextline:
    tail = strchr(head, '\n');
    if(!tail) break;
    head = tail+1;
  }

kb_main_used が kb_main_total から (kb_main_free と kb_main_cached と kb_main_buffers の合計)を引いているのと、kb_main_cached が kb_page_cache と kb_slab_reclaimable の和になるように計算していますが、それ以外は、/proc/meminfoの値をそのまま使っているように思いました。

freeの使用量にはキャッシュやバッファを含まないと結論付けました。

topコマンド

次にtopコマンドを調べました。なんとなくfreeと同じだろうと予測があったので、ざくっとしか読んでいません。

top.cのmain関数から、frame_make() → sysinfo_refresh(int forced) → meminfo() と遷移しているのを追えました。このmeminfoはfreeで読んだものと同じなので、おそらくtopとfreeの出力はだいたい同じだと理解しました。

sarコマンド

さて問題のsarコマンドです。sarの出力は、キャッシュなども使用量に含むので、freeとかよりも使用率が高く出るでしょ、という点を確認したかったのでした。

今回確認したソースコードは以下のURLからとってきました。
https://github.com/sysstat/sysstat

最初、sar.c のmain関数から読み始めたのですが、いろいろ複雑な処理をしているように見えたので、途中で方針を変えて、出力する部分を中心に読むことにしました。どうやらpr_stats.c が出力部分を担当しているようなので、この中の stub_print_memory_stats 関数から読み始めました。

すると、526行目で空きメモリを計算して、534行目でシステムのメモリ総量から空きメモリを引いて、使用量を計算しています。あれれ?これだとfreeと一緒だな、となりちょっと困惑。

その後で、ChangeLogを読んでみると、version11.7.4でfree(1)やtop(1)の出力と合わせるように、計算方法変えましたという記述がありました。
https://github.com/sysstat/sysstat/blob/master/CHANGES#L371

対象のサーバのバージョンを調べると sysstat バージョン 10.1.5 だっったので、該当のバージョンのファイルを調べると、キャッシュとかバッファとか込みで計算しているのが確認できました。
https://github.com/sysstat/sysstat/blob/v10.1.5/pr_stats.c#L443

なお、メモリ使用状況の情報源はfreeとかtopと同様に/proc/meminfo のように思いました。(自信ないです。)

まとめ

バージョン11.7.4より前のsarでは、使用量にキャッシュやバッファを含んでいるので、その使用率を見て「メモリが逼迫している」と言ってはいけないと結論づけました。

Linuxのメモリ管理やキャッシュの仕組みの理解が甘いことを痛感したので、この本を読み直そうと思います。「詳解 システム・パフォーマンス」も読みかけですし、しっかりと理解できるようにしたいと思います。