2016年12月8日

RHEL4 ELS終了&RHEL5 ELS開始 想定問答

------------ 基本的なものはナレッジベースにあります:

ナレッジベース「Red Hat Enterprise Linux 延長ライフサイクルサポートアドオン (ELS) と、サポートのライフサイクルは何を示していますか? 」https://access.redhat.com/ja/node/1190613  -- より抜き書き

Red Hat Enterprise Linux 延長ライフサイクルサポートアドオンとは何ですか?

Red Hat Enterprise Linux (RHEL) 延長ライフサイクルサポートアドオン (ELS) は、ライフサイクルの延長を提供するサービスです。これにより、正規のライフサイクルが終了した後も一定期間、Red Hat Enterprise Linux の特定のメジャーバージョンのサポートを継続して受けることができます。Red Hat Enterprise Linux 延長ライフサイクルサポートアドオンは、Red Hat Enterprise Linux 5 では 2020 年 11 月 30 日まで提供されます。

Red Hat Enterprise Linux 延長ライフサイクルサポートアドオンは、どのバージョンで利用できますか?

ELS は、Red Hat Enterprise Linux 4 では 2017 年 3 月 31 日まで、Red Hat Enterprise Linux 5 では サポート終了( 2017 年 3 月 31 日)後から 2020 年 11 月 30 日まで利用できます。

ELS の詳細情報

以下のドキュメントを参照してください。

延長ライフサイクルのサポートアドオンのパッケージ化と販売方法

ELS はオプションのアドオンサブスクリプションで、有料サポートを一度に 1 年間延長できます。ELS は、単年サブスクリプションだけが利用できます。 一度に複数年分を購入することはできません。ELS アドオンサブスクリプションを購入する前に、既存の Red Hat Enterprise Linux サブスクリプションを購入する必要があります。

ELS が有効なリリースをお持ちのお客様に送られるエラータ通知のアーカイブはどこで取得できますか?

RHEL 4: https://rhn.redhat.com/errata/rhel4els-errata.html

RHEL 5: https://rhn.redhat.com/errata/rhel5els-errata.html

将来の通知を選択する方法は?

https://access.redhat.com/site/security/updates/advisory/ で自由に選択できます。

ELS アドオンは、Red Hat KVM、Red Hat Enterprise Virtualization、またはその他の Red Hat でサポートされているハイパーバイザー上で実行している仮想化ゲストに利用できますか?

はい。延長ライフサイクルサポート期間の Red Hat Enterprise Linux はどのバーションも、正規のライフサイクルと ELS に相当する期間中のホストバーションのゲストとしてサポートされます。ゲストに対する ELS アドオンの価格は、インスタンスベースで決められています。

延長ライフサイクルサポートは、延長期間に何を提供しますか?

このサポートをお持ちのお客様は、Red Hat の公式サポートにアクセスし、通常では利用できない、正規のサポート期間後にリリースされた一部の緊急優先度の不具合修正や、重要な影響を与えるセキュリティ修正の配信を利用できます。各メジャーリリースのすべてのパッケージが、上述の重要な修正サポートを受け取れる資格があるわけではありません。 したがって、詳細については、パッケージ除外リストを参照する必要があります。このサービスを購入されないと、以前にリリースされたエラータ、ドキュメント、およびナレッジベースの情報へのアクセスに限定されます。

除外されるパッケージの詳細については、http://www.redhat.com/rhel/server/extended_lifecycle_support/exclusions/ の一覧を参照してください。

RHEL 5については除外リストではなくinclusion listが公開されました https://access.redhat.com/articles/2901071  (※ 2017-03-29追記)

通常、どのようなコンポーネントまたはパッケージがこのサポート提供に含まれませんか?

デスクトップアプリケーション、Extras チャンネルのコンテンツや、Red Hat Directory Server、Red Hat Satellite、または JBoss Enterprise Middleware などの異なるサブスクリプションの対象である製品は、Red Hat Enterprise Linux ELS の対象外になります。Red Hat Enterprise Linux 4 の場合は、Red Hat Cluster Suite と Global File System が対象外となります。Red Hat には、追加パッケージを除外する権利があります。

RHEL バージョンから別の RHEL バージョンに ELS サブスクリプションを移行することはできますか?

はい。ELS サブスクリプションはバージョン固有のものではありません。

Red Hat ライフサイクルポリシーと、このサービスとの関連性については、どのドキュメントを参照できますか?

詳細については、http://www.redhat.com/security/updates/errata を参照してください。

Extended Life Cycle Phase と Extended Life Cycle Support アドオンとの違いは?

Extended Life Cycle Phase (ELP) は、正規のサポート期間が終了した後の期間を指しています。お客様が正規のサポート期間が終了した後も Red Hat Enterprise Linux 製品を引き続き使用する場合にその利点を享受するには、有効なサブスクリプションが必要となります。

サブスクリプションを購入せずに Red Hat Enterprise Linux 3 を実行できますか?

