ミルク色の記録

やったこと、やってみたこと

RaspbianでOS再起動せずにネットワーク再起動で設定反映できるようにした

Raspbianのいつのバージョンだったか忘れたけど、固定IPアドレスの設定を/etc/dhcpcd.confに行うようになったあたりで、変更したネットワーク設定をサービス再起動で適用する方法がよくわからなくなった。

とりあえずdhcpcd.confで設定しているのだからdhcpcdを再起動してみたが反映されない。

$ sudo systemctl restart dhcpcd
Warning: The unit file, source configuration file or drop-ins of dhcpcd.service changed on disk. Run 'systemctl daemon-reload' to reload units.

警告が出ているので、daemon-reloadを行ってからdhcpcdを再起動してみたが、警告がでなくなっただけで反映されない。

$ sudo systemctl daemon-reload
$ sudo systemctl resart dhcpcd

networkingを再起動してみても反映されない。

$ sudo systemctl restart networking

OS再起動すれば反映されるけど、ネットワーク設定の変更だけでOSの再起動したくないので、何か手はないかと調べていたらフォーラムで次の記事を見つけた。

lb.raspberrypi.org

どうやらip addr flush devで一度インターフェイスの設定を飛ばしてあげれば良いらしい。

フォーラムの記事ではPythonスクリプト書かれていたけど、参考にしてシェルスクリプトでコマンドを作ってみた。

restart-resize コマンド

全てのインターフェイスの再起動だけではなくて、指定したインターフェイスだけの再起動もできるようにした。

書いたスクリプトは次の通り。

#!/bin/bash
#
# restart-network applies network interface configuration changes without restarting the OS.
# This implementation is based on the method described in the following forum article:
#
#   https://lb.raspberrypi.org/forums/viewtopic.php?t=199860
#
# [Usage]
#
#   * When restarting all network interfaces (the lo interface is excluded)
#
#       $ sudo restart-network
#
#   * When restarting the specified network interface
#
#       $ sudo restart-network eth0
#

check_privilage()
{
    if [ "`whoami`" != "root" ]; then
        echo "Require root privilege"
        exit 1
    fi
}

stop_dhcpcd()
{
    systemctl daemon-reload
    systemctl stop dhcpcd
}

flush_ip_address()
{
    ip addr flush dev $1
}

flush_ip_addresses()
{
    DEVICES=(`ls /sys/class/net`)
    for DEVICE in ${DEVICES[@]}
    do
        if [ "$DEVICE" != "lo" ]; then
            flush_ip_address $DEVICE
        fi
    done
}

start_dhcpcd()
{
    systemctl start dhcpcd
}

check_privilage

TARGET="all"

if [ $# -eq 1 ]; then
    TARGET=$1
fi

stop_dhcpcd

if [ $TARGET == "all" ]; then
    flush_ip_addresses
else
    flush_ip_address $TARGET
fi

start_dhcpcd

これを使って、全てのインターフェイスを再起動する場合は次のように実行する。

$ sudo restart-network

指定したインターフェイスだけ再起動する場合は次のように実行する。

$ sudo restart-network eth0

これでいちいちOS再起動しなくて良くなった。