- 投稿日:2020-10-17T21:42:45+09:00
Linux: 強制ロック(mandatory lock)
Linuxでファイルの強制ロック(mandatory lock)をする方法です。
強制ロックとは
- アドバイザリロックとは異なり、Linux固有の機能。POSIXやUNIXにはない。
- ロックを掛けたプロセス以外からの、read()やwrite()をできなくする。
- race conditionが発生する可能性があったりして、ロックの信頼性は高くない。ロックと同時にreadやwriteが獲得されると、ロック中なのに読み書きできてしまうらしい。
強制ロックが有効になる環境を作る
強制ロックを有効にするには、2つの条件を満たす必要があります。
- ロックされるファイルは
-o mand
でマウントされたファイルシステムでないとならない。- ロックされるファイルは、set-group-IDビットがOnで、group-executeビットがOffでないとならない。
mkdir dir mount -t tmpfs -o mand,size=1m tmpfs ./dir chmod g+s,g-x dir/lockfile echo hello > dir/lockfile強制ロックを発動する
強制ロックを発動するために、システムコールを呼び出すPythonスクリプトを作ります。
lock.py#!/usr/bin/env python import fcntl, os, time, sys f = open(sys.argv[1], "r+") fcntl.lockf(f, fcntl.LOCK_EX) print(f.readlines()) time.sleep(10)このlock.pyは、10秒間dir/lockfileを排他的強制ロックします。lock.pyを実行している10秒間の間に、他のプロセスからdir/lockfileを読み込もうとすると、pythonのプロセスが終了するまで待たされます。
# ロックする ./lock.py # 別ターミナルで cat dir/lockfile # 10秒程度待たされるこの10秒間に、
lslocks
や/proc/locks
を確認すると、ロックが掛かっている事がわかります。root@vagrant:~/dir# lslocks COMMAND PID TYPE SIZE MODE M START END PATH lvmetad 463 POSIX 4B WRITE 0 0 0 /run/lvmetad.pid cron 866 FLOCK 4B WRITE 0 0 0 /run/crond.pid atd 848 POSIX 4B WRITE 0 0 0 /run/atd.pid lxcfs 849 POSIX 4B WRITE 0 0 0 /run/lxcfs.pid iscsid 1135 POSIX 5B WRITE 0 0 0 /run/iscsid.pid python 1818 POSIX 0B WRITE 1 0 0 /dev/pts/0 ☝?ここ root@vagrant:~/dir# cat /proc/locks 1: POSIX MANDATORY WRITE 1818 00:2c:3 0 EOF ??ここ 2: POSIX ADVISORY WRITE 1135 00:13:1503 0 EOF 3: POSIX ADVISORY WRITE 849 00:13:1498 0 EOF 4: POSIX ADVISORY WRITE 848 00:13:1487 0 EOF 5: FLOCK ADVISORY WRITE 866 00:13:1485 0 EOF 6: POSIX ADVISORY WRITE 463 00:13:1258 0 EOF参考
- 投稿日:2020-10-17T19:25:11+09:00
Ubuntu 20.04にSambaを使用してファイルサーバを立てる
Ubuntuに、Sambaを使ってゲストアカウントで接続できるファイルサーバをたてます。
環境
Ubuntu 20.04を使いました。
$ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 20.04.1 LTS Release: 20.04 Codename: focal1. sambaのインストール
apt install
でSambaをインストールします$ sudo apt install sambaversion 4.11がインストールされました。
$ samba -V Version 4.11.6-Ubuntu2. 共有するディレクトリの作成
任意の場所に共有用のディレクトリを作成します。
$ cd /home $ mkdir share $ chmod 777 share3. sambaサーバの設定
$ sudo vi /etc/samba/smb.confこの辺はよく分かっていないので、ネットにある記事を参考に設定しました。
[global] unix charset = UTF-8 dos charset = CEP932 display charset = UTF-8 bind interface only = yes map to guest = Bad User [public] comment = public path = /home/share public = yes writable = yes printable = no create mode = 0777 directory mode = 07774. サーバの起動
$ sudo service smbd start5. 自動起動設定
必要に応じて自動起動の設定をしておきます。
$ sudo sytemctl enable smbd5. macからの接続
Finderでサーバへ接続を開く、もしくは
Cmd + k
し、サーバアドレスにsmb://<ip address or hostnanme>と、入力すれば接続できます。
- 投稿日:2020-10-17T03:55:15+09:00
Raspberry Pi 4にCentOS7をインストール&設定
ラズパイ4を購入したので、Raspbianではなく一般的なサーバーとしてよく使われるCentOSを入れてみたいと思います!!
ただし、実用的じゃないので自分はすぐにRaspbianに戻しました(笑)
参考にさせて頂いたサイト
Raspberry Pi 4 で CentOS 7 を動かす
CentOSにntpサーバを入れて、日本標準時刻に自動的に合わせるためのメモ
CentOS 7 NTP設定・・・ちょっと待て!?Raspberry Pi Imagerの準備
こちらは、microSDのフォーマットやOSの書き込みなどを自動で行ってくれるソフトです!
Raspberry Pi Downloads - Software for the Raspberry Pi
ここから、任意のOSを選択してダウンロード&インストールをしましょう!
私は、microSDの書き込みをWindowsで行ました。ディスクイメージのダウンロード
上記のサイトだと、CentOSをデフォルトでサポートしていないので、下記のリンクからラズパイ4用のCentOS7のディスクイメージをダウンロードしましょう。
Raspberry Pi Imagerを使って、microSDに書き込む
ディスクイメージのダウンロードが終わったら、インストールしたRaspberry Pi Imagerを使って、microSDに書き込みます。
- Operating System:ダウンロードしたディスクイメージ
- SD Card:PCに挿している書き込みたいSDカード
2つ指定すると、「WRITE」が押せるようになるので押して書き込みましょう。
しばらく待って、この画面がでたら書き込みが完了!!
ラズパイに有線LANを挿して、SSHで接続する
書き込みが終了したら、書き込んだSDカードをラズパイに挿して起動しましょう!
起動したら、デフォルトの以下のユーザーでログインして、IPアドレスを確認します。ユーザ名:root
パスワード:centosログインできたら、以下のコマンドを打って、IPアドレスを確認しましょう !
ip a | grep 192
そうすると、192から始まるIPアドレスが取得できます。
[root@localhost ~]# ip a | grep 192 inet 192.168.0.2/24 brd 192.168.0.255 scope global noprefixroute dynamic eth0ここから分かるとおり、このラズパイのIPアドレスは「192.168.0.2」ということが分かりましたので、別のPC(今回はmac)からSSHでログインします。
(Windowsの方はTera TermというソフトをDLをしてそこからログインします。)まずは、ターミナルで以下のコマンドをうち、ラズパイでログインした通りにここでもログインしましょう。
ssh root@調べたラズパイのIPアドレス私の場合だと、以下のようなコマンドになります。
ssh root@192.168.0.2そしたら、このようになるのでyesと入力します。
The authenticity of host '192.168.0.2 (192.168.0.2)' can't be established. ECDSA key fingerprint is SHA256:mOsYHnXBZPXZIAs0bzk7eOv3hZ4Rt2mJKfzlZiylR3o. Are you sure you want to continue connecting (yes/no/[fingerprint])?次は、パスワードが求められるので「centos」と入力してEnterを押します。
Warning: Permanently added '192.168.0.2' (ECDSA) to the list of known hosts. root@192.168.0.2's password:このような状態になれば、ログインは成功です!!
Last login: Tue Apr 21 17:23:37 2020 from 192.168.0.7 [root@localhost ~]#
ここまでをまとめると、このような感じになるはずです
rootのパスワードを変更する
初期状態だと、誰でもログインできてしまうので以下のコマンドを打って、任意のパスワードへ変更しましょう。
passwd rootすると、新しいパスワードの入力と確認が求められるので2回入力します。
「passwd: すべての認証トークンが正しく更新できました。」
と表示されたら完了です!!!パーティションの拡張を行う
まず、以下のコマンドを打ってください。
df -hそうするとこのような結果が表示されると思います。
[root@localhost ~]# df -h ファイルシス サイズ 使用 残り 使用% マウント位置 /dev/root 1.4G 1.2G 211M 85% / devtmpfs 1.9G 0 1.9G 0% /dev tmpfs 2.0G 0 2.0G 0% /dev/shm tmpfs 2.0G 17M 1.9G 1% /run tmpfs 2.0G 0 2.0G 0% /sys/fs/cgroup /dev/mmcblk0p1 286M 52M 235M 18% /boot tmpfs 391M 0 391M 0% /run/user/0/def/rootを見てみると、microSDは32GBのものを使用しているのに、うまく使いきれていません…
なので、以下のコマンドを入力して拡張しましょう!
/usr/bin/rootfs-expandそうすると、最後にDone.と表示されると成功です
なので、もう一度df -hと入力すると拡張されていることが分かります。
vimエディタのインストール
以下のコマンドを入力して、vimというエディタをインストールしましょう。
sudo yum install vim -yNTPサーバーを入れて日本の標準時に合わせる
/etc/chrony.confを編集して、NTPサーバーの指定しましょう!
デフォルトでは以下のようになっているので/etc/chrony.conf# Use public servers from the pool.ntp.org project. # Please consider joining the pool (http://www.pool.ntp.org/join.html). server 0.centos.pool.ntp.org iburst server 1.centos.pool.ntp.org iburst server 2.centos.pool.ntp.org iburst server 3.centos.pool.ntp.org iburstこのserver から始まる行が、海外の時刻を提供しているサーバーらしいので、全部コメントアウトして、以下の行を追加します。
# Use public servers from the pool.ntp.org project. # Please consider joining the pool (http://www.pool.ntp.org/join.html). ### ↓ここからコメントアウト # server 0.centos.pool.ntp.org iburst # server 1.centos.pool.ntp.org iburst # server 2.centos.pool.ntp.org iburst # server 3.centos.pool.ntp.org iburst ######## ↑ここまでコメントアウト ### ↓ここから追加 # 日本標準時を提供しているNTPサーバー(stratum 1) server ntp.nict.jp iburst # 上記サーバーと直接同期しているNTPサーバー(stratum 2) server ntp.jst.mfeed.ad.jp iburst ####### ↑ここまで追加今回は、時刻補正のためのNTPなので、以下の行を追加してサーバーとしては使わないようにする。
port 0海外のNTPサーバーと大幅にずれていると設定出来ないらしいので、以下のコマンドで手動設定しましょう。
chronyc makestep以下のコマンドを入力して、NTPサーバーの再起動と起動時に自動で実行するようにします。
systemctl restart chronyd systemctl enable chronyd
dateコマンドを入力して見ます。
2020年 4月 23日 木曜日 16:23:00 UTCJSTになってない!!!!
ちゃんとJSTになって時刻が日本時間になっているかたは、以上です、お疲れ様でした。
なので、timedatectlコマンド入力して見ます。
Local time: 水 2020-04-22 16:23:51 UTC Universal time: 水 2020-04-22 16:23:51 UTC RTC time: n/a Time zone: UTC (UTC, +0000) NTP enabled: yes NTP synchronized: yes RTC in local TZ: no DST active: n/a!?!?!?!?
そもそも、タイムゾーンがUTCだったのでいくらやってもUTC時刻に補正されちゃうんですね….???なので、以下のコマンドでタイムゾーンを東京に変更して、もう一度NTPサーバーの再起動を行い、dateで時間を確認します。
timedatectl set-timezone Asia/Tokyo systemctl restart chronyd date
すると….
2020年 4月 23日 木曜日 01:24:14 JSTちゃんとJSTの時刻が設定されました!!!!
ちなみに、ラズパイを再起動して確認してみても
[root@localhost ~]# date 2020年 4月 23日 木曜日 01:39:05 JSTうまく設定できてることが確認できました???
- 投稿日:2020-10-17T01:04:58+09:00
Dockerのコマンドまとめ
はじめに
Dockerは多くのIT開発企業で導入されている環境構築を楽にする技術です。
Dockerのコマンドをまとめます。今回のDockerコマンド
- docker login
- docker pull
- docker images
- docker run
- docker run --name
- docker run --rm
- docker ps -a
- docker restart
- docker exec -it (コンテナID)or(コンテナ名) bash
- docker commit (コンテナID)or(コンテナ名) (新しいimage名)
- docker tag (source) (target)
- docker push
- docker rmi
- docker stop
- docker rm
- docker system prune
詳細
docker login
Dockerにログインするコマンド。
Dockerを使用する場合は最初に行う。ターミナル% docker login Username: => Dockerに登録したユーザー名を入力 Password: => Dockerに登録したパスワードを入力 => ユーザー名、パスワードが合っていれば、ログインする。(Login Succeededと表示される)docker pull
Docker imageをdockerhubからホストにダウンロードするコマンド。
ターミナル例)hello-worldというimageをダウンロードする時 % docker pull hello-world => hello-worldがダウンロードされる => ユーザー名、パスワードが合っていれば、ログインする。(Login Succeededと表示される)docker images
ホストの中にあるdocker imageのリストを表示するコマンド。
ターミナル例)hello-worldというimageをダウンロードした後 % docker images => REPOSITORY TAG IMAGE ID CREATED SIZE hello-world latest (自動作成のID) (作成した時) (データサイズ)docker run
コンテナを作るコマンド。
ターミナル例)hello-worldというimageをダウンロードした後 % docker run hello-world => hello-worldのコンテナが作成され、実行される。 % docker run -it ubuntu bash => ubuntu(OSの名前、dockerhubに存在するdocker image)のコンテナが作成され、bashというプログラムを実行させる。 (bashはshellの名前。ubuntuのデフォルトのコマンドをbashに上書きして実行している。ちなみにubuntuのデフォルトのコマンドはbashなので、今回はdocker -it run ubuntuでも同じ。)docker run --name
名前をつけてコンテナを作るコマンド。
ターミナル% docker run --name sample ubuntu => sampleという名前のコンテナがubuntuというdocker imageから作成される。docker run --rm
コンテナを起動した後、すぐにコンテナを削除コマンド。
ターミナル% docker run --rm hello-world => hello-worldというdocker imageからコンテナを作成し、実行した後、すぐにコンテナが削除される。 (一度しか使わないコンテナは残さないために、すぐに削除する。)docker ps -a
全てのコンテナを表示するコマンド。
ターミナル% docker ps -a => 全てのコンテナが表示される。 % docker ps => 実行中のコンテナのみされる。docker restart
一度実行したコンテナをリスタートするコマンド。
ターミナル% docker restart (コンテナID)or(コンテナ名) => コンテナIDで指定したコンテナがリスタートされる。(STATUSがUPとなる)docker exec -it (コンテナID)or(コンテナ名) bash
リスタートしたコンテナにプログラムを実行させるコマンド。(bashの部分は適宜、実行したいプログラムに置き換える)
ターミナル% docker exec -it (コンテナID)or(コンテナ名) bash => リスタートしたコンテナの中に入ることができる。(bashにより)docker commit (コンテナID)or(コンテナ名) (新しいimage名)
更新したコンテナを新しいDocker imageとして保存するコマンド。
ターミナル% docker commit (コンテナID)or(コンテナ名) (新しいimage名) => docker imageが保存され、IDが表示される。docker tag (source) (target)
docker imageのimage名を変更するコマンド。
docker imageをdockerhubにpushする前に、ホストのimageのリポジトリ名とpush先の自身のdockerhubのリポジトリ名を同じにするために使う。(dockerhubのリポジトリはdockerhubで作成しておく必要がある)ターミナル% docker tag (ホストのdocker imageのリポジトリ名:タグ名) (dockerのユーザー名/リポジトリ名) => docker imageのリポジトリ名がdockerhubのリポジトリ名と同じになる。(タグ名は指定しなければ、latestとなる。)docker push
docker imageを自分のリポジトリに作成するコマンド。
ターミナル% docker push (image名) => dockerhubにdocker imageがpushされる。(image名はdockerのユーザー名/リポジトリ名と同じにしておく)docker rmi
docker imageを削除するコマンド。(image名はdockerのユーザー名/リポジトリ名と同じにしておく)
ターミナル% docker rmi (image名)or(image id) => 指定したdocker imageが削除されるdocker stop
実行中のコンテナをストップするコマンド。(STATUSをUP→EXITEDにする)
ターミナル% docker stop (コンテナ名)or(コンテナID) => 指定したコンテナがストップされる。docker rm
コンテナを削除するコマンド。
ターミナル% docker rm (コンテナ名)or(コンテナID) => 指定したコンテナが削除されるdocker system prune
ストップしているコンテナ全てを一括で削除するコマンド。
ターミナル% docker system prune => ストップしているコンテナが全て削除される参考
Udemy
かめれおん講師 「米国AI開発者がゼロから教えるDocker講座」
有料ですが、初学者の私にも非常に理解しやすかったです。
最後に
本投稿が初学者の復習の一助となればと幸いです。