はい。Red Hat Enterprise Agreement の契約内容により、製品がライフサイクルのどの時期であるかに関わらず、Red Hat Enterprise Linux がインストールされ、実行しているすべてのシステムにはサブスクリプションが必要となります。この要件については常にアグリーメントに含まれていましたが、RHEL 3 に関しては表現に一貫性がありませんでした。したがって、Red Hat は、このポリシーから Red Hat Enterprise Linux 3 を除外しました。ただし、Red Hat Enterprise Linux がインストールされ、実行しているすべてのシステムにサブスクリプションの購入を求める要件については、Red Hat Enterprise Linux 4 と以降のすべてのリリースに適用されます。

------------ 以下は私の作文

Q: RHEL5の通常サポートが2017年3月31日に終了することはいつ決まったのかおしえてください

A: RHEL5は2007年に7年間のライフサイクルを定義してリリースされました。その時点では2014年3月31日までの通常サポートが予定されていました。
その後2012年に通常ライフサイクルが7年から10年に延長され2017年3月31日にて通常サポートが終了するように変更されました。
最新のライフサイクルについては以下をご確認ください。

Q: 現在あるRHEL4を2017年3月31日より後もそのまま利用を継続できますか?

A: 利用すること自体は可能です。ただし以下の点にご注意ください。
  • 修正の提供が行われないソフトウェアを利用することはセキュリティ上・運用上の大きな問題となります。ソフトウェアに問題が発見されても一切修正は提供されませんので、何かソフトウェアの修正が必要な問題が発生した場合には多くの場合現実的な対策がありません。
  • ひきつづきサブスクリプションのご購入が必要である点をご注意ください。

Q: ELSを購入せずに現在あるRHEL5を2017年3月31日より後もそのまま利用を継続できますか?

A: 利用すること自体は可能です。ただし以下の点にご注意ください。
  • 修正の提供が行われないソフトウェアを利用することはセキュリティ上・運用上の大きな問題となります。ソフトウェアに問題が発見されても一切修正は提供されませんので、何かソフトウェアの修正が必要な問題が発生した場合には多くの場合現実的な対策がありません。
  • ひきつづきサブスクリプションのご購入が必要である点をご注意ください。

Q: ELSを購入せずに現在あるRHEL5をそのまま利用して2017年3月31日になるとどうなりますか?

A: お客様の手元では特に何もイベントは起きません。新規に修正が提供されないだけで、現在ご利用のシステムをそのまま利用しつづけるすること自体は可能です。

Q: RHEL5のELSを利用するにはどうしたらいいですか?

A: ELSを利用する具体的な手順については、提供前で未確定につき正確な回答ができません。

おおまかな手順については以下のとおりとなります。
1. subscription-manager list --availableコマンドで、利用可能な製品一覧を確認する。ELSが含まれるサブスクリプションのPool IDを確認する。
2. subscription-manager attach --pool=<2で確認したID> としてサブスクリプションとシステムを対応づける。
3. subscription-manager repos で利用可能なリポジトリ一覧を確認する。この中でELSのパッケージを含むリポジトリ名を確認する。
4. subscription-manager repos --enable="3で確認したリポジトリ名"  としてyum リポジトリを有効化する。

ELS提供後に実際に操作する際にはサポートにてご対応可能です。

Q: RHEL5むけELSでサポートされる範囲を教えてください

A: ELSでは特定のアーキテクチャおよびパッケージがサポート範囲から除外されますが、具体的な内容は現時点では未定です。特定のパッケージやアーキテクチャについてELSでのサポート対象としてほしいというご希望があればサポート窓口までおしらせください。

Q: 私はRHEL5.{0〜10}を使っています。RHEL5のELSの対象が5.11だけだと聞きました。5.11にアップデートしない場合には何が起きますか?

A: お客様の手元では特に何もイベントは起きません。RHEL5についてのあらゆる修正は、現在すでにRHEL5.11むけにのみ提供されています。ELSでもその状態が継続します。レッドハットはお客様に最新のマイナーリリースへのアップデートをお勧めいたします。

