株式会社アイズ・ソフトウェア

/~eyes-software-co-jp/A1A2
お問い合わせ |  情報セキュリティへの取組について情報セキュリティ方針個人情報保護方針) |  ブログ

BLOG 社員ブログ

Raspberry Pi 400 をSSDから起動する

●Raspberry Pi 400 をSSDから起動する
ラズパイのOSを入れるメディアとして使用されているSDカードには「寿命」があります。寿命と言っても、何年で壊れるいうのではなく、何回書き込みをしたら壊れるというものです。
とは言え、スマホやデジカメで写真や音楽データを保存するような使い方では、寿命に達することはほとんどありません。
しかし、ラズパイでOSを入れたシステムディスクとして使用していると、一時的なファイルを作成したり、ログファイルを作成したりと、頻繁にファイル書き込みが行われます。ネット上で「raspberry pi SDカード 寿命」でググると24時間稼働して1年ほどで壊れたなんていう記事もあります。
先ほどのキーワードでググった結果には「SDカードの寿命を延ばす」方法を書いた記事がたくさん検索されます。

あまりSDカードのアクセスをしないプログラムを動かすのなら問題ないかもしれませんが、ネットサーフィンに使用するような場合はネットからダウンロードしたファイルをSDカードへキャッシュとしてコピーしますので、SDカードへのアクセスが多くなります。
その為、早く寿命に到達する可能性があります。

社員Iが入手したRaspberry Pi 400 はそのような使い方をする予定の為、寿命対策に外部USBメディアをシステムディスクとして使用し、SDカード無しで起動できるようにしてみました。


RaspberryPi 400に使用する外部USBメディアはUSB3接続のSSDを購入しました。スティック型のUSBメモリより少し大きいくらいのものです。安定して運用できる様なら本体に両面テープで張り付けようと考え、できるだけ小さいものにしました。これ

外部USBメディアから起動させるための設定手順は以下のサイトを参考にしました。
ラズパイ4をUSB接続のSSDから起動する方法(USBブート)
手順の概略は、SDカードの中身をSSDにコピーし、USBメディアからブートできるように設定変更します。 参照先のページでは、Raspberry Pi 4を対象にし、bootloaderのアップデートから記載されていますが、Raspberry Pi 400は購入時点でUSB Bootに対応した bootloaderになっていますので、ここの手順から実行します。
SDカードの中身をSSDにコピーした後、SDカードをスロットから抜いて再起動します。

ブート失敗の画面
このような画面が出て、起動に失敗しました。
「Unsupported block size 4096」というエラーが出ています。SSDのブロックサイズ4096をサポートしていないのでブートできないようです。

SDカードからブートして接続したSSDの属性を調べてみました。

$ sudo fdisk -l 
Disk /dev/sda: 119.2 GiB, 128026935296 bytes, 31256576 sectors
Disk model: Tech            
Units: sectors of 1 * 4096 = 4096 bytes
Sector size (logical/physical): 4096 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 268431360 bytes
Disklabel type: dos
Disk identifier: 0xc3872196

Device     Boot  Start      End  Sectors   Size Id Type
/dev/sda1         8192   532479   524288     2G  c W95 FAT32 (LBA)
/dev/sda2       532480 31256575 30724096 117.2G 83 Linux
セクターサイズは4098になっています。
SSDのセクターサイズは変えられなさそうですので、SSDからのブートはあきらめるしかないようです。(チップメーカーのユーティリティーで変更できるものはあるようです。)

●SDカードからブート、システムディスクをSSDにする
次の案として、SDカードでブートし、システムディスクとしてSSDを使用することとしました。これはRaspberry PiのbootloaderがUSBデバイスからの起動に対応していなかった頃にSDカードの寿命対策として使われていた方法です。

いま、手元にはRaspberryPi OSの入ったSDカードとそのコピーのSSDがあり、両方にブートパーティションとルートパーティションが存在します。
それを生かせば、少しの設定変更でSSDをシステムディスクとしてOSを起動することはできそうです。
設定については以下のページを参考にしました。
Raspberry Pi 3B+ SSD起動ディスク化 MicroSD必要と不要 両方試してみた

1. 「Raspberry Piの設定」画面でSDカードでブートされるように設定を戻す。
端末からraspi-configを実行し、6 Advances Options → A6 Boot Orderへ入り、B1 Card Boot に設定する。
$ sudo raspi-config

raspi-config メイン画面    raspi-config アドバンスドオプション画面    raspi-config ブートオーダー画面  
2. SSDをUSBポートから抜き、SDカードで起動する。
3. SSDをUSBポートに挿す。するとSSDのブートパーティションとルートパーティションが自動でマウントされる。
4. SSDのブートパーティションにあるcmdline.txtをSDカードのブートパーティションにコピーする。SDカードのcmdline.txtは別名でバックアップしておく。
$ cd /boot
$ sudo cp -p cmdline.txt cmdline_org.txt
$ sudo cp -p /media/[username]/boot/cmdline.txt ./
[username]は現在ログインしているアカウントのユーザー名

5. リブートする。
$ sudo reboot
ブート成功後のデスクトップ画面

あれ? デスクトップにbootとrootfsのアイコンができています。

使っていないSDカードが自動でマウントされてしまいました。
未使用のパーティションなのでマウントさせないか、隠したいですね。 使用しないパーティションは削除しても良いのですが、バックアップを兼ねて残しておきたいです。
その為にfstabに未使用パーティションを記述してマウントすることで、自動マウントによるアイコンが表示されないように設定しました。

a. マウントポイントを決めてディレクトリを作成する。
/mnt/unused/boot、/mnt/unused/rootfs をマウントポイントとすることにし、これらのディレクトリをmkdirで作成します。
$ cd /mnt
$ sudo mkdir -p unused/boot
$ sudo mkdir -p unused/rootfs
b. SDカードのパーティションのUUIDを調べる。
blkidコマンドで調べることもできますが、SDカード内のfstabを見れば分かります。
$ cd /media/[username]/rootfs/etc/
$ cat fstab
proc            /proc           proc    defaults          0       0
PARTUUID=c74c9849-01  /boot           vfat    defaults          0       2
PARTUUID=c74c9849-02  /               ext4    defaults,noatime  0       1
#
# a swapfile is not a swap partition, no line here
#   use  dphys-swapfile swap[on|off]  for that
//192.168.0.15/raspberry-pi-smb /mnt/smb    cifs    _netdev,guest,file_mode=0777,dir_mode=0777  0   0
bootのUUIDが c74c9849-01 、rootfsのUUIDが c74c9849-02 でした。

