ITエンジニアの技術メモ

神奈川在住のITエンジニアの備忘録です。主にプログラミング(Perl, Java など)やネットワーク技術について、自分の中で整理するためにゆるゆると書いています。誰かのご参考になれば幸いです。

SNMP Report PDU が使われる場面

先日、SNMP report - ITエンジニアの技術メモ にて、「SNMP Report はあまり見たことがない」と書いたが、最近、SNMP Report が使われる場面を見つけたのでメモしておく。

 

https://www.ietf.org/rfc/rfc2574.txt に以下の記載がある。

4. Discovery

The User-based Security Model requires that a discovery process
obtains sufficient information about other SNMP engines in order to
communicate with them. Discovery requires an non-authoritative SNMP
engine to learn the authoritative SNMP engine's snmpEngineID value
before communication may proceed. ★This may be accomplished by
generating a Request message with a securityLevel of noAuthNoPriv, a
msgUserName of zero-length, a msgAuthoritativeEngineID value of zero
length, and the varBindList left empty. The response to this message
will be a Report message containing the snmpEngineID of the
authoritative SNMP engine as the value of the
msgAuthoritativeEngineID field within the msgSecurityParameters
field. It contains a Report PDU with the usmStatsUnknownEngineIDs
counter in the varBindList.

・・・

これによると、SNMPマネージャが (SNMPv3)エージェントに空のリクエストを投げる。それに対して、エージェントが SNMP Report に自分のエンジンIDを含めて応答する。これでSNMPマネージャはエージェントのエンジンIDを知ることができ、SNMPv3通信を開始すると読める。

つまり、SNMP Report は、SNMPマネージャがSNMPv3エージェントのエンジンIDを知る目的で使用されることがある。

 

以下も参考にさせて頂きました。

SNMP v3 の engineID とかのメモ - ngyukiの日記

2038年問題への対応

C言語で作成されたアプリの2038年問題への対応について調べてみた。なお、2038年問題については以下を参照。

2038年問題 - Wikipedia

 

2038年問題で主に問題として挙げられるのは、時刻データを格納する time_t 型が符号付き 32bit なので、その最大値は (2^31 − 1) = 2,147,483,647 となり、扱える年数が 2,147,483,647秒 (≒ 68年) までに限られてしまうことである。

 上述の time_t 型は、time.h にて long 型として定義(typedef)されており、long 型は limits.h でその最大値が定義されている。long 型の最大値は処理系 (コンパイラ) によって変わり、32bit 環境のものでは (2^31 − 1) = 2,147,483,647 となり、64bit 環境のものでは (2^63 - 1) = 9,223,372,036,854,775,807 となることが多いようだ。time_t 型が (2^63 - 1) まであれば、西暦3000億年くらいまで使用できるので、もうxxxx年問題とか気にしなくて良いレベルである。

 

つまり、long 型が 64bit で定義されている環境 (処理系) でアプリをコンパイルすれば、time_t 型で扱える年数が格段に増えて、2038年問題を回避できるはず。最近の環境ではそうなっていることが多いと思うので、新しめの環境でアプリをコンパイルすれば、だいたい2038年問題対策は出来ていることになるのだろう。

# 時刻を表すのに time_t 型を使わず、int 型などを使っていたら、その部分の修正も必要になってくるが・・。

 

以下も参考にさせて頂きました。 

C言語と2038年問題 - エクセレンス★ブログ

 

シェルスクリプトで標準エラー出力を纏める

シェルスクリプト標準エラー出力を一つのファイルに纏めたい場合、

exec 2> 出力先ファイル

シェルスクリプト内に記載する。こうすると、これ以降の標準エラー出力が「出力先ファイル」に吐かれる。これをシェルスクリプトの冒頭付近に書いておけば、シェルスクリプト内でコマンドを実行するたびに、

command 2> 出力先ファイル

とかやらなくて済むので楽。

プロフィールムービーの作成方法

フリーソフトなどを使い、結婚式で使用するプロフィールムービーをほぼ無料で作成した。その方法について書く。

