2010年10月1日金曜日

snmpd.conf proc行でプロセスのフルパスを参照させる

【目的】
"/etc/snmp/snmpd.conf"ファイル内の"proc"行で、
監視するプロセス名をフルパスを参照できるようにする。

ディフォルトではsnmpは'/proc/プロセスID/status' 内からプロセス名を参照する。
ps -e の結果としても現れる。
しかし、このファイル内のプロセス名はパスが表示されない。

そこで、参照先を'/proc/プロセスID/cmdline'に変更する。

/etc/snmp/snmpd.conf 内にて、
proc httpd ← ディフォルト
これを
proc /usr/sbin/httpd ←フルパスで参照できるようにする。


変更点は一箇所である。
net-snmpのヘッダファイル'linux.h'にて、コメントアウトされている下記をコメントインするだけである。
#define USE_PROC_CMDLINE

ただし、RPMパッケージによって管理したいため、次の方針をとることにする。
src.rpmファイルからパッチを適用した、rpmのパッケージを自作する。
src.rpmファイルとはソースコードや依存関係などを記述したspecファイルが
まとまったものである。
これを元に作成するのが手軽でいいだろう


【手順概要】
src.rpmに関しての知識が疎い場合もあるだろうか。
まずは
(1) src.rpmファイルから通常のrpmのパッケージを作る

上を理解したうえで、
(2) パッチを適用した、rpmのパッケージを自作する



【(1) src.rpmファイルから通常のrpmパッケージを作る】
◆ SRPMファイルのダウンロード
$ cd $HOME

$ wget "http://どこか/i386/SRPM/net-snmp-*.*.*.src.rpm"

プロキシを経由するなら
$ http_proxy=x.x.x.x:8080 \
wget "http://どこか/i386/SRPM/net-snmp-*.*.*.src.rpm"


◆ rpmbuild の実行権限の付与
rpmbuildを利用するのだが、rootでは実行したくない。
しかし、一般ユーザーが書き込み権限を持っていないディレクトリに
ファイルを保存しようとするため、ツールは実行できない。
そこで、rpmbuild が書き込むディレクトリ先を変更する。

マクロの設定をする。
$ echo "%_topdir $HOME/rpm" > $HOME/.rpmmacros

各種ディレクトリを作成する。
$ mkdir -p $HOME/rpm/{BUILD,RPMS,SOURCES,SPECS,SRPMS}


◆ rpmパッケージ作成に必要なファイルのインストール
$ rpm -ivh net-snmp-*.*.*.src.rpm
下記エラーは無視してよい。
1:net-snmp            
警告: ユーザ mockbuild は存在しません - root を使用します
警告: グループ mockbuild は存在しません - root を使用します

$ cd rpm

ソースコード、パッチなどのrpmパッケージの生成に必要なファイルが置かれる。
$ ls SOURCES/

RPMパッケージを作るための設定ファイルが置かれる。
$ ls SPECS/
net-snmp.spec


◆ バイナリパッケージとソースパッケージのビルド
"-ba"オプションがバイナリパッケージ(RPMS)とソースパッケージ(SRPMS)を作成するためのオプションである。
ビルドにはスペックファイルが必要である。
$ rpmbuild -ba ./SPECS/net-snmp.spec

ビルドに必要なソースファイルなどは下記に保存される。
$ ls BUILD/

SRPMファイルは下記に保存される。
$ ls SRPMS/
net-snmp-*.*.*.src.rpm

そして、下記に目的のRPMのバイナリができる。
$ ls $HOME/rpm/RPMS/i386/
net-snmp-*.*.*.i386.rpm
net-snmp-debuginfo-*.*.*.i386.
net-snmp-devel-*.*.*.i386.rpm
net-snmp-libs-*.*.*.i386.rpm
net-snmp-perl-*.*.*.i386.rpm
net-snmp-utils-*.*.*.i386.rpm


◆ インストール
$ cd $HOME/rpm/RPMS/i386/

$ su 

必要なパッケージをインストールする。
# rpm -ivh net-snmp-*.*.*.i386.rpm \
net-snmp-libs-*.*.*.i386.rpm

インストールされたことを確認する。
# rpm -q net-snmp net-snmp-libs
net-snmp-*.*.*
net-snmp-libs-*.*.*



【(2) パッチを適用したrpmのパッケージを自作する】
◆ パッチの作成
先程の続きから、
一般ユーザに戻る。
# exit
$ cd $HOME/rpm/BUILD/

変更をするファイルをバックアップしておく。
$ cp net-snmp-*.*.*/include/net-snmp/system/linux.h \
net-snmp-*.*.*/include/net-snmp/system/linux.h.default

ファイルを書き換える。
今回は"/etc/snmp/snmpd.conf"ファイル内の"proc"行でフルパスを参照できるようにするための変更である。
$ vi net-snmp-*.*.*/include/net-snmp/system/linux.h
下記を有効にする。
#define USE_PROC_CMDLINE

パッチを作成する。
$ diff -up net-snmp-*.*.*/include/net-snmp/system/linux.h.default \
net-snmp-*.*.*/include/net-snmp/system/linux.h \
> ../SOURCES/net-snmp-*.*.*-proc_fullname.patch

$ cd ../


◆ スペックファイルの編集
パッチを適用するためにスペックファイルを変更する。
$ cd SPECS

$ cp net-snmp.spec net-snmp.spec.default

$ vi net-snmp.spec

(変更箇所)
変更前
Release: 9%{?dist}.1
Epoch: 1

変更後
Release: 9%{?dist}.1.org.1
Epoch: 2

(追記箇所)
'PatchXXX:'行の最後に、下のフォーマーットで先ほど作成したパッチ名を記載する。
Patch100: net-snmp-*.*.*-proc_fullname.patch

'%patchXXX'行の最後にパッチコマンドオプションを記載する。
%patch100 -p1 -b .proc_fullname

変更履歴を'%changelog'配下に記載する。

* Thu Sep 30 2010 Name - *.*.*.org.1
- define USE_PROC_CMDLINE


◆ バイナリパッケージとソースパッケージのビルド
パッチを適用した、バイナリパッケージとソースパッケージをビルドする。
$ rpmbuild -ba net-snmp.spec

$ cd ../

パッチを適用したRPMバイナリパッケージができている。
$ ls RPMS/i386
net-snmp-*.*.*.org.1.i386.rpm
net-snmp-debuginfo-*.*.*.org.1.i386.rpm
net-snmp-devel-*.*.*.org.1.i386.rpm
net-snmp-libs-*.*.*.org.1.i386.rpm
net-snmp-perl-*.*.*.org.1.i386.rpm
net-snmp-utils-*.*.*.org.1.i386.rpm
※64bitOSでは RPSM/x86_64 配下になる
 またパッケージ名も異なる


◆ インストール
$ cd RPMS/i386

$ su 

パッチ適用前のパッケージをインストールしていれば、
オプションを'i'ではなく'U'にしてコマンドを実行する。
# rpm -Uvh net-snmp-*.*.*.orig.1.i386.rpm \
net-snmp-libs-*.*.*.orig.1.i386.rpm \
net-snmp-utils-*.*.*.orig.1.i386.rpm

インストールされたことを確認する。
# rpm -q net-snmp net-snmp-libs
net-snmp-*.*.*.org.1
net-snmp-libs-*.*.*.org.1