cgminerをsystemdで管理する方法

## はじめに
ASICマイニング用のマイニングツール`cgminer`を、systemdで管理する方法です。

cgminerはフォアグラウンドで動作させる必要があり、そのままではバックグラウンドで動作させる事はできません。
今回はscreenを介して、バックグラウンドで動作させます。
併せて、systemdによりサービスとして管理させます。

## 動作確認した環境
以下の環境で動作を確認しています。
環境に応じて、適宜読み替えて下さい。

```
$ sudo cat /etc/debian_version 
10.7

$ uname -a
Linux debian 4.19.0-10-686-pae #1 SMP Debian 4.19.132-1 (2020-07-24) i686 GNU/Linux

$ cgminer --version
cgminer 4.11.1-wrk

$ cgminer -n
 [2021-03-22 13:43:40.226] USB all: found 5 devices - listing known devices
.USB dev 0: Bus 1 Device 3 ID: 0403:6015
  Manufacturer: 'GekkoScience'
  Product: 'NewPac Bitcoin Miner'                    
 [2021-03-22 13:43:40.231] 1 known USB devices      
```

`cgminer`は、以下のリポジトリをcloneし、hand makeしました。

https://github.com/wareck/cgminer-gekko

以下、cgminerが動作する状況を前提とします。

## cgminerをscreenで動かす・止める

以下のシェルスクリプトで、`screen`で、デタッチした状態で起動させます。
cgminer自身はroot権限を必要としない為、実行は一般ユーザーで問題ありません。

``` cgminer.screen.sh
#!/bin/sh

MINER="/usr/local/bin/cgminer"
SERVER="<Pool Addr>"
ADDR="<Your Wakllet Address>"
WORKER="<Your Worker Name>"
PASS="x"
SCREEN="cgminer"

screen -S ${SCREEN} \
${MINER} \
-o ${SERVER} \
-u ${ADDR}.${WORKER} 
```

実行すると、screen内でcgminerが起動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/53593/9742d791-8980-cfc7-617d-d354329c347b.png)

Ctrl+a, Ctrl+dで、デタッチし、プロセスを確認します。

```
$ screen -ls
There is a screen on:
        3979.cgminer    (03/22/2021 01:53:44 PM)        (Detached)
1 Socket in /run/screen/S-mika.
```

再度アタッチするには、以下のコマンドを実行します。
```$ screen -S cgminer -r
```

以降、screen使いの諸兄においてはいつもの事と思われますので、screenそのものの使い方は省略します。

### cgminerを停止する
デタッチされた状態からcgminerを停止するには、プロセスに`q`を送信します。

```
$ screen -S cgminer -X stuff "q"
```


この直後、`screen -ls`を実行すると、該当のプロセスが終了している事が確認できます。

```
$ screen -ls
No Sockets found in /run/screen/S-mika.
```
以上で、cgminerをscreenで運用する事が出来るようなりました。出来るようになりました。

## systemdでサービス化する
ここまでの内容を踏まえ、cgminer + screenを、systemdで管理させるようにします。

### 実行用のシェルスクリプトを用意する

本番の実行用シェルスクリプトを用意します。
今回、実行するユーザーは`mika:mika`、ホームディレクトリは`/home/mika/`とします。

``` /home/mika/bin/cgminer.sh
#!/bin/sh

MINER="/usr/local/bin/cgminer"
SERVER="<Pool Addr>"
ADDR="<Your Wakllet Address>"
WORKER="<Your Worker Name>"
PASS="x"

${MINER} \
-o ${SERVER} \
-u ${ADDR}.${WORKER} 
```

さいごに、スクリプトに実行権限を付けておきましょう。

```
$ chmod +x ./cgminer.sh
```

### systemdにサービスを追加する
rootに昇格後、以下のファイルを作成し、systemdにサービスとして追加します。

```/etc/systemd/system/cgminer.service 
[Unit]
Description=cgminer
After=network-online.target

[Service]
User=mika
Group=mika
TimeoutStopSec=90
WorkingDirectory=/home/mika/bin
ExecStart=/usr/bin/screen -Dm -S cgminer /home/mika/bin/cgminer.sh
ExecStop=/usr/bin/screen -S cgminer -X stuff "q"
Restart=always

[Install]
WantedBy=multi-user.target
```