例としてRHEL5.6で構築されたシステムがあり、2016年9月28日にRHEL5に対して提供された bind の脆弱性への対応 RHSA-2016:1944-1 (https://rhn.redhat.com/errata/RHSA-2016-1944.html) を適用する場合を考えます。
この場合、提供されたパッケージ bind-9.3.6-25.P1.el5_11.9.i386.rpm は、RHEL5.6時点のbindパッケージではなく RHEL5.11までbindパッケージに行われた全ての修正を累積したパッケージを元にして作成されています。

RHELの過去のマイナーリリースに対してのサポートポリシーについては、ナレッジベース「RHEL の特定リリースに関するサポート状況」 https://access.redhat.com/ja/articles/2710221 をご確認ください。

Q: 私はRHEL5.{0〜10}を使っています。どのような場合でも一切マイナーリリースを変更できません。ELSを買って意味がありますか?

お客様のシステムによっては「RHEL5.6提供からRHEL5.7が出るより前の期間に提供されたパッケージしか利用してはいけない。5.7以降で導入された機能拡張や修正は一切導入できない」というような制限があるかもしれません。このような場合にはELSで提供される修正は全て最新のパッケージ(RHEL5.11)を対象としたものですので、ELS add-onをご購入されても提供パッケージという点では特にメリットはございません。
サポート窓口での根本原因調査の可否について、サービス内容の違いが存在します。

Q: RHEL5.{0〜10}を使っています。ELS利用時に5.11へのアップデートによってアプリケーションの動作に影響が出ないよう努力しているという件について文章化されたものはありますか。

A:
ELSに限らずレッドハットではマイナーバージョンアップによって互換性を壊さないことを非常に高い優先度の目標としております。過去のバージョンで動作したアプリケーションが更新により動作しなくなる場合にはリグレッションとよばれるバグとして扱われます。

互換性維持のポリシー文書が以下から辿れます.
少し古いですが以下に上ページの和訳もあります。

マイナーバージョン間で互換性を維持するという内容は以下の部分です。

-----------------------------------------------------------
Compatibility Within A Major Release

One of the core goals of the Red Hat Enterprise Linux family of
products is to provide a stable, consistent runtime environment for
thirdparty applications. To support this goal, Red Hat seeks to
preserve application binary compatibility, configuration file
compatibility, and data file compatibility for all package updates
issued within a major release. For example, a package update from Red
Hat Enterprise Linux 6.1 to Red Hat Enterprise Linux 6.2, or a package
update that fixes an identified security vulnerability, should not
break the functionality of deployed applications as long as they
adhere to standard Application Binary Interfaces (ABIs).
-----------------------------------------------------------

Q: RHEL for SAP HANAには通常型番のELSが利用できますか?

A: RHEL for SAP HANAには RHEL6と7ベースのものしかないので現在のところELSやそのSAP HANA版は存在していません。

Q: RHEL for SAP Applicationsには通常型番のELSが利用できますか?

A: RHEL for SAPにはELSは存在していません。

Q: RHEL for HPC, RHEL WorkstationにELSはありますか?

A: RHEL Server以外にはELSは提供されません

Q: RHEL 4 や RHEL 5 を使っていく上でELS以外に気にするべきことがありますか?

A: はい、あります。現在up2dateやyumで更新をおこなうために利用されているRed Hat Network Classic のサービス終了が2017年7月31日に近づいています。
RHEL4には(Red Hat Satellite 5を購入する以外に)対応できる方法がありません。RHEL5ではRed Hat Subscription Management(RHSM)とよばれる新しい方式で登録しなおすことで、引き続きyumをつかった更新が可能になります。RHSMを利用することができるのはRHEL5.7以降のバージョンです。

RHN ClassicからRHSMへの移行については以下をご確認ください。    


Q: 過去にRHEL4のELSで修正された重大なセキュリティ上の問題の実績をおしえてください

A:

完全な一覧は以下でご確認ください: https://rhn.redhat.com/errata/rhel4els-errata.html

Q: RHEL4やRHEL5からRHEL7への更新方法をおしえてください

A: まず、レッドハットからサポートされるアップグレード方法は存在しません。メジャーバージョン間のin-place upgradeは「RHEL6からRHEL7」という組み合わせで初めてサポートされました。

基本的な方針としては、現行のRHEL4やRHEL5のシステムと同等のシステムを別にRHEL7(または他社製品やサービス)をベースとして作成し、現行のシステムから新しいシステムに移行することをお勧めします。

パートナー各社にて移行支援のサービスなどが提供されています。詳しくはhttps://jp-redhat.com/rhel4-eol/ をご確認ください。

Q: RHEL4やRHEL5からRHEL7の更新差分をおしえてください

A: 各種資料がございます。

Q: Java6(RHバンドルのもの)を利用しているが、ELSの範囲にJavaも入るのでしょうか?

A: OpenJDKのサポート期間は通常のパッケージとことなり個別に設定されています(OpenJDKのみで他のソフトウェアにはこのような例外はないです)
をごらんください。OpenJDK 6 (1.6)のサポートは December 2016 で終了します。

ELSにOpenJDK7はふくまれるかと思われます(制限が明確になっていませんが過去の事例から推定しています)。しかしOpenJDK 6については上記のとおり今年の年末でサポートが終了しますのでELSで新規の修正が提供されることはありません。

Q:「ELS特設ページ(http://jp-redhat.com/rhel4-eol/)」はいつ作成され公表されたのでしょうか?

A: 2016年9月30日に公開いたしました。

2016年12月3日

元号の処理がどこで行われているか探してみる

この記事はLinux Advent Calendar 2016の4日目の記事です。

わりとマイナーな機能ですが、linuxでja_JP.utf8のlocaleで以下のようにコマンドを叩くと、元号をちゃんと処理して表示してくれたりします。
$ LC_TIME=C date +'%EY'
2016
$ LC_TIME=ja_JP.utf8 date +'%EY'
平成28年
ちょっと前に国の象徴のおじいさん(82)が「退位したい」みたいなこと言ってましたし、いいかげん年なのでしんどかろうと思います。法律の要件とかはわかりませんが退位が行われれば元号が変わるでしょうから、庶民の我々も少なくともこのコードを修正しないといけないわけです。 

これはどこからきているのかを探りましょう。
 $ ldd `which date`
    linux-vdso.so.1 (0x00007ffd14593000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fea550ed000)
    /lib64/ld-linux-x86-64.so.2 (0x000056070c37e000)
シンプル。linux kernel, dateコマンドの中身, libcのどれかに絞られました。
kernelはありえないので候補から外します。心配な人はstraceでもして安心してください。
date本体もないと思っているのですが念の為確認します。
$ LC_TIME=ja_JP.utf8 ltrace date +'%EY'
(中略)
strftime(" \345\271\263\346\210\22028\345\271\264", 1024, " %EY", 0x7f8f5c1464a0)                                                   = 12
fwrite("\345\271\263\346\210\22028\345\271\264", 11, 1, 0x7f8f5c142600)                                                             = 1
(以下略)
libcのstrftimeがやっているようです。man 3 strftime を見ます。
(ー略ー)
        %E     Modifier: use alternative format, see below. (SU)
(ー略ー)
(SU) The Single UNIX Specification mentions %Ec, %EC, %Ex, %EX, 
       %Ey,  %EY,  %Od,  %Oe, %OH, %OI, %Om, %OM, %OS, %Ou,
       %OU, %OV, %Ow, %OW, %Oy, where the effect of the O modifier
       is to use alternative  numeric  symbols  (say,  roman numerals),  and 
       that  of  the  E modifier is to use a locale-dependent alternative
       representation.
あ、Single UNIX Specificationで決まってたのか。ってことはきっとAppleのOS Xとかでもつかえるんだろうな。。持ってないので知らないけど。

さて、libcでlocale-dependentだということがわかりました。ソースコードとってきましょう。
$ find glibc-2.24 |grep ja
./localedata/locales/ja_JP
./benchtests/strcoll-inputs/lorem_ipsum#ja_JP.UTF-8
./po/ja.po
./debian/po/ja.po
ということで以下のファイルに含まれてそうです。
glibc-2.24/localedata/locales/ja_JP
いかにもそれらしい「era」というエントリがあります。きっとこれなんですが……

era     "<U002B><U003A><U0032><U003A><U0031><U0039><U0039><U0030><U002F><U0030><U0031><U002F><U0030><U0031><U003A><U002B><U002A><U003A><U5E73><U6210><U003A><U0025><U0045><U0043><U0025><U0045><U0079><U5E74>";/
        "<U002B><U003A><U0031><U003A><U0031><U0039><U0038><U0039><U002F><U0030><U0031><U002F><U0030><U0038><U003A><U0031><U0039><U0038><U0039><U002F><U0031><U0032><U002F><U0033><U0031><U003A><U5E73><U6210><U003A><U0025><U0045><U0043><U5143><U5E74>";/
        "<U002B><U003A><U0032><U003A><U0031><U0039><U0032><U0037><U002F><U0030><U0031><U002F><U0030><U0031><U003A><U0031><U0039><U0038><U0039><U002F><U0030><U0031><U002F><U0030><U0037><U003A><U662D><U548C><U003A><U0025><U0045><U0043><U0025><U0045><U0079><U5E74>";/
        "<U002B><U003A><U0031><U003A><U0031><U0039><U0032><U0036><U002F><U0031><U0032><U002F><U0032><U0035><U003A><U0031><U0039><U0032><U0036><U002F><U0031><U0032><U002F><U0033><U0031><U003A><U662D><U548C><U003A><U0025><U0045><U0043><U5143><U5E74>";/
        "<U002B><U003A><U0032><U003A><U0031><U0039><U0031><U0033><U002F><U0030><U0031><U002F><U0030><U0031><U003A><U0031><U0039><U0032><U0036><U002F><U0031><U0032><U002F><U0032><U0034><U003A><U5927><U6B63><U003A><U0025><U0045><U0043><U0025><U0045><U0079><U5E74>";/
        "<U002B><U003A><U0032><U003A><U0031><U0039><U0031><U0032><U002F><U0030><U0037><U002F><U0033><U0030><U003A><U0031><U0039><U0031><U0032><U002F><U0031><U0032><U002F><U0033><U0031><U003A><U5927><U6B63><U003A><U0025><U0045><U0043><U5143><U5E74>";/
        "<U002B><U003A><U0036><U003A><U0031><U0038><U0037><U0033><U002F><U0030><U0031><U002F><U0030><U0031><U003A><U0031><U0039><U0031><U0032><U002F><U0030><U0037><U002F><U0032><U0039><U003A><U660E><U6CBB><U003A><U0025><U0045><U0043><U0025><U0045><U0079><U5E74>";/
        "<U002B><U003A><U0031><U003A><U0030><U0030><U0030><U0031><U002F><U0030><U0031><U002F><U0030><U0031><U003A><U0031><U0038><U0037><U0032><U002F><U0031><U0032><U002F><U0033><U0031><U003A><U897F><U66A6><U003A><U0025><U0045><U0043><U0025><U0045><U0079><U5E74>";/
        "<U002B><U003A><U0031><U003A><U002D><U0030><U0030><U0030><U0031><U002F><U0031><U0032><U002F><U0033><U0031><U003A><U002D><U002A><U003A><U7D00><U5143><U524D><U003A><U0025><U0045><U0043><U0025><U0045><U0079><U5E74>"

ソースコードのくせに謎エンコードされてて読めないよ! >_<

きっとunicodeの表が頭に全部はいっててデコードできる人は心の目で読めるんですがそんなハンドアセンブルの100倍くらいしんどそうなスキルは持っていません。ちなみにハンドアセンブルも表がないとできません。

しょうがないので<Uxxxx>; みたいなのが来たらxxxx部分にあたるunicode文字に置換する使い捨てスクリプトをシコシコ書きます。

import os, re

def main():
    for line in file('ja_JP'):
        out = ""
        while 1:
            m = re.search('(<U([0-9a-fA-F]+)>;?)', line)
            if m:
                out = out + line[:m.start()] + unichr(int(m.group(2), base=16))
                line = line[m.end():]
            else:
                out = out + line
                break
        print out.encode('utf8'),

main()
 これを実行すると.. でました
era     "+:2:1990/01/01:+*:平成:%EC%Ey年";/
        "+:1:1989/01/08:1989/12/31:平成:%EC元年";/
        "+:2:1927/01/01:1989/01/07:昭和:%EC%Ey年";/
        "+:1:1926/12/25:1926/12/31:昭和:%EC元年";/
        "+:2:1913/01/01:1926/12/24:大正:%EC%Ey年";/
        "+:2:1912/07/30:1912/12/31:大正:%EC元年";/
        "+:6:1873/01/01:1912/07/29:明治:%EC%Ey年";/
        "+:1:0001/01/01:1872/12/31:西暦:%EC%Ey年";/
        "+:1:-0001/12/31:-*:紀元前:%EC%Ey年"
元年だけ別の行になってるんですね…… 明治は6年からなので旧暦のごちゃっとしたあたりは気にしないと。

というわけで元号の場所はわかりました。おじいさんが退位したらここを直してみんなでglibcをアップデートしよう。

ではでは。


追記

「別ファイルになってないの?」と聞かれたので追記 。
たとえば /usr/share/i18n/locales/ja_JP のように別ファイルになっていて、localedefを使うことで独自のlocaleを定義することもできる。
でもlocaleの設定がおこなわれるのはプロセスの最初のほうで setlocale() されるタイミングだから結局元号の処理更新を反映したいプロセスの再起動が必要なのは変わらないのでした……。

2016年9月27日

srad.slack.com 利用案内


スラドのIRCをもうちょっとモバイルにやさしいところでやりたい(?)的なことでslackに挑戦中。

参加方法について

Google Formの参加用フォームにメールアドレスを入れると参加できます: https://goo.gl/forms/SLWmqyldlgvbvNGN2
※入力したメールアドレスは参加者に見えてしまうので気になる人は捨てフリーメール使ってください

チャンネルについて

メインで使うのは 
 #announce アナウンス用チャンネル
 #random 雑談チャンネル
 #relay-test IRCnetの#すらっしゅどっと と相互リレーしているチャンネル
他のチャンネルを作るのは自由にどうぞ。

クライアントについて

slackにはWebやslack専用クライアントを利用して接続してもいいけどIRCクライアントやXMPPに対応した汎用のメッセンジャーアプリも使えます。

IRC, XMPPクライアントからの繋ぎ方は https://srad.slack.com/account/gateways
IRC用とXMPP用の設定と専用パスワードとかが各個人用に生成されて記載されてる。
IRCの文字コードはUTF-8

2016年6月3日

Red Hat SatelliteとRed Hat Insights は何が違うか

全然違うのだけれど混乱してる人がいたので……

何が目的か:
・Red Hat Satellite → パッケージと設定の管理を中心としたライフサイクル管理システム
・Red Hat Insights → プロアクティブな問題対応を目的としたレポート生成システム

何ができるか:
・Satellite → パッケージと設定の配布を含む実際の操作。auditを考慮したロギングなど履歴の管理。
・Insights → レポートをだすだけ。現在の最新状況だけが見える。

何を見るか:
・Satellite → 基本的にパッケージと設定のバージョンを管理
・Insights → パッケージのバージョンだけでなくディスク残容量や設定内容、ファームウェアやCPUの型番なども見る

どこで動くか
・Satellite → オンプレ
・Insights → SaaS

ライセンス
・Satellite → OSS
・Insights → 解析エンジンはSaaSなのでそもそも配布していない

2016年2月15日

OOM Killerにであったら何をするべきか?

OOM killerで大事なプロセスが殺される。困りますね。。 google で OOM Killerと入力すると 「無効」とか補完されます。しかしどうするのが良いのか、あまりよく説明されている記事がみあたらなかったので自分の考えをメモしておきます。

OOM Killer の目的は何か?

まずは何故OOM Killerが発生しているのかについて、ざっくりイメージをつかみましょう。linux kernelはプロセスからの「メモリくれ」という要求に対してたぶん足りそうだという場合に「OK」といって渡します。実際のメモリ割り当てはアクセスが発生するタイミングまで遅延させます。これを遅延アロケーションといい、だいたいにおいてうまく動きます。ただし必ずうまくいくと保証されているわけではないので破綻することがあります。

OOM Killerはこの遅延アロケーションが破綻しそうなときに、適当にプロセスを殺すことでメモリを開放してやろう、そうやってメモリを開けて動作を継続したほうが全滅するよりはマシだろうという緩和策です。
「半端に動くんじゃなくて死んでくれた方がいいです」という場合には、 sysctl で以下のように設定して、OOM Killerを動作させるのではなくカーネルをpanicさせることができます。
vm.panic_on_oom = 1
OOM Killerは破綻したときの緩和策だったので、OOM Killerを止めて破綻をより直接的にシステム停止に繋げています。きっちり死んでくれるのでOOM Killerよりわかりやすいですね。

何故OOM Killerが発生しているかを調査する

できればOOM Killerを避けたいですが、避けるためには何故OOM Killerが発生しているのかを調査する必要があります。これをおこなうためには、まずさきほどのpanic_on_oom設定をおこないます。

加えてpanic時にメモリダンプを取得する仕組み(いろいろありますがRHELやFedoraだとkdump)を仕込みましょう。これでpanicしたときのダンプを調査することで、多くの場合OOM Killerの発生原因を推定できます。

RHELであれば「カーネルクラッシュダンプガイド」にダンプの設定と解析ツールについての解説があります。

https://access.redhat.com/documentation/ja-JP/Red_Hat_Enterprise_Linux/7/html/Kernel_Crash_Dump_Guide/index.html

対処その1. アプリケーションに対してストレージを速くする

メモリにはざっくり3種類あります。
  • ファイルやブロックデバイスをバックエンドとするfile mapped page
  • バックエンドはなく、必要になるとswap領域にバックエンドを作るanonymous page
  • 特に使われていないfree
linuxでは基本的にはディスクやファイル、swap領域に対するキャッシュとしてメモリは扱われます。そうではなくメモリ上に必ず維持されるようにする仕組み(mlock)もありますがそれが気になる人はこんなblog読まなくて大丈夫なはずなので割愛します。

アプリケーションが何かしらストレージへ書きだすとき、まずは書き出すべき情報をメモリ上に保持します。このようなメモリをDirtyと呼びます。
Dirtyなメモリはストレージへの反映による永続化が必要な情報を持っているので、ストレージに書きだしをおこなうまでは消せません。恒常的にストレージの負荷が高いとDirtyなメモリがどんどん増えていきます。

さきほどのメモリダンプを解析ツールに食わせると、dirtyなページが多くなっているのですぐわかります。このような場合、対処としては以下があります
  • ストレージの障害をチェックする。何かデグレードが発生して遅くなっている可能性を排除しましょう。 高いストレージだとストレージ側で統計情報がとれます。これも確認しましょう。
  • ストレージを増強する。根本対策です。
  • アプリケーションの書きだしを遅くする。dirtyなページを書きだすプロセスの実行を遅くします。
    アプリケーションがdirect I/Oとよばれる手法を利用している場合に限られますが、cgroupで制限することができます。systemdのunit内にBlockIOWriteBandWidth=で利用する帯域幅の上限を設定することができます。指定された上限にを越えて書きこみをしようとするとアプリケーションは一時停止します。
    https://access.redhat.com/documentation/ja-JP/Red_Hat_Enterprise_Linux/7/html/Resource_Management_Guide/sec-Modifying_Control_Groups.html#sec-Modifying_Unit_Files
  • 書きだしを遅くする(その2)。共有ストレージを持つクラスタ構成の場合、ストレージに対しての計算ノード数を減らします。
  • 書きだしを遅くする(その3)。メモリがでかいときはvm.dirty_ratioを変更したりすると良いケースもあります。これはdirtyなページが何パーセント溜まったら、新規に書きだしを行おうとしているプロセスを一時停止するかの指標です。
  • メモリを増やす。ストレージへの負荷が適度に増減する場合、次に負荷が減るまでなんとか持てばいいので、その余裕がある時間をかせぎます。場合によりますが、メモリがとても少ない場合をのぞいてあまり有効な対応ではありません。

対処その2. 積極的にswapさせる

利用しているアプリケーションのメモリ管理があまりうまくできていないと、実際の利用はそれほどでもないのにanonymousとして確保するメモリ量がじわじわ増大していきます。このような場合、アプリケーションによりますがswapを積極的に行うことも一つの手です。

 sysctlで、以下のようにするとRHELではfile mappedと同じ程度の基準でanonymousメモリをswapに吐きだします。
vm.swappiness = 100
 ゆっくりとしたメモリ消費増加への対策としてはswapはそれなりに有効です。もちろんswapがあふれると破綻しますから適宜swap使用量を監視する必要があります。

swapについてはとにかく発生させたくないと、拒否反応を示す人がいます。
「swapで遅くなる」という現象のほとんどは、1) anonymous pageを一旦swapへ書きだしてメモリから除いたあと、2) もう一度アクセスしようとしたときに発生します。
この2の動作をswap inと呼びます。vmstatだとsiと書いてある欄で表示されます。これが継続的に発生する場合、swapによるパフォーマンス劣化が発生していると考えてまず間違いありません。この場合、アプリケーションのメモリ利用パターンがswapの積極的な利用に向いていません。