c. SSD側のfstabを修正します。
/etc/fstabは以下の様になっています。
proc            /proc           proc    defaults          0       0
PARTUUID=c3872196-01  /boot           vfat    defaults          0       2
PARTUUID=c3872196-02  /               ext4    defaults,noatime  0       1
#
# a swapfile is not a swap partition, no line here
#   use  dphys-swapfile swap[on|off]  for that
//192.168.0.15/raspberry-pi-smb /mnt/smb    cifs    _netdev,guest,file_mode=0777,dir_mode=0777  0   0
これを以下のように変更します。
proc            /proc           proc    defaults          0       0
PARTUUID=c74c9849-01  /boot           vfat    defaults          0       2
PARTUUID=c3872196-02  /               ext4    defaults,noatime  0       1
#
# unused devices
PARTUUID=c3872196-01  /mnt/unused/boot          vfat    defaults,ro          0       2
PARTUUID=c74c9849-02  /mnt/unused/rootfs        ext4    defaults,ro,noatime  0       1
#
# a swapfile is not a swap partition, no line here
#   use  dphys-swapfile swap[on|off]  for that
//192.168.0.15/raspberry-pi-smb /mnt/smb    cifs    _netdev,guest,file_mode=0777,dir_mode=0777  0   0
2行目、SDカードのブートパーティションを/bootとしてマウントするようにします。
6行目、SSDのブートパーティションを/mnt/unused/bootとしてマウントします。変更されないように"ro"オプションを付けておきます。
7行目、SDカードのルートパーティションを/mnt/unused/rootfsとしてマウントします。同様に"ro"オプションを付けておきます。
編集を終了したらリブートします。

これでデスクトップに未使用のメディアが表示されなくなりました。

システムディスクをSSDに変える事で全体的に速くなりました。
特に、日本語入力をする時に待たされることが無くなり、ネットサーフィンも快適に行えます。

最後に
ここに記載した方法は用意した外部USBメディアで起動できない場合の方法です。
外部USBメディアから起動する為の設定を行った後に起動方法を変更しているので外部USBメディア及びSDカードに使用しない領域を作ってしまいます。
なので、最初からブートできることが分かっているメディアを使用することを推奨します。
  • Category:
  • タグ:RaspberryPi
  • Author:eyes-software-co-jp

Raspberry Pi 400 レビュー