追加が終わったら、サービスをリロードします。

```
# systemctl daemon-reload
```

### サービスを起動する

サービスをstart後、statusを見ると、以下のように動作している事が確認できます。

```
# systemctl start cgminer
# systemctl status cgminer
● cgminer.service - cgminer
   Loaded: loaded (/etc/systemd/system/cgminer.service; disabled; vendor preset: enabled)
   Active: active (running) since Mon 2021-03-22 14:15:45 JST; 2s ago
 Main PID: 7699 (screen)
    Tasks: 15 (limit: 4175)
   Memory: 2.2M
   CGroup: /system.slice/cgminer.service
           ├─7699 /usr/bin/SCREEN -Dm -S cgminer /home/mika/bin/cgminer.sh
           ├─7700 /bin/sh /home/mika/bin/cgminer.sh
           └─7701 /usr/local/bin/cgminer -o stratum+tcp://sa256.example.com:8888 -u ...

Mar 22 14:15:45 debian systemd[1]: Started cgminer.
```

### サービスを停止する

先と同様に、サービスをstopすると、cgminerおよびscreenが停止している事が確認できます。
メインプロセスが戻り値`1`で終了しているので異常のように思えますが、正常です。
（子プロセスがいきなりexitしてしまったので、Failと思っているようです）

```
root@debian:~# systemctl stop cgminer 
root@debian:~# systemctl status cgminer
● cgminer.service - cgminer
   Loaded: loaded (/etc/systemd/system/cgminer.service; disabled; vendor preset: enabled)
   Active: failed (Result: exit-code) since Mon 2021-03-22 14:18:03 JST; 1s ago
  Process: 7699 ExecStart=/usr/bin/screen -Dm -S cgminer /home/mika/bin/cgminer.sh (code=exited, status=1/FAILURE)
  Process: 8165 ExecStop=/usr/bin/screen -S cgminer -X stuff q (code=exited, status=0/SUCCESS)
 Main PID: 7699 (code=exited, status=1/FAILURE)
    Tasks: 0 (limit: 4175)
   Memory: 316.0K
   CGroup: /system.slice/cgminer.service

Mar 22 14:15:45 debian systemd[1]: Started cgminer.
Mar 22 14:18:03 debian systemd[1]: Stopping cgminer...
Mar 22 14:18:03 debian systemd[1]: cgminer.service: Main process exited, code=exited, status=1/FAILURE
Mar 22 14:18:03 debian systemd[1]: cgminer.service: Failed with result 'exit-code'.
Mar 22 14:18:03 debian systemd[1]: Stopped cgminer.
```

### 自動起動を設定する

Linux Serverを普段使いされている諸兄においては、いつもの事と思われますので、詳細は省略します。

```
# systemctl enable cgminer
# systemctl start cgminer
```

## おわりに
設定とか、例外処理とか、いろいろと端折りましたが、個人でも普段使いならこの程度で問題ない気がします。
DockerコンテナからUSBパススルーとかすると面白かったのかも知れませんが、そこまでの気力もないので、このあたりで。

## おまけ1 - デバイスの認識

USB ASICであるGekkoScience NEWPACは、OS上からは以下のように認識されます。

```
$ lsusb 
Bus 001 Device 003: ID 0403:6015 Future Technology Devices International, Ltd Bridge(I2C/SPI/UART/FIFO)
```

Windowsではドライバを`COMポート`から`WinUSB`に変更する必要がありましたが、Linuxの方では、その辺りよしなにしてくれるようです。

## おまけ2 - SHA256について
BItCoinで使用されている暗号化アルゴリズム`SHA256`ですが、現状ASIC Minerを使用した業者により大量のハッシュレートが提供されており、20GHs程度ではお金になりません。苦笑
今回、同じ暗号化アルゴリズムを採用している`すすコイン`を掘らせております。

https://susukino.com/index-jp.html

正直ネタコインの域を超えない感じは否めませんが、技術的興味を満たすには十分でしょう。