20210101のLinuxに関する記事は9件です。

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.html

SIGEVENT manual
https://linuxjm.osdn.jp/html/LDP_man-pages/man7/sigevent.7.html

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

NFSサーバーの構築ついて纏めてみる

NFSを実現するサービス

サービス名 サーバー クライアント 説明
portmap RPCプログラム番号をTCP/IPポート番号に変換
nfsd ファイルシステムのエクスポートとクライアント要求の処理
mountd リモートファイルシステムのマウントおよびアンマウント

portmap

/etc/rpc
portmapper  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  portmapper

NFSサーバーの設定

サービスを開始するには次の通りです。

systemctl start rpcbind
systemctl start nfs-server
systemctl start nfs-lock

NFSサーバー側で特定のディレクトリを公開することを、エクスポートと言います。
エクスポートするディレクトリは、/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は不要

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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.conf
acl 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.conf
acl private-subnet src <プライベートサブネットのCIDR>
http_access allow private-subnet

其の2

/etc/squid/acl/whitelist.txtにプロキシを経由したいサーバーのプライベートIPアドレスまたは、サブネットのCIDRを記述する。

squid.conf
acl Whitelist dstdomain "/etc/squid/acl/Whitelist.txt"
http_access allow Whitelist
http_access deny all

クライアント側設定

/etc/yum.conf
proxy=http://<proxyのプライベートIP>:3128
/etc/wgetrc.
http_proxy=http://<proxyのプライベートIP>:3128
https_proxy=http://<proxyのプライベートIP>:3128
~/.curlrc
proxy=http://<proxyのプライベートIP>:3128

HTTPサーバーとプロキシサーバのリンク

Apache について纏めてみる
Nginx について纏めてみる

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

パスワードなしで sudo で apt を実行できるようにする

パスワードなしで sudo で apt を実行できるようにする

echo $USER ALL=NOPASSWD: /usr/bin/apt | sudo tee -a /etc/sudoers
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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.
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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.
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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

結果はこんな感じ。
image.png
金曜日、1月1日、4時51分に再起動、そこから現在まで動いてるよって意味。

3:00とか夜中に再起動することになるから、後から確認できる方法知っておこう。

必要なサービスは起動と同時に立ち上がるようにしておこう

例えば下記はSamba(ファイルサーバーのサービス)を起動と同時に立ち上げるコマンド。

systemctl enable smb

systemdで再起動の定期実行はダメ!

最初はコレ↓で定期実行しようとした。
CentOSで日付・曜日・時間を指定して定期実行したいんだよなあ

systemctl enable 再起動のサービス なんてことやっちゃったもんだから、

定時再起動 ⇒ CentOS起動と同時に再起動のサービス開始 ⇒ 再起動 ⇒ CentOS起動と同時に再起動のサービス開始 ⇒ 再起動 ⇒ ………

無限ルーーーーープになっちゃったよ☆(・ω<)

「諸君、〇分後に再起動を開始する」

shutdownのオプションで -k にすれば、接続してる端末再起動するぞいって通知 できる。
これ使用頻度低いけど便利。

ふーん、そういうこともできるのね、って感じで覚えておこうと思った。

蛇足

起動と同時にLineに通知するなり、メール飛ばすなりする仕組み作りたいなと思った!

再起動するとMac mini上のネットワークドライブがアンマウントされちゃう…(´・ω・`)
(tico = CentOS上にSambaで構築したファイルサーバー)
image.png
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

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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-x11

guiを起動する

Kali Linux> kex -m

F8で抜ける
重要オプション
-m  全画面表示しない
--win windowsモード
--sl シームレス

ツールのインストール(15分くらい)

K L> sudo apt install -y kali-linux-default

あるいは強く,

K L> sudo apt install -y kali-linux-large

windowsの機能の有効化

WSL
windowsハイパーバイザープラットホーム
仮想マシンプラットホーム

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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

パッケージを誰にも公開するつもりが無く、単にインストール&アンインストールを簡単にすることだけが目的ならば、ここで示したように野良パッケージを作れば十分だと思います。ただし、誰にも公開しないとしてもパッケージをきちんと管理したいならば、やはり情報を整備すべきです。次回以降、少しずつ説明して参ります。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む