Raspberry Pi 400 を購入しましたので、レビューをさせていただきます。
本ブログの投稿者である社員Iの学生の頃、今のパソコンはマイコンと呼ばれ、個人ユーザーが使うコンピューターはキーボード一体型の物が普通でした。
代表的なものはPC-8001とか、APPLE ][とかですね。
貧乏学生には買えませんでしたが、学校にある物で遊ばせてもらっていました。
そんな時代の人間なので、昨年Raspberry Pi 400が発表されてすぐに 欲しい!と物欲が刺激され、日本語版が発売されるのを首を長くして待っていました。
そして、やっと入手。入手したのはディスプレイ以外で必要なものが全てセットされたスターターキットです。
「Raspberry Pi beginner's guide」日本語版という書籍も付いています。


本体上から

後ろから

見た目はラズパイの公式ケースなどと同様の白とピンクのツートンカラーのキーボードです。



「0」~「¥」までのキーは狭くなっています。
F10キーに電源マークが付いています。Fn+F10で電源のON/OFFができるようです。今までのRaspberry Piには電源管理の機能はなくて、シャットダウン後に電源ケーブルを抜くなどして電源をOFFにする必要がありました。
普通のパソコンとして使うにはこういう電源制御が必要ですね。
F11、F12キーは無く、Fnキーと同時押しの必要があります。使用頻度低いので問題ないです。

スターターキットに添付されているSDカードにはすでにRaspberryPi OSが書き込まれています。
そのまま、SDカードスロットに挿し込んでACアダプタを接続するとセットアップがはじまります。
セットアップ手順は従来のRaspberry Piと基本的に同じなので、以前の記事を参考にしてください。
ただし、Wifiの有無などによる違いはあります。

セットアップが終了したらメニューからシャットダウンさせます。
右上の電源LEDが消えました。シャットダウン後に電源ケーブルを抜く必要のあった今までのRaspberry Piとは違います。
電源を入れるにはF10キーを押します。Fnキーはいりません。0.5秒程度の長押しで起動します。
電源を切るにはFnキーとF10キーを同時に長押しします。画面左下のラズベリーマークをクリックしたら現れるスタートメニューからシャットダウンを選択しても電源が切れます。

ここからがレビューになります。
キーボードは10キーのないコンパクトな薄型。キーを打つと少したわむ感じがします。
自分は古いタイプのキーボード、キーの高さがあり、打つときのストロークのあるキーボードを普段使っているので、このタイプは使いにくいです。薄型の物に慣れている方、弘法キーボードを選ばずな方は問題ないでしょう。

本体の後ろにはUSBや電源の差し込み口があり、現在は4本のケーブルが挿してあります。左からマウス、PCスピーカー、電源、ディスプレイにつながっています。
自分はキーボードの位置を動かすことも多いので、なるべくここに繋げるケーブルは少なくしたいと思っています。そのためにはスピーカー内蔵型のディスプレイを買ったり、Bluetoothマウスを買ったりと投資が必要になりますが。

パソコンとしての使用感は他のLinuxPCとほぼ同じです。
Windowsとの比較になりますが、アプリのインストール等を行うのに端末を起動してコマンドの入力が必要であったり、いちいちパスワードが必要であったりと、そういうことになれていない人には使いにくいでしょう。
なお、アプリのインストールはGUIでもできますが、"パッケージ"単位でのインストールなのでコマンドで打つときと同程度の知識が必要です。
後はマルチメディア系は弱いですね。必要に応じてアプリをインストールすればいいのですが、それでもYahoo Newsの動画は見れないです。


以前の記事ではRaspberry Piをファイルサーバーに使用する為に設定したので、sambaの設定をしましたが、このRaspberry Pi 400は端末として使用するつもりですのでファイルサーバーのファイルを利用できるようにします。
その為にはcifsという機能を使用します。これはlinuxでsambaサーバーをマウントする為の機能です。
sambaサーバーのマウントは以下ように行います。
まず、マウントポイントを作成し、以下のコマンドでマウントできます。
smbサーバーはホスト192.168.0.15にraspberry-pi-smbの名前で構築していますので、デバイス名は「//192.168.0.15/raspberry-pi-smb」とします。

$ sudo mkdir -p /mnt/nas
$ sudo mount -type cifs //192.168.0.15/raspberry-pi-smb /mnt/nas -O guest 

起動時にマウントする為にはfstabに以下の様に追加します。
//192.168.0.15/raspberry-pi-smb /mnt/nas	cifs	_netdev,guest,file_mode=0777,dir_mode=0777	0	0

修正したfstabが正しくできているかマウントして確認します。
$ sudo mount -a
$ df
ファイルシス                  1K-ブロック      使用     使用可 使用% マウント位置
/dev/root                        29633928   9433640   18900776   34% /
devtmpfs                          1800564         0    1800564    0% /dev
tmpfs                             1965428     28648    1936780    2% /dev/shm
tmpfs                             1965428      8828    1956600    1% /run
tmpfs                                5120         4       5116    1% /run/lock
tmpfs                             1965428         0    1965428    0% /sys/fs/cgroup
/dev/mmcblk0p1                     258095     49281     208814   20% /boot
//192.168.0.15/raspberry-pi-smb 488254460 247512428  240742032   51% /mnt/nas
tmpfs                              393084        12     393072    1% /run/user/330
マウントは成功していますね。

fstabを設定したのでRaspberry Pi 400を再起動しました。しかしマウントできませんでした。どこが悪いのでしょう?
ググってみると以下のページを見つけました。
Raspberry Pi 3 に NAS をマウントさせる
fstabを読み込んでディスクをマウントする時点ではネットワークは有効になっていない為にマウントできないようです。

リンク先にはコマンドで行う方法で書いてありますが、GUIで設定しました。
GUIで行う場合は 「Raspberry Piの設定」画面で行います。
スタートメニュー->設定->Raspberry Piの設定 を選択し、「Raspberry Piの設定」画面を開き、下図のように設定します。

この設定を行う事で起動時からネットワークが有効になりcifsをマウントし、NASのファイルを使用できるようになりました。

今後の展開としてはUSB接続のSSDからブートできるようにしたいなと考えています。
端末として使う為SDカードのアクセスも多いので、SDカード寿命対策と高速化の一石二鳥を図ります。

  • Category:
  • タグ:RaspberryPi
  • Author:eyes-software-co-jp

ラズベリーパイその後

前回までの投稿で古いラズベリーパイを使用してホームサーバーを構築しました。
現在、そのラズベリーパイはホームサーバーとしては使用していません。
では、どうなっているかというと、I2S-DACという基盤とvolumio2というソフトウェアを使用したネットワーク音楽プレイヤーになっています。

volumio2とは何かというと、「音楽再生に特化したRaspberyPi用Linuxディストリビューション」です。もう少し簡単に言うと「音楽プレイヤーソフトウェア」です。
この面白い所は、ユーザーインターフェースはwebアプリとなっていてネットワーク上にあるPCやスマホからブラウザを通して制御できるというものです。なので、自分自身のディスプレイでGUIを使用するにはパワー不足である初代のラズベリーパイでも制御ができます。下の写真がVolumio2の画面です。


I2S-DACはラズベリーパイの上に乗っている白い基盤です。
I2S-DACのI2Sとは"Inter-IC Sound"の略で、デジタル音声信号を伝送する標準規格です。
I2S-DACのDACとは"Digital-Analog Converter"の略でデジタル音声信号をスピーカーへ出力できるようなアナログ音声信号へ変換する装置です。
ラズベリーパイは楽曲データとして持っているデジタル音声信号のデータをI2Sインターフェースを通してDACへ送信し、DACがアナログ音声信号へ変換することで音楽が再生されます。

ラズベリーパイとI2S-DACとの間はI2S信号をジャンパ線で繋げます。新しいラズベリーパイはGPIOピンにI2S信号が出ているのですが、Raspberry Pi Model Bの場合、I2S信号の出力にはピンが立っていません。その代わりにピンを立てる為の穴が開いています。
そこにピンをはんだ付けし、ジャンパ線でI2S-DACと繋げます。自分はピンを用意していなかったので、ジャンパ線を直接はんだ付けしました。
今更、初代のラズベリーパイで何かを作ろうという人はいないと思いますが、参考用に穴と信号の対応を以下の写真に載せておきます。

I2S-DAC基板上の同名のピンとジャンパ線でつなげば配線は完了です。

SDカードにVolumio2のイメージを書き込み、Volumio2の設定画面でI2S-DACの種類を設定すればネットワーク音楽プレイヤーの完成です。
SDカードへのイメージ書き込み方法、Volumio2の設定方法はググって見てください。ディスプレイなしでWi-Fiを設定する方法はその手があったか!と感心するような方法で設定するようになっていますよ。
下の写真はVolumio2の音声信号出力先を設定する画面ですが、ここでDAC ModelにI2S-DACの製品名を選択します。要はI2S基板のドライバを選択するものです。
自分の使用する製品が選択しに無い場合でもあきらめないでください。製品名でググってみればその製品のユーザーが何を設定したかのブログ記事が出てくる可能性があります。あれば何を選択すればいいかわかります。


完成したラズベリーパイは自宅のステレオに繋げて音楽を聴いています。約20年前に購入したエントリークラスのコンポです。オーディオマニアでもない自分には充分いい音で鳴ってくれています。

  • Category:
  • タグ:RaspberryPi
  • Author:eyes-software-co-jp

ラズベリーパイでホームサーバーを構築しよう -- メディアサーバー構築編

今回はラズパイにDLNAサーバー機能をインストールします。

● DLNAサーバーとは
DLNAサーバーとは、ホームネットワークを介してビデオ、写真、音楽等のコンテンツを共有する機能です。
DLNAに対応した機器間では他の機器に保存してあるビデオ、写真、音楽等を再生することができます。 AV家電では「ソニールームリンク」「お部屋ジャンプリンク」等の名前でBDレコーダーに機能が組み込まれています。また、スマホでも対応ソフトをインストールし、ホームネットワークへ接続すればコンテンツの共有や再生が可能です。

● DLNAサーバーをインストール
ラズパイでDLNAサーバーを構築するにはReadyMedia(旧名miniDLNA)というソフトウェアが主流です。
名称はReadyMediaですが、インストールする際のパッケージ名称やネットでググる際にも旧名のminiDLNAの方が通りが良いので、本ページでもminiDLNAの名称で通すことにします。

miniDLNAのインストールは簡単です。以下のコマンドでパッケージをインストールします。
$ sudo apt-get install -y minidlna 
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています
状態情報を読み取っています... 完了
以下のパッケージが新たにインストールされます:
  minidlna
アップグレード: 0 個、新規インストール: 1 個、削除: 0 個、保留: 0 個。
132 kB のアーカイブを取得する必要があります。
    :
インストール完了したらPC等のブラウザから以下のURLを表示させてみます。
<http://raspberrypi:8200/>
正しくインストールされていれば、下記の様に表示されます。

(この画面では既にコンテンツを登録していますが、インストール直後ならメディアライブラリの数は0件です)

miniDLNAサーバーのインストール時には、 /var/lib/minidlna の下のディレクトリのコンテンツを管理するようになっています。
今回は外部ディスクをサーバーにするのが目的なので、外部ディスクのコンテンツを管理するように設定します。
併せて、ログ等も外部ディスクに作成されるようにします。

外部ディスクのコンテンツを保存するディレクトリは以下としました。
格納先のルートディレクトリを/mnt/hdd/minidlna とし、その下にサブディレクトリを作成します。
  • /mnt/hdd/minidlna/musics
  • /mnt/hdd/minidlna/movies
  • /mnt/hdd/minidlna/photos
  • /mnt/hdd/minidlna/cache
  • /mnt/hdd/minidlna/log
上記のディレクトリは以下のコマンドで作成してください
$ cd /mnt/hdd
$ mkdir minidlna
$ cd minidlna
$ mkdir musics movies photos cache log
$ sudo chmod 777 *

次に設定ファイル/etc/minidlna.confを編集します。
変更する項目は以下の項目です。
 media_dir : コンテンツを格納するディレクトリを記述する
 db_dir: コンテンツを読み込んだデータベースのディレクトリを記述する
 log_dir: ログファイル出力先ディレクトリを記述する

今回の設定に当てはめると/etc/minidlna.confの変更箇所は以下の様になります。
---- ここから ----
media_dir=/mnt/hdd/minidlna
db_dir=/mnt/hdd/minidlna/cache
log_dir=/mnt/hdd/minidlna/log
---- ここまで ----

/etc/minidlna.conf を変更したらminidlnaサービスをリスタートさせます。
$ sudo service minidlna restart

● メディアファイルの格納
ここまでの設定で 音楽は/mnt/hdd/minidlna/musics、
静止画は/mnt/hdd/minidlna/photos、
動画は/mnt/hdd/minidlna/movies の下に格納するよう設定されました。
それぞれのディレクトリにコンテンツのファイルを格納するとminiDLNAはディレクトリを自動的にスキャンして管理します。

どの様な方法でコンテンツを格納しても良いのですが、一つの例としてPCからWindowsMediaPlayerを使ってCDよりファイルを読み込んで格納する方法を示します。
この方法はDLNAの機能を使用しているのではなく、前回の投稿「ラズベリーパイでホームサーバーを構築しよう -- NAS構築編」にて共有したNASへ録音しているだけですので、この例の方法で録音する場合は音楽の格納先が共有されている必要があります。
ちょうど、サンプルにふさわしいCDを持っていました。「eyes 渡辺美里
これをラズパイのDLNAサーバーに録音してみましょう。
  • WindowsMediaPlayer (WMP)を起動する
  • WMPのメニューバーよりツール->オプション を選択し、オプション画面の「音楽の取り込み」タブを表示させる。

  • 取り込んだ音楽を保存する場所 の「変更」ボタンを押し、フォルダーの参照画面を開く。

  • フォルダーツリーより「\\raspberrypi\raspberry-pi-smb\minidlna\musics」を選択する。
    ツリーになければ、フォルダー入力エリアに直接書いて指定する。
  • 「OK」ボタンを押す
  • 「音楽の取り込み」タブで形式を指定する。
    形式は何を指定しても良いが、こだわらなければ、MP3でよい。
  • 「OK」を押して設定を完了する。
  • PCにCDを入れ、WMPのCD再生画面より取り込む曲にチェックを入れる。「アルバム」横の箱にチェックを入れればすべての曲にチェックが入る。

  • 「CDの取り込み」を押して録音を開始する。
これで録音は完了です。

録音できているか、コンテンツの参照ができるかをスマホの音楽プレイヤーで確認しましょう。
使用した音楽プレーヤーはAndroidの「BubbleUPnP」というアプリです。
アプリを起動し、右下の「Library」をタップしてライブラリ画面を表示させ、左上の「SelectLibrary...」をタップすると

ライブラリの選択肢に「raspberrypi:minidlna」が現れました。これを選択し、Musicのフォルダを掘ってくと、録音したeyesが現れました。
曲をタップして再生するとブツ切れることも無く普通に再生されました。


これでDLNAサーバーのインストールと確認は完了です。
これから手持ちのCDをたくさん登録して音楽に浸りましょう。

ラズベリーパイでホームサーバーを構築しよう -- NAS構築編

前回の投稿ではRaspberry Pi Model B へ最新のRaspberry Pi OSをインストールするところまで完了しました。
今回はネットワーク設定を行い、NASを構築するまでを行います。

● ホスト名の設定
ラズパイを複数使用していたり、参加ネットワークの決まり等でホスト名(WindowsでいうところのPCの名前)を変更したい場合は、以下のファイルを編集します。
/etc/hostname
/etc/hosts

例えばホスト名を「RPi-Server」にしたい場合、これらのファイルの中の「raspberrypi」の部分を「RPi-Server」に変更します。
変更後はラズパイをリブートします。

なお、今回の例ではホスト名の変更はせずに、初期設定の「raspberrypi」のまま進めています。

● IPアドレスの設定
ラズパイをサーバーにする場合、IPアドレスが変わらないように固定します。(一般に固定IPといいます)
これはPC等から接続する際に毎回IPアドレスが変わってしまうと、IPアドレスが分からなくなりサーバーに接続できなくなるためです。
ラズパイのIPアドレスを固定IPにする方法については以下のサイト等を参考にしました。 「ラズベリーパイで固定IPアドレスを設定する

最初にIPアドレスを決めます。
我家のLANは192.168.0.1~192.168.0.10までのローカルアドレスをルーターのDHCP機能で割り当てる様にしています。
ラズパイも同様にルーター側の設定で固定IPアドレスを振る様にしますが、最初はラズパイ側で固定IPアドレスを設定してみます。
ラズパイのIPアドレスは自動で割り当てられるアドレスと重ならないように 192.168.0.15 に設定する事とします。
デフォルトゲートウェイ、DNSサーバーのIPアドレスは、ルーターがそれらの機能を兼ねており、そのIPアドレスが192.168.0.1ですので、192.168.0.1とします。

ラズパイのネットワーク設定は画面から、又は端末から設定できますが、今回は画面から設定することとします。
画面上部のメニューバーの右にある「↑↓」のアイコンがネットワークの状態を示す物です。これをクリックすると、プルダウンメニューが出ますので、「Wireless & Wired Network Setting」を選択します。

表示された「NetworkPeferences」画面の右上にあるプルダウンメニューより「eth0」を選択します。

「Automatically configure empty option」のチェックを外します。これはIPアドレスが自動割り当てされる場合にチェックするものです。
「Disable IPv6」はIPv6ネットワークでは使用しないので付けたままとします。
「IPv4 Address」にはラズパイのIPアドレス 192.168.0.15 を設定します。
「Router」「DNS Server」には 192.168.0.1 を設定します。

全ての入力を終えたら「適用」「閉じる」押して設定を完了させてから、ラズパイをリブートします。

リブート後、仮想端末からネットワークの設定を確認しました。192.168.0.15になっていますね。


● 外部のPCから操作できるように設定する
使い慣れたPC上でTeraTermというターミナルエミュレータでコマンドを使った操作ができる様に設定します。
これはPCから操作したいという事でなければ設定しなくても構いません。

PC等他のコンピュータからログインしたり、ファイルをコピーしたりする為にはSSHという機能を使用します。
ラズパイの場合、SSH機能は無効になっていますので、以下の手順で有効にします。

スタートメニュー->設定->Raspberry Piの設定 を選択し、「Raspberry Piの設定」画面を開きます。

「Raspberry Piの設定」画面の「インターフェイス」タブを表示させ、「SSH」という項目を有効にします。

その後、「OK」ボタンを押して完了です。
これで、PCからTeraTermでログインできるようになりました。

● 外部ディスクを接続する
ラズパイのNASを構築するにあたって、HDDはラズパイでの使用をやめてもPCにつなげて使える様にするため、HDDはNTFSとすることにしました。
NTFSフォーマットのHDDを使用するにあたってHDDは事前にPC側でフォーマットしておきます。
ラズパイでNTFSフォーマットしたHDDはPC側では認識しません。この事には注意してください。
PCに接続しないのであれば、HDDはどの形式でフォーマットしても構いません。

フォーマット済の外付けHDDをラズパイに接続してみました。
ディスクの状態を見るdfコマンドを打ったところ、下の様に表示されました。
$ df
ファイルシス   1K-ブロック    使用    使用可 使用% マウント位置
/dev/root         30358348 3150888  25921652   11% /
devtmpfs            187244       0    187244    0% /dev
tmpfs               220224       0    220224    0% /dev/shm
tmpfs               220224    3252    216972    2% /run
tmpfs                 5120       4      5116    1% /run/lock
tmpfs               220224       0    220224    0% /sys/fs/cgroup
/dev/mmcblk0p1      258095   48676    209420   19% /boot
tmpfs                44044       4     44040    1% /run/user/1000
/dev/sda1        160833532   96120 160737412    1% /media/pi/work
自動的にマウントされ、/media/pi/work にマウントされたことがわかります。

NASとして使うには自動マウントでなく、OS起動時から固定的にマウントされるようにします。
その為には、/etc/fstab というファイルを編集します。fstabは起動時にマウントするディスク等の情報を記述するファイルです。
fstabを編集するにあたっては、事前に以下を決めておきます。
  • デバイス名
  • マウントポイント
  • ファイルシステムの種類
  • マウントオプション
デバイス名とはOSが認識するディスクの名前で、上の場合 /dev/sda1がそれにあたります。
デバイス名の代わりにUUIDを指定することもできます。UUIDとはデバイスを識別するためのIDで、ディスク、パーティションごとに異なった値を持つものです。
複数のディスク、複数のパーティションがある場合やディスクを接続するUSBポートが変わった場合には接続後のデバイス名が変わることがあります。なので、UUIDを指定することを推奨します。
UUIDを調べるには、以下のコマンドを使用します
$ sudo blkid /dev/sda1
/dev/sda1: LABEL="work" UUID="C01C7B171C7B07A4" TYPE="ntfs" PARTUUID="d686d686-01"
UUIDは「C01C7B171C7B07A4」であることがわかりました。
マウントポイントとは接続したディスクのディレクトリの事です。
自動的にマウントされた時には /media/piの下にマウントされましたが、/mediaは自動的にマウントされるメディアの為のディレクトリですので、NASとして使うにはあまり適切ではありません。
なので、/mntの下に hdd というディレクトリを作成し、そこへマウントする事とします。
以下のコマンドでマウントポイントを作っておきます。
$ cd /mnt
$ sudo mkdir hdd
$ sudo chmod 777 hdd

マウントオプションはNTFSの場合、以下の物を指定する事を推奨します。
 nofail : 指定するとHDDが壊れたり取り外されていてもOSをブートできる。指定しない場合、マウントに失敗するとOSは起動しない。
 permissions : ファイルのオーナーによるアクセス権の管理を行う
 default : 上記以外はデフォルトを使用する
自動でマウントされたディスクを一旦アンマウントしてマウントしてマウントに成功するか確認しておきます。
以下のコマンドでアンマウントとマウントを行います。
$ sudo umount /media/pi/work
$ sudo mount UUID=C01C7B171C7B07A4 /mnt/hdd
マウントしたらdfコマンドで正しくマウントできているか確認しておきます。

UUIDを調べ、マウントポイントも作成したので、次にfstabを編集します。
編集にはエディタを使用します。ラズパイにインストールされているエディタには端末上で使用する vi、nano。画面上で使用するテキストエディタがありますが、使いやすいものを使えばよいです。 ただし、特権ユーザーでファイルを編集する必要があるので、
$ sudo vi /etc/fstab のように、プログラム名の前にsudoを付けるてエディタを起動する必要があります。
以下の行を /etc/fstabへ追加します。
----- ここから ----
UUID=C01C7B171C7B07A4 /mnt/hdd ntfs default,nofail,permissions 0 0
----- ここまで ----

fstabの編集が終わったら、再起動してdfコマンドでマウントできているかを確認してください。

● Sambaをインストールする
Sambaとは、Windowsネットワークの共有ファイルサーバーを構築する為のフリーソフトウェアです。
ラズパイなど、Linux系OSの走るコンピュータでNASを構築するのには一般的に使用されているものです。
Sambaのインストールには以下のコマンドを使用します。
$ sudo umount /media/pi/work
$ sudo apt-get install -y samba
途中、「DHCP から WINS 設定を使うよう smb.conf を変更しますか? 」というメッセージが表示され、<はい><いいえ>の選択を促されます。 ここでは<いいえ>を選択してください。


インストールが完了したら、設定ファイル /etc/samba/smb.conf の編集をおこないます。 samba.confの最後に、以下の行を追加します。
---- ここから ----
[raspberry-pi-smb]
comment = Raspberry Pi USB DISK /dev/sda1
path = /mnt/hdd
guest ok = yes
browseable = yes
writable = yes
read only = no
create mask = 0777
directory mask = 0777
---- ここまで ----

上の例で「raspberry-pi-smb」という名前がありますが、これは共有ディレクトリの名前になります。好きな名前を付けてください。
samba.confの編集が終わったら以下のコマンドを実行して変更した設定を有効にするか、リブートします。
$ sudo services smbd restart
次にPC側でNASを参照できるかを確認します。
エクスプローラーのアドレスバー に 「\\raspberrypi」 と入力し、リターンを押します。
(raspberrypiはラズパイのホスト名です。ホスト名の設定をしていない場合はこの名前になります。)

すると「raspberry-pi-smb」というフォルダが見えます。
これをクリックしてフォルダを開き、ラズパイの外付けHDDのファイルが見えるか、書き込めるかを確認します。

NAS側でユーザー毎のアクセス制御をしないのであれば、設定はここまでです。
Windowsのユーザーごとにファイルのアクセス権を管理する場合の設定については、またいつか書きましょう。

ラズベリーパイでホームサーバーを構築しよう -- インストール編

会社で使われていない古いラズベリーパイがあるので、借りてきました。
このラズベリーパイで自宅のホームサーバーを構築します。

● そもそも、「ラズベリーパイ」略して「ラズパイ」とはどのような物でしょう?
ラズパイは小型のシングルボードコンピュータです。そしてラズパイはパソコンとほぼ同じ事ができ、そのうえ、GPIOという仕組みにてコンピュータ外部の機器と接続してそれらを操作することもできる物です。

我社でも、ラズパイをETロボコンのリモートスタート用に使用したり、インターンシップでソケット通信の教育に使用したりと活用してきました。

● ラズパイ始めるぞ。
まず、用意したのは以下のもの。
  1. Raspberry Pi Model B + 32Gbyte SDカード
  2. 液晶モニタ(VGA入力のみ)
  3. 164Gbyte HDD + USB接続HDDケース
  4. FOMA充電器
  5. HDMI->VGA変換器
  6. FOMA - MiniUSB変換コネクタ
ラズパイも含めて、現役でない物の寄せ集めで構築します。

心配なのがFOMA充電器と、HDMI->VGA変換器。
FOMA充電器は出力が5.4V 700mAとラズパイの推奨電源(5.0V 1.2A)より電圧が高く電流が少ないです。
HDMI-VGA変換器はラズパイ側で適切な設定が可能かどうか次第です。

結局FOMA充電器はアンペア不足でダメでした。ブラウザを起動すると画面がチラチラと揺れます。なので、スマホ用充電器に変えました。

◆ インストールの前に、
まず、最初に借りてきたラズパイの動作確認をしておきます。
この時点でラズパイを壊したくないので、PCからUSB電源を取り、PCで使っているディスプレイを接続して起動を確認しました。インストール完了までは不安のある機器は使用しません。
はい、問題なく立ち上がりました。

次に現在のSDカードのバックアップを取ります。それには「Win32 Disk Imager」というソフトを使います。
以下のサイトからダウンロードし、インストールします。
Win32 Disk Imager 日本語情報トップページ
Win32 Disk ImagerをインストールしてSDカードのバックアップを取る手順については以下のページに詳しく書いてあります。それを参考にしてください。
【Raspberry Pi】SDカードを丸ごとバックアップする方法について

◆ OSはどれをつかうの?
バックアップを取ったので、OSのインストールを開始します。
Rasupberry Piで使用できるOSはいくつかあります。そのうちのどれを入れたら良いのでしょう。
一般的な使い方なら
  • Raspberry Pi OS with desktop (以前はRsapbianという名称でした)
  • ubuntu
また、用途毎に特化したOSというのもあります。
動画、画像、音楽を配信するメディアセンターを作るなら
  • OSMC
  • LibreELEC
レトロゲームに使うなら
  • RetroPie
組み込み制御等に使うなら
  • Raspberry Pi OS Lite
  • Windows 10 IOT core (Windowsという名前が付いていますが、PCで使うWindowsとは異なるものです)

今回は一番一般的で、ネット上に情報の溢れているRaspberry Pi OS with desktop を使うことにします。

◆ インストールを始めよう
「Raspberry Pi Imager」というツールを使ってOSを"SDカード"にインストールします。
その後にOSを入れたSDカードを使ってラズパイを起動し、初期設定を行う手順です。

「Raspberry Pi Imager」とOSのインストール手順については以下のページに詳しく書いてあります。
Raspberry Pi OS (Raspbian)のインストール - 公式Imager対応
raspberry pi OS のダウンロードページへ行き、そこで「Download for Windows」のボタンを押して、「imager_1.5.exe」をダウンロードします。
ダウンロードしたimager_1.5.exe をダブルクリックで起動し、Raspberry Pi Imagerをインストールします。
以降の手順で「このアプリがデバイスに変更を加えることを許可しますか?」の画面が表示される個所があります。表示されたら「はい」を押します。
Raspberry Pi Imagerがインストールできたらスタートメニューに追加されたRaspberry Pi Imagerのアイコンをクリックして起動します。


Raspberry Pi Imager画面が表示されます。


画面にて 「CHOOSE OS」ボタンを押し、表示されたプルダウンメニューより「Raspberry Pi OS(32-bit)」を選択します。
他のOSをインストールしたい場合は、このプルダウンメニューからそのOSを選択します。


画面にて「CHOOSE SD CARD」ボタンを押して、インストールしたいSDカードを選択します。


選択完了すると「WRITE」ボタンが有効になるので、それを押します。


十数分で書き込みが完了します。完了したらRaspberry Pi Imagerを終了し、SDカードをPCから取り外します。




◆ 初期設定をしよう
インストールの完了したSDカードをRaspberry Piに挿入し、ディスプレイ、キーボード、マウスを接続します。

最後にUSB端子に電源を接続してRaspberry Piを起動します。

すると、起動画面に続きセットアップ画面が表示されます。


セットアップ画面では「NEXT」ボタンを押します。


次に国、言語、タイムゾーンの設定を行います。国に日本を選択すると、言語とタイムゾーンは日本のものになります。


次にpiユーザーのパスワードを入力します。2カ所に同じパスワードを入力します。


次に画面設定を行います。セットアップ画面には「デスクトップの周りに黒い枠が見えますか」という質問が表示されます。
画面がディスプレイいっぱいに表示されていなければ質問の左側のボタンをチェックします。
今回はディスプレイいっぱいではなかったですが、実際に使用するディスプレイでは無いので、そのまま「NEXT」ボタンを押しました。


次にアップデートを行います。今回はまだネットワークケーブルを接続していないので「SKIP」を押しました。
有線ネットワークやWiFiの設定が済んでいる場合は「NEXT」を押してRaspberry Pi OSのアップデートをさせます。


アップデート画面の次はセットアップ完了画面になります。ここで「Done」を押してセットアップ完了です。


初期設定時にはLANをつなげていなかったので、アップデートをスキップしました。
その為、LAN接続後に、OSを最新にアップデートします。
以下のページを参考にしました。
Raspberry Pi の OS を最新の安定版にアップデートする
画面上部のツールバーからターミナルを選択してコマンド操作できる端末を開きます。
その端末で順に以下のコマンドを入力します。
$ sudo apt update

$ sudo apt full-upgrade

$ sudo apt clean
ここまで終わったらシャットダウン又はリブートします。

ssh/scpでパスワード無しで接続する方法

以前参加したプロジェクトで、複数のLinuxマシン間で設定ファイルを共有したいという要求がありました。
普通であれば、nfsやSMBでファイル共有するのですが、そのプロジェクトはファイルサーバーを持たないシステムでした。
そこで、scpを利用してリモートコピーでファイル等化を実現しようということになりました。 幸い、等化元となるファイルの存在するマシンは決まっていたので、 システム起動時にそのマシンからファイルをscpでコピーすることで実現可能でした。
通常scpはコピー時にパスワードを聞いてきますが、下記の設定を行う事でパスワード入力が不要となるようにしました。

設定方法について以下に例をあげて記載します。
この例では コピー元マシンのIPアドレス、ユーザー名は以下としています。
     IPアドレス:192.168.1.10
    ユーザ :user1
    パスワード:pass1
コピー先のマシンのIPアドレス、ユーザー名は以下とします。
    IPアドレス:192.168.1.11
    ユーザ :user2
    パスワード:pass2

コピー元マシンにログインし、以下のコマンドを入力します。

$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/user1/.ssh/id_rsa):
Created directory '/home/user1/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/user1/.ssh/id_rsa.
Your public key has been saved in /home/user1/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:p7Jl9VtQhtEdQHdP6Y1boxApXDbuLaEgD399OXey4go user1@192.168.1.10
The key's randomart image is:
+---[RSA 2048]----+
|        . .+++.+=|
|         ooo.ooo+|
|     o .  .oo +.o|
|      = . +.ooooo|
|       oSoo+o=o+o|
|        .+ .oo+o.|
|      . E   o o  |
|       = . . +   |
|      .   ..o    |
+----[SHA256]-----+

