私はBusyboxとmuslをベースにしたRaspberry PiでAlpine Linuxを実行しています。
実行すると、そのインターフェイスのバックグラウンドでも起動しますifup eth0
。udhcpc
つまり、イーサネットケーブルが接続されている場合はifup
すぐにIPアドレスを受け取り、そうでない場合は接続するまでバックグラウンドで回転してからIPアドレスを受け取ります。しかし、これはワンタイムです。
IPアドレスを取得してケーブルを抜くと、そのIPアドレスが保持されます。たとえば、一部のネットワーク要求を試みると、タイムアウトするping google.com
までこのインターフェイスを介して要求を試みます。複数のネットワークインターフェイスがある場合は特に問題になります。この場合、最初のネットワークインターフェイスを引き続き使用しようとし、インターネットに接続されている可能性がある他のネットワークインターフェイスを無視します。
ケーブルが切断されたか、接続が失われたことを検出し、インターフェイスを設定解除し、再接続して再構成するのに適した軽量ソリューションは何ですか?
もしかしたら、ここに私の/etc/network/interfaces
ファイルもあります。
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet dhcp
auto eth1
iface eth1 inet dhcp
答え1
一般的なシステムでは、このコマンドはip monitor link dev ethX
イベント指向のアプローチとして使用され、キャリア状態の変化に応答することができます(例NO-CARRIER
:)。
利用できないから忙しい箱Q / Aへの私の答えで説明されているように、最小限の実装IPリンクダウンと物理リンク損失の違い、これ運送業者の状態名前の人イーサネット次のサイトでも利用可能:
/sys/class/net/ethX/carrier
NO-CARRIER
0 はインターフェイスのフラグである演算子がないことを意味します。- 1 は演算子を意味します。
この値は、インターフェイスが起動した後にのみ使用できますip link set ethX up
。それ以外の場合は、読み込み時にエラーが返されます。これ運送業者の状態そして動作状態ほとんどすべての設定で同じです(この場合は含める、詳細については前のリンクを参照)、使いやすくなります。動作状態次に戻ることができます/sys/class/net/ethX/operstate
。
lowerlayerdown
演算子がない場合(インタフェース開放型)、up
通信会社の場合、down
インターフェイスが次の場合行政以下に。
したがって、それを置き換えるには、次のシェル関数のようにip monitor link dev ethX
定期的にポーリングして同じ情報を取得できます/sys/class/net/ethX/operstate
。この関数は、約2秒ごとに引数として提供されたインターフェイスをポーリングし、変更のみを出力します。
stateevent () {
local fileoperstate=/sys/class/net/"$1"/operstate
local operstate oldoperstate=$(cat "$fileoperstate")
while sleep 2; do
operstate=$(cat "$fileoperstate")
if [ "$oldoperstate" = "$operstate" ]; then
continue
fi
oldoperstate="$operstate"
echo "$operstate"
done
}
OPの目的は、接続が切断されたインターフェイスへのパスを最終的に失い、タイムアウトがなく、デュアルホームRPiとの競合がないようにすることです(独自のルーティングテーブルで2つのデフォルトゲートウェイを別々に処理するソリューションがありますが、非常に複雑です)。特に、DHCPとの統合には独自のアプローチが必要であり、依然としてキャリア損失を処理する必要があります。
一部のテストでは、アドレス損失(パス損失を含む)は単にパス損失よりも簡単であることがわかりました。あるいは、そのパス(特にカーネルの自動LANルーティング)が後で正しく復元されない可能性があります。これは、RPiが独自のクライアントであるまれな場合は、DHCPで設定された独自のアドレスに接続しないでください。たとえば、RPiに割り当てられたアドレスに固執する必要があることを意味します。ルオ127.0.0.1 や、ここに追加された他のアドレスなどのインターフェイスです。
忙しい箱udhcpc
'この問題を簡単に解決するのに役立つ組み込み関数があります。
信号:
USR1
リース更新
USR2
リース終了
それでは、走りながら尋ねてください。ウズベキスタンタスク自体を実行するには、単純な信号を使用します。 releaseはアドレスを削除し(インターフェースが切断されたため、DHCPサーバーに通知する方法はありませんが問題ではありません)、renewはそのアドレス(およびパス)を再追加します。
以下は、前の関数の出力から来るイベントを使用してこれを実行するイベントループ関数です。
eventloop () {
local intf=$1
local state
while read -r state; do
case "$state" in
lowerlayerdown)
pkill -USR2 -f "(^|/)udhcpc( | .* )-i $intf( |$)"
;;
up)
pkill -USR1 -f "(^|/)udhcpc( | .* )-i $intf( |$)"
;;
down)
;;
esac
done
}
インターフェイスが管理上終了した場合(ただいま使用されていても)、アクションは必要ありませんip link set eth0 down
。パスはカーネルによって削除され、LANパスは後でそれ自体で再追加されます。ウズベキスタンインターフェイスがバックアップされたら。
上記の2つのシェル関数を含み、次に終わる名前のシェルスクリプトmanageudhcpc.sh
(通常、で始まる)を持つことができます。#!/bin/sh
stateevent "$1" | eventloop "$1"
2回実行します(返されないのでフォークします)。
./manageudhcpc.sh eth0 &
./manageudhcpc.sh eth1 &
OPに任せます。
- 始めるには、このスクリプトを統合してください。
- 初めて起動するときにインターフェイスが何をしているかを見てください。ウズベキスタン接続されていないインターフェイスから始めて初期リースを待っている場合は、動作が異なる場合があります。
メモ:
- 両方のネットワークでDHCP用に設定された2つのインターフェイスを使用して、Alpine 3.12およびAlpine Edge LXCコンテナで正常にテストされました。
- 非常に保守的です拡張正規表現正しいものを見つけるために使用されますウズベキスタン正確なAlpineバージョンによっては変更が必要な場合があります(3.12とEdgeの間で変更する必要があるため、両方で動作しました)。それpidファイル代わりに使用できます。