Category Archives: その他

FreeBSDでOMRON UPSを監視する

OMRONのUPSを使っているが、長年監視を放置していた。いい加減監視したいと思って設定したので、記録を残しておく。
まず、OpenBSD/NetBSDな人は以下を参照のこと。

オムロン製UPSをOpenBSD/NetBSDで使うためのメモ (GitHub Gist)

本記事は上記を参考に、FreeBSD 14.0向けに設定してみた記録になる。

やることは以下。

  • nutをインストールする
  • UPSのVendor IDとProduct IDを調べる
  • nutユーザがデバイスを使えるようにdevdを設定する
  • nutを設定する(※本稿では全部は扱わない)

諸事情あってproduct IDはすべて伏せている。参考にして設定する奇特な人は、XXXXのような部分は適宜読み替えてほしい。

nutをインストールする

pkgでいっぱつ。

# pkg install nut

UPS関係だから名前にUPSが入ってるだろうと思って pkg search ups しても出てこない。
nutという名前は覚えて帰ろう。

UPSのVendor IDとProduct IDを調べる

なんでもいいので調べる。
ここでは dmesgugenX.X を調べたあと、usbconfigdump_device_desc を使って調べた。

# usbconfig -d ugenX.X dump_device_desc
ugen0.3:  at usbus0, cfg=0 md=HOST spd=LOW (1.5Mbps) pwr=ON (100mA)
(...snip...)
  idVendor = 0x0590 
  idProduct = 0xXXXX 

nutユーザがデバイスを使えるようにdevdを設定する

nutはnutユーザで動作するので、通常 root:wheel/dev/ugenX.X (の指す /dev/usb/X.X) を触れない。
devd を設定して、OMRON UPSだったらnutユーザにプレゼントしよう。
設定後は service devd restart をお忘れなく。

/usr/local/etc/devd/nut-usb-omron.conf:

notify 100 {
  match "system" "USB";
  match "subsystem" "INTERFACE";
  match "type" "ATTACH";
  match "vendor" "0x0590";
  match "product" "0xXXXX";
        action "chgrp nut /dev/$cdev; chmod g+rw /dev/$cdev";
};

/usr/local/etc/devd/nut-usb.conf を参考に書いたが、subsystemはDEVICEではなくINTERFACEになるようだ。
うまくいかないなら devd -d を実行して確認するといい。

nutを設定する

こんな感じ。
driverは参考資料では blazer_usb だが、maintenance-onlyだよ、というので nutdrv_qx に変えた。

/usr/local/etc/nut/ups.conf:

[XXXXX]
        driver = nutdrv_qx
        port = auto
        desc = "OMRON XXXXX"
        vendorid = 0590
        productid = XXXX
        subdriver = ippon