swap inによるパフォーマンス劣化が継続的ではなくちょこちょこ程度で起きる場合、主要ではないアプリケーションがswap outしている可能性が考えられます。この影響を緩和したい場合「メモリを増設するのは高いのでswap領域をSSDにしてしのぐ」というアイデアには一考の余地があります。

利用しているアプリケーションに、ある程度予想がつくゆっくりとしたメモリ利用の増加がある場合にはswapと適当な頻度でのサービス再起動の組み合わせは有効です。ただしswap inが継続的に発生する場合はswapによる緩和策はあまり向いていません。

対処その3. アプリケーションのメモリ消費を制限する

swapが向いていないアプリや、メモリの大量消費が突発的に発生するアプリケーションもあります。後者は70%くらいバグな気がしますが、残念ながらそういうアプリケーションでも使わないといけないシチュエーションはあります。

そのような場合、cgroupを利用してアプリケーションのメモリ消費を制限することが有効です。systemdを利用しているディストリビューションでは、systemdがcgroupの設定を管理します。 RHELであれば以下に和訳ドキュメントがあるので読みましょう。
https://access.redhat.com/documentation/ja-JP/Red_Hat_Enterprise_Linux/7/html/Resource_Management_Guide/index.html 

てっとり早く答えにたどりつきたい人は以下ページを見て、MemoryLimitを設定しましょう。 これで、指定したサービスの消費メモリを制限できます。制限に触れるとOOM Killerが動作しますが、このcgroup内のプロセスだけを殺しますのでサービスだけが死にます。周りにあまり迷惑がかからないのはいいですね。
https://access.redhat.com/documentation/ja-JP/Red_Hat_Enterprise_Linux/7/html/Resource_Management_Guide/sec-Modifying_Control_Groups.html#sec-Setting_Parameters_from_the_Command-Line_Interface


