ℹ️本記事は古いコンテンツを変換して表示しています。
表示が崩れたり、リンクが正しくない可能性があります。ご了承ください。
ℹ️本記事は古いコンテンツを変換して表示しています。
表示が崩れたり、リンクが正しくない可能性があります。ご了承ください。
2019/01/02 17:01 : FreeBSDのバージョンを取得する
そんなものはfreebsd-version
コマンドで取れるのは分かってる。でも、どうしてもコマンドを叩けない、叩きたくない、というときのためのメモ。主にjailの管理用で、User Land側のバージョン取得が目的。
そんなものはfreebsd-version
コマンドで取れるのは分かってる。でも、どうしてもコマンドを叩けない、叩きたくない、というときのためのメモ。主にjailの管理用で、User Land側のバージョン取得が目的。
目的のUser Landバージョンはfreebsd-version -u
で取れる。なんと答えはこいつ自身が持っていた。シェルスクリプトにハードコード。
cat /bin/freebsd-version | grep USERLAND_VERSION= USERLAND_VERSION="11.2-RELEASE-p2"
もちろんこれは実装依存なので、できるだけ依存すべきではない。が、こちらの要求もやや無茶なのでしょうがない。あと、freebsd-version
は10.0で導入されたようなので、9.xにはないことにも注意。(とっくにEOLだけど)
HISTORY The freebsd-version command appeared in FreeBSD 10.0.
Kernelバージョンはきっとkernelが持っているだろうと思ってstrings /boot/kernel/kernel
すれば、11.2-RELEASE
とか出てくる。
以下、カーネルバージョンの取得スクリプト。無駄にがんばった。64bit intの計算が曲者。結局10進数に変換してからbc
を使った。
#!/bin/sh data_address=0x$(objdump -h /boot/kernel/kernel | awk '{ if ($2 == ".data") { print $4 }}') data_offset=0x$(objdump -h /boot/kernel/kernel | awk '{ if ($2 == ".data") { print $6 }}') version_address=0x$(objdump -j .data -t /boot/kernel/kernel | awk '{ if ($6 == "version") { print $1 } }') version_length=0x$(objdump -j .data -t /boot/kernel/kernel | awk '{ if ($6 == "version") { print $5 } }') # convert to decimal data_address=$(printf "%u" $data_address) data_offset=$(printf "%u" $data_offset) version_address=$(printf "%u" $version_address) version_length=$(printf "%u" $version_length) version_offset=$(bc -e "$data_offset + $version_address - $data_address" < /dev/null) dd if=/boot/kernel/kernel iseek=$version_offset bs=1 count=$version_length 2>/dev/null | tr -d '\00'
$ sh get_kernel_version FreeBSD 11.2-RELEASE-p2 #0: Tue Aug 14 21:45:40 UTC 2018 root@amd64-builder.daemonology.net:/usr/obj/usr/src/sys/GENERIC
awkで64-bit intを計算してみる。途中からおかしい。
% echo 0x81448760 0x8130c100 | awk '{ printf "0x%x\n", $1 - $2 }' 0x13c660 % echo 0xf81448760 0xf8130c100 | awk '{ printf "0x%x\n", $1 - $2 }' 0x13c660 % echo 0xff81448760 0xff8130c100 | awk '{ printf "0x%x\n", $1 - $2 }' 0x13c660 % echo 0xfff81448760 0xfff8130c100 | awk '{ printf "0x%x\n", $1 - $2 }' 0x13c660 % echo 0xffff81448760 0xffff8130c100 | awk '{ printf "0x%x\n", $1 - $2 }' 0x13c660 % echo 0xfffff81448760 0xfffff8130c100 | awk '{ printf "0x%x\n", $1 - $2 }' 0x13c660 % echo 0xffffff81448760 0xffffff8130c100 | awk '{ printf "0x%x\n", $1 - $2 }' 0x13c660 % echo 0xfffffff81448760 0xfffffff8130c100 | awk '{ printf "0x%x\n", $1 - $2 }' 0x13c680 % echo 0xffffffff81448760 0xffffffff8130c100 | awk '{ printf "0x%x\n", $1 - $2 }' 0x13c800 % echo 0xfffffffff81448760 0xfffffffff8130c100 | awk '{ printf "0x%x\n", $1 - $2 }' 0x138000 % echo 0xffffffffff81448760 0xffffffffff8130c100 | awk '{ printf "0x%x\n", $1 - $2 }' 0x180000
floatっぽいなと思ってpythonで試す。予想通り。
Python 2.7.12 (default, Jul 7 2016, 02:34:32) [GCC 4.2.1 20070831 patched [FreeBSD]] on freebsd9 Type "help", "copyright", "credits" or "license" for more information. >> print("0x%x" % int(float(0xffffffffff81448760) - float(0xffffffffff8130c100))) 0x180000
shは?
$ printf "0x%x\n" $(( 0xF000000000000000 - 0x1 )) 0x7ffffffffffffffe
POSIX.1な範囲で(unsigned) 64-bit intの計算ができる子はbc以外にいないものか……。