通信テストは、以下のようにしてドライバを直接実行すればいい。read: (... のような出力が定期的に出ればOK。

# /usr/local/libexec/nut/nutdrv_qx -DDDD -a XXXXX

あとはUPSがどうなったらどうしたい、の話になるので、man nut.conf でも実行してnutと仲良くなるといい。

私はドライバ出力を食ってprometheusに出力したかっただけなので、nut自体は使っていない。

FreeBSDのVMでHDD容量を拡張

ESXiなどでディスクサイズを拡張したときどうするか。
再起動すれば認識するのは分かっているが、再起動したくない。

というときは、以下でよい模様。

$ sudo camcontrol reprobe da0

あとはgpart resizeしたりgrowfsしたり、zpool online -eしたりすればよい。

gitlab-runnerにrefusing to work with credential missing host fieldと言われたら

GitLabでCIしていたら特定のホストで動いたときだけ fatal: refusing to work with credential missing host field というエラーが発生した。
あまり情報も整理していないのでメモ程度だが、残さないよりマシと思って書き残すことにした。

結論:

  • GitLabにHTTPSでアクセスしている、かつ、HTTPSでクライアント証明書の提示を要求していて、gitlab-runner側に使う証明書と鍵を設定している。(この時点でたぶん、大多数の人は当て嵌まらないハズ。)
  • クライアント側証明書に使われている署名のハッシュアルゴリズムがSHA-1になっていて、opensslに蹴られていた。

とはいえ、opensslがなんらかの理由でイヤと言えば全部このエラーになってしまう気がするので、調べ方も重要であろう。

gitlab-runnerはいろんな環境変数やらなんやらを設定してgitを叩くので、手動で実行しても同じ問題は再現しづらい。
そこで、gitlab-runnerに細工をして実行することにする。
具体的には、以下を実施した。

  • 環境変数を設定した状態でgitlab-runnerを起動する。GIT_TRACE=1, GIT_CURL_VERBOSE=1あたりが特に有効。詳しくは Git-Internals-Environment-Variables を読まれたし。
  • runnerが作る一時ファイルはすぐに消されてしまうものがあるので、必要ならshell scriptなどで書いた偽のgitを作り、PATHを通しておく。

今回だと、GIT_TRACE=1GIT_CURL_VERBOSE=1 を設定することで、GitLab側のJob出力で以下を得た。

16:23:14.638471 http.c:845              == Info: could not load PEM client certificate from /var/tmp/gitlab_runner/builds/(中略)/ほげほげ.tmp/CI_SERVER_TLS_CERT_FILE, OpenSSL error error:0A00018E:S

このファイルを調べようとしたが、普段は存在しない。実行中だけ存在するものと考えて偽gitにファイルコピーを仕込んだ結果、この証明書はgitlab-runnerに設定しているものと同じと分かった。
また、opensslのエラーコードから、これはどうやらmd too weakというエラーらしいことが分かり、ハッシュアルゴリズムを疑った。
(実際、このエラーはFreeBSD 14なシステム上のgitlab-runnerだけで起きていて、13では起きなかった。opensslのバージョン違いによる差であったのだろう。)

謝辞: manを読んでおきながら読み飛ばして GIT_CURL_VERBOSE に気づいてなかったとき、教えていただいたzunda氏に感謝します。

余談: 今回の問題発生時は最初にGitLabサーバのHTTPSポートに接続してTCP handshakeを行い、直後にgitlab-runner側が切断するという不可解な動作をしていた。
どうやら証明書のチェックはTCP connect後にやっているらしい。
いずれにせよ、切断(先にFIN送出)しているのがgitlab-runner側なので、gitlab-runner側の問題であることは明白だったのだが、少々混乱もした。

SambaにINTERNAL_ERRORされた

ついうっかりSambaを更新したら、Firefoxでファイルをダウンロードしたときに失敗するようになってしまった。

ネットワークからの取得は終わっていて.partファイルはちゃんとできている。しかし、その後.partファイルから本来のファイルに差し替えるところで失敗しているように見える。
あとに残るのは .zip.part みたいなファイル(中身はOK)と、0バイトな .zip ファイル。

うんうん唸りながらログを集めていたところ、Sambaがrenameに対してINTERNAL_ERRORを返しているのを見つけた。
前後のログからどうもoplockが怪しい、ということで oplock = no を指定したら解消した。
少なくとも、20回やって毎回失敗していたのが成功して、続けて2件のダウンロードも成功したので、大丈夫であろう。

oplockを有効にすると30%ほどもパフォーマンスが上がるよ!とあるが、失敗するのでは話にならないので、とりあえずこれで。

Wiresharkで見た様子:

log.smbdの様子: (↑とは違うタイミング)

[2023/02/11 12:49:27.186686,  5, pid=63759, effective(1001, 0), real(0, 0), class=locking] ../../lib/dbwrap/dbwrap.c:180(dbwrap_lock_order_unlock)
  dbwrap_lock_order_unlock: release lock order 1 for /var/db/samba4/locking.tdb
[2023/02/11 12:49:27.186922, 10, pid=63759, effective(1001, 0), real(0, 0), class=locking] ../../source3/lib/dbwrap/dbwrap_watch.c:1027(dbwrap_watched_watch_state_destructor_fn)
  dbwrap_watched_watch_state_destructor_fn: Watcher 63759:6 not found
[2023/02/11 12:49:27.187162,  3, pid=63759, effective(1001, 0), real(0, 0), class=smb2] ../../source3/smbd/smb2_server.c:3957(smbd_smb2_request_error_ex)
  smbd_smb2_request_error_ex: smbd_smb2_request_error_ex: idx[5] status[NT_STATUS_INTERNAL_ERROR] || at ../../source3/smbd/smb2_server.c:2053
[2023/02/11 12:49:27.187387, 10, pid=63759, effective(1001, 0), real(0, 0), class=smb2] ../../source3/smbd/smb2_server.c:3849(smbd_smb2_request_done_ex)
  smbd_smb2_request_done_ex: mid [5705] idx[5] status[NT_STATUS_INTERNAL_ERROR] body[8] dyn[yes:1] at ../../source3/smbd/smb2_server.c:4005

Compressorで出力したビデオに日付を付けてPhotosに認識させたい

Compressor でなにも考えずに圧縮したビデオを Photos に入れると、作成日がビデオの日付として使われる。
昔のビデオを加工したときに期待通りに並ばずに腹立たしいので、日付をつけたい。

そんなときは、Job Annotations で Date を付けるとよい。
Job Annotations は Job を選んでいるときに設定できる。

Date の形式は任意の文字列になっていて、どんな文字列も受け付けてくれる。
が、適当な形式では Photos 側が認識してくれない。
いくつか試したところ、少なくとも 2022-07-07T23:59:59+09:00 のような ISO 8601 形式は受けつけてくれることが分かった。

これで、整理していなかったビデオも整理して Photos に入れられる。

macOSでWindowsインストール用USBメモリを作る

めもめも。
先人達の情報もいろいろありそうだが読まずにやってみた。

  1. 起動用とインストール用の2つのパーティションを作る。1つはFAT32, もう1つはExFATにする。
    diskutil partitionDisk /dev/diskX 2 MBR FAT32 EFISYS 1024M ExFAT INSTALLER R
    
  2. Windowsのインストール用ISOをマウントする。
  3. ISO中のboot, bootmgr, bootmbr.efi, efi, sources/boot.wimを、EFISYSボリュームにコピーする。
  4. ISO中の全ファイルをINSTALLERボリュームにコピーする。
    ※たぶんboot系は要らないが、選別するほうが面倒なので全部コピーした。

ダメだったやつ一覧

  • ISOをddで書く: 起動用の一部のパーティション(?)しか見えず、インストーラは起動するがインストール用の物件が見えないと怒られる。(ドライバのインストールが要るよ、とわけのわからないことを言われる)
  • balenaEtcherでISOを書く: どうやら上と同じ。
  • GPTでフォーマットする: インストール開始できるが、すぐに “Windows could not prepare the computer to boot into the next phase of installation” というエラーになる。

寝正月2018

新年明けましておめでとうございます。
寝正月万歳です。

去年はGo Langに手を染め、しかし見た目の汚さが許容できず、LispやらSchemeに逃げました。
長年親しんだC/Perl/Pythonのようには自由にかけませんが、いずれはメイン言語にしていきたいものです。

さて、寝ぼけた頭で、いま頭に詰まっている内容を吐き出します。
Schemeまわりは以下の件でどこかにこぼれ落ちていったので、またそのうち。

Continue reading 寝正月2018