$ ssh-copy-id -i ~/.ssh/id_rsa.pub user2@192.168.1.11
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/user1/.ssh/id_rsa.pub"
The authenticity of host '192.168.1.11 (192.168.1.11)' can't be established.
ECDSA key fingerprint is SHA256:yYVW4kiK3FlmSR+PPodLBhmH9sNdpivwwStcln+L76A.
Are you sure you want to continue connecting (yes/no)? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
user2@192.168.1.11's password: pass2
Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'user2@192.168.1.11'"
and check to make sure that only the key(s) you wanted were added.
上記手順の中で、ssh-keygen コマンドはファイル名やパスフレーズの入力を求められますが、何も入力せずにエンターキーを押してください。
ssh-copy-idコマンドではパスワードの入力が求められます。コピー先ユーザーのパスワードを入力してください
これでパスワード無しでscpやsshができるようになります。
ssh-copy-idの出すメッセージの最後にあるように、"ssh user2@192.168.1.11" でコピー先ユーザーへログインしてみましょう。

以上

マルチスレッド処理のサンプル

コンピュータのプログラミングにおいて、複数の処理を並行して実行したい場合、main()関数から順次実行されるメインスレッド以外に、並行動作させるサブスレッドを生成することで平行処理を実現します。
では、複数の処理を並行して実行させたいプログラムって、どんなプログラムでしょうか?
例えば「処理A」ボタンと「処理B」ボタンを置き、押された方の処理を実行するプログラムを作成する事とします。シングルスレッドでは、処理Aが終了するまで処理Bを行えません。
これがマルチスレッドであれば、「処理A」を行っている間にも「処理B」ボタンを受け付け、処理Bを行うことが出来るようになります。
今回のサンプルとしたチャットプログラムも同様で、相手に送信する通信文の入力を受け付け、送信している間は相手からの通信文は受信できません。
マルチスレッド化する事で通信文の入力および送信と、相手からの通信文の受信を並行して行えるようにできます。(注)