これに加えて、サービス停止時の再起動設定もsystemdのunitに書くことができます。ただし自動再起動の設定をするのは「大量消費→OOM Killer→再起動→大量消費→……」 のタイトなループに陥る可能性が排除できている場合に限定しましょう。このループが数日や数ヶ月など、許容できる場合なら
Restart=yes  
とunitに書くことでsystemdが再起動の面倒もみてくれます。

対処その4. メモリを増やす 

「さっきあまり有効でないって書いてたのに!?」と思うかもしれませんが、アプリケーションが必要とするメモリ量の見積りが単純に低すぎる場合があります。

dirtyなページがあまり多いわけでもなく、swapさせてもswap inが発生しつづける場合は、アプリケーションが必要としている量のメモリを用意できていない場合が考えられます。可能であればアプリケーションの処理を勘案して必要サイズを推定しましょう。
メモリ使用量を調査するためのツールについては以下ドキュメントに紹介されています。
https://access.redhat.com/documentation/ja-JP/Red_Hat_Enterprise_Linux/7/html/Performance_Tuning_Guide/sect-Red_Hat_Enterprise_Linux-Performance_Tuning_Guide-Memory-Monitoring_and_diagnosing_performance_problems.html

メモリを大量消費するアプリケーションには、自身がどれくらいのメモリを消費するか調整するための設定が用意されていることが多いです。これを増減させて消費メモリ量の増減とパフォーマンスへの影響を観察すると落としどころがみつかるかもしれません。

