Ubuntu18.04でスリープ後ネットワークが繋がらなくなった話

# はじめに
最近スリープ（Suspend）後にネットワークが繋がらなく事案が多発。
PCを開きっぱなしで放置してスリープにしていたのが悪いと思って放置していたが、コマンドできちんとスリープにしてもネットが繋がらなくなったため、こりゃあいかんと思いググって直しました。
ちなみにこのバグは、ネットワークの再起動を行っても意味がなく、PC自体を再起動しないと直らないらしいです。
なので、以下のコマンドは効きません。

```bash:network_restart
$ sudo service network-manager restart
```

# 環境
Ubuntu 18.04

# 解決方法
## r8169を利用しているかの確認
調べてみると、ネットワークカーネルモジュールが**r8169**を利用しているとこのバグが起きるらしい。
なので、ネットワークカーネルモジュールを調べてみる。

```bash:network_kernel_module
$ sudo lshw -C network
  *-network                 
       description: Ethernet interface
       product: RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller
       vendor: Realtek Semiconductor Co., Ltd.
       physical id: 0
       bus info: pci@0000:03:00.0
       logical name: enp3s0
       version: 10
       serial: 8c:16:45:0f:1c:3f
       size: 100Mbit/s
       capacity: 1Gbit/s
       width: 64 bits
       clock: 33MHz
       capabilities: pm msi pciexpress msix vpd bus_master cap_list ethernet physical tp mii 10bt 10bt-fd 100bt 100bt-fd 1000bt 1000bt-fd autonegotiation
       configuration: autonegotiation=on broadcast=yes driver=r8169 driverversion=2.3LK-NAPI duplex=full firmware=rtl8168g-3_0.0.1 04/23/13 ip=192.168.11.26 latency=0 link=yes multicast=yes port=MII speed=100Mbit/s
       resources: irq:137 ioport:d000(size=256) memory:f1304000-f1304fff memory:f1300000-f1303fff
  *-network DISABLED
       description: Wireless interface
       product: Realtek Semiconductor Co., Ltd.
       vendor: Realtek Semiconductor Co., Ltd.
       physical id: 0
       bus info: pci@0000:05:00.0
       logical name: wlp5s0
       version: 00
       serial: 98:22:ef:ee:87:fb
       width: 64 bits
       clock: 33MHz
       capabilities: pm msi pciexpress bus_master cap_list ethernet physical wireless
       configuration: broadcast=yes driver=rtl8821ce latency=0 multicast=yes wireless=unassociated
       resources: irq:141 ioport:c000(size=256) memory:f1100000-f110ffff
  *-network
       description: Ethernet interface
       physical id: 2
       logical name: docker0
       serial: 02:42:ce:64:a6:c0
       capabilities: ethernet physical
       configuration: broadcast=yes driver=bridge driverversion=2.3 firmware=N/A ip=172.17.0.1 link=no multicast=yes

```

Ethernet interfaceのdriverを探します。
1つ目の`-network`→`configuration`→`driver`ですね。
そうすると、`driver=r8169`となっており、例の**r8169**が使用されてることが確認できました。

## スクリプトファイルの作成
システムがスリープ状態になる前後に、`/lib/systemd/system-sleep`以下にある実行可能なスクリプトをすべて実行しているらしい。
この辺の話は、`$ man systemd-suspend.service`で確認できる。
今回は`/lib/systemd/system-sleep`に、Ethernetのインターフェイスをリロードするスクリプトを作成することで、スリープ後にEthernetを再起動してネットが再度つながるようにする。
スクリプトは以下の通り。

```bash:r8169-refresh
#!/bin/bash

PROGNAME=$(basename "$0")
state=$1
action=$2

function log {
    logger -i -t "$PROGNAME" "$*"
}

log "Running $action $state"

if [[ $state == post ]]; then
    modprobe -r r8169 \
    && log "Removed r8169" \
    && modprobe -i r8169 \
    && log "Inserted r8169"
fi
```

これを`/lib/systemd/system-sleep/r8169-refresh`として保存。
更に、実行可能にするために、権限を変更しておく。

```bash:chmod
$ sudo chmod +x /lib/systemd/system-sleep/r8169-refresh
```

## 挙動確認
一度スリープ状態にした後、解除してネットが繋がるかを確認したところ、問題なくネットが通じた。
ログで確認してみる。

```bash:log
tk@tk-ThinkPad-E480:~$ grep r8169-refresh /var/log/syslog
Nov 14 21:20:00 tk-ThinkPad-E480 r8169-refresh[4187]: Running suspend pre
Nov 14 21:20:05 tk-ThinkPad-E480 r8169-refresh[4296]: Running suspend post
Nov 14 21:20:05 tk-ThinkPad-E480 r8169-refresh[4305]: Removed r8169
Nov 14 21:20:06 tk-ThinkPad-E480 r8169-refresh[4310]: Inserted r8169
```

きちんと作動していることが確認できた。

# おわりに
最近Network Disable Errorが起こるのでUpdateしてくれって警告を無視していたのがダメだったのかもしれない。
こういうスクリプトをさっとかけるようになりたい。（全部コピペ）

# 参照
-[Ubuntu 18.04 - Ethernet disconnected after suspend](https://askubuntu.com/questions/1029250/ubuntu-18-04-ethernet-disconnected-after-suspend)