uhubctlでスタックしたUSBデバイスにプログラム的に電源を遮断する方法
一般的な状況を想像してみてください:リモートサーバー、ダーチャ路由器、またはテストベンチで4Gモデムがフリーズしているか、Raspberry Piボードが異常モードに陥り、3Dプリンターのコントローラーがコマンドに応答しなくなったとします。通常のOS再起動ではUSBポートへの電力供給が継続しているため解決せず,唯一の手がかりは現場に赴いてケーブルを手動で抜くことです。
「歩く管理者」として働きたくない場合は、uhubctlユーティリティが便利です。Vadim Mikhaylovが2015年にC言語でこのツールを書き、プロジェクトは今でも活発です。プログラムの主な目的は、ハブコントローラーに対して低レベルのUSBコマンドを送信し、特定のポートからVBUS電力を物理的に 제거することです。
動作原理とハードウェアの落とし穴
uhubctlは空から奇迹を演じるわけではありません。ポートごとの電力切り替え(PPPS)をハードウェアでサポートしているハブでのみ動作します。USB 2.0およびUSB 3.0の仕様には已久しいものの、電力コンポーネントのコスト削減により、多くの低価格ハブでは全ポートの電力が単一ラインに統合されています。
それでも、市場には互換性のあるデバイスが十分に存在します。リポジトリには数十種類の検証済みモデルの詳細なテーブルが維持されています:
- Dell、LG、BenQ、Acer製モニターの内蔵ハブ。
- Raspberry Piシングルボードコンピュータ(3B+および4Bモデルでは、いくつかのニュアンスはありますが電力を無効化できます)。
- Anker、D-Link、Rosonway、Plugableの外部ハブ。
- AsusのマザーボードおよびKUNBUS RevPi産業コントローラー。
内部構造
uhubctlはlibusbライブラリまたはLinuxカーネルインターフェース経由でハブと通信します。Linuxカーネル6.0ではsysfsを通じたポート無効化の標準メカニズムが導入されました。ユーティリティはまずこれを試み、古いシステムやmacOSの場合はlibusbにフォールバックします。
USB 3.0には一つのニュアンスがあります。モダンなハブをUSB 3.0ポートに接続すると、システムは仮想USB 2.0ハブと仮想USB 3.0ハブという2つの別々の論理デバイスとして認識します。片方のブランチのみでポートへの給電を切断すると、接続されたデバイスは単に別の速度に切り替えて動作を継続する可能性があります。uhubctlはこのルーチンを処理し、両方の仮想ハブで同期的な切断を実行します。
インストールとクイックスタート
ほとんどのLinuxディストリビューションでは、標準リポジトリからすでに利用可能です:
sudo apt install uhubctl
macOSでは、Homebrew経由でインストールします:
brew install uhubctl
ディストリビューションに古いバージョンがある場合は、Gitソースからコンパイルするのは簡単です。gccとlibusb-devが必要です:
git clone https://github.com/mvp/uhubctl
cd uhubctl
make
sudo make install
まず、パラメータなしでユーティリティを実行して、利用可能なハブと接続されているデバイスのリストを確認する必要があります:
sudo uhubctl
このコマンドはバストポロジー、バス/デバイスアドレス形式でのハブアドレス、各ポートの状態を出力します。
コマンド例
デフォルトハブの2番目のポートへの給電を遮断するには、次を実行します:
sudo uhubctl -a off -p 2
-a 2の代わりに、-l off -a 2アクションを渡すこともできます。給電を無効化し短い一時停止を待ってから再度有効にします。フリーズした機器のハードリセットに適しています:
sudo uhubctl -a cycle -p 2 -d 3
-dパラメータは給電を復元する前に3秒間の遅延を設定します。複数のポートを同時にリセットする必要がある場合は、カンマまたはダッシュで区切って指定します:-l 1,2,3または-l 1-3。
Linuxでのアクセス権の設定
デフォルトでは、USBデバイスへの直接操作にはroot権限が必要です。sudoでスクリプトを実行したくない場合は、udevルールを/etc/udev/rules.d/ファイルに追加します:
SUBSYSTEM=="usb", DRIVER=="hub|usb", MODE="0666"
SUBSYSTEM=="usb", DRIVER=="hub|usb", RUN="/bin/sh -c \"chmod -f 666 $sys$devpath/*port*/disable || true\""
その後、udevadm control --reload-rulesを実行すると、権限が更新されます。
実践的な使用例
開発者とシステム管理者は、uhubctlをさまざまなタスクで使用しています:
- 監視ファーム内のフリーズしたLTEモデムや路由器の自動リセット。
- 外部LEDインジケーター、ファン、Webカメラの制御。
- 外部ハードドライブの安全な切断によるファントム負荷の排除とエネルギー節約。
- OctoPrintとの統合による3Dプリンターの遠隔オン/オフ。
- CI/CDパイプラインでのハードウェアテスト(デバッグボードをテストベンチに物理的に再接続する必要がある場合)。
制限事項とハードウェアの特性
ユーティリティをスクリプトに組み込む前に、システムのハードウェアの特性を確認する必要があります。例えば、一部のRaspberry Piモデルでは、4つのポートの電力ラインが並列に接続されています。1つのポートをオフにしようとすると、システムが4つすべてのポートの電力を切断します。
さらに、一部のUSB給電ガジェットはデータ信号線が切断されても充電電流を引き続き消費する場合があります。この場合は、特定のハブをマルチメーターまたは負荷抵抗でテストすることだけが解決策になります。
自律的なテストベンチ、スマートホーム、または接続された周辺機器を持つサーバーの管理している場合、uhubctlは立ち往生したハードウェアへの長距離旅行からあなたを救うコンパクトなツールの1つです。プログラムはGPLv2ライセンスで配布されており、不必要な複雑さなしでタスクを解決します。開始前の唯一の確認事項は、USBハブが電力管理をサポートしていることです。
関連プロジェクト