ここからC言語でマルチスレッド処理を行う手順についてサンプルプログラムにて説明します。
本サンプルプログラムはソケット通信で送受信を行うチャットプログラムの一部です。実際のソケット通信は関数化しており、本サンプルでは省略しています。

このプログラムはメイン関数(メインスレッド)でコンソールからの通信文の入力を受け付け、それをチャット相手に送信します。
並行して動作するサブスレッドではチャット相手からの通信文を受信し、コンソールへ表示します。
メインスレッドもサブスレッドも相手が終了してソケットが切断されるか、Ctrl-Dが入力されるまでループして通信を繰り返します。

  1. recv_thread()がメインスレッドと並行して動くスレッドになります。
    引数の param はスレッドを生成する pthread_create()の第4引数が渡されます。スレッドに渡すパラメータがある場合は、これを使用します。
    渡す引数が複数ある場合は、パラメータブロックを構造体や配列で作成し、それをポインタで渡すのが一般的です。
  2. end_flag、complete_flag はサブスレッドの動作を制御するためのフラグです。
    メインスレッドとサブスレッドの間で相互の通知が必要ない場合は不要です。
  3. start_thread()はスレッドを起動する関数です。
    スレッド起動にはpthread_create()を使用します。引数はスレッドID、スレッド属性、スレッド、スレッドへ渡す引数です。
    スレッドIDはpthread_create()が生成したスレッドIDを取得するものなので、ポインタ渡しになることに注意してください。
    スレッド属性はpthread_attr_init()で生成した属性を渡します。スレッド属性変更の必要が無ければNULLでかまいません。
    スレッド属性にはデタッチ状態、スケジューリングポリシー、スケジューリングパラメータがあります。
    デタッチ状態はとはスレッド終了時のリソース解放処理を変更するもので、PTHREAD_CREATE_DETACHEDに設定するとスレッド終了を待ち合わせるpthread_join()が不要になります。
    詳しくはpthread_attr_initのmanページを見てください。
  4. terminate_thread()はスレッドを終了させる関数です。
    end_flagをtrueにセットし、受信スレッドの繰り返し処理を終わらせます。その後、pthread_join()を呼んでスレッドの終了を待ち合わせます。
    このサンプルコードではcomplete_flagを参照してスレッドの処理終了を待ち、スレッドが一定時間以内に終了しなかった場合はpthread_cancel()を呼び出し強制終了するようにしています。これはスレッドがループの中で待ちになるような場合への対応です。
  5. main()はメインスレッドで、コメントと合わせて読めばどんな処理をしているかは判るのでここでの説明は省略します。


