- 投稿日:2021-01-12T22:36:47+09:00
障害時に早く作業するためのノウハウ集
目的
障害が起きた時に早く
- 原因特定
- 暫定対応
するために、知っておいた方が良い知識をまとめる。
ここで言う「障害」は、Web/Batch サーバの負荷が上がることを指す。
原因特定
- ロードアベレージから問題を切り分ける
- 1以下であれば軽く、1〜3くらいだとやや重く、それ以上だとこれらがボトルネックの可能性が高い
- ロードアベレージが高い場合
- CPU使用率、メモリ使用率、ディスクI/O
- ロードアベレージが低い場合
- TCPコネクション数
- 他サービスの遅延
- ネットワーク I/O はロードアベレージに換算されないので
- 下記でコマンド紹介しているけど、理想的にはモニタリングツールでさくっと見たい
- Datadog
- newrelic
- Mackerel
- ...
- 後コマンドも色々書いたけど、sar コマンドで大部事足りそう
ロードアベレージ
- top コマンド
- load average 項目に 1分 5分 15分の値が表示される
- Tasks 項目で各状態のタスクの数を見ることができる
- 合計タスク数 , 稼働中, 待機中, 停止タスク, ゾンビタスク
CPU使用率
- 全体の使用率
- アプリケーション側とカーネル空間側の切り分け
- top コマンド
- userはユーザモード、sysはシステム(カーネル)モードのCPU使用時間
- 後者は、ファイルへの書き込み時のカーネルのwrite()のシステムコールなど
- sar コマンド
- 過去タイミングでの値も確認できる
- %userはユーザモード、%systemはシステムモードCPU使用率
- 該当プロセスを特定する
- top コマンド
- Shift+p: CPU使用率順にソート
- ps コマンド
- ps aux
- a->自分以外のユーザーのプロセスについても表示
- u->ユーザー名と開始時刻を表示
- x->デーモンプロセスを表示
- ps -L
- スレッド情報も合わせて確認
- LWP列に軽量プロセスもしくはスレッドのID、NLWP列に総スレッド数
- passenger-status コマンド
- passenger で処理してるプロセス一覧が表示される
- なぜそのプロセスがボトルネックなのか特定する
- passenger-status --show=requests コマンド
- passenger で処理してる内容をプロセス毎に確認できる
- 適時 PID や path で絞り込む
- プロファイラ(oprofile)
- プログラム全体のどこに時間がかかっているか調べる
- どんな関数が何回呼ばれ、どのくらい時間がかかっているのか
メモリ使用率(ディスク I/O 遅延)
- 全体の使用率
- free コマンド
- メモリ総量(freeコマンド1行目のtotal列)
- ページキャッシュも含んだ利用できるメモリ量(freeコマンド2行目のfree列)
- 同期されていないページキャッシュを含むため、本当に利用可能なメモリ量より多めに見積もってしまっている
- 実際に利用できるメモリ量(MemFree+Inactive)
- 「MemFreeが少ない→利用可能な物理メモリ量が足りない」わけではない
- Inactive: 既にストレージと同期済みの捨てられるページキャッシュ
- cat /proc/meminfo | egrep -e "Active:|Inactive:|MemFree:"
- ps コマンド
- VSZ(Virtual Set Size)はプロセスが確保した仮想メモリ領域のサイズ
- RSS(Resident Set Size)は物理メモリ領域
- 値が高い場合、大量のスワップが発生している可能性がある
- passenger-memory-stats コマンド
- passengerのプロセスのメモリの使用状況が確認できる
- VMSize: 仮想メモリ領域のサイズ
- Private: 物理メモリの領域のサイズ
- ディスク I/O 遅延が起きているか確認
- top コマンド
- Dの状態が続いてるプロセスがあればその可能性あり
- D: 割り込み不能
- R: 実行中
- S: スリープ状態
- T: 停止中
- Z: ゾンビプロセス
- vmstat コマンド
- cpu項の「id」列ではアイドル(空いている)割合をパーセント
- 「wa」列ではストレージのIO完了待ち
- swapが多発/読み書き量が増えていないか確認
- sar -W
- pswpin/s 1秒間にスワップインしているページ数
- pswpout/s 1秒間にスワップアウトしているページ数
- sar -B
- pgpgin/s 1秒間にスワップ領域からメモリへページ・インしたキロバイト数
- pgpgout/s 1秒間にメモリからスワップ領域へページ・アウトしたキロバイト数
- 該当プロセスを特定する
- top コマンド
- Shift+m: メモリ使用率順にソート
- passenger-status コマンド
- passenger で処理してるプロセス一覧が表示される
- なぜそのプロセスがボトルネックなのか特定する
- passenger-status --show=requests コマンド
- プロファイラ(oprofile)
ディスク空き容量
- df コマンド
- Used:使用しているディスク容量
- Available:ディスクの空き容量
- Use%:ディスク使用率
- Mounted on:ディレクトリ
- df -h
- 空き容量を人が見やすいようなGB,MB,KB表示にできる
- df ディレクトリ名
- 各ディレクトリの空き容量
- du コマンド
- du -s /home
- /homeの合計容量のみ確認
TCPコネクション数
- netstatコマンド
- ホストのネットワーク接続状態やソケット/インターフェイスごとのネットワーク統計などを確認する
- ESTABLISHED状態(接続中)のコネクションのみが表示
- netstat -an
- -a: 現在のすべての接続を表示する
- TCP接続に加えて、UDPやRAWソケットについてもリストアップされる
- -n: 出力をIPアドレスなど数値のみに抑制する
- State
- ESTABLISHEDとなっているのが現在有効な接続
- LISTENである接続は、外部からの接続待ち受け(ソケットのLISTEN状態)を行っている
- netstat -s
- IPやTCP/UDP、ICMPといったプロトコルごとの統計情報が確認
ネットワーク I/0
- I/O 遅延が起きているか確認
- top コマンド
- Sの状態が続いてるプロセスがあればその可能性あり
- ネットワークを介したデータ送受信も含むため
- 外部サービス間で遅延が起きてないか確認
- スロークエリの特定
SELECT id, time, state, substring(info,1,200) FROM INFORMATION_SCHEMA.PROCESSLIST where time > 1 and info is not null order by time desc;
- なぜ遅いのかは実行計画を確認
explain select a,b from abc;
ログ調査
- アプリケーションログ
- rails 前提だと、Rails.logger の出力先
- apache ログ
- /etc/httpd/conf/httpd.conf で設定内容を確認する
- syslog
- /var/log
- /etc/rsyslog.conf で設定内容を確認する
暫定対応
よく使うものを記載する。
apache
- apacheの再起動(停止させずに)
# /etc/rc.d/init.d/httpd graceful
ロードバランサ
- 外部からのトラフィックを遮断する
- ALBからインスタンスを切り離す
- aws コンソールの ec2 画面に入る
- 左メニューの「ターゲットグループ」をクリック
- 対象のターゲットグループをクリック
- Targetsタブからインスタンスを指定して「Deregister」をクリック
プロセス停止
- kill -USR1 [PID]
- 止まらなければ、止めて問題ないことを確認した上で kill -9 [PID]
- 子プロセスを停止する
- 親プロセスをkillしても、子プロセスが停止するとは限らない
- その場合Linuxでは「initプロセスの養子」となる
- 一般的なデーモンプログラムなどは自分が死ぬときは基本的に子プロセスをkillする場合が多い
ロールバック
アプリケーション依存
参考
- 【初心者向け】Linuxのプロセスについて一通りわかる!
- 【初心者向け】サーバが重い時に確認すべきこと & サーバの基礎知識
- LoadAverage(ロードアベレージ)について
- システムの負荷の原因を切り分ける方法
- topコマンドの使い方
- psコマンドで表示される内容について調べた
- Linuxパフォーマンス調査などで使うコマンドメモ
- 【Linuxコマンド】dfでディスクの空き容量を確認する
- netstat ~ホストのネットワーク統計や状態を確認する
- 投稿日:2021-01-12T18:33:18+09:00
DLしたLaravelの環境構築方法(Linux)
【前提条件】composerがインストール済み Lamp環境が正常に構築できている。
githubからDLしたLaravelプロジェクトをとりあえず動かせる
用にするまでの設定します。1、laravelプロジェクトをDLしてみる
ギットハブにアクセスしてとりあえず適当なLaravelのプロジェクトをDLしてみましょう【プロジェクト名testlaravel】
2、composerをインストールする
DLしたtestlaravelプロジェクトのserveを起動しようとするとこのようなエラーが出てきます。
/var/www/html/testlaravel$ php artisan serve こんなエラーが出てきます↓ PHP Warning: require(/var/www/html/testlaravel/vendor/autoload.php): failed to open stream: No such file or directory in /var/www/html/testlaravel/artisan on line 18 Warning: require(/var/www/html/testlaravel/vendor/autoload.php): failed to open stream: No such file or directory in /var/www/html/testlaravel/artisan on line 18 PHP Fatal error: require(): Failed opening required '/var/www/html/testlaravel/vendor/autoload.php' (include_path='.:/usr/share/php') in /var/www/html/testlaravel/artisan on line 18 Fatal error: require(): Failed opening required '/var/www/html/testlaravel/vendor/autoload.php' (include_path='.:/usr/share/php') in /var/www/html/testlaravel/artisan on line 18Composerが入っていないためLaravelプロジェクトが起動できないのでcomposerをインストールします
/var/www/html/testlaravel# composer install3、composerのインストールが完了したら
composerのインストールが完了したら早速testlaravelプロジェクトを立ち上げてみましょう
/var/www/html/testlaravel# php artisan serve立ち上がることは立ち上がりますが、ここで必ず500サーバーエラーが発生します。
4、.envファイルとAPP_KEYの設定を行う
ここでエラーが発生する要因としてlaravelに.envファイルが作成されていない
APP_keyが作成されていない事が要因でサーバーエラーが発生しています。まずは.envファイルを作成してみます。コマンドで以下の用に入力します
cp .env.example .envこの段階ではまだenvファイルは作成されてませんのでAPP_KEYの作成をしてみます
php artisan key:generatevi .envと入力して無事.envファイルが作成されていれば完成です
↓こんな奴ですAPP_NAME= APP_ENV= APP_KEY= APP_DEBUG= APP_URL= LOG_CHANNEL= DB_CONNECTION= DB_HOST= DB_PORT= DB_DATABASE= DB_USERNAME= DB_PASSWORD= (以下略)
- 投稿日:2021-01-12T16:13:22+09:00
マジョカアイリス細長液晶をラズパイで使う
この記事について
ラズパイのLinux framebuffer の仕組みを使ったfbtft にて、細長液晶へ映像を送ります。
今回の記事は、デスクトップ画面を縮小転送しています。
カーネル5.4以下での方法です。ラズパイ細長液晶で Doom
— でべ (@devemin) January 12, 2021
まるまる画面転送は遅いなw pic.twitter.com/BnDHkm8lIi環境
ラズパイ3B+ (カーネル5.4以下。 カーネル5.4~の場合は、下の方(できない場合)を参照)
マジョカアイリス細長液晶
電源(茶色基板液晶なら6V程、みどり基板液晶なら12V程?)
https://github.com/htlabnet/inside_magimajopures/wiki/sushi_chika接続
@komikoni さんのが見やすいです。
https://github.com/htlabnet/inside_magimajopures/blob/main/640x48_LCD_ESP32/640x48_LCD_ESP32.inoですです!
— でべ (@devemin) January 10, 2021
RD は 3.3V につなげないと表示されないかもしれません? pic.twitter.com/pwNns43idw// 1 - GND [to GND] // 2 - RST [to RSPI - 4] // 3 - GND [to GND] // 4 - D0 [to RSPI - 5] // 5 - D1 [to RSPI - 6] // 6 - D2 [to RSPI - 13] // 7 - D3 [to RSPI - 19] // 8 - D4 [to RSPI - 26] // 9 - D5 [to RSPI - 12] // 10 - D6 [to RSPI - 16] // 11 - D7 [to RSPI - 20] // 12 - GND [to GND] // 13 - RD [to 3.3V] // 14 - WR [to RSPI - 7] // 15 - CS [to RSPI - 2] // 16 - DC [to RSPI - 3] // 17 - TE [OPEN] // 18 - VDD [to 3.3V] // 19 - VDDIO [to 3.3V] // 20 - LED+ [to 5.5V~] // 21 - LED- [to GND] // 22 - GND [to GND]コマンド
液晶をラズパイに接続後、下記コマンド2つを実行すると、液晶が黒い画面になり、映像転送の準備OKとなります。
sudo modprobe flexfb width=320 height=96 buswidth=8 init=\ -1,0xC8,0xFF,0x93,0x42,\ -1,0x2A,0x00,0x00,0x01,0x3F,\ -1,0x2B,0x00,0x00,0x00,0x5F,\ -1,0x36,0xC8,\ -1,0xC0,0x0E,0x0E,\ -1,0xC1,0x10,\ -1,0xC5,0xFA,\ -1,0x3A,0x55,\ -1,0xB1,0x00,0x18,\ -1,0xE0,0x00,0x1C,0x21,0x02,0x11,0x07,0x3D,0x79,0x4B,0x07,0x0F,0x0C,0x1B,0x1F,0x0F,\ -1,0xE1,0x00,0x1C,0x20,0x04,0x0F,0x04,0x33,0x45,0x42,0x04,0x0C,0x0A,0x22,0x29,0x0F,\ -1,0x11,-2,130,\ -1,0x29,-2,10,\ -3 sudo modprobe fbtft_device name=flexpfb speed=10000000 gpios=reset:4,dc:3,wr:7,cs:2,db00:5,db01:6,db02:13,db03:19,db04:26,db05:12,db06:16,db07:20(できない場合)
この記事はカーネル5.4以下でのやり方です。5.4以上でやると、flexfb 等のモジュールのmodprobe で not found になります。
fbtft リポジトリのwiki によると、カーネル5.4以降ではfbtftという名前で、デバイスツリーでの管理になってるようです。uname -rで5.4 以降のカーネルが稼働している場合、このページのやり方ではできなそう
https://github.com/notro/fbtft/wiki
fbtft_device and flexfb are gone in 5.4下記ページが参考になりそうでした
https://akkiesoft.hatenablog.jp/entry/20201218/1608217260デスクトップの映像を転送する
https://github.com/notro/fbtft/wiki/Framebuffer-use
こちらで紹介されていた、Framebuffer mirroring の仕組みを利用します。https://github.com/tasanakorn/rpi-fbcp
こちらの、sudo apt-get install cmake git clone https://github.com/tasanakorn/rpi-fbcp cd rpi-fbcp/ mkdir build cd build/ cmake .. make sudo install fbcp /usr/local/bin/fbcpmake の前に、main.c の 57行目を
screen_resource = vc_dispmanx_resource_create(VC_IMAGE_RGB565, vinfo.xres, vinfo.yres, &image_prt);↓
screen_resource = vc_dispmanx_resource_create(VC_IMAGE_RGB565, vinfo.xres*2, vinfo.yres/2, &image_prt);に修正して、make してください。
(1ラインごとにずれている仕様を補正しているつもりです。)fbcpビルドした fbcp を実行すれば、映像が細長液晶に転送されています!
ラズパイのデスクトップそのまま送られるので、いろいろ出来そう?お楽しみください♪
(ちなみに、映像をまるっと縮小コピーしてるだけなので遅いです・・・)
補足
液晶をリセットしたいときは、液晶基板への3.3v電源を抜き差して、
sudo modprobe -r flexfb sudo modprobe -r fbtft_device lsmod | grep fbでドライバがアンロードされるので、再度ドライバを読み込んでください。
参考
つぎ
— でべ (@devemin) January 10, 2021
fbset -i -fb /dev/fb1
これでframebuffer として登録されるので、python なりアプリなりもろもろで画像転送できる
参考:https://t.co/ljVkNjdXr5https://t.co/YOOzGghdzXhttps://t.co/PIL93s7vR0https://t.co/iKOd1lxmmFhttps://t.co/adJu7p6mXY
- 投稿日:2021-01-12T09:00:20+09:00
Raspberry Pi 4とWSL2を使ってYocto Project入門
はじめに
先日Raspberry Pi 4でUbuntuデスクトップを動かして遊ぶでラズパイを触ってみたのですが,今度はこのラズパイをYocto Projectを使って動かしてみました.
Yoctoをはじめて使ってみたのですが,いい入門になったと思うので内容をまとめます.Ycto Projectとは?
主には組込みおよびIoT向けのLinuxディストリビューションを作成するための仕組み・ツールが用意されています.柔軟にカスタマイズしながら組込みLinuxイメージをビルドすることができます.多くの組込みLinuxプロバイダで採用されているようです.
Yocto Project - Wikipediaやってみたこと
手もとにあったRaspberry Pi 4をYoctoでビルドしたイメージで起動してみました.
- Raspberry Pi 4をターゲットにしてビルド
- 簡単なレシピを用意してHello world!
- Wi-FiでSSH接続できるように設定
- Pythonを追加して開発環境の構築
- ツールチェーンを作成してクロスコンパイル環境構築
今回の開発環境
YoctoのビルドはWSL2のUbuntu 20.04 LTSで行いました.ターゲットは前述のとおりRaspberry Pi 4です.
- Windows 10 Pro(20H2)
- Ubuntu 20.04 LTS(WSL2)
- Yocto Project(3.2 Gatesgarth)
- Raspberry Pi 4(4GB)
前準備
まずはWSL2をインストールします.ディストリビューションは今回はUbuntu 20.04 LTSを使っています.
手順は例えばこちらを参考にしてください.
https://docs.microsoft.com/ja-jp/windows/wsl/install-win10環境が立ち上がったら,とりあえずパッケージの更新を行っておきます.
$ sudo apt update && sudo apt upgrade -y次にYocto Project Quick Startを参考にして必要なパッケージのインストールを行います.
$ sudo apt install -y gawk wget git-core diffstat unzip texinfo gcc-multilib build-essential chrpath socat cpio python python3 python3-pip python3-pexpect xz-utils debianutils iputils-ping libsdl1.2-dev xtermRaspberry Pi 4をターゲットにしてビルド
まずはPoky(リファレンス・ディストリビューション)をGitでクローンします.
バージョンはこの時点で最新のGatesgarth(Yocto 3.2)
を指定しています.
Releases - Yocto Project$ mkdir ~/yocto && cd ~/yocto $ git clone git://git.yoctoproject.org/poky $ cd poky $ git checkout -b gatesgarth-24.0.1 refs/tags/gatesgarth-24.0.1次にRaspberry Pi用のBSPレイヤーを追加します.
OpenEmbedded Layer Indexにmeta-raspberrypi
というのがあるので,これをクローンします.ブランチはPokyに合わせてgatesgarth
を指定しています.$ cd ~/yocto/poky $ git clone git://git.yoctoproject.org/meta-raspberrypi $ cd meta-raspberrypi $ git checkout -b gatesgarth origin/gatesgarth
meta-raspberrypi
のREADMEに書かれている手順を参考にします.Dependencies This layer depends on: * URI: git://git.yoctoproject.org/poky - branch: master - revision: HEAD * URI: git://git.openembedded.org/meta-openembedded - layers: meta-oe, meta-multimedia, meta-networking, meta-python - branch: master - revision: HEAD Quick Start 1. source poky/oe-init-build-env rpi-build 2. Add this layer to bblayers.conf and the dependencies above 3. Set MACHINE in local.conf to one of the supported boards 4. bitbake core-image-base 5. Use bmaptool to copy the generated .wic.bz2 file to the SD card 6. Boot your RPIまずは
oe-init-build-env
を読み込んで環境をセットアップします.実行するとrpi-build
ディレクトリが作成されて移動しています.ビルドはこのディレクトリで行います.$ cd ~/yocto/poky $ source oe-init-build-env rpi-build次にこのレイヤーの追加設定を行います.
add-layer
するとconf/bblayers.conf
にmeta-raspberrypi
が追加されます.$ bitbake-layers add-layer ../meta-raspberrypi/ $ cat conf/bblayers.conf : BBLAYERS ?= " \ /home/user/yocto/poky/meta \ /home/user/yocto/poky/meta-poky \ /home/user/yocto/poky/meta-yocto-bsp \ /home/user/yocto/poky/meta-raspberrypi \ "次にREADMEに書かれている依存レイヤーも同様に追加します.こちらもブランチは
gatesgarth
を指定します.またadd-layer
実行する順番によってエラーが出てしまうので,下記の順で追加を行ってください.$ cd ~/yocto/poky $ git clone git://git.openembedded.org/meta-openembedded $ cd meta-openembedded $ git checkout -b gatesgarth origin/gatesgarth $ cd ~/yocto/poky/rpi-build $ bitbake-layers add-layer ../meta-openembedded/meta-oe/ $ bitbake-layers add-layer ../meta-openembedded/meta-python/ $ bitbake-layers add-layer ../meta-openembedded/meta-multimedia/ $ bitbake-layers add-layer ../meta-openembedded/meta-networking/ $ cat conf/bblayers.conf : BBLAYERS ?= " \ /home/user/yocto/poky/meta \ /home/user/yocto/poky/meta-poky \ /home/user/yocto/poky/meta-yocto-bsp \ /home/user/yocto/poky/meta-raspberrypi \ /home/user/yocto/poky/meta-openembedded/meta-oe \ /home/user/yocto/poky/meta-openembedded/meta-python \ /home/user/yocto/poky/meta-openembedded/meta-multimedia \ /home/user/yocto/poky/meta-openembedded/meta-networking \ "次に
local.conf
のMACHINE
を設定します.指定するマシン名はこちらのMachinesを参考にしてください.今回は下記のように設定しています.~/yocto/poky/rpi-build/conf/local.confMACHINE ?= "raspberrypi4-64"最後にWSL2を使った場合に下記のエラーがビルド時に出てしまいました.(VMwareにインストールしたUbuntu 18.04ではこのエラーは発生しませんでした.)Stack Overflowにあった対処で解決しました.
ERROR: Task (/home/user/yocto/poky/meta/recipes-kernel/linux-libc-headers/linux-libc-headers_5.8.bb:do_install) failed with exit code '134'
~/yocto/poky/rpi-build/conf/local.confPSEUDO_IGNORE_PATHS_append = ",/run/"ここまでで設定は完了です.
bitbake
コマンドでビルドを実行します.ビルドにはかなり時間がかかりますし,PCもフルで動きます.気長に待ちましょう.
参考に自分のノートPC(CPU:Core i7-8550U,メモリ:16.0 GB)では3~4時間ほどかかりました.またSSDは50GBほど使用します.$ cd ~/yocto/poky/rpi-build $ bitbake core-image-baseまたWSL2を使用している場合は下記の警告が表示されます.対処はこちらの「6. Optimize your WSLv2 storage often」参照してください.
WARNING: You are running bitbake under WSLv2, this works properly but you should optimize your VHDX file eventually to avoid running out of storage spaceビルドが完了すると
rpi-build/tmp/deploy/images/raspberrypi4-64
にOSイメージができあがっています.
bmaptool
コマンドを使ってcore-image-base-raspberrypi4-64.wic.bz2
をSDカードに書き込みます.ただ今回使用しているWSL2環境ではSDカードのデバイス名をどのように指定するのかが分かりませんでした.$ cd ~/yocto/poky/rpi-build/tmp/deploy/images/raspberrypi4-64 $ sudo apt install -y bmap-tools $ sudo bmaptool copy core-image-base-raspberrypi4-64.wic.bz2 /dev/sdX # SDカードのデバイス名をどのように指定できるのか不明そこで今回はwic.bz2を解凍してからWindows上でRaspberry Pi Imagerを使ってSDカードに書き込みました.
$ cd ~/yocto/poky/rpi-build/tmp/deploy/images/raspberrypi4-64 $ cp core-image-base-raspberrypi4-64.wic.bz2 /tmp/. # シンボリックリンクになっているので適当な場所にコピー $ bunzip2 /tmp/core-image-base-raspberrypi4-64.wic.bz2 $ mv /tmp/core-image-base-raspberrypi4-64.wic /mnt/c/Users/user/Downloads/. # Windows側の適当なディレクトリに移動Operating SystemでUse customから
core-image-base-raspberrypi4-64.wic
を選択してSDカードに書き込みます.
他にもEtcherやDD for Windowsなどで書き込んでも問題ないと思います.
作成したSDカードをラズパイに挿して電源を入れるとOSが起動します.
コンソールへの出力が止まってEnterキーを押すとlog in:
と表示されるのでroot
でログインします.パスワードはありません.
成功すれば最小限の環境ですがしっかりとターミナルで操作が可能です.raspberrypi4-64 log in: root root@raspberrypi4-64:~# uname -mnr raspberrypi4-64 5.4.72-v8 aarch64 root@raspberrypi4-64:~# cat /etc/issue Poky (Yocto Project Reference Distro) 3.2.1 \n \l簡単なレシピを作成してHello world!
次は自前の簡単なソースコードを書いて,コンパイルしてできた実行バイナリをインストールする手順をまとめます.
下記が参考になります.
Creating a General Layer Using the bitbake-layers Scriptまずはレイヤーを作成します.下記のコマンドを実行すると
meta-hello
ディレクトリとその中に雛形が作成されます.$ cd ~/yocto/poky $ bitbake-layers create-layer meta-hello $ ls meta-hello/ COPYING.MIT README conf recipes-example続けて作成したレイヤーの追加設定を行います.
$ cd ~/yocto/poky/rpi-build $ bitbake-layers add-layer ../meta-hello/ $ cat conf/bblayers.conf : BBLAYERS ?= " \ /home/user/yocto/poky/meta \ /home/user/yocto/poky/meta-poky \ /home/user/yocto/poky/meta-yocto-bsp \ /home/user/yocto/poky/meta-raspberrypi \ /home/user/yocto/poky/meta-openembedded/meta-oe \ /home/user/yocto/poky/meta-openembedded/meta-python \ /home/user/yocto/poky/meta-openembedded/meta-multimedia \ /home/user/yocto/poky/meta-openembedded/meta-networking \ /home/user/yocto/poky/meta-hello \次にソースコードを用意します.下記のように
files
ディレクトリを作成しソースコードを配置します.$ cd ~/yocto/poky/meta-hello $ mkdir -p recipes-hello/hello && cd recipes-hello/hello $ mkdir files && cd files $ vim hello.c用意したのはC言語のHello worldです.
hello.c#include <stdio.h> int main(int argc, char const *argv[]) { printf("Hello, world!\n"); return 0; }次にレシピ(パッケージのビルドのために使用されるメタデータ)を作成します.
$ cd ~/yocto/poky/meta-hello/recipes-hello/hello $ vim hello_1.0.bbレシピファイルの書き方はこちらが参考になります.
Single .c File Package (Hello World!)
ただし,このままではビルドに失敗するのでTARGET_CC_ARCH += "${LDFLAGS}"
を追加します.
Default Linker Hash Style Changed
またLIC_FILES_CHKSUM
のmd5
が分からない場合は空白にしておくと,ビルド時に正しい値がエラーで表示されます.hello_1.0.bbSUMMARY = "Simple helloworld application" SECTION = "hello" LICENSE = "MIT" LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302" TARGET_CC_ARCH += "${LDFLAGS}" SRC_URI = "file://hello.c" S = "${WORKDIR}" do_compile() { ${CC} hello.c -o hello } do_install() { install -d ${D}${bindir} install -m 0755 hello ${D}${bindir} }最終的に次のようなディレクトリ・ファイル構成になります.
meta-hello/ ├── COPYING.MIT ├── README ├── conf │ └── layer.conf ├── recipes-example │ └── example │ └── example_0.1.bb └── recipes-hello └── hello ├── files │ └── hello.c └── hello_1.0.bb最後に
local.conf
のIMAGE_INSTALL_append
でイメージの追加を指定します.~/yocto/poky/rpi-build/conf/local.confIMAGE_INSTALL_append = " hello" # 先頭の空白文字が必要なので注意ここまで準備ができたらビルドを行います.
$ cd ~/yocto/poky/rpi-build/ $ bitbake core-image-baseできあがったOSイメージをSDカードに書き込んでラズパイで起動します.ログインして
hello
コマンドが実行できることを確認します.うまくいくとHello, world!
が表示されます.raspberrypi4-64 log in: root root@raspberrypi4-64:~# hello Hello, world!Wi-FiでSSH接続できるように設定
次はWi-Fi経由でSSH接続できるように設定します.
ここまでの環境で,ip
コマンドで確認するとwlan0
は認識されているようです.root@raspberrypi4-64:~# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq qlen 1000 link/ether dc:a6:32:b8:2b:4a brd ff:ff:ff:ff:ff:ff 3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP8000> mtu 1500 qdisc pfifo_fast qlen 1000 link/ether dc:a6:32:b8:2b:4b brd ff:ff:ff:ff:ff:ffWi-Fi接続を行うにはConnManを使用するのが簡単そうです.local.confでイメージの追加設定を行います.
またSSH接続を行うためにOpenSSHの追加を行います.こちらを参考にしてIMAGE_FEATURES
に指定するとよさそうです.~/yocto/poky/rpi-build/conf/local.confIMAGE_INSTALL_append = " connman connman-client" IMAGE_FEATURES_append = " ssh-server-openssh"ここまでで
bitbake core-image-base
してOSイメージをビルドして,SDカードからラズパイを起動します.
connmanctl
コマンドを使って次の手順でWi-Fi接続設定を行います.root@raspberrypi4-64:~# connmanctl connmanctl> enable wifi connmanctl> scan wifi connmanctl> services Buffalo-A-0F20 wifi_dca632b82b4b_42756666616c6f2d412d30463230_managed_psk Buffalo-G-0F20 wifi_dca632b82b4b_42756666616c6f2d472d30463230_managed_psk WARPSTAR-D56FD6 wifi_dca632b82b4b_57415250535441522d443536464436_managed_psk connmanctl> agent on connmanctl> connect wifi_dca632b82b4b_42756666616c6f2d412d30463230_managed_psk Passphrase? connmanctl> exitパスフレーズの入力まで完了したら
connmanctl
を終了し,再度ip
コマンドで確認するとwlan0
にIPアドレスが割り振られています.
このIPアドレスにSSH接続を試すとrootでログインができるはずです.$ ssh root@192.168.1.8 # ラズパイのwlan0に割当たっているIPアドレス Last login: Sun Jan 10 02:06:14 2021 from 192.168.1.7 root@raspberrypi4-64:~#SSH接続とは直接関係ないですが,手もとの開発環境でSFTPが使えると便利だったので追加しています.
ついでにrootのパスワード設定とpiユーザの新規作成も行っておきます.あわせてsudo
コマンドも追加します.
またOpenSSHの追加で調べているとsystemdを有効にする設定をよく見かけたのでこれも入れておきます.~/yocto/poky/rpi-build/conf/local.confIMAGE_INSTALL_append = " openssh-sftp-server sudo" IMAGE_FEATURES_append = " ssh-server-openssh" # user settings INHERIT_append = " extrausers" EXTRA_USERS_PARAMS = "useradd -P raspberry pi;usermod -P raspberry root;" # systemd settings DISTRO_FEATURES_append = " systemd" VIRTUAL-RUNTIME_init_manager = "systemd" DISTRO_FEATURES_BACKFILL_CONSIDERED = "sysvinit" VIRTUAL-RUNTIME_initscripts = "" IMX_DEFAULT_DISTRO_FEATURES_append = " systemd"ここまででビルドして,ラズパイで起動してSSH接続を確認します.(今回のビルドはまた時間がそこそこかかります.)
rootの他にpiユーザでもSSHでログインできます.パスワードは新規に設定したものを使用します.(この例だとraspberry
)piユーザでsudoを使えるようにするにはrootから
visudo
コマンドで設定します./etc/sudoersroot ALL=(ALL) ALL pi ALL=(ALL) ALL # ここを追記Pythonを追加して開発環境の構築
開発環境としてPythonを追加します.ラズパイを使っているので
rpi-gpio
を追加してGPIOの制御を簡単に行ってみます.また手元にLEDなどがなかったので,raspi-gpio
というGPIOを制御するコマンドを使って確認をします.~/yocto/poky/rpi-build/conf/local.confIMAGE_INSTALL_append = " python3 python3-pip rpi-gpio raspi-gpio"OSイメージをビルドしてラズパイで起動します.rootユーザで確認をしています.
Pythonとpipが使用できるか確認してみます.下記のように出力されてrpi-gpio
が追加されていることも確認できます.# python3 --version Python 3.8.5 # python3 -m pip list Package Version ---------- ------- pip 20.0.2 RPi.GPIO 0.7.0 setuptools 49.6.0
raspi-gpio
コマンドが使えることも確認しておきます.helpで簡単な使い方が確認できると思います.
GPIO1番ピンはデフォルトだと入力でプルアップになっているようです.# raspi-gpio help # raspi-gpio get 1 GPIO 1: level=1 fsel=0 func=INPUT pull=UPPythonでGPIOを制御する簡単なサンプルコードを書きます.GPIO1番ピンを出力設定にして,1秒ごとにON/OFFを切り替えます.
gpio.pyimport time import RPi.GPIO as GPIO def main(): pin_num = 1 GPIO.setmode(GPIO.BCM) GPIO.setup(pin_num, GPIO.OUT) for i in range(10): GPIO.output(pin_num, i % 2) print(f'GPIO {"ON" if i % 2 else "OFF"}') time.sleep(1) GPIO.cleanup(pin_num) if __name__ == '__main__': main()上記のPythonコードを実行しながら
raspi-gpio
を繰り返し実行してGPIO1番ピンを確認すると,funcが出力に切り替わってlevelが0/1と切り替わっている様子が確認できます.# python3 gpio.py # 実行中に下記を別セッションで確認 # raspi-gpio get 1 GPIO 1: level=0 fsel=1 func=OUTPUT pull=NONE # raspi-gpio get 1 GPIO 1: level=1 fsel=1 func=OUTPUT pull=NONE # raspi-gpio get 1 GPIO 1: level=0 fsel=1 func=OUTPUT pull=NONE # raspi-gpio get 1 GPIO 1: level=1 fsel=1 func=OUTPUT pull=NONEGPIOをデバイスファイルから制御する方法
raspi-gpioを使わずにGPIOをデバイスファイルから制御する方法についても簡単にまとめておきます.
下記の手順で確認するとGPIO1番ピンがデフォルトでは入力になっているのが分かります.この方法でもPythonのサンプルコードを実行して出力に切り替わってON/OFFしている様子が確認できます.# cd /sys/class/gpio # ls export gpiochip0 gpiochip504 unexport # echo 1 > export # ls export gpio1 gpiochip0 gpiochip504 unexport # cd gpio1 # ls active_low device direction edge power subsystem uevent value # cat active_low direction value 0 in 1ツールチェーンを作成してクロスコンパイル環境構築
最後にツールチェーンをビルドして,ローカルのPCにクロスコンパイル環境を構築します.
今回はC++のコードをビルドして動かしたのですが,実行するとlibstdc++.so.6
が見つからないというエラーが出ました.C++標準ライブラリがデフォルトでは入っていなさそうなので,追加の設定を行います.~/yocto/poky/rpi-build/conf/local.confIMAGE_INSTALL_append = " libstdc++" TOOLCHAIN_TARGET_TASK_append = " libstdc++-staticdev"ここまでの内容をまとめると,最終的にlocal.confは次の内容になっています.
~/yocto/poky/rpi-build/conf/local.confMACHINE ?= "raspberrypi4-64" # for WSL2 PSEUDO_IGNORE_PATHS_append = ",/run/" # image IMAGE_INSTALL_append = " hello connman connman-client openssh-sftp-server sudo python3 python3-pip rpi-gpio raspi-gpio libstdc++" IMAGE_FEATURES_append = " ssh-server-openssh" # user settings INHERIT_append = " extrausers" EXTRA_USERS_PARAMS = "useradd -P raspberry pi;usermod -P raspberry root;" # systemd settings DISTRO_FEATURES_append = " systemd" VIRTUAL-RUNTIME_init_manager = "systemd" DISTRO_FEATURES_BACKFILL_CONSIDERED = "sysvinit" VIRTUAL-RUNTIME_initscripts = "" IMX_DEFAULT_DISTRO_FEATURES_append = " systemd" # for c++ TOOLCHAIN_TARGET_TASK_append = " libstdc++-staticdev"local.confを書き終えたらOSイメージとツールチェーンのビルドを行います.ツールチェーンのビルドにはまた時間がかかりますのでゆっくりと待ちましょう.またSSDもこれまでの手順で80GBほど使用しますので注意してください.
$ cd ~/yocto/poky/rpi-build $ bitbake core-image-base $ bitbake core-image-base -c populate_sdk # ツールチェーンのビルドビルドが完了すると
rpi-build/tmp/deploy/sdk
にツールチェーンができあがっています.この中の.shファイルを実行するとインストールを行うことができます.インストール先はデフォルトでは/opt/poky/3.2.1
になっています.
environment-setup-cortexa72-poky-linux
を読み込むとクロスコンパイル環境を使うことができます.$ cd ~/yocto/poky/rpi-build/tmp/deploy/sdk $ sudo ./poky-glibc-x86_64-core-image-base-cortexa72-raspberrypi4-64-toolchain-3.2.1.sh $ source /opt/poky/3.2.1/environment-setup-cortexa72-poky-linux今回はC++のHello world!をCMakeを使ってビルドしてラズパイで動かしてみます.
$ mkdir ~/hello && cd ~/hello $ vim hello.cpp $ vim CMakeLists.txt $ mkdir build && cd build $ cmake .. $ make今回使用した
hello.cpp
とCMakeLists.txt
は次の内容です.hello.cpp#include <iostream> int main(int argc, char const *argv[]) { std::cout << "Hello, world!" << std::endl; return 0; }CMakeLists.txtcmake_minimum_required(VERSION 3.0.0) project(hello VERSION 0.1.0) set(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "limited configs" FORCE) add_executable(hello hello.cpp ) target_compile_features(hello PRIVATE cxx_std_17 )ビルドしてできあがった実行バイナリを
readelf
コマンドで確認してみます.MachineがAArch64
になっており,クロスコンパイルができていることが分かります.(今回ビルドを実施したPCはx86_64
)$ readelf -h hello ELF Header: Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 Class: ELF64 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: DYN (Shared object file) Machine: AArch64 Version: 0x1 : $ uname -m x86_64実行バイナリを
scp
コマンドでラズパイにコピーして動かすと,Hello, world!
が表示されます.ローカルPC$ scp ./hello root@192.168.1.8:/home/root/.RaspberryPi# ~/hello Hello, world!おわりに
今回はRaspberry Pi 4をターゲットにして,Yocto Projectを使ってLinuxをビルドし実際に動かしました.基本的な手順についてある程度は確認することができたと思います.Yoctoは日本語の情報が少ないのと,とにかくビルドに時間がかかってしまうため,初心者にはとっつきにくいところがあると感じました.この記事は,はじめてYoctoを触ってみる人にとって,ちょうどいいチュートリアルになると思います.Yoctoをはじめて触ってみる人たちの参考にしてもらえるとありがたいです.
参考にした書籍
最後に参考にした書籍の紹介です.とっかかりはYocto Project入門を参考にさせてもらいました.Yoctoをはじめて触ったので大変助かりました.今回まとめている内容も,特に前半はこちらの書籍の内容を参考にして自分の開発環境に合わせて動かし,また追加で調べながらまとめていきました.
- 投稿日:2021-01-12T07:18:50+09:00
【Shell】文字列分解の様々なパターン
はじめに
- 用途は少ないが、文字列を1文字ずつ分解して処理する場合がある。
- その際に、各環境で利用できるオプションや日本語問題に対応する必要がある。
- 今回は、文字列分解コマンドの複数パターン紹介と無難パターンを記録する。
環境
- Mac OS X 10.15.6
- ZSH 5.7.1
結果
- 以下、結果の内容。
# パターン1 : foldとgrep(v)の利用 # ※全角の場合は、空行が入るためgrepで削除。 echo "Good" | fold -1 | grep -v '^$' # パターン2 : sedとtrの利用 # ※最終行が追加されるので、最後のsedで削除 echo "Good" | sed 's!.!& !g' | tr ' ' '\n' | sed '$d' # パターン3 : sedとxargsの利用(無難) echo "Good" | sed 's/./& /g' | xargs -n1 # パターン4 : grep(o)の利用 # ※grepのoオプションは、環境によって利用できない。(POSIX未対応のため) echo "Good" | grep -o .# 各パターンの出力結果 G o o d
内容
パターン1
- 主に以下のような処理。
- foldを利用して、出力幅を1文字に限定。
- grepのvオプションを利用して、不要な空行を削除。
- ※半角のみであれば、foldのみで問題ない。
パターン2
- 主に以下のような処理。
- sedで一文字ずつ後ろにスペースを追加。
- trで追加された改行へ置換。
- sedで最後に追加された不要な改行を削除
パターン3
- 主に以下のような処理。
- sedで一文字ずつ後ろにスペースを追加。
- xargsのnオプションを利用して、入力引数の最大値指定。
パターン4
- 主に以下のような処理。
- grepのoオプションを利用して、1文字ずつマッチする毎に出力。
- ※oオプションは、環境によって利用できない場合がある。自身の環境は可能。
まとめ
- 上記のことから、環境および全角対応等の点からパターン3のsedとxargsの利用を無難とする。
- ただ、短述的で不要処理の無さという点から、パターン4の利用も検討する。
参考
- 投稿日:2021-01-12T06:22:58+09:00
KVM をインストールする
新しい PC を買って KVM をインストールしたので手順のまとめてみました。
1. Linux のインストール
まずは Linux をインストールします。今回は Ubuntu 20.04 をインストールしました。
自分の使っている PC で仮想化をサポートしているか確認します。結果が 0 などとなる場合は CPU の BIOS の設定を確認してください。
$ egrep -c '(vmx|svm)' /proc/cpuinfo 12これはやらなくて構いませんデフォルトのエディタを vi にして sudo をパスワードなしで実行できるようにします。
$ sudo update-alternatives --config editor $ sudo visudo[ユーザー名] ALL=(ALL:ALL) NOPASSWD:ALL上記の行を以下の行より後ろに追加します。[ユーザー名] は自分が使っているユーザー名に変更します。
%sudo ALL=(ALL:ALL) ALL参考: Set Vim as your default editor for Unix
2. KVM のインストール
KVM ホストに VM に関連するパッケージをインストールします。
$ sudo apt update $ sudo apt install -y qemu qemu-kvm libvirt-daemon libvirt-clients bridge-utils virt-manager $ sudo reboot次に自分が使用しているユーザーを libvirt と kvm グループに追加します。既に追加されている場合は必要ありません。
$ sudo adduser `id -un` libvirt Adding user '<username>' to group 'libvirt' ... $ sudo adduser `id -un` kvm Adding user '<username>' to group 'kvm' ...virt-top や virt-df などのツールもインストールしても良いかもしれません。Python や jq なども必要あであればインストールします。
参照: KVM/Installation
libvirtd が active か、QEMU 上でもハードウェア仮想化が有効かを確認します。
$ sudo systemctl is-active libvirtd active $ virt-host-validate QEMU: Checking for hardware virtualization : PASS QEMU: Checking if device /dev/kvm exists : PASS <snip> QEMU: Checking for secure guest support : WARN (AMD Secure Encrypted Virtualization appears to be disabled in kernel. Add kvm_amd.sev=1 to the kernel cmdline arguments)参照: KVM: Bare metal virtualization on Ubuntu with KVM
AMD Secure Encrypted Virtualization は仮想マシンで使用しているメモリ暗号化をハードウェアでサポートする技術のようですが KVM ホストを共有する使い方はしないのでここでは一旦無視します。
参照: AMD Secure Encrypted Virtualization (SEV)
3. ディスクの構成
例えば qcow2 イメージ用にシステムディスクとは別のディスクを使用する場合はディスクのフォーマットなどを行います。まずパーティション作成で使用する parted はここら辺が参考になりました。
参照: Parted
KVM に swap が必要かという話。あっても良いようです。
ファイルシステムの比較をここで軽くしてみました。ここら辺は好みだと思います。
以下では KVM でのストレージプールの設定を変更しデフォルトで使用するディレクトリを変更しています。
現在の pool のストレージプールのリストを表示します。
$ virsh pool-list Name State Autostart ------------------------------- default active yesdefault を削除します。
$ virsh pool-destroy default Pool default destroyed ~$ virsh pool-undefine default Pool default has been undefined $ virsh pool-list Name State Autostart ------------------------------新しく default を作成します。ここでは新しいストレージプールのディレクトリを /datasotore1/images としています。
$ virsh pool-define-as --name default --type dir --target /datastore1/images Pool default defined $ virsh pool-autostart default Pool default marked as autostarted $ virsh pool-start default Pool default started $ virsh pool-list Name State Autostart ------------------------------- default active yes参照: デフォルトのストレージプールをlibvirtから変更するにはどうすればよいですか?
対象のディレクトリのパーミッションは以下の通りとなっていました。
drwxrwxr-x 2 libvirt-qemu kvm 247 Jan 11 18:10 imagesこの作業はもしかすると virsh pool-edit --pool default として既存の設定を変更したほうが早いかもしれません。
4. ネットワークの確認
デフォルトでは KVM インストール時に virbr0 と言う仮想ブリッジが作成されます。
$ ip addr show virbr0 4: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000 link/ether 52:54:00:5e:9e:a2 brd ff:ff:ff:ff:ff:ff inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0 valid_lft forever preferred_lft forever $ brctl show bridge name bridge id STP enabled interfaces virbr0 8000.5254005e9ea2 yes virbr0-nic $ virsh net-list Name State Autostart Persistent -------------------------------------------- default active yes yesこのブリッジを NAT として利用して仮想マシンは外のネットワークにアクセスできます。使わない場合は消してしまっても良いと思います。もちろん消さなくても良いと思います。消すならこのあたり。
$ virsh net-destroy default $ virsh net-undefine default参照: https://www.cyberciti.biz/faq/linux-kvm-disable-virbr0-nat-interface/
こことか見ると以下の sysctl のパラメータを 0 にするように書かれています。
net.bridge.bridge-nf-call-ip6tables=0 net.bridge.bridge-nf-call-iptables=0 net.bridge.bridge-nf-call-arptables=0これは恐らく br_netfilter というモジュールがロードされている場合の話。Ubuntu 20.04 ではデフォルトではロードされて無かったので必要ないと思います。多分w
5. ネットワークの設定
仮想マシンに割り当てた IP アドレス宛に外から通信したい場合は Linux 上でブリッジを作成します。Ubuntu 20.04 で netplan を使用する場合はこんな感じ。
$ cat /etc/netplan/60-eno1-config.yaml network: version: 2 ethernets: eno1: dhcp4: false dhcp6: false bridges: br0: interfaces: - eno1 dhcp4: false dhcp6: false addresses: - 10.0.0.249/24 gateway4: 10.0.0.1 nameservers: addresses: - 1.1.1.1 - 1.0.0.1 parameters: forward-delay: 0 stp: false optional: true上記を明示的に KVM に登録することもできるが KVM ホストでブリッジを作った時点で KVM ゲストは見えるようになります。STP をどうするかは文章に寄って違ったりしますが多いのは無効。有効でも動かない落ちうことはないみたいです。
参考: CentOSのKVMで使う仮想ネットワークについて調べてみた
CentOS ではデフォルトで使用されているためと思いますが、Network Manager を使った例も沢山あります。ここら辺もお好みで。
作成したブリッジは brctl コマンドで確認することができます。
$ brctl show bridge name bridge id STP enabled interfaces br0 8000.a0369fa9f098 no enp4s0f0上記で作成したブリッジを KVM ゲストに割り当てて IP アドレスを割り振れば該当の IP に対して KVM 環境の外からもアクセスすることができます。
6. 内部ネットワークを作成する
KVM の内部で使用するネットワークを作成します。virt-manager でも作れますがここでは xml ファイルから作成してみます。
まずは xml ファイルを作成します。恐らく以下が一番シンプルな記述だと思います。ここで IP アドレスや DHCP などの設定もできます。
$ cat virbr1.xml <network> <name>virbr1</name> <bridge name='virbr1' stp='on' delay='0' /> </network>参照: KVM (Kernel-based Virtual Machine) による仮想環境の構築手順(KVMのインストールと仮想ネットワーク作成手順)
以下のコマンドで KVM にブリッジを作成し起動時に自動で構成されるようにします。
$ virsh net-define ./virbr1.xml Network virbr1 defined from ./virbr1.xml $ virsh net-autostart virbr1 Network virbr1 marked as autostarted $ virsh net-start virbr1 Network virbr1 started正常に作成されたかは以下のコマンドで確認ができます。
$ brctl show bridge name bridge id STP enabled interfaces virbr1 8000.525400a99a82 yes virbr1-nic $ virsh net-list Name State Autostart Persistent -------------------------------------------- default active yes yes virbr1 active yes yes実際の設定ファイルはここにあります。uuid や mac address は自動で付与してくれます。一度登録したものは virsh net-edit コマンドで編集することができます。
$ sudo cat /etc/libvirt/qemu/networks/virbr1.xml <!-- WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE OVERWRITTEN AND LOST. Changes to this xml configuration should be made using: virsh net-edit virbr1 or other application using the libvirt API. --> <network> <name>virbr1</name> <uuid>379d3199-365e-4c99-b331-77d50ed7b2ac</uuid> <bridge name='virbr1' stp='on' delay='0'/> <mac address='52:54:00:a9:9a:82'/> </network>参照: net-define
7. virsh をリモートで実行する
KVM ホストに直接 ssh などでログインするのはあまり好ましくない場合もあります。virsh や virt-manager で KVM の設定をしますがリモートでの実行も可能です。
virsh をリモートから実行するにはまずクライアントに libvirt-clients をインストールします。
$ sudo apt install libvirt-clients次に以下のようなコマンドを実行します。
$ virsh -c qemu+ssh://test@10.0.0.250/system list Id Name State ---------------------- 1 c20h running上記の場合は ssh で接続しているため ssh の公開鍵認証などの設定をする必要があります。また .bash_aliases などに以下のように書いておくと便利かもしれません。
$ cat .bash_aliases | grep vir alias virsh='virsh -c qemu+ssh://test@10.0.0.250/system' $ virsh list Id Name State ---------------------- 1 c20h runningvirt-manager は GUI の File > Add Connection から設定が可能です。virsh, virt-manager 共に Windows Subsystem for Linux(WSL)上の Linux でも実行できるので便利です。
参照: SSHSetup
- 投稿日:2021-01-12T02:49:28+09:00
GCPのUbuntuでDiskをマウントする。
現状のFilesystemを確認
dfはマウントされたファイルシステムのみを表示します。
$ df -h Filesystem Size Used Avail Use% Mounted on /dev/root 16G 4.0G 12G 26% / devtmpfs 2.0G 0 2.0G 0% /dev tmpfs 2.0G 0 2.0G 0% /dev/shm tmpfs 394M 960K 393M 1% /run tmpfs 5.0M 0 5.0M 0% /run/lock tmpfs 2.0G 0 2.0G 0% /sys/fs/cgroup /dev/sda15 105M 9.2M 96M 9% /boot/efi /dev/loop0 56M 56M 0 100% /snap/core18/1932 /dev/loop1 56M 56M 0 100% /snap/core18/1944 /dev/loop2 130M 130M 0 100% /snap/google-cloud-sdk/161 /dev/loop3 130M 130M 0 100% /snap/google-cloud-sdk/162 /dev/loop4 71M 71M 0 100% /snap/lxd/16922 /dev/loop5 68M 68M 0 100% /snap/lxd/18150 /dev/loop6 32M 32M 0 100% /snap/snapd/10238 /dev/loop7 32M 32M 0 100% /snap/snapd/10492 tmpfs 394M 0 394M 0% /run/user/1005新たに追加したDiskを見つける。
GCPにおいてはDiskの名前が末尾に書いてます。
(この例ではsdbが新たなに作成したディスクです。)ll /dev/disk/by-id lrwxrwxrwx 1 root root 9 Jan 11 16:46 scsi-0Google_PersistentDisk_mysql-2-backup -> ../../sdb現在利用できるブロックデバイスを一覧表示する。
$ sudo lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT loop0 7:0 0 55.3M 1 loop /snap/core18/1885 loop1 7:1 0 128.8M 1 loop /snap/google-cloud-sdk/160 loop3 7:3 0 70.6M 1 loop /snap/lxd/16922 loop4 7:4 0 55.4M 1 loop /snap/core18/1932 loop5 7:5 0 128.8M 1 loop /snap/google-cloud-sdk/159 loop6 7:6 0 31M 1 loop /snap/snapd/9607 loop7 7:7 0 31M 1 loop /snap/snapd/9721 loop8 7:8 0 67.8M 1 loop /snap/lxd/18150 sda 8:0 0 16G 0 disk ├─sda1 8:1 0 15.9G 0 part / ├─sda14 8:14 0 4M 0 part └─sda15 8:15 0 106M 0 part /boot/efi sdb 8:16 0 16G 0 diskフォーマット
mkfs.ext4 -F -E lazy_itable_init=0,lazy_journal_init=0,discard /dev/disk/by-id/scsi-0Google_PersistentDisk_mysql-2-backup# mkfs.ext4 -F -E lazy_itable_init=0,lazy_journal_init=0,discard /dev/disk/by-id/scsi-0Google_PersistentDisk_mysql-2-backup mke2fs 1.45.5 (07-Jan-2020) Discarding device blocks: done Creating filesystem with 4194304 4k blocks and 1048576 inodes Filesystem UUID: a9b02fa8-593b-4ee4-9764-0bff20b8b558 Superblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 4096000 Allocating group tables: done Writing inode tables: done Creating journal (32768 blocks): done Writing superblocks and filesystem accounting information: donemount
$ mkdir -p /mnt/mysql-2-backup $ mount -o discard,defaults /dev/disk/by-id/scsi-0Google_PersistentDisk_mysql-2-backup /mnt/mysql-2-backup再起動時の自動マウント設定
/etc/fstab
に下記を追加する/dev/disk/by-id/scsi-0Google_PersistentDisk_mysql-2-backup /mnt/mysql-2-backup ext4 defaults 1 1デバイスへの書き込みアクセスをすべてのユーザーに付与します。
chmod a+w /mnt/mysql-2-backupfstabをバックアップ
cp /etc/fstab /etc/fstab.backupFilesystemが認識されているか確認
sdbが増えてます。
# df -h Filesystem Size Used Avail Use% Mounted on /dev/root 16G 3.7G 12G 24% / devtmpfs 2.0G 0 2.0G 0% /dev tmpfs 2.0G 0 2.0G 0% /dev/shm tmpfs 394M 960K 393M 1% /run tmpfs 5.0M 0 5.0M 0% /run/lock tmpfs 2.0G 0 2.0G 0% /sys/fs/cgroup /dev/sda15 105M 9.2M 96M 9% /boot/efi /dev/loop0 56M 56M 0 100% /snap/core18/1932 /dev/loop1 56M 56M 0 100% /snap/core18/1944 /dev/loop2 130M 130M 0 100% /snap/google-cloud-sdk/161 /dev/loop3 130M 130M 0 100% /snap/google-cloud-sdk/162 /dev/loop4 71M 71M 0 100% /snap/lxd/16922 /dev/loop5 68M 68M 0 100% /snap/lxd/18150 /dev/loop6 32M 32M 0 100% /snap/snapd/10238 /dev/loop7 32M 32M 0 100% /snap/snapd/10492 tmpfs 394M 0 394M 0% /run/user/1005 /dev/sdb 16G 45M 15G 1% /mnt/mysql-2-backup
- 投稿日:2021-01-12T02:49:28+09:00
GCPのUbuntuでDiskをマウント、フォーマットする。
現状のFilesystemを確認
dfはマウントされたファイルシステムのみを表示します。
$ df -h Filesystem Size Used Avail Use% Mounted on /dev/root 16G 4.0G 12G 26% / devtmpfs 2.0G 0 2.0G 0% /dev tmpfs 2.0G 0 2.0G 0% /dev/shm tmpfs 394M 960K 393M 1% /run tmpfs 5.0M 0 5.0M 0% /run/lock tmpfs 2.0G 0 2.0G 0% /sys/fs/cgroup /dev/sda15 105M 9.2M 96M 9% /boot/efi /dev/loop0 56M 56M 0 100% /snap/core18/1932 /dev/loop1 56M 56M 0 100% /snap/core18/1944 /dev/loop2 130M 130M 0 100% /snap/google-cloud-sdk/161 /dev/loop3 130M 130M 0 100% /snap/google-cloud-sdk/162 /dev/loop4 71M 71M 0 100% /snap/lxd/16922 /dev/loop5 68M 68M 0 100% /snap/lxd/18150 /dev/loop6 32M 32M 0 100% /snap/snapd/10238 /dev/loop7 32M 32M 0 100% /snap/snapd/10492 tmpfs 394M 0 394M 0% /run/user/1005新たに追加したDiskを見つける。
GCPにおいてはDiskの名前が末尾に書いてます。
(この例ではsdbが新たなに作成したディスクです。)ll /dev/disk/by-id lrwxrwxrwx 1 root root 9 Jan 11 16:46 scsi-0Google_PersistentDisk_mysql-2-backup -> ../../sdb現在利用できるブロックデバイスを一覧表示する。
$ sudo lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT loop0 7:0 0 55.3M 1 loop /snap/core18/1885 loop1 7:1 0 128.8M 1 loop /snap/google-cloud-sdk/160 loop3 7:3 0 70.6M 1 loop /snap/lxd/16922 loop4 7:4 0 55.4M 1 loop /snap/core18/1932 loop5 7:5 0 128.8M 1 loop /snap/google-cloud-sdk/159 loop6 7:6 0 31M 1 loop /snap/snapd/9607 loop7 7:7 0 31M 1 loop /snap/snapd/9721 loop8 7:8 0 67.8M 1 loop /snap/lxd/18150 sda 8:0 0 16G 0 disk ├─sda1 8:1 0 15.9G 0 part / ├─sda14 8:14 0 4M 0 part └─sda15 8:15 0 106M 0 part /boot/efi sdb 8:16 0 16G 0 diskフォーマット
mkfs.ext4 -F -E lazy_itable_init=0,lazy_journal_init=0,discard /dev/disk/by-id/scsi-0Google_PersistentDisk_mysql-2-backup# mkfs.ext4 -F -E lazy_itable_init=0,lazy_journal_init=0,discard /dev/disk/by-id/scsi-0Google_PersistentDisk_mysql-2-backup mke2fs 1.45.5 (07-Jan-2020) Discarding device blocks: done Creating filesystem with 4194304 4k blocks and 1048576 inodes Filesystem UUID: a9b02fa8-593b-4ee4-9764-0bff20b8b558 Superblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 4096000 Allocating group tables: done Writing inode tables: done Creating journal (32768 blocks): done Writing superblocks and filesystem accounting information: donemount
$ mkdir -p /mnt/mysql-2-backup $ mount -o discard,defaults /dev/disk/by-id/scsi-0Google_PersistentDisk_mysql-2-backup /mnt/mysql-2-backup再起動時の自動マウント設定
/etc/fstab
に下記を追加する/dev/disk/by-id/scsi-0Google_PersistentDisk_mysql-2-backup /mnt/mysql-2-backup ext4 defaults 1 1デバイスへの書き込みアクセスをすべてのユーザーに付与します。
chmod a+w /mnt/mysql-2-backupfstabをバックアップ
cp /etc/fstab /etc/fstab.backupFilesystemが認識されているか確認
sdbが増えてます。
# df -h Filesystem Size Used Avail Use% Mounted on /dev/root 16G 3.7G 12G 24% / devtmpfs 2.0G 0 2.0G 0% /dev tmpfs 2.0G 0 2.0G 0% /dev/shm tmpfs 394M 960K 393M 1% /run tmpfs 5.0M 0 5.0M 0% /run/lock tmpfs 2.0G 0 2.0G 0% /sys/fs/cgroup /dev/sda15 105M 9.2M 96M 9% /boot/efi /dev/loop0 56M 56M 0 100% /snap/core18/1932 /dev/loop1 56M 56M 0 100% /snap/core18/1944 /dev/loop2 130M 130M 0 100% /snap/google-cloud-sdk/161 /dev/loop3 130M 130M 0 100% /snap/google-cloud-sdk/162 /dev/loop4 71M 71M 0 100% /snap/lxd/16922 /dev/loop5 68M 68M 0 100% /snap/lxd/18150 /dev/loop6 32M 32M 0 100% /snap/snapd/10238 /dev/loop7 32M 32M 0 100% /snap/snapd/10492 tmpfs 394M 0 394M 0% /run/user/1005 /dev/sdb 16G 45M 15G 1% /mnt/mysql-2-backup
- 投稿日:2021-01-12T01:29:47+09:00
Cloud9+Railsでmysqlを導入する際に手間取った記録
・Cloud9+Rails+MySQLでRailsアプリケーションを作成を試みる。
・MySQLの導入に手間取る。
・rails newをすでに実行していたため、Gemfileにmysqlを記述し、bundle installを実行するとエラーAn error occurred while installing mysql2 (0.5.2), and Bundler cannot continue. Make sure that `gem install mysql2 -v '0.5.2' --source 'https://rubygems.org/'` succeeds before bundling.手順
https://qiita.com/kumas/items/e2c647dca08fd46b5c7a
こちらを参考にアプリケーションの作成をしましたが、知識不足のため、手間取りました。①作成したディレクトリに移動して、rails newを実行
②Gemfileにて
gem 'sqlite' #デフォルトのsqliteをMySQLへ変更 gem 'mysql'③bundle installを実行すると上記エラー
④
sudo yum install mysql-develで解決するとのことだが、これもエラーで返されてお手上げ。。
解決した方法
sudo apt-get install libmysqld-dev「そういや、cloud9のenvironments作成時にUbuntu選択してたなぁ。そのエラーかな?」
調べるとそうでした。というか基本的なことがわかってなかった。https://qiita.com/ryota-0906/items/2da9dcd54a6840b59364
https://qiita.com/hal-bo/items/1e0568120c545bf723c6Ubuntu環境でパッケージ形式の違うRedHut系のyumコマンド使っていたら、そりゃエラーを返されますよね。
超絶基本的な話ですが、Linuxのパッケージファイルの形式は理解しておかないといけない。