Archive: 2014/05

ハンバーガーSUKEYA

なっちゃんとハンバーガー
手作りハンバーガー「SUKEYA」にて

今日のランチは箱崎小学校の裏手、住宅街にひっそりと佇む手作りハンバーガー「SUKEYA」へ。

カリッと焼き上げられたバンズに手作りのパティがベストマッチ。トマトとピクルス、ベーコンと卵、レタスと千切りキャベツで野菜もたっぷり。全部載せると大変な事になりそうな勢い。

まさに佐世保バーガーに匹敵するボリュームとクオリティで550円。ドリンクも大きなコップにたっぷりで150円~だし、箱崎っぽい良心を感じる。

お昼時とあってテイクアウトのお客さんもひっきりなしに来ていたよ。

ハンバーガーSUKEYA TEL:092-204-2000 月曜定休 11時半~15時、18~21時
〒812-0053 福岡市東区箱崎2-2-27

【参照】
●Hamburger SUKEYA(スケヤ) http://www.sukeya.biz/
●食べログ http://tabelog.com/
スケヤ (SUKEYA) - 箱崎九大前ハンバーガー
●Facebook https://www.facebook.com/
Sukeya

ホットシューカバー

2012年12月に調達したOLYMPUS PEN Lite E-PL5

ホットシューカバー復活
PEN Lite E-PL5

なんだかんだで1年半になるものの、ストロボ撮影なんて数えるほどもしないので全く気付かなかったのだが、いつしか「ホットシューカバー」が無くなっていた。

機能的には全く問題無く、単に気分の問題だが…やっぱり気分がよろしくないので、速やかに調達しようと手配を試みたのだが、どういうわけかヨドバシやAmazonはおろか、本家オリンパスのオンラインショップですら取り扱いが無く、安そうな割に予想外に入手困難な代物である事に気付いた。

唯一取り扱いがあったのが、【楽天市場】カメラのミツバ。1個200円、メール便送料164円というのは決して手が出ない価格ではないのだが、何となくここで妥協したら「負け」のような気がしてカートに入れたところで、調査を再開。

一般に流通していない事を考えると、どうやら修理用の保守部品としてのみ存在するものと推察されるので、オリンパスサービスステーションに相談すれば手に入る可能性がありそうだ。

というわけで、ようやく平日の天神方面に出掛ける用事があったので、渡辺通りオリンパスサービスステーション福岡に問合せて目論み通り調達に成功。

1個100円だったので、また紛失する可能性を考えて2個査収。税込216円で済んだのは作戦勝ちと言っていいだろう。

【参照】
●オリンパスイメージング http://olympus-imaging.jp/
OLYMPUS PEN Lite E-PL5
サービスステーション
●Wikipedia http://ja.wikipedia.org/wiki/
オリンパス・ペン

TrustyとIPMI

ようやく落ち着いたかに見えるgoto2048/fplug_for_linuxによる消費電力測定。

明るさや温度、湿度も測れるというので調子に乗っていろいろと試してみているのだが、実は激安と言えどもサーバグレードであるHP ProLiant ML110 G7には筐体内にも多数のセンサが実装されていて、HP Integrated Lights-Out 3 (iLO 3)でリモート監視できるようになっている。

「折角なのでこちらもゴニョゴニョできないかしらね…?」とグルグル調べてみたところ、何気にIntelligent Platform Management Interface (IPMI)と互換性がある事から、LinuxベースでもOpenIPMIによって取得できる事がわかったので、Kodai's Blog: Ubuntu 9.10でML115のIPMIを利用する【自宅サーバ構築】9. HP ProLiant ML110 G7で温度とFAN回転率解析: Pythonと自分 ~ a python lifeを参考にUbuntu 14.04(Trusty Tahr)ベースでトライした。

基本的には

yano@ML110G7:~$ sudo apt-get install openipmi ipmitool
yano@ML110G7:~$ sudo /etc/init.d/ipmievd start
yano@ML110G7:~$ sudo /etc/init.d/openipmi start
すれば良いだけなのだが、/dev/ipmi0がお馴染みの"No such file or directory"というエラーになった。

しかし、手動で