============ ここから ============

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <time.h>
#include <pthread.h>

#include "socket.h"
#include "console.h"

volatile bool end_flag;
volatile bool complete_flag;

void * recv_thread( void * param )
{
    int fd = *((int *)param);  // 引数で渡される通信ソケットのディスクリプタ
    char message_buffer[79];
    int rtn;

    while( !end_flag )
    {
        
        // ソケットから通信文を受信する
        rtn = receive_socket( fd, message_buffer, sizeof( message_buffer ));
        // 通信文が取得できた場合
        if ( rtn > 0 )
        {
            // 通信文をコンソールへ表示する
            rtn = output_console( message_buffer );
        }
        // ソケットが切断された場合
        else if ( rtn == 0 )
        {
            fprintf( stdout,"disconnected.\n" );
            // ループから抜ける
            break;
        }
        // ソケット通信エラーの場合
        else
        {
            fprintf( stdout, "receive_soket error.\n");
            // ループから抜ける
            break;
        }
    }
    end_flag = true;
    complete_flag = true;
}

int start_thread( pthread_t * thread_id, int fd)
{
    int rtn;
    pthread_attr_t attr;
    // スレッド属性オブジェクトを初期化し、値を設定する
    pthread_attr_init( &attr );
    pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_JOINABLE );

    end_flag = false;
    complete_flag = false;
    // 受信スレッドを生成する
    rtn = pthread_create( thread_id, &attr, recv_thread, &fd );

    // スレッド属性オブジェクトを破棄する
    rtn = pthread_attr_destroy( &attr );
    return rtn;
}