HPCなどでは「でかいデータを扱うからでかいメモリが要るんだよ!」 みたいなケースもあります。こういうときは金と物理(メモリ)の力で殴るしかないです。

対処ではない: oom_score_adj 

OOM killerの調整ということで検索すると名前がよくでてくるoom_score_adjですが、特定プロセスをOOM killerの対象外にしたり対象になる確率を上げたり下げたりということができます。
しかしOOM killerが発生した原因であるメモリ逼迫については何も改善しないので、あまり意味はありません。

特定のプロセスが死ななければ他がランダムに殺されても大丈夫でしょうか? 普通はランダムに殺されても問題ないというプロセスはほぼ無いはずです。不要なプロセスが存在するなら、特にscoreとかいじる前に単純に起動しないようにする方がいくらかマシです。

oom_score_adjを活用できるシチュエーションをどうにか考えだしてみると、
1)  大事なプロセスに関連したものについてはOOM killerの対象外にしておく
2)  メモリ逼迫を検出するためのカナリア役として優先的に殺されるプロセス(無意味にメモリを確保する)を仕込んでこれを監視に利用
3) カナリア役が殺され次第できるだけ正常な終了手順で大事なプロセスを終了

というような仕組みを作り込む時くらいではないかと思います。OOM killerが動きだしたあとに大容量メモリを確保しているであろう大事なプロセスの終了処理がうまく動くかは非常に疑問ですが、終了処理が追加メモリをあまり使わず動作する場合には使えそうです。