ちなみに、持っているPCはWindows10。作成したプロフィールムービーは 家庭用のDVDプレーヤーで再生される前提。

  1. パワーポイントで内容を作成。「画面の切り替え」⇒「自動的に切り替え」で、一定時間でスライドが切り替わるようにしておく。また、必要に応じてアニメーションを入れる。
  2. パワーポイントを保存する時に動画形式 (mp4) を選択して保存する。
  3. 作成したmp4動画をオーサリングソフトを使って DVDビデオ形式に変換する。今回はオーサリングソフトとして DVD Flick (http://www.dvdflick.net/) を使用した。
  4. 作成したDVDビデオデータをDVDに焼く。DVDに焼く際、ファイナライズしないと読み込めないDVDプレーヤーがあるらしいので、ファイナライズできる焼きソフトを使った方が良い。今回は ImgBurn (http://www.imgburn.com/) を使用した。

 

この方法なら、DVD-R(W)を購入する以外の費用はかからずに済む。冒頭で「"ほぼ"無料」 と書いたのは、DVD-R(W)を購入する費用があるため。なお、パワーポイントを持っていない場合もあると思うが、(パワーポイントを含む) Microsoft Office は一か月無料の体験版が使える。

Microsoft 公式 – 家庭向け Office の無料試用版ダウンロード

 

[補足]

上記手順は、ある程度 ITリテラシーがないと難しいかもしれないので、よく分からなかったり、時間のない人は式場側に頼んでしまった方が良いかも。(その分のお金はかかると思うが・・)

Javaのvolatile変数

Javaの「volatile」は、「synchronized の軽量版」という認識しか持っておらず、あまり理解できていない気がしたので、ちょっと調べてみた。

マルチスレッド処理において、フィールド変数に volatile を付けると、各スレッドはその変数を参照する際、スレッド固有の領域ではなく、常に最新の値を見に行く。つまり、各スレッドが古い値を参照してしまうことはなくなる。

synchronized と何が違うのかと言うと、synchronized はロックを取得し、処理中は他のスレッドをブロックするが、volatile はそれはしない。単に、スレッドが対象のフィールド変数を参照する時に、常に最新の値を見れるようになるだけ。これをカッコよく (難しく) 言うと、volatile は「可視性」は持っているが、「アトミック性」は持っていない、ということになるとのこと。
Javaの理論と実践: volatile を扱う

なので、複数スレッドからアクセスされるクラスにおいて、例えば以下のように、あるフィールド変数の値を加算して、加算した結果が特定の数値だったら特別な処理を行いたい場合、synchronized だと実現できるが、volatile では実現できない。

volatile int counter = 0;

void updateCounter {
    counter++;
    if (counter == 100) { // ★
        doSomething();
    }
}

というのは、あるスレッドが counter を加算して counter が 100 になって ★ の箇所に入ろうとしたところに、別スレッドが counter を加算して counter が 101 になってしまう可能性があるからである。そうなると、本来実行したかった doSomething() が実行されない。

こんな感じで volatile は扱うのがちょっと難しいので、基本は synchronized を使い、それだと性能が出ない場合などに volatile を検討するくらいで良いのではないかと考えている。

perlで現在時刻を (秒以下の精度で) 取得する。

perl には、現在時刻を取得する関数として localtime 関数がある。ただし、この関数では秒以下の精度で時刻を取得できない。そうしたい場合は、Time::HiRes モジュールの gettimeofday 関数を取得する。gettimeofday関数を使ったサンプルを以下に示す。

use strict;
use warnings;
use Time::HiRes "gettimeofday";

my $currentTimeStr = getCurrentTimeStr();
print $currentTimeStr;

sub getCurrentTimeStr {
    my ($epochSec, $microSec) = gettimeofday();
    my ($sec, $min, $hour, $day, $mon, $year) = localtime($epochSec);
    $year += 1900;
    $mon++;
    return "$year/$mon/$day $hour:$min:$sec.$microSec";
}

上記を実行すると、現在時刻として、例えば、

2018/10/20 23:35:29.844079

が出力される。上記の実行結果の通り、秒以下(マイクロ秒)の精度で現在時刻を取得できる。

SNMP report

先日、初めて SNMP report に遭遇したので、少し調べた時のメモ。

SNMP report は主に SNMPv3 で使用される。SNMPエージェントが、SNMP マネージャからの SNMP リクエストを受け取り、リクエスト処理中に問題が発生した場合などに、SNMP マネージャに SNMP report を返すことがある。SNMP マネージャでは、SNMP report を受け取ったら、その内容を見て SNMP リクエストを修正して再送する等の対応をとれる。

SNMP に関わって長いが、これまで SNMP report を見たことがなかったので、SNMP report はあまり活用されていないのだろうか。

 

参考にしたサイト

https://www.ietf.org/rfc/rfc2572.txt

SNMP Operations (Essential SNMP)

http://net-snmp.sourceforge.net/wiki/index.php/REPORT