KVM上の仮想マシンのディスクサイズの増やし方(LVM)
最近はコンテナ主流ですが、まだまだホスト型の仮想マシンも利用します。(主に検証用)
適当に作った仮想マシンを再利用とかしていると、ディスク容量が足りなくなることがよくあるので、増やし方をメモしておきます。
まずは仮想マシンの作り方
virt-install --connect=qemu:///system -n Fedora30 -r 4096 --disk path=/var/lib/libvirt/qemu/fedora30.img,size=32,format=qcow2 --vcpus=4 --os-type linux --network network=default --nographics --extra-args=--extra-args='ks=file:/fedora-ks.cfg console=tty0 console=ttyS0,115200n8' --location /data/Resource/Fedora-Server-dvd-x86_64-30-1.2.iso
こんな感じでテキストインストールです。 普通にやると、 /dev/mapper/fedora-rootが/にマウントされており、この/を拡張可能となります。
ディスク/パーティションサイズの増やし方
の流れです
QEMUイメージの拡張
# qemu-img info /var/lib/libvirt/qemu/fedora30.img
image: /var/lib/libvirt/qemu/fedora30.img
file format: qcow2
virtual size: 64G (68719476736 bytes)
disk size: 29G
cluster_size: 65536
Format specific information:
compat: 1.1
lazy refcounts: true
# file /var/lib/libvirt/qemu/fedora30.img
/var/lib/libvirt/qemu/fedora30.img: QEMU QCOW Image (v3), 68719476736 bytes
拡張
# qemu-img resize /var/lib/libvirt/qemu/fedora30.img +5G
Image resized.
# qemu-img info /var/lib/libvirt/qemu/fedora30.img
image: /var/lib/libvirt/qemu/fedora30.img
file format: qcow2
virtual size: 69G (74088185856 bytes)
disk size: 29G
cluster_size: 65536
Format specific information:
compat: 1.1
lazy refcounts: true
これで、ディスクの拡張ができました。この増やした分のサイズを仮想マシンに適用していきます。
パーティションサイズ拡張
まずはディスクのパーティションの拡張です。
# parted /dev/sda
(parted) p
モデル: ATA QEMU HARDDISK (scsi)
ディスク /dev/sda: 74.1GB
セクタサイズ (論理/物理): 512B/512B
パーティションテーブル: msdos
ディスクフラグ:
番号 開始 終了 サイズ タイプ ファイルシステム フラグ
1 1049kB 1075MB 1074MB primary ext4 boot
2 1075MB 68.0GB 66.9GB primary lvm
(parted) resizepart 2 100%
(parted) p
番号 開始 終了 サイズ タイプ ファイルシステム フラグ
1 1049kB 1075MB 1074MB primary ext4 boot
2 1075MB 74.1GB 73.0GB primary lvm
LVM物理ボリューム拡張
パーティションが拡張されたので、その上のLVM物理ボリュームの拡張です
# pvdisplay
--- Physical volume ---
PV Name /dev/sda2
VG Name fedora
PV Size <62.33 GiB / not usable 3.85 MiB
Allocatable yes (but full)
PE Size 4.00 MiB
Total PE 15955
Free PE 0
Allocated PE 15955
PV UUID Yq9YcH-V4rM-QHFf-5gyR-tUh8-0PmE-y4Vwt3
# pvs
PV VG Fmt Attr PSize PFree
/dev/sda2 fedora lvm2 a-- 62.32g 0
# pvresize /dev/sda2
Physical volume "/dev/sda2" changed
1 physical volume(s) resized or updated / 0 physical volume(s) not resized
# pvs
PV VG Fmt Attr PSize PFree
/dev/sda2 fedora lvm2 a-- <68.00g 5.67g
# pvsisplay
--- Physical volume ---
PV Name /dev/sda2
VG Name fedora
PV Size <68.00 GiB / not usable 2.00 MiB
Allocatable yes
PE Size 4.00 MiB
Total PE 17407
Free PE 1452
Allocated PE 15955
PV UUID Yq9YcH-V4rM-QHFf-5gyR-tUh8-0PmE-y4Vwt3
Freeのところを増やすことができました。
LVM論理ボリューム拡張
拡張した物理ボリューム上の論理ボリュームの拡張です。今回はrootしか切ってないので全部利用します
# lvdisplay
--- Logical volume ---
LV Path /dev/fedora/swap
LV Name swap
VG Name fedora
LV UUID CrBKUg-42Pr-l3PM-g0w8-atOG-CgvK-WPI7r6
LV Write Access read/write
LV Creation host, time localhost, 2019-06-03 15:55:13 +0900
LV Status available
# open 2
LV Size 3.20 GiB
Current LE 820
Segments 1
Allocation inherit
Read ahead sectors auto
- currently set to 256
Block device 253:1
--- Logical volume ---
LV Path /dev/fedora/root
LV Name root
VG Name fedora
LV UUID QBQwNS-q36Z-Rg2Y-9kTh-uwRA-2Nfn-llxArG
LV Write Access read/write
LV Creation host, time localhost, 2019-06-03 15:55:13 +0900
LV Status available
# open 1
LV Size 59.12 GiB
Current LE 15135
Segments 1
Allocation inherit
Read ahead sectors auto
- currently set to 256
Block device 253:0
# lvextend -l +100%FREE /dev/sda2fedrora/root
Size of logical volume fedora/root changed from 59.12 GiB (15135 extents) to 64.79 GiB (16587extents).
Logical volume fedora/root successfully resized.
# lvdisplay
--- Logical volume ---
LV Path /dev/fedora/swap
LV Name swap
VG Name fedora
LV UUID CrBKUg-42Pr-l3PM-g0w8-atOG-CgvK-WPI7r6
LV Write Access read/write
LV Creation host, time localhost, 2019-06-03 15:55:13 +0900
LV Status available
# open 2
LV Size 3.20 GiB
Current LE 820
Segments 1
Allocation inherit
Read ahead sectors auto
- currently set to 256
Block device 253:1
--- Logical volume ---
LV Path /dev/fedora/root
LV Name root
VG Name fedora
LV UUID QBQwNS-q36Z-Rg2Y-9kTh-uwRA-2Nfn-llxArG
LV Write Access read/write
LV Creation host, time localhost, 2019-06-03 15:55:13 +0900
LV Status available
# open 1
LV Size 64.79 GiB
Current LE 16587
Segments 1
Allocation inherit
Read ahead sectors auto
- currently set to 256
Block device 253:0
論理ボリュームも拡張できました。ただこの状態でdfでチェックしても増えていません。 ファイルシステムも拡張してあげる必要があります。 今回はxfsのため、以下のコマンドです
# xfs_growfs /
meta-data=/dev/mapper/fedora-root isize=512 agcount=16, agsize=983040 blks
= sectsz=512 attr=2, projid32bit=1
= crc=1 finobt=1, sparse=1, rmapbt=0
= reflink=0
data = bsize=4096 blocks=15498240, imaxpct=25
= sunit=0 swidth=0 blks
naming =version 2 bsize=4096 ascii-ci=0, ftype=1
log =internal log bsize=4096 blocks=2560, version=2
= sectsz=512 sunit=0 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0
data blocks changed from 15498240 to 16985088
# df -h
ファイルシス サイズ 使用 残り 使用% マウント位置
/dev/mapper/fedora-root 65G 28G 38G 42% /
これで無事に拡張できたのではないかと思います。正直結構面倒ではありますが、kernelとか大きいビルドをするときは、割とディスク容量が足りなくなることがあるので、メモっておくと使う機会は割りとあります。
kgdbによるkernelデバッグ(2)
前回に引き続いてkgdbによるLinux kerenlのデバッグです。
実際にアタッチするのと、kernel moduleのシンボルの解決について記します。
アタッチ
remoteからのアタッチになるので、gdb実行側で、kernelのシンボル情報を読み込ませる必要があります。
vmlinuxファイルに入っているので、前回展開したものをgdbに読み込ませます。
その後、シリアル接続の情報を設定します。
# gdb vmlinux
(gdb) set remotebaud 115200
targetとなる端末では、アタッチするためにkerenlを一旦止める必要があります。目当ての動作中のデバッグをするには、breakpointを貼って、breakpointで止まったところを見る必要があります。
止めるには以下のコマンドを実行するか、ブートオプションのkgdbwaitを使います。
# echo g > /proc/sysrq-trigger
この状態で、gdbで
(gdb) target remote /dev/ttyS0
というようにシリアルからアタッチ出来ると思います。あとはいつものgdbです。continueコマンドでkernel実行を継続すれば、止めてたshellも復帰します。
kernel moduleのデバッグ
この状態だと、kernel coreのシンボル解決は出来ますが、moduleについては情報がないため、デバッグ出来ない状態です。
moduleのアドレス情報は起動ごとに異なるので、まずはターゲット上で目当てのmodule情報を収集します。
moduleの各セクションのアドレス情報は、/sys/modue/
取得したアドレス情報はgdbに登録します。gdbのヘルプを見ると、
(gdb) help add-symbol-file Load symbols from FILE, assuming FILE has been dynamically loaded. Usage: add-symbol-file FILE [-readnow | -readnever] [-o OFF] [ADDR] [-s SECT-NAME SECT-ADDR]... ADDR is the starting address of the file's text. Each '-s' argument provides a section name and address, and should be specified if the data and bss segments are not contiguous with the text. SECT-NAME is a section name to be loaded at SECT-ADDR. OFF is an optional offset which is added to the default load addresses of all sections for which no other address was specified.
とあるので、textのアドレスとそれ以外のアドレスを入れる感じですね。 これを手で入れるのは面倒なので、スクリプトを作成します。
(print-section.sh ターゲットに配置)
#!/bin/sh
cd /sys/module/$1/sections/
if [ $? -ne 0 ]; then
echo "cannot found module"
exit 1
fi
addr=`cat .text`
echo -n "$addr"
for A in .*
do
if [ "$A" = "." ]; then continue; fi
if [ "$A" = ".." ]; then continue; fi
if [ "$A" = ".text" ]; then continue; fi
addr=`cat $A`
echo -n " -s $A $addr"
done
echo
(kgdb-attach.sh リモートに配置)
#/bin/bash
gdbinit=".gdbinit"
dirdriver="lib/modules/4.16.7_D1+/kernel/drivers/"
vmlinux="boot/vmlinux-4.16.75_D1+"
declare -A modules
modules=(
["mod1"]="${dirdriver}/.../mod1.ko"
["mod2"]="${dirdriver}/.../mod2.ko"
)
echo "" > ${gdbinit}
echo "file $vmlinux" >> ${gdbinit}
echo "set remotebaud 115200" >> ${gdbinit}
for m in ${!modules[@]}; do
section="`ssh root@192.168.100.1 bash ./print-section.sh ${m}`"
echo "add-symbol-file ${modules[$m]} $section" >> ${gdbinit}
done
gdb
echo "" > ${gdbinit}
kgdb-attach.shの配列にデバッグしたい、もしくは関連するモジュールを入れて実行すると、アドレス情報を取ってきてgdbを実行します。
gdbの自動設定はgdbinitを使用しています。生成される.gdbinitの場所次第で警告が出ると思いますが、これを解消するには、homeディレクトリに、
# vi ~/.gdbinit
add-auto-load-safe-path /.../.gdbinit
というようにすれば大丈夫だと思います。
これでkerenl moduleに対してもデバッグできるようになりました。
kernelの開発だけでなく、kerenlの動きの理解や、ユーザランドのアプリの検証などにも使えると思うので気軽にkernelにアタッチしてみましょう!
最近はシリアルポートがない端末も増えてきてるので、ethernet経由でのデバッグもやってみようと思います。
kgdbによるkernelデバッグ
久しぶりにkerenlデバッグをする機会があったのでまとめておきます。 環境は以下
kernelをデバッグするときは、kernelを一旦止める必要があるため、基本的には外部からアタッチする形になります。
使うツールはgdbです。
qemuなどの仮想環境上で動いている場合は、qemu上のgdbserverが使えるのか、その限りではないです(?)
仮想環境上で試せる場合は先にそちらで試したほうがいいですね。
やり方はkernel Documentに書いてあります。(Documentation/dev-tools/gdb-kernel-debugging.rst)
kernel config
まずは、デバッグ対象のkerenlのconfigで、kgdbによるデバッグができるよう設定を行います。 Documentation/dev-tools/kgdb.rstやネットで書いてある通りです。
# make menuconfig
(kgdbの有効化 & シリアルコンソールからのデバッグ有効化)
Kernel hacking --->
[*] Kernel debugging
[*] KGDB: kernel debugger --->
<*> KGDB: use kgdb over the serial console
(kernelのデバッグシンボルを残す)
Compile-time checks and compiler options --->
[*] Compile the kernel with debug info
[ ] Reduce debugging information
[*] Provide GDB scripts for kernel debugging <= 必須ではないが、仮想環境上でのデバッグやkernelのビルド環境上でデバッグする場合は
その他のconfig
上記以外に以下のconfigを設定しますが、正直やり方があっているかわかりません。今の所問題はないようです。
CONFIG_FRAME_POINTER
ファイルにフレーム情報を保存するコードを埋め込むなどするので、スタックトレースなどが正確になる(らしい)ので、これを有効化します。
いろんなところで、
-> Kernel hacking
-> Compile-time checks and compiler options
の中に設定項目があると書いてありますが見えません。menuconfigで"/"を押し、探してみると、UNWINDER_FRAME_POINTERに依存されているので、
-> Kernel hacking
(X) Frame pointer unwinder
とします。これにより
CONFIG_FRAME_POINTER=y
CONFIG_UNWINDER_FRAME_POINTER=y
となります。
CONFIG_STRICT_KERNEL_RWX
これはkernelのメモリ空間をroとし、セキュリティを高める設定ですが、これが有効だと、breakpointの設定ができなくなります。 breakpoint自体は貼れるけど、動かすと多分こんな感じになる。
(gdb) c
Cannot inser breakpont 1.
Error accessing memory address 0xffff...: 不明なエラーです-1.
ただ、x86の場合、強制的に有効化されています。私は無理やり有効化しています。
# vim arch/x86/Kconfig
- select ARCH_HAS_STRICT_KERNEL_RWX
- select ARCH_HAS_STRICT_MODULE_RWX
+ #select ARCH_HAS_STRICT_KERNEL_RWX
+ #select ARCH_HAS_STRICT_MODULE_RWX
# make prepare
# make menuconfig
こうすると、.configから設定が消えると思います。
nokaslr
configとは異なりますが、この設定も無効化する必要があります。KASLRとは仮想メモリアドレスをランダム化し、セキュリティを高める仕組みですが、これが有効だとデバッグシンボルを入れてもgdbが関数などのアドレスを見つけられません。
そのためこれを無効化するんですが、これはkernelのブートオプションで無効化できます。(configでも無効化できると思いますがやったことはありません)
kernelのブートオプションにnokaslrを入れるだけです。設定方法は、kgdbの設定と一緒に紹介します。
Build
私はRPMでのパッケージ管理を崩したくない(デバッグ,開発時もリリースと手順を変えないことで、影響を減らしたい)のと、対象PCが貧弱なので、ビルドマシンでRPM化しています。
# make rpm-pkg
このとき、Makefileの
VERSION = 4
PATCHLEVEL = 16
SUBLEVEL = 7
EXTRAVERSION =
でRPMの名前が決まるので、EXTRAVERSIONにデバッグ番号などをつけています。
出来たRPMは端末Aにインストールします。develパッケージはこの用途では入れる必要はないと思いますが、別途systemtapなど端末A自体でデバッグを行う場合は必要になると思います。
別途端末Bでもvmlinuxが必要なため、RPMを展開します。vmlinuxもbzip2で圧縮されているので展開しておきます。
端末B
# rpm2cpio kernel.rpm | cpio -id
# bunzip2 boot/vmlinuz-xxx
kgdb設定
端末Aでkgdbの接続設定を行います。その前にちゃんとシリアルコンソールで接続できるか確認しておいたほうがいいでしょう。
シリアルコンソール接続方法
端末Aでシリアル接続を有効かします。systemdを利用している場合です。
# systemctl start serial-getty@ttyS0.service
# vi /etc/securetty
+ ttyS0
これで、端末Bからminicomなどで接続すると、端末Aにログインできるはずです。私はこのやり方が簡単なので使っていますが、systemdが起動しないとログインできないので、OS起動時から入りたい場合はgrubに設定することになります。
接続できることがわかったら、kgdbの設定を行います。kernelのブートオプションに設定します。基本的には2つです。
kgdboc=[kms][[,]kbd][[,]serial_device][,baud]
kgdbwait
kgdbocは接続情報、kgdbwaitはOSブート時に、kgdb接続を待ち受けるかです。kgdbwaitが有効だとkernelはできるだけ早くkgdbの待受に入ります。boot時のデバッグや、breakpointを貼ってから起動する場合などに使います。
以下は設定例です。KASLRの無効化設定も入れています。
# vi /etc/default/grub
GRUB_CMDLINE_LINUX="rhgb nokaslr kgdboc=ttyS0,115200 kgdbwait"
# grub2-mkconfig -o /boot/efi/EFI/fedora/grub.cfg
これでOSを再起動したら、remoteのgdbでkernelにアタッチできるようになりました。
接続方法は次の記事に回します。
flatpak(1)
Flatpakを少し触ってみました。
Flatpak—the future of application distribution
どのディストリビューションでも同じ動きをし、flatpak環境下で動作させることで、sandbox的な制御も 可能となるようです。 アプリケーションはgithubのような、flathubというリポジトリがあり、主要なアプリケーションは簡単に インストールすることができます。
libreofficeや、VLCといった大きいアプリケーションほど、どの環境でも動作するというのは 助かるので、GUIアプリケーションの導入元としてはありだと思いました。 ただ、アプリケーションのバージョンアップがちゃんと追従するのかは確認ですかね。
sandboxとして、アプリケーションの制限をどのように行っているかは、次の記事にします。
ニューラルネットワーク自作入門メモ
最近AIや機械学習が自分の周りでも聞かれるようになってきたので、基本だけ抑えておこうと思い読んでみました。 読んでみてなんとなくニューラルネットワークがわかった気になれるいい本だったと思います。
文字認識もいいんですが、画像認識はどうなのかと思い、 CIFAR-10 and CIFAR-100 datasets で方式はそのままで試してみました。 データの読み取り方法は、サンプルにもありますが、
def unpickle(self, file): import _pickle fo = open(file, 'rb') dict = _pickle.load(fo, encoding='latin1') fo.close() return dict
こんな感じで、dict型で取得できます。この中に、dataとlabelsがあり、dataは32323(RGB)の値が入っているようなので、まずはこの1次元配列をそのまま入力層として利用してみました。 本のサンプルから変更しているところはこんな感じ
epochs = 5 for e in range(1, epochs): data_dict = n.unpickle('cifar-10-batches-py/data_batch_' + str(e)) # go through all records in the training data set for record in range(len(data_dict['labels'])): # split the record by the ',' commas #all_values = record.split(',') # scale and shift the inputs inputs = (numpy.asfarray(data_dict['data'][record]) / 255.0 * 0.99) + 0.01 # create the target output values (all 0.01, except the desired label which is 0.99) targets = numpy.zeros(output_nodes) + 0.01 # all_values[0] is the target label for this record targets[int(data_dict['labels'][record])] = 0.99 n.train(inputs, targets) pass pass
for record in range(len(test_dict['labels'])): # split the record by the ',' commas #all_values = record.split(',') # correct answer is first value correct_label = int(test_dict['labels'][record]) # scale and shift the inputs inputs = (numpy.asfarray(test_dict['data'][record]) / 255.0 * 0.99) + 0.01 # query the network outputs = n.query(inputs) #print(outputs) # the index of the highest value corresponds to the label label = numpy.argmax(outputs) # append correct or incorrect to list if (label == correct_label): # network's answer matches correct answer, add 1 to scorecard scorecard.append(1) print (label, " == ", correct_label) else: # network's answer doesn't match correct answer, add 0 to scorecard scorecard.append(0) print (label, " != ", correct_label) pass pass
これでやってみると、正解率はだいたい20%ほど。 こんなもんかという感じですが、色をまとめて入れるのはどうかという気もするのでもう少し工夫したり、CNNをやってみてもいいかも。 なかなか楽しいですが、これを自分のサービスに入れ込もうとするにはいろいろやってみて応用を効かせられるようにならないといけないですね。