まれに有効: vm.overcommit_memory設定によるovercommitの禁止

vm.overcommit_memoryによるovercommitの禁止は「ほとんど全てのアプリケーションが必要より多くメモリをリクエストしてくる」ため、非常に効率は悪くなりますがメモリ確保の要求量(割り当て量ではない)が特定の値を越えるとOOM Killerによるプロセスの終了が発生します。早く失敗することで延々処理したあと死ぬよりはマシなのではないか、という考え方ですね。

特定のアプリケーションがメモリのほとんどを占め、必要分ギリギリしか要求しないことが分かっている、なおかつ他のプロセスはほぼ動作していない。という前提が満たせる場合はいいのですが、なかなか厳しいです。実際のところアプリケーションによっては通常の利用時に消費されるメモリ量の数十倍から100倍くらいのメモリを要求することもごく普通にあります。極めて特殊な、アプリケーションを選ぶ対策と言ってよいかと思います。

おまけ

いろいろいじりたい人にはRHELのドキュメント「パフォーマンスチューニングガイド」がまずはおすすめ。
https://access.redhat.com/documentation/ja-JP/Red_Hat_Enterprise_Linux/7/html/Performance_Tuning_Guide/chap-Red_Hat_Enterprise_Linux-Performance_Tuning_Guide-Performance_Features_in_RednbspHat_EnterprisenbspLinuxnbsp7.html


