- 投稿日:2021-01-01T23:07:23+09:00
timer_createでsigeventのsigev_notifyにSIGEV_THREADを設定したときの動作(C言語)
背景
私が現在開発している組込みシステムでは、周期処理に様々な方法が用いられている。中でもtimer_create関数でsigevent構造体のsigev_notifyにSIGEV_THREADを設定し、一定時間が経過したら指定した関数を一つのスレッド(タイマスレッド)として起動する方法はよく使われている手法の一つである。開発中のシステムでは、この方法で周期タイマを実現している箇所が複数存在し、システムを起動させると常にタイマスレッドの生成・終了が行われている。この時、生成されたタイマスレッドがそれぞれどこで生成されたものか気になったので、タイマスレッドのスレッド名を調べてみた。(タイマスレッドの名称とtimer_createを呼び出したスレッド名が一致すると思っていたため。)すると、生成された全てのタイマスレッドが同じスレッド名になっていた。そこで、timer_createでSIGEV_THREADを設定したときの周期タイマの動作について調査してみた。
timer_createの概要
int timer_create(clockid_t clockid, struct sigevent *restrict evp, timer_t *restrict timerid)引数:
第一引数:クロックID
第二引数:sigevent情報 →詳細
第三引数:タイマID格納用ポインタプロセス毎にタイマを作成する。タイマ満了時sigeventで設定した動作が行われる。
(周期時間の設定やタイマの開始はtimer_settime関数で行う。)SIGEV_THREADを設定したときの動作(※自分の環境の場合)
一番最初にSIGEV_THREADが設定されたタイマが作成されたとき、タイマ満了時に起動用のタイマスレッドが生成される。(親スレッドのスレッド名が引き継がれる。)
タイマ満了時、最初に生成されたタイマスレッドで指定した関数を起動する。
→SIGEV_THREADが設定されたタイマが複数作成された場合でも、最初に作成されたタイマスレッドで関数を起動する。そのため、タイマスレッドを生成したスレッド以外は、タイマの作成を行ったスレッドとタイマスレッド名が異なることになる。
但し、既にタイマスレッドが動作しているときに他のタイマが満了した場合、新規にタイマスレッドを生成する。(この時のスレッド名はタイマ満了時に起動するスレッド名と同じ。関数が終わるとタイマスレッドはすぐに終了する。)参考文献
この記事は以下の情報を参考にして執筆しました。
timer_create() manual
http://www.yosbits.com/opensonar/rest/man/freebsd/man/ja/man2/timer_create.2.htmlSIGEVENT manual
https://linuxjm.osdn.jp/html/LDP_man-pages/man7/sigevent.7.html
- 投稿日:2021-01-01T19:55:31+09:00
NFSサーバーの構築ついて纏めてみる
NFSを実現するサービス
サービス名 サーバー クライアント 説明 portmap ○ ○ RPCプログラム番号をTCP/IPポート番号に変換 nfsd ○ ファイルシステムのエクスポートとクライアント要求の処理 mountd ○ リモートファイルシステムのマウントおよびアンマウント portmap
/etc/rpcportmapper 100000 portmap sunrpc rpcbind rstatd 100001 rstat rup perfmeter rstat_svc rusersd 100002 rusers nfs 100003 nfsprog ypserv 100004 ypprog mountd 100005 mount showmount
- TCP/UDPポート番号は動的に割りあてられます。
- つまり、RPCクライアントが利用するには、まずポート番号を知ることが必要です。
- portmapはRPCクライアントから問い合わせがあると、対応するサービスのポート番号を返します。
RPCを利用してサービスを提供するプログラムは、起動時に自分の情報をportmapに登録します。
RPCサービスの接続状況は、rpcinfo で確認できます。
rpcinfo -p program vers proto port service 100000 4 tcp 111 portmapper 100000 3 tcp 111 portmapper 100000 2 tcp 111 portmapper 100000 4 udp 111 portmapper 100000 3 udp 111 portmapper 100000 2 udp 111 portmapperNFSサーバーの設定
サービスを開始するには次の通りです。
systemctl start rpcbind systemctl start nfs-server systemctl start nfs-lockNFSサーバー側で特定のディレクトリを公開することを、エクスポートと言います。
エクスポートするディレクトリは、/etc/exports に記述します。/etc/exports/share 192.168.1.0/255.2255.255.0(rw) /pub *.example.com(ro)
/etc/exportsのオプション 説明 ro 読み取り専用 rw 読み書き no_root_squash rootでのアクセス時にroot権限で実行 root_squash rootでのアクセス時に匿名アカウント権限で実行 all_squash 全てのアクセスを匿名アカウント権限で実行 エクスポート状況を表示したり、/etc/exports の変更を反映させるには、exports を使います。
exportsのオプション 説明 -a 全てのディレクトリをエクスポート/アンエクスポート -r 全てのディレクトリを再エクスポート -u アンエクスポート -v 詳細表示 エクスポートしているディレクトリを調べるには、showmount を使う。
showmountのオプション 説明 -a クライアントのホスト名とマウントしているディレクトリを表示 -e 指定したホストでエクスポートしているディレクトリを表示 NFSの統計情報を調べるには、nfsstat を使う。
nfsstatのオプション 説明 -s NFSサーバー側の統計のみ表示 -c NFSクライアント側の統計のみ表示 -n NFSの統計のみ表示 -r RFCの統計のみ表示 -o net ネットワーク層の統計を表示 NFSクライアントの設定
- NFSを使って、リモートファイルシステムをマウントするには、mount を使う。
- ファイルタイプシステムには、nfs を指定します。
- ローカルファイルシステムには、マウントポイントとなるディレクトリを用意しておきます。
mount -t nfs linux:/pib /mnt/nfs
NFS特有ののマウントオプション 説明 bg マウントに失敗してもバックグラウンドで試行 fg フォアグラウンドで実行 soft ソフトマウント hard ハードマウント intr ハートマウント時の割り込みを許可 retrans ソフトマウントの場合の再試行回数 nolock ファイルのロックを行わない rsize= 読み取りのブロックサイズ wsize= 書き込みのブロックサイズ /etc/fstab に記述しておくと、システムの起動時に、リモートファイルシステムを自動的にマウントできます。
linux:/pib /mnt/nfs nfs defaults 0 0リンク
AWSには、EFSがあるので不要かと思われるが、↓の記事が上手く纏められていた。
EC2上にNFSサーバ/クライアント構築する
✳️NFSv4以降の手順なので、portmap、rpcbind、nfslockは不要
- 投稿日:2021-01-01T19:51:40+09:00
Squid について纏めてみる
squid.conf
squid.conf 説明 http_port ポート番号 visible_hostname ホスト名 hierarchy_stoplist キャッシュを利用しない文字列 maximum_object_size キャッシュ可能な最大サイズ minimun_object_size キャッシュ可能な最小サイズ maximum_object_size_in_memory メモリ上の最大ファイルサイズ ipcache_size キャッシュするIPアドレス数 cache_dir キャッシュを格納するディレクトリと容量などのパラメータ cache_mem メモリ上のキャッシュサイズ cache_access_log クライアントのアクセスログ cache_log キャッシュのログ ftp_user anonymousでFTPアクセスする際のパスワード ftp_passive FTPのパッシブモード reference_age キャッシュの保存期間 request_header_max_size HTTPリクエストヘッダの最大サイズ request_body_max_size HTTPリクエストボディの最大サイズ reply_body_max_size レスポンスの最大サイズ acl アクセスコントロールリストの設定 http_access アクセスコントロールリストの制御 アクセス制御
acl
ホストやプロトコルの集合にアクセスコントロールリストを行う。
書式 :
acl ACL名 ACLタイプ 文字列もしくはファイル名
ACLタイプ 説明 src クライアント側のIP dst 代理アクセス先サーバーのIP srcdomain クライアントのドメイン名 dstdomain 代理アクセス先サーバーのドメイン名 port 代理アクセスサーバーのポート番号 myport クライアントのポート番号 arp MACアドレス proto プロトコル method HTTPのメソッド time 有効な時間 http_access
アクセスコントロールリストに対しての制御を、http_access で行う。
書式 :
http_access allow|deny ACL名
アクセス制御の設定例
次の例では、192.168.0.0/24からのアクセスを禁止しています。
squid.confacl test src 192.168.0.0/255.255.255.0 http_access deny testやってみる系(Amazon Linux2)
AWSでは、まあ、NAT ゲートウェイを使えばいいでしょうが。。。
準備
クライアントからプロキシを経由して、yumなどを実行できるようにする。
サブネット
- piblic-subnet(プロキシサーバー)
- private-subnet(クライアント)
セキュリティグループ
- public-sg:22,3128
- private-sg:22(public-sgからの接続を許可する。)
プロキシサーバー設定
其の1
Squidの設定ファイルに直接対象のIPアドレスまたはサブネットのCIDRを記述する。
squid.confacl private-subnet src <プライベートサブネットのCIDR> http_access allow private-subnet其の2
/etc/squid/acl/whitelist.txt
にプロキシを経由したいサーバーのプライベートIPアドレスまたは、サブネットのCIDRを記述する。squid.confacl Whitelist dstdomain "/etc/squid/acl/Whitelist.txt" http_access allow Whitelist http_access deny allクライアント側設定
/etc/yum.confproxy=http://<proxyのプライベートIP>:3128/etc/wgetrc.http_proxy=http://<proxyのプライベートIP>:3128 https_proxy=http://<proxyのプライベートIP>:3128~/.curlrcproxy=http://<proxyのプライベートIP>:3128HTTPサーバーとプロキシサーバのリンク
- 投稿日:2021-01-01T15:41:10+09:00
パスワードなしで sudo で apt を実行できるようにする
- 投稿日:2021-01-01T11:58:19+09:00
shell script が bash で起動されたかどうか判定する方法
shell script が bash で起動されたかどうか判定する方法
sh ./check.sh
のようにsh
を使って起動されるのを検出してエラー終了させたい。スクリプト
check.sh
#!/bin/bash if [ x$BASH_SOURCE = x"" ] ; then echo please run by $0 or bash $0 instead. exit 1 fi echo OK: you are using bash.実行例
$ sh ./check.sh please run by ./check.sh or bash ./check.sh instead.$ ./check.sh OK: you are using bash.$ bash ./check.sh OK: you are using bash.
- 投稿日:2021-01-01T11:58:19+09:00
bash で起動されたかどうか判定する方法
bash で起動されたかどうか判定する方法
sh ./check.sh
のようにsh
を使って起動されるのを検出してエラー終了させたい。スクリプト
check.sh
#!/bin/bash if [ x$BASH_SOURCE = x"" ] ; then echo please run by $0 or bash $0 instead. exit 1 fi echo OK: you are using bash.実行例
$ sh ./check.sh please run by ./check.sh or bash ./check.sh instead.$ ./check.sh OK: you are using bash.$ bash ./check.sh OK: you are using bash.
- 投稿日:2021-01-01T06:00:23+09:00
CentOS8を毎日定時に再起動させたいんだよなあ
何か調子悪いからとりあえず再起動
最近CentOSで実行してる日次のrsync(ファイルサーバーのバックアップ)が時々失敗してる…(´・ω・`)
原因はまだよく分かってないけど、ひとまず毎日再起動していみることにしました。
再起動のシェルスクリプト
これ。
shutdown -r now
-r
が『再起動』のオプション。
-h
は『電源切る』のオプションだから注意。
(電源切っちゃったらマシンの前まで行って、電源ボタンぽちってしないといけないよ)定期実行をcronに登録
まずは下記コマンドでcron設定ファイルをviで編集。
crontab -e
下記内容を追記。
0 3 * * * /usr/sbin/shutdown -r now分 時 日 月 曜日 コマンド
上記の場合は毎日3:00に『/usr/sbin/shutdown』を実行しなさいよ!オプションは『-r now』よ!な意味。
shutdownの前に/usr/sbin/を付けてるのは何で?
cronで『コマンドが見つかりません』の例外回避の為です。
コマンドによっては 端末では実行できるのにcronだとできない ことがあります。
(cronで実行する時にパスが通っていないのが理由)なので、ただのコマンドではなく 絶対パスで指定したコマンド にする目的で
/usr/sbin/
を付けています 。shutdownの絶対パスを知りたい時は下記コマンド。
which shutdownホントか~?ホントにお前再起動したんか~?
下記コマンドで簡易的に確認できるん。
last reboot結果はこんな感じ。
金曜日、1月1日、4時51分に再起動、そこから現在まで動いてるよって意味。3:00とか夜中に再起動することになるから、後から確認できる方法知っておこう。
必要なサービスは起動と同時に立ち上がるようにしておこう
例えば下記はSamba(ファイルサーバーのサービス)を起動と同時に立ち上げるコマンド。
systemctl enable smb
systemdで再起動の定期実行はダメ!
最初はコレ↓で定期実行しようとした。
CentOSで日付・曜日・時間を指定して定期実行したいんだよなあ
systemctl enable 再起動のサービス
なんてことやっちゃったもんだから、定時再起動 ⇒ CentOS起動と同時に再起動のサービス開始 ⇒ 再起動 ⇒ CentOS起動と同時に再起動のサービス開始 ⇒ 再起動 ⇒ ………
無限ルーーーーープになっちゃったよ☆(・ω<)
「諸君、〇分後に再起動を開始する」
shutdownのオプションで
-k
にすれば、接続してる端末 に 再起動するぞいって通知 できる。
これ使用頻度低いけど便利。ふーん、そういうこともできるのね、って感じで覚えておこうと思った。
蛇足
起動と同時にLineに通知するなり、メール飛ばすなりする仕組み作りたいなと思った!
再起動するとMac mini上のネットワークドライブがアンマウントされちゃう…(´・ω・`)
(tico = CentOS上にSambaで構築したファイルサーバー)
Mac側に定期実行のスクリプト設定するなり、アンマウントされないように設定するなり必要ありそう…。
うーん、これは残課題です。参考サイトさん
https://eng-entrance.com/linux-command-shutdown
https://rainbow-engine.com/linux-scheduled-reboot-script/
https://teratail.com/questions/75302
https://gist.github.com/koudaiii/49ac3f8b7c207f0da31f
https://netacore.jp/restart-automatically-centos-server/バージョン
CentOS Linux release 8.3.2011
- 投稿日:2021-01-01T03:09:38+09:00
WSL2でKali Linux Guiを使う
wsl2
MS Storeでkaliをgetして,
PoweShellで現バージョンを確認PoweShell> wsl -l -vバージョンを1から2へ変更する
PoweShell> wsl --set-default-version2もしくは個別に
PoweShell> wsl --set-version kali-linux 2カーネルコンポーネントの更新が必要なら単に指示に従えばよい.
Kali LInuxを起動
Xサーバであるkexをinstallする
Kali Linux> sudo apt update Kali Linux> sudo apt upgrade Kali Linux> sudo apt install kali-win-kex Kali Linux> sudo apt install dbus-x11guiを起動する
Kali Linux> kex -mF8で抜ける
重要オプション
-m 全画面表示しない
--win windowsモード
--sl シームレスツールのインストール(15分くらい)
K L> sudo apt install -y kali-linux-defaultあるいは強く,
K L> sudo apt install -y kali-linux-largewindowsの機能の有効化
WSL
windowsハイパーバイザープラットホーム
仮想マシンプラットホーム
- 投稿日:2021-01-01T02:12:43+09:00
Gitでdebパッケージ開発:(その1)最小構成による野良パッケージ作成
自作ユーティリティをaptで管理したいという動機で、debパッケージの作り方を調べました。
真面目にやろうとすると色々情報を揃えてやらないといけないのですが、いきなり全部整備するのではなく、ステップバイステップで書いていこうと思います。なお、筆者の環境はUbuntu 18.04LTSです。debパッケージを作成する最小構成
最初のサンプルとして、次のシェルスクリプトをパッケージ化することを考えます。
#!/bin/sh echo " ^ ^" echo "=o.o=" echo " m m_|~" exit 0これを/usr/bin/mycatというファイル名で管理すれば、シェル上でmycatと入力すればいつでも可愛らしい猫を呼び出せるようになります。素晴らしい。
#念のため、mycatという名の実行ファイルが他に存在しないことを確認しておきましょう。
% which mycat mycat not foundさて、debパッケージを作るための最小構成条件は次の通りです。
- パッケージ管理ディレクトリ(任意の名前で構いません)の下にフェイクのルートディレクトリがあること
- さらにその下に
- インストールイメージがあること
- DEBIANディレクトリ(許可属性755または775)があること
- さらにその下にcontrolファイルがあること
ここでは次のようなディレクトリ構成にしましょう。
mycat └── Debian ├── DEBIAN │ └── control └── usr └── bin └── mycat最初の"mycat"がパッケージ管理ディレクトリ、その下にある"Debian"がフェイクのルートディレクトリです。さらにその下にあるusr/bin/mycatが、aptインストール後には/usr/bin/mycatとなるイメージです。mycatの許可属性は755としておいて下さい。
% mkdir -p mycat/Debian % cd Debian % mkdir -m 755 DEBIAN % mkdir -p usr/bin % cd usr/bin (〜mycatを上の中身に編集〜) % chmod 755 mycat % cd ../../DEBIAN (controlを以下の要領で作成)controlの中身は、少なくとも次の5項目を含んでいなければなりません。
- Package - パッケージ名
- Version - パッケージバージョン番号
- Description - パッケージの説明
- Maintainer - メンテナの名前と連絡先
- Architecture - 実行可能アーキテクチャ
各項目は':'(コロン)で区切られた後に書かれます。例えば次のような具合です。
Package: mycat Version: 1.0 Description: Call your lovely cat! Maintainer: (あなたの名前) <(あなたのe-mailアドレス)> Architecture: all#バージョン番号の付け方や実行アーキテクチャについてはここでは説明しませんが、お調べになることを強くお勧めします。
この上でパッケージ管理ディレクトリmycatまで戻り、dpkg-debコマンドでdebファイルを作成します。% cd ../.. % fakeroot dpkg-deb --build Debian .fakerootコマンドはfakerootパッケージに、dpkg-debコマンドはdpkg-devパッケージにそれぞれ入っています。コマンドが無いという人はそれぞれ上記をインストールしましょう。
% apt install fakeroot dpkg-dev
dpkg-debが成功したら、debパッケージファイルmycat_1.0_all.debが出来ているはずです。dpkgコマンドを使ってインストールしてみましょう。
% sudo dpkg -i mycat_1.0_all.deb途中、パスワード入力を求められます。成功したら、早速mycatコマンドを試してみましょう。
% which mycat /usr/bin/mycat % mycat ^ ^ =o.o= m m_|~やったー可愛い猫ちゃんが表示されました!アンインストールも試してみましょう。
% sudo dpkg -r mycat % which mycat mycat not foundパッケージを誰にも公開するつもりが無く、単にインストール&アンインストールを簡単にすることだけが目的ならば、ここで示したように野良パッケージを作れば十分だと思います。ただし、誰にも公開しないとしてもパッケージをきちんと管理したいならば、やはり情報を整備すべきです。次回以降、少しずつ説明して参ります。