タワ記

気が向いた時にだけ書く、技術メモっぽいもの。

Linuxで使用するCPU数を動的に変更するスクリプト

この記事に書いてあること

  • タイトル通り。

enable-cpucores.sh

#!/usr/bin/env bash

MAX_CPU_INDEX=$(cat /sys/devices/system/cpu/present | awk -F "-" '{print $2}')
CPU_CORES=$((${MAX_CPU_INDEX}+1))
ENABLE_CORES=$1
SYS_CPU=/sys/devices/system/cpu/cpu

if [ ${EUID:-${UID}} != 0 ]; then
    echo "This script must be run as root."
    exit -1
fi

if [ $# -lt 1 ]; then
    echo "usage: $0 number_of_enable_cpu_cores"
    exit -1
fi

echo "Number of CPU: ${CPU_CORES}"

if [ ${ENABLE_CORES} -lt 1 ]; then
    echo "Number of enable cpu cores must be larger than 1."
    exit -1
fi

if [ ${ENABLE_CORES} -gt ${CPU_CORES} ]; then
    echo "Number of enable cpu cores must be smaller than ${CPU_CORES}."
    exit -1
fi

echo "Number of enable cores: ${ENABLE_CORES}"

ENABLE_LAST_INDEX=$((${ENABLE_CORES}-1))
DISABLE_FIRST_INDEX=${ENABLE_CORES}

echo "Always enable CPU index 0"

for n in `seq 1 ${ENABLE_LAST_INDEX}`; do
    echo "Enable CPU index $n"
    echo 1 > ${SYS_CPU}$n/online
done

for n in `seq ${DISABLE_FIRST_INDEX} ${MAX_CPU_INDEX}`; do
    echo "Disable CPU index $n"
    echo 0 > ${SYS_CPU}$n/online
done

使い方

4コアに制限する

$ sudo ./enable-cpucores.sh 4

動機

作ったプログラムの性能が、CPUコア数の影響をどの程度受けるのかを簡単に調べたかったので。

補足

プロセス1つとかだったら、tasksetコマンドで縛った方がお手軽。

Linuxで動いているローカルのsshサーバーホストのアドレスをbonjourで解決できるようにする

この記事に書いてあること

  • ローカルにいるsshサーバーホストにログインしたいけど、そのためにホストに固定IPを振ったり、DNSサーバーの設定変えたりするのが面倒なので、手っ取り早くbonjourを使うことにしたという話。
  • ssh hoge.local」でアクセス可能にする方法。

Ubuntu 20.04の場合の結論から先に。

$ sudo cp /usr/share/doc/avahi-daemon/examples/ssh.service /etc/avahi/services
$ sudo systemctl restart avahi-daemon.service

動機

わりとネットワーク周りの仕事をするという職業柄、どうしても実験用に何かしらのホストを立ち上げるということが多いです。
一度立ち上げてしまえば、そのホストはssh越しで操作するので直接触れることはあまりないのですが、そのためにはアドレス解決をできるようにしておかないといけません。
そのためには、

  • ホストのIPアドレスはstaticに振る、またはdhcpで固定のアドレスを振る
  • ホストの名前は/etc/hostsに書く、またはローカルのDNSサーバーをしかるべく設定する

ということになりますが、数が多いと毎度設定するのも面倒です。仕事が終わればその設定はゴミになりますし、私のようなアホの子は設定ファイルを見て「あれ?これもう要らねー設定だろ消してしまえ」と実は必要だった設定を消してしまったり、いつまでもゴミな設定を残してしまっていたりします。
そんなことからは解放されたいわけです。

方法としてのBonjour

Bonjourについては各位ググっていただくとして、よろしく設定してやれば対象ホストに対して「ssh hoge.local」みたいな感じでログイン可能になります。

インストール

Linuxで使えるBonjourの実装はavahiというものになります。
最近のUbuntu Desktopだと標準でインストールされています。他のディストリビューションは分かりませんが、大抵パッケージ化されているのではないでしょうか。

設定手順

ありがたいことにsshホストであることを広告するための設定が例として入っています。
Ubuntuの場合は/usr/share/doc/avahi-daemon/examples/ssh.serviceになります。他のディストリビューションの場合は/usr/share/docのどこかに入っていると思うので探せば見つかると思います。
この設定ファイルを/etc/avahi/servicesにコピーし、あとはavahi-daemonを再起動してやれば広告するようになります。

アクセス手順

正しく広告が行われると「ホスト名.local」という名前でアクセスできるようになります。
なお、当然ですがクライアント側は.localなドメインをavahiで名前解決するように設定されている必要があります。
Ubuntuの場合は標準で設定されているので、特に気にする必要はありません。

Ubuntu Server 20.04のインストール中にエラーが出る件

この記事に書いてあること

  • Ubuntu Server 20.04のインストール中にエラーが出たけど、回避できるかもしれない方法。

インストール先を確保するあたりでエラーが出る

何が原因かよくわかりませんが、ディスクの初期化なのかパーティションの確保なのか、そこら辺でインストーラ(subiquity)がエラーを吐いて進まない現象が出ました。
bugs.launchpad.net
どうもこれっぽいのですがsubiquityをアップデートしても直りませんでした。

回避策

インストール先のディスクにはLinux系の別のOSがインストール済みだったのですが、どうもこれがよろしくないのではないかと思い、手動でディスクを初期化したところエラーが出ませんでした。

Bluetooth LE(BLE)接続のマウスがWindows 10 Ver.2004で突然動かなくなる問題への対処方法

はじめに追記

  • 本記事中ではVer.2004(May 2020 Update; 20H1)としていますが、筆者環境で確認した限り、Ver.20H2(October 2020 Update)、Ver.21H1(May 2021 Update)、Ver.21H2でも同様です。

この記事に書いてあること

  • Windows 10 Ver.2004でBLE接続のマウス(たぶんキーボードなども)が使用中に突然動かなくなる問題へ対処するための設定方法。
  • BLEがぶら下がっているUSBホストコントローラの省電力設定を無効化すれば回避できたよ。

電源の管理タブどこへ行ったし

ということがありました。ありがたいことに「省電力絡みで切れることがあるよ」とリプライをいただいたので調べたところ、「デバイスマネージャからBluetoothバイスのプロパティの[電源の管理]タブで『電力の節約のために、コンピューターでこのデバイスの電源をオフにできるようにする』のチェックを外すとよい」という情報がありました。ところが、

f:id:twkmn:20200713131954p:plain

この赤丸部分にあったはずの[電源の管理]タブが、Windows 10 Ver.2004からは消滅しています。デバイスマネージャを見ていると、他のデバイスには[電源の管理]タブが存在するものもあるので、はてさて……。

USBホストコントローラの電源設定で回避

それならば「マウスがぶら下がっているデバイス」の方の電源設定を変更すればいいのでは?と思いました。PCの場合Bluetoothは基本的に、内蔵されているものかUSBドングルかどちらかなのですが*1、内蔵されているものも内部的にはUSBで接続されています。したがって、Bluetoothがぶら下がっているUSBの何某かの省電力設定が無効化できればよさそうです。ということで、

f:id:twkmn:20200713134743p:plain

まずBluetoothカテゴリにある当該のマウスを選択します(私の場合はMX Anywhere 2S)。選択だけしてプロパティは出さずに、

f:id:twkmn:20200713135135p:plain

[表示]メニュー-[デバイス(接続別)]を選びます。そうしますと、

f:id:twkmn:20200713135503p:plain

マウス(私の場合はMX Anywhere 2S)が、どこにぶら下がっているかがわかります。この環境の場合ですと、PCI Expressの先に「AMD USB 3.10ホストコントローラ」-「USBルートハブ」-「インテル Bluetoothホスト」がつながって、そこにマウスがさらにつながっているということになります。それでは一番怪しそうなUSBのホストコントローラ(この環境ではAMD USB 3.10 eXtensible Host Controller)のプロパティを見てみます。

f:id:twkmn:20200713140428p:plain

「電源の管理タブ」ありました。「電力の節約のために、コンピューターでこのデバイスの電源をオフできるようにする」のチェックを外して[OK]を押します。

とりあえずこの設定で、今のところは突然動かなくなる問題は発生していません。

余談

もしかしたらホストコントローラじゃなくて、一階層下のルートハブでもいいのかもしませんが、試していません。

*1:規格上はUARTもしくはSDIOもありえますが、最近はUSBしかお見掛けしないです。

Ubuntu 18.04でWireshark 3.0をソースからビルドしてインストールする。

この記事に書いてあること

  • Ubuntu 18.04でWireshark 3.0をソースからビルドしてインストールする方法。
  • 特定グループに所属している(root以外の)ユーザーにキャプチャする権限を付与する方法。

気付いたらいろいろ変わっていた

いつから変わったのか調べてはいませんが、Wiresharkのビルドシステムがautoconf/configureベースからcmakeに変更されていました。
ついでにQt5を使うようになっていました。
Ubuntu 18.04にインストールしようとしたら、地味に依存関係を探すのが面倒だったので、備忘録として残しておきます。

ソースコードのダウンロード

https://www.wireshark.org/download.htmlからソースコードをダウンロードできます。

依存ライブラリなどのインストール

$ sudo apt install cmake flex bison libgcrypt20-dev libssh-dev libpcap-dev libsystemd-dev qtbase5-dev qttools5-dev qtmultimedia5-dev libqt5svg5-dev

コンパイラ等はすでにインストールされている前提です。
しかしQt系のパッケージの銘々はいったいどういうルールになっているのでしょうか・・・・・・

ソースコードの展開とビルド・インストール

$ tar xvf wireshark-3.0.0.tar.xz 
$ cd wireshark-3.0.0
$ cmake .
$ make -j4
$ sudo make install

かつてconfigureしていた代わりにcmakeを使います。
make -jNのNはプロセッサコア数などに合わせて調整してください。

root以外のユーザーでキャプチャ可能にする

基本的には
https://wiki.wireshark.org/CaptureSetup/CapturePrivileges#Other_Linux_based_systems_or_other_installation_methodsの手順でOKです。
キャプチャ権限を持ったwiresharkグループを作り、ユーザーをwiresharkグループに登録する形です。

$ sudo groupadd wireshark
$ sudo gpasswd -a $USER wireshark
$ sudo chmod u+s /usr/local/bin/dumpcap 
$ sudo setcap cap_net_raw,cap_net_admin+eip /usr/local/bin/dumpcap 

必要に応じて、いったんログアウトしてください。
さて、これで行けるかと思いきや、wiresharkを実行するとインターフェースの一覧が出てきませんでした。
直接dumpcapを実行するとライブラリがロードできないというエラーが出ます。そこで、

$ sudo ldconfig

してやると、無事にwiresharkグループ所属のユーザーがキャプチャできるようになりました。

公開鍵をauthorized_keysに一撃で追加する。

この記事に書いてあること

  • タイトルそのままです。

公開鍵でsshログイン

公開鍵を使ってsshにログインするには、ホストのユーザーディレクトリにある.ssh/authorized_keysに公開鍵を追加する必要があります。
ssh_keygenすると.ssh/id_rsa.pubのようなファイルが出来上がるので、その内容をホストのauthorized_keysに追加すればOKです。
まあコピペでもいいわけですが・・・

一撃でやりたい

毎度のことなので一撃で済ませたいなと思ったので。

$ cat .ssh/id_rsa.pub | ssh foo@barhost -- "cat >> .ssh/authorized_keys"

そんなの当たり前じゃないかと言われそうですが、備忘録として。

Proxy配下のUbuntu DesktopでDockerを動かした時に地味にハマった。

※この記事はUbuntu 16.04(Desktopのみ)を前提として記載しています。

この記事に書いてあること

  • Proxy配下にあるUbuntu 16.04 DesktopでDockerを動かした際にプロキシとネームサーバー関連の設定で困ったよ。

Docker

Dockerは言わずと知れた、コンテナ型仮想環境を利用するためのソフトウェアです。
詳細についてはここでは述べませんので、必要のある方はググってくださいませ。

Proxy配下のUbuntu DesktopでDockerを使いたい

Ubuntu Desktopを使っているけど、「手元環境上において、Docker Hubで環境が提供されているようなサービスを試食したい」というケースがあると思います。
個人のプライベートな環境ではおそらく問題になりませんが、企業内では当該の環境がProxyの配下におり、直接外には出られないことも多いのではないでしょうか。

docker pullができない

Proxy配下だと、Docker pullができなくていきなりハマります。
これについてはすでに触れられている方がいらっしゃいましたので、リンクを貼っておきます。
要はdockerdを起動するときに、環境変数HTTP_PROXYを適切に設定しておけばよい、ということになります。
qiita.com

コンテナ環境からDNSによる名前解決ができない

Dockerはよくできていて、DNS設定が書かれている/etc/resolv.confは、通常ですとホスト環境の/etc/resolv.confを利用するようになってます。
したがって特に何もしなくても、Dockerホストの環境上で名前解決ができている場合には、コンテナ側からも問題なく動作するはずです。
ところが、Ubuntu DesktopをDockerホストにした場合、/etc/resolv.confを見ると・・・

# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
#     DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN

nameserver 8.8.8.8
nameserver 8.8.4.4

Google Public DNSを見に行くように設定されてしまいます。これらのアドレスへ直接アクセスできるネットワーク環境であれば問題にはなりませんが、Proxy配下にあるような場合は到達できず、名前解決ができません。

なぜGoogle Public DNSを見に行く設定になるのか

先ほども述べましたが、通常ですとホスト環境の/etc/resolv.confが利用されます。それがなぜ勝手にGoogle Public DNSになってしまうのでしょうか。
答えはsyslogに残っていました。

Feb 11 20:40:22 ubuntu-vm systemd[1]: Starting Docker Application Container Engine...
Feb 11 20:40:22 ubuntu-vm dockerd[7191]: time="2018-02-11T20:40:22.491330975+09:00" level=info msg="libcontainerd: new containerd process, pid: 7199"
.. 省略 ..
Feb 11 20:40:53 ubuntu-vm dockerd[7191]: time="2018-02-11T20:40:53.648196834+09:00" level=info msg="No non-localhost DNS nameservers are left in resolv.conf. Using default external servers: [nameserver 8.8.8.8 nameserver 8.8.4.4]"

「(ホストの)resolv.confの中にlocalhost以外のDNSサーバーがないから、8.8.8.8と8.8.4.4を使うよ」ということでした。
つまりホスト上のresolv.confと同じ内容にすると、自ら(localhost=自コンテナ)に対して名前問い合わせをすることになります。
一般的には(DNS機能のない)自らに問い合わせをしたところでエラーになるだけなので、代わりにGoole Public DNSを設定しておく仕様にしたのでしょうか。

なぜUbuntu Desktopのresolv.confは自分を指しているのか

ホスト環境の/etc/resolv.confでは、DNSとして127.0.1.1(自分)を引くようになっています。これはUbuntu Desktopが標準で抱えるNetwork ManagerがDNSのキャッシュを行っているので、それを利用するためです。
Ubuntu Desktopのデフォルトでは、DNSキャッシュはNetwork Manager管理下のdnsmasqが行なっています。
(なお厳密にはデフォルト設定だと「キャッシュ」は行なっておらず、単にForwarderとして動作しているだけだったりします)

Dockerホストに対してDNS問い合わせしたい

ホスト上にはDNSキャッシュが動いていますので、コンテナ側からはホストに対して問い合わせをすれば、期待通りに動きそうです。
そのためコンテナを起動する際に、--dnsオプションを使ってDockerホストのアドレスを(ここではホスト上のインターフェースdocker0が172.17.0.1の場合を例として)指定します。
以下、Docker Hub上のbusyboxイメージを使う場合で例示しています。

# docker run -it --dns=172.17.0.1 --rm busybox
/ # cat /etc/resolv.conf 
nameserver 172.17.0.1
/ # 

/etc/resolv.confが書き換わりました。これで引けるかと思いきや、ホスト側のdnsmasqはデフォルトでは127.0.1.1しかlistenしていません。
したがって、これだけですと問い合わせてもエラーとなりますので、172.17.0.1もlistenするように設定を追加する必要があります。
追加設定はホストの/etc/NetworkManager/dnsmasq.dにファイルを追加することで行います。
ここではdocker0というファイルを追加することにします。

# vim /etc/NetworkManager/dnsmasq.d/docker0

中身は以下のようにします。

listen-address=172.17.0.1

ファイルを作成したら、NetworkManagerを再起動します。

# systemctl restart network-manager.service

では、試してみましょう。

# docker run -it --dns=172.17.0.1 --rm busybox
/ # nslookup www.google.com
Server:    172.17.0.1
Address 1: 172.17.0.1

Name:      www.google.com
Address 1: 2404:6800:400a:809::2004 kix05s02-in-x04.1e100.net
Address 2: 216.58.199.228 kix05s02-in-f4.1e100.net
/ # 

期待通り、名前解決することができました。