Wi-Fiセンサ用ディスクイメージ編集 (2019)

ディスクイメージファイルをマウント

Rasbianのディスクイメージは、2つのパーティションになっていて、2つ目がOSが使うルートパーティションである。それをディスクとしてマウントすれば、中身の編集を行うことができる。

その際、2つめのパーティションの先頭セクタ(単位はバイト数)を引数に与える必要がある。そのためfdisk -lの出力からそれを切り出し、mountのオプションに加えてマウントする。

ただし、イメージをSDに焼くコンピュータ上で行うのでなければあまり効率的ではない。(Macならbashが入っているので使えるかも。Windowsでも最近はbashが入っているので試す価値はある。)

#!/bin/bash

IMG_FILE=$1
MOUNT_DIR=$2

# ディスクイメージの先頭セクタを得る
TMP=$(fdisk -l $IMG_FILE | sed -r "s/^.*img2\s+([0-9]+)\s+.*$/\1/" | tail -1)
START_SEC=$((TMP*512))

# ディスクイメージをマウント
mount -t ext4 -o loop,offset=${START_SEC} ${IMG_FILE} ${MOUNT_DIR}

if [ $? != 0 ]; then
    echo "mount failed"
    exit
fi

loopデバイスのマウントはroot権限でしか行えないので、sudoで実行する。

利用例:

8tops上でimageファイルを/home/toyoki/mnt/img1にマウントする場合

sudo ./mount_raspi_img.sh /nfs/raspi-img/raspi_toyoki-lab.20190506.pi3.img /home/toyoki/mnt/img1

(mnt/img1は予めmkdirしておく。)

ディスクイメージ内のパラメータをセットするスクリプト例

さしあたって、センサ個々に設定を変えるに必要があるのは次の2つである。

上記のようにマウントして、この2つを書き換えるシェルスクリプト例

(パソコンの上で行う場合の注意)

以下のスクリプトは8tops上で実行するよう変数を設定してある。

#!/bin/bash

# 引数 [-d 作業用マウントディレクトリ] [-s サーバールート] -n 端末名 -a エリア名 ディスクイメージファイル名

usage_exit() {
        echo "Usage: $0 [-d mount_dir] [-s server_root] -n sensor_name -a area image_file" 1>&2
        exit 1
}
MOUNT_DIR=/mnt/tmp # imageファイルのマウントポイント(コマンドライン引数で上書き)
NAME2NUM_SCR=./name2portNum.py # 名前→ポートプログラム
PORT_LIST_DIR=./port_nums # サーバ上の既存端末リストの在り処
AREA_NAME="" # 地域名 ex. kofu, fuefuki, hakushu, ...
SERVER_ROOT="raspimngr@8tops.yamanashi.ac.jp:~/pcap_data/"

# 引数処理
while getopts "d:n:a:s:h:" OPT
do
    case $OPT in
        d) MOUNT_DIR=$OPTARG
           ;;
        n) SENSOR_NAME=$OPTARG
           ;;
	a) AREA_NAME=$OPTARG
	   ;;
	s) SERVER_ROOT=$OPTARG
	   ;;
        h) usage_exit
           ;;
        \?) usage_exit
            ;;
    esac
done
shift $(($OPTIND - 1))
if [ $# -eq 1 ]; then
    IMG_FILE=$1
else
    usage_exit
fi

# port番号重複の有無チェック
SEARCH_NUM=$(${NAME2NUM_SCR} ${SENSOR_NAME} | head -1 | tr -d '\n')

RESULT=$(ls ${PORT_LIST_DIR} | grep ${SEARCH_NUM})
if [ "${RESULT}" != "" ]; then
    echo "名前 ${SENSOR_NAME} が使うポート番号 ${SEARCH_NUM}はすでに存在します。"
    exit
fi

# ディスクイメージの先頭セクタを得る
TMP=$(fdisk -l $IMG_FILE | sed -r "s/^.*img2\s+([0-9]+)\s+.*$/\1/" | tail -1)
START_SEC=$((TMP*512))

# ディスクイメージをマウント
mount -t ext4 -o loop,offset=${START_SEC} ${IMG_FILE} ${MOUNT_DIR}

if [ $? != 0 ]; then
    echo "mount failed"
    exit
fi

# **設定作業**
# port_nameの書き換え
${NAME2NUM_SCR} ${SENSOR_NAME} > ${MOUNT_DIR}/home/pi/conf/port_id.txt

# area名 (scp_pcaps.pyの送信先サブディレクトリ名)
echo ${AREA_NAME} > ${MOUNT_DIR}/home/pi/conf/area_name.txt
# サーバ//pcapディレクトリ名 (scp_pcaps.pyの送信先サーバ/ディレクトリ)
echo ${SERVER_ROOT} > ${MOUNT_DIR}/home/pi/conf/server_root.txt
# /var/wifi_pr/の掃除
/bin/rm ${MOUNT_DIR}/var/wifi-pr/*.pcap > /dev/null 2>&1

# 書き込み内容を表示
echo "以下を書き込みました. (エリア名、ポート、センサ名、送信先ディレクトリ)"
cat ${MOUNT_DIR}/home/pi/conf/*.txt

# 終了:アンマウント
umount ${MOUNT_DIR}