int terminate_thread( pthread_t thread_id )
{
    int rtn;
    // 受信スレッドを終了させる
    end_flag = true;
    // 受信スレッドの処理終了を1秒まで待つ
    for ( int i = 0 ; i < 10 && !complete_flag ; i++ )
    {
         struct timespec tm = { 0, 100*1000*1000 };
         nanosleep( &tm, NULL );
    }
    // スレッドが終了しなかった場合
    if ( !complete_flag )
    {
        // 強制的にスレッドを終了させる
        rtn = pthread_cancel( thread_id );
    }
    // 受信スレッドの終了を待つ
    rtn = pthread_join( thread_id, NULL );
    return rtn;
}

int main( int argc, char *argv[] )
{
    int fd;
    pthread_t  thread_id;
    char message_buffer[79];
    int rtn;

    // サーバーソケットを生成し、接続されるのを待つ
    fd = create_socket_server();
    // 接続失敗の場合、終了する
    if ( fd == -1 )
    {
        exit(1);
    }

    // 受信スレッドを生成する
    rtn = start_thread( &thread_id, fd );

    // 通信文の送受信を繰り返す
    while( !end_flag )
    {
        // コンソールから入力された通信文を取得する
        rtn = input_console( message_buffer, sizeof( message_buffer ));
        // 通信文が取得できた場合
        if ( rtn > 0 )
        {
            // ソケットで通信文を送信する
            rtn = send_socket( fd, message_buffer );
        }
        // Ctrl-Dが入力された場合
        else if ( rtn == 0 )
        {
            fprintf( stdout, "disconnect.\n");
            // ループから抜ける
            break;
        }
        // 入力エラーの場合
        else
        {
            fprintf( stdout, "input_console error.\n");
            // ループから抜ける
            break;
        }
    }
    // 受信スレッドを終了させる
    rtn = terminate_thread( thread_id );

    // ソケットをクローズする
    destroy_socket( fd );

    exit(0);
}
============ ここまで ============