2016年2月2日

logitechのマウスから謎のイベントが発生してハマった話と暫定的な対策

今にいたるも正確な原因はつかめていないのだが、同じようなハマり方をする人がいるかもしれないのでメモ。

問題


1. 自宅および会社のX環境で、logitech(logicool)の M705, Performance MXを楽しく使っていたのだが、不定期にフォーカスの動き方がおかしくなる現象に見舞われた。

2. 現象が発生するとキーボードのフォーカスはAlt+tabなどで他のwindowに移動できるが、マウスのフォーカスはある1つのwindowに固定されたまま他のwindowに移動できない。

3. マウスの電源オフするかunifiedレシーバを抜くと現象がおさまって普通に動作する。

4. はじめはランダムに発生していたが電源いれるといきなり発生するようになった。

さて、現在のところ原因追及はできていない。だがXよりも下位の、usbhid以下のどこかがおかしいようだ。原因追及は4のほぼ常時発生するようになってから進捗した。

再現&観測手順


1. 他のマウスとM705を2本接続し、M705の電源を一旦切った状態で操作をはじめる

2. xev起動( xev | grep -A3 Button )

3. もうひとつのマウスで xevのwindow上にカーソルを持っていったのちM705の電源を入れると以下のようなイベント表示があらわれる。

ButtonPress event, serial 33, synthetic NO, window 0x3a00001,
    root 0x2da, subw 0x0, time 520218479, (136,90), root:(1337,150),
    state 0x0, button 20, same_screen YES
存在しない20番目のボタンが押されたというイベントだ。そのためこのウィンドウ内でマウスのドラッグがはじまった状態になり、マウスのフォーカスが失われない。(観察した範囲では20番ボタンに限らず2番ボタンなどのイベントも発生する)

なおなんらかの方法(電源offやunified receiverの接続断)で接続を切ると対応するButtonRelease eventが発生してドラッグ状態が解除される。おそらくこれはxinputのどこかの終了処理が行っているのだろう。発生したイベントに対応するボタンがあればそれをクリックすることでもButtonReleaseイベントが発生するので対策になる。

現象が再現している状態でxinputコマンドによりマウスの状態を見ると20番ボタンがdownになっていることでも確認できる。
$ xinput query-state 11
2 classes :
ButtonClass
    button[1]=up
    button[2]=up
    button[3]=up
    button[4]=up
    button[5]=up
    button[6]=up
    button[7]=up
    button[8]=up
    button[9]=up
    button[10]=up
    button[11]=up
    button[12]=up
    button[13]=up
    button[14]=up
    button[15]=up
    button[16]=up
    button[17]=up
    button[18]=up
    button[19]=up
    button[20]=down
    button[21]=up
    button[22]=up
    button[23]=up
    button[24]=up
ValuatorClass Mode=Relative Proximity=In
    valuator[0]=1622
    valuator[1]=1635
    valuator[2]=0
    valuator[3]=-3

暫定的な対策

solaarにより Side Scrolling を有効にすることでこの現象が発生しなくなった。
正直なところ原因をはっきりさせていないので、これで対策になっているのかもわからないのだが、とりあえず動いている。

 暫定的な対策その2(??)

 もろもろ未確認だが、solaarがデバイス検出時行っている初期化処理で何か起きてるような気がする。solaarを全く動作させずに利用していると対策になるかもしれない。

solaarは過去1年くらい平和に動いていたのと、新しく買ったマウスではsolaarで問題が発生しないので、マウスの中の何かしらの状態とsolaarがリバースエンジニアリングして喋ってるlogitech独自プロトコルのあわせ技で問題が発生している可能性が疑われる。。

実験:
  • マウス接続 → solaar起動 → ボタン20down発生 → solaar終了→down継続→マウスoff/on→ボタン20down発生せず
  • solaar起動 → マウス接続 → ボタン20down発生 → マウスoff/on→ボタン20down再度発生

根本的(?)な対策

logicoolのサポートに連絡して押していないボタンについて押したような動作があると相談したところ、故障が疑わしいということで対応していただけました。保証期間内だと相談するといいかもしれません。

 おそらく関連するbugzilla

https://bugs.freedesktop.org/show_bug.cgi?id=77037
closeされちゃってるけどたぶんこの問題と似た話。「xinputで状態確認するとよさそう。俺んとこはドラッグ中のような状態になってた」とコメントを書くためにアカウントを取ろうとしたら失敗したのでメールで申請中……。