yano@ML110G7:~$ sudo modprobe ipmi_si
yano@ML110G7:~$ sudo modprobe ipmi_msghandler
yano@ML110G7:~$ sudo modprobe ipmi_poweroff
yano@ML110G7:~$ sudo modprobe ipmi_devintf
yano@ML110G7:~$ sudo modprobe ipmi_watchdog
yano@ML110G7:~$ sudo /etc/init.d/ipmievd start
yano@ML110G7:~$ sudo /etc/init.d/openipmi start
する分には大丈夫なのでよくよく調べてみると、
yano@ML110G7:~$ locate ipmi_msghandler
/lib/modules/3.5.0-48-generic/kernel/drivers/char/ipmi/ipmi_msghandler.ko
yano@ML110G7:~$ locate ipmi_si
/lib/modules/3.13.0-24-generic/kernel/drivers/char/ipmi/ipmi_si.ko
/lib/modules/3.13.0-27-generic/kernel/drivers/char/ipmi/ipmi_si.ko
/lib/modules/3.5.0-48-generic/kernel/drivers/char/ipmi/ipmi_si.ko
yano@ML110G7:~$
という状況から、Ubuntu 14.04(Trusty Tahr)にはipmi_msghandlerが無くなった事からロードエラーになり/dev/ipmi0の作成処理に入っていないらしいので、/etc/default/openipmiでIPMI_MSGHANDLERが"yes"になってなければmodprobeしないよう/etc/init.d/openipmiを改修。
yano@ML110G7:~$
yano@ML110G7:~$ diff -c /etc/init.d/openipmi.orig /etc/init.d/openipmi
*** /etc/init.d/openipmi.orig 2014-03-19 13:49:09.000000000 +0900
--- /etc/init.d/openipmi 2014-05-29 11:06:35.761795525 +0900
***************
*** 321,329 ****
load_ipmi_modules ()
{
local locdelay
! modprobe ipmi_msghandler > /dev/null 2>&1
! modules_loaded ipmi_msghandler
! [ ${OnePlusLoaded} -ne 1 ] && unload_all_ipmi_modules && RETVAL=$((RETVAL | 1)) && return
load_hw_modules
[ $((RETVAL & 1)) -eq 1 ] && unload_all_ipmi_modules && RETVAL=$((RETVAL | 1)) && return

--- 321,332 ----
load_ipmi_modules ()
{
local locdelay
!
! if [ "${IPMI_MSGHANDLER}" = "yes" ]; then
! modprobe ipmi_msghandler > /dev/null 2>&1
! modules_loaded ipmi_msghandler
! [ ${OnePlusLoaded} -ne 1 ] && unload_all_ipmi_modules && RETVAL=$((RETVAL | 1)) && return
! fi
load_hw_modules
[ $((RETVAL & 1)) -eq 1 ] && unload_all_ipmi_modules && RETVAL=$((RETVAL | 1)) && return
yano@ML110G7:~$
センサーの情報は「ipmitool sdr」で確認できるが、
yano@ML110G7:~$ sudo ipmitool sdr
UID Light | 0x00 | ok
Health LED | 0x00 | ok
VRM 1 | 0x00 | ok
Power Supply 1 | 0x00 | ok
Fan 1 | 54.88 percent | ok
Fan 7 | 46.65 percent | ok
Fan 8 | 41.16 percent | ok
01-Inlet Ambient | 27 degrees C | ok
02-CPU | 40 degrees C | ok
03-P1 DIMM 1-4 | 33 degrees C | ok
04-P1 Mem Zone | 35 degrees C | ok
05-P1 Mem Zone | 33 degrees C | ok
06-HD Max | 50 degrees C | ok
07-VR P1 | 38 degrees C | ok
08-VR P1 | 41 degrees C | ok
09-VR P1 Zone | 35 degrees C | ok
10-VR P1Mem Zone | 32 degrees C | ok
11-PCI 1 Zone | 32 degrees C | ok
12-PCI 2 Zone | 33 degrees C | ok
13-PCI 3 Zone | 32 degrees C | ok
14-PCI 4 Zone | 30 degrees C | ok
15-System Board | 28 degrees C | ok
16-System Board | 31 degrees C | ok
Memory | 0x00 | ok
yano@ML110G7:~$
Fan 1が背面ファン、Fan 7がCPUファン、Fan 8が前面ファン。CPUとHDは実際には採れていなくて、それぞれ40、50の固定値出力となっている模様。

fplug_for_linux

先日導入したgoto2048/fplug_for_linux

F-PLUG
F-PLUG

温度(Temperature)の応答メッセージが1バイト短い問題は、ひとまずデータの最後から2バイトに注目するように改修したのだが、やはり「1バイト短い」だけではなく別種別の応答が返ってくる事例もあってゴミデータっぽい値となっている事がわかった。

そういうわけで定石通り「SEOJクラスコード」が期待と違ったらリトライするようにしようかと思ったのだが、そこで温度(Temperature)の応答メッセージで「SEOJクラスコード」が漏れる問題に再び行く手を阻まれた。

もしかして、TIDが使われていない(常時ゼロ)のが問題なのではないか?というのも気になったので、カウントアップするTIDを載せてみたものの結果は変わらず。しかし、「SEOJクラスコード」が無くても「TIDがある」事で各情報の要求と応答メッセージが紐付けできるようになるので、fpstatusを下のように改修してみた。

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

#include "fplug.h"

#undef DEBUG
#define ENOTCONN_RETRY_MAX 10
#define MSG_RETRY_MAX 5

#define FPLUG_EXEC(fd,msg,buf) fplug_exec((fd),(msg),sizeof((msg)),(buf),sizeof((buf)))

typedef unsigned char uchar;
static uint16_t tid = 0x0001;

void hunt_tid(uchar *buf)
{
*(uint16_t *)&buf[2] = tid++;
}

typedef uchar uchar;

static void dump_message( char *mes, uchar *buf, int size )
{
#ifdef DEBUG
int cnt;
printf( "%s", mes );
for ( cnt=0; cnt printf( "%02X,", buf[cnt] );
}
printf( "\n" );
#endif
return;
}

int fplug_exec(int fd, uchar *req_msg, size_t req_len, uchar *res_buf, size_t bufsiz)
{
struct timespec tmspec = { 0, 1000 * 1000 };
int ret, i, j;
uchar req_buf[BUFSIZ];

memcpy(req_buf, req_msg, req_len);

for (i = 0;i < MSG_RETRY_MAX; i++ ) {
hunt_tid(req_buf);
dump_message( "Command:", req_buf, req_len);
for (ret = j = 0;j < ENOTCONN_RETRY_MAX; j++ ) {
ret = write(fd, req_buf, req_len);
if ( ret == req_len )
break;
#ifdef DEBUG
printf("write()=%d,errno=%d\n", ret, errno);
#endif
switch ( errno ){
case ENOTCONN :
tmspec.tv_nsec = 500 * 1000 * 1000;
nanosleep(&tmspec, NULL);
break;
}
}
if ( ret <= 0 )
break;

tmspec.tv_sec = 0;
tmspec.tv_nsec = 250 * 1000 * 1000;
nanosleep(&tmspec, NULL);

ret = read(fd, res_buf, bufsiz);
if ( ret <= 0 )
continue;

dump_message( "read:", res_buf, ret );
if (4 < ret && !memcmp(req_buf, res_buf, 4)){ // TID match
#ifdef DEBUG
printf("read()=%d,errno=%d\n", ret, errno);
#endif
return ret;
}
}

return -1;
}

int fplug_main( int fd, int mode )
{
int cmd;
int cnt;
int ret;
int i=0;
uchar buf[BUFSIZ];
uchar *szMode, szResult[BUFSIZ];
time_t timer;
struct tm *t;

strcpy(szResult, "--");
szMode = szResult;

switch(mode) {
case 'h':
szMode = "FP_HUMID";
for ( i = 0; i < MSG_RETRY_MAX && 0 < (ret = FPLUG_EXEC(fd, Humid, buf)); i++ ){
uint16_t a = *(uint16_t *)&buf[ret-2];
if ( 100 < a )
continue;
sprintf(szResult, "%d", a );
break;
}
break;
case 'i':
szMode = "FP_ILLUM";
for ( i = 0; i < MSG_RETRY_MAX && 0 < (ret = FPLUG_EXEC(fd, Illum, buf)); i++ ){
uint16_t a = *(uint16_t *)&buf[ret-2];
if ( 0xFFFD < a )
continue;
sprintf(szResult, "%d", a );
break;
}
break;
case 't':
szMode = "FP_TEMP";
for ( i = 0; i < MSG_RETRY_MAX && 0 < (ret = FPLUG_EXEC(fd, Temp, buf)); i++ ){
int16_t a = *(int16_t *)&buf[ret-2];
if ( a < -100 || 500 < a )
continue;
sprintf(szResult, "%.1f", (float)a / 10);
break;
}
break;
case 'w':
szMode = "FP_WATT";
for ( i = 0; i < MSG_RETRY_MAX && 0 < (ret = FPLUG_EXEC(fd, RWatt, buf)); i++ ){
int16_t a = *(int16_t *)&buf[ret-2];
if ( 2000 < a )
continue;
sprintf(szResult, "%.1f", (float)a / 10);
break;
}
break;
default:
szMode = "FP_unknown";
break;
}
printf( "%s=%s;", szMode, szResult);
}

int main(int argc, char *argv[])
{
int fd;
struct termios oldtio, newtio;
char *cmd;

if ( argc == 1 ) {
printf("Usage: fpstatus