注) 非同期通信を利用してプログラミングすることでも、同様の動作を実現できます。

上記サンプルプログラムを使用して発生した障害,問題などに関して,プログラムの作者および(株)アイズ・ソフトウェアは一切の責任を負いません。
使用はご自身の責任で行ってください。

Linux Tips (Twitter過去記事)

我が社のツイッターでは過去にlinuxのTips(ヒント、ノウハウ等)をツイートしていたことがありました。
その過去記事をここでまとめて紹介します。

linuxでディレクトリをマウントする方法

以前参加したプロジェクトで、NASをマウントして使用する物がありました。
そのシステムではNASが起動していない等の理由でマウントできなかった時には、予備として自ホスト内のディレクトリを同じパスで参照するというものでした。

そこで、予備側を参照させる為に考えたのが以下の方法です。

  1. シンボリックリンクを使う。
  2. 自ホストをNFSマウントする。
しかし、前者はマウントとシンボリックリンクの切り替え時にいちいちファイルを消してディレクトリまたはシンボリックリンクを作成しなければならないという手間があります。
また、後者は /etc/exportsの設定とnfsdを起動させる必要があります。
そこで他に簡単な方法がないかなとググってみました。

すると、「mount --bind」でディレクトリをマウントできるという記事を見つけました。

例えば、/home/APP/Config というディレクトリを /home/ext-mount/Config というパスで参照できるようにするには、
/home/APP/Config を /home/ext-mount/Config にマウントすればよいのです。
このコマンドは下記となります。

# mount --bind /home/APP/Config /home/ext-mount/Config


通常、ファイルやディレクトリの実体とアクセスするパスを関連させるにはシンボリックリンクを使用したほうが特権も不要で便利です。
使うのは今回の例のように条件によりマウント先を切り替える様な時ぐらいで、使用頻度は高くないと思います。

以上