名 前
name_to_handle_at, open_by_handle_at − パ ス 名 に 対 す る ハ ン ド ル の 取 得 と ハ ン ド ル に よ る フ ァ イ ル の オ ー プ ン
書 式
#define
_GNU_SOURCE /* feature_test_macros(7) 参 照
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int
name_to_handle_at(int dirfd, const char
*pathname,
struct file_handle *handle,
int *mount_id, int
flags);
int
open_by_handle_at(int mount_fd, struct
file_handle *handle,
int flags);
説 明
シ ス テ ム コ ー ル name_to_handle_at() と open_by_handle_at() は openat(2) の 機 能 を 2 つ に 分 割 し た も の で あ る 。 name_to_handle_at() は 指 定 さ れ た フ ァ イ ル に 対 応 す る ハ ン ド ル を 返 す 。 open_by_handle_at() は name_to_handle_at() が 返 し た ハ ン ド ル に 対 応 す る フ ァ イ ル を オ ー プ ン し 、 オ ー プ ン さ れ た フ ァ イ ル デ ィ ス ク リ プ タ ー を 返 す 。
name_to_handle_at()
name_to_handle_at() シ ス テ ム
コ ー ル は 、 引
き 数 dirfd と pathname
で 指 定 さ れ る
フ ァ イ ル に 対
応 す る フ ァ イ
ル ハ ン ド ル と
マ ウ ン ト ID を 返
す 。 フ ァ イ ル
ハ ン ド ル は 引
き 数 handle で 返 さ
れ る 。 handle は 以
下 の 形 式 の 構
造 体 へ の ポ イ
ン タ ー で あ る
。
struct
file_handle {
unsigned int handle_bytes; /* Size of f_handle [in, out] */
int handle_type; /* Handle type [out] */
unsigned char f_handle[0]; /* File identifier (sized by
caller) [out] */ };
f_handle で 返 さ れ る ハ ン ド ル を 保 持 す る の に 十 分 な 大 き さ の 構 造 体 を 確 保 す る の は 、 呼 び 出 し 元 が 責 任 を も っ て 行 う 必 要 が あ る 。 呼 び 出 し 前 に 、 handle_bytes フ ィ ー ル ド は f_handle 用 に 格 納 さ れ た サ イ ズ で 初 期 化 す べ き で あ る (<fcntl.h> で 定 義 さ れ て い る 定 数 MAX_HANDLE_SZ で フ ァ イ ル ハ ン ド ル の 最 大 サ イ ズ が 規 定 さ れ て い る )。 呼 び 出 し が 成 功 で リ タ ー ン す る 際 、 handle_bytes フ ィ ー ル ド は f_handle に 実 際 に 書 き 込 ま れ た バ イ ト 数 に 更 新 さ れ る 。 呼 び 出 し 元 で は 、 handle−>handle_bytes を 0 に 設 定 し て 呼 び 出 し を 行 う こ と で 、 file_handle 構 造 体 に 必 要 な サ イ ズ を 知 る こ と が で き る 。 こ の 場 合 、 こ の 呼 び 出 し は エ ラ ー EOVERFLOW で 失 敗 し 、 handle−>handle_bytes に 必 要 な サ イ ズ が 設 定 さ れ る 。 呼 び 出 し 元 は こ の 情 報 を 使 っ て 、 正 し い サ イ ズ の 構 造 体 を 割 り 当 て る こ と が で き る (下 記 の 「 例 」 を 参 照 )。
handle_bytes フ ィ ー ル ド を 使 用 す る 以 外 は 、 呼 び 出 し 元 は file_handle 構 造 体 の 内 容 を 意 識 せ ず に 扱 う べ き で あ る 。 フ ィ ー ル ド handle_type と f_handle は 後 で open_by_handle_at() を 呼 び 出 す 場 合 に だ け 必 要 で あ る 。
flags 引 き 数 は 、 下 記 の AT_EMPTY_PATH と AT_SYMLINK_FOLLOW の う ち 0 個 以 上 の 論 理 和 を 取 っ て 構 成 さ れ る ビ ッ ト マ ス ク で あ る 。 引 き 数 pathname と dirfd は そ の 組 み 合 わ せ で ハ ン ド ル を 取 得 す る フ ァ イ ル を 指 定 す る 。 以 下 の 4 つ の パ タ ー ン が あ る 。
* |
pathname が 空 で な い 文 字 列 で 絶 対 パ ス 名 を 含 む 場 合 、 こ の パ ス 名 が 参 照 す る フ ァ イ ル に 対 す る ハ ン ド ル が 返 さ れ る 。 | ||
* |
pathname が 相 対 パ ス が 入 っ た 空 で な い 文 字 列 で 、 dirfd が 特 別 な 値 AT_FDCWD の 場 合 、 pathname は 呼 び 出 し 元 の カ レ ン ト ワ ー キ ン グ デ ィ レ ク ト リ に 対 す る 相 対 パ ス と 解 釈 さ れ 、 そ の フ ァ イ ル に 対 す る ハ ン ド ル が 返 さ れ る 。 | ||
* |
pathname が 相 対 パ ス が 入 っ た 空 で な い 文 字 列 で 、 dirfd が デ ィ レ ク ト リ を 参 照 す る フ ァ イ ル デ ィ ス ク リ プ タ ー の 場 合 、 pathname は dirfd が 参 照 す る デ ィ レ ク ト リ に 対 す る 相 対 パ ス と 解 釈 さ れ 、 そ の フ ァ イ ル を 参 照 す る ハ ン ド ル が 返 さ れ る 。 (な ぜ 「 デ ィ レ ク ト リ フ ァ イ ル デ ィ ス ク リ プ タ ー 」 が 役 に 立 つ の か に つ い て は openat(2) を 参 照 。 ) | ||
* |
pathname が 空 の 文 字 列 で flags に AT_EMPTY_PATH が 指 定 さ れ て い る 場 合 、 dirfd に は 任 意 の 種 別 の フ ァ イ ル を 参 照 す る オ ー プ ン さ れ た フ ァ イ ル デ ィ ス ク リ プ タ ー か AT_FDCWD (カ レ ン ト ワ ー キ ン グ デ ィ レ ク ト リ を 意 味 す る ) を 指 定 で き 、 dirfd が 参 照 す る フ ァ イ ル に 対 す る ハ ン ド ル が 返 さ れ る 。 |
mount_id 引 き 数 は 、 pathname に 対 応 す る フ ァ イ ル シ ス テ ム の マ ウ ン ト の 識 別 子 を 返 す 。 こ の 識 別 子 は /proc/self/mountinfo の い ず れ か の レ コ ー ド の 最 初 の フ ィ ー ル ド に 対 応 す る 。 対 応 す る レ コ ー ド の 5 番 目 の フ ィ ー ル ド の パ ス 名 を オ ー プ ン す る と 、 こ の マ ウ ン ト ポ イ ン ト の フ ァ イ ル デ ィ ス ク リ プ タ ー が 得 ら れ る 。 こ の フ ァ イ ル デ ィ ス ク リ プ タ ー は こ の 後 の open_by_handle_at() の 呼 び 出 し で 使 用 で き る 。 デ フ ォ ル ト で は 、 name_to_handle_at() は pathname が シ ン ボ リ ッ ク リ ン ク の 場 合 に そ の 展 開 (dereference) を 行 わ ず 、 リ ン ク 自 身 に 対 す る ハ ン ド ル を 返 す 。 AT_SYMLINK_FOLLOW が flags に 指 定 さ れ る と 、 pathname が シ ン ボ リ ッ ク リ ン ク の 場 合 に リ ン ク の 展 開 が 行 わ れ る (リ ン ク が 参 照 す る フ ァ イ ル に 対 す る ハ ン ド ル が 返 さ れ る )。
open_by_handle_at()
open_by_handle_at() シ ス テ ム
コ ー ル は handle が
参 照 す る フ ァ
イ ル を オ ー プ
ン す る 。 handle は
前 に 呼 び 出 し
た name_to_handle_at() が 返
し た フ ァ イ ル
ハ ン ド ル で あ
る 。
mount_fd 引 き 数 は 、 handle が そ の フ ァ イ ル シ ス テ ム に 関 連 す る と 解 釈 さ れ る マ ウ ン ト さ れ た フ ァ イ ル シ ス テ ム 内 の 任 意 の オ ブ ジ ェ ク ト (フ ァ イ ル 、 デ ィ レ ク ト リ な ど ) の フ ァ イ ル デ ィ ス ク リ プ タ ー で あ る 。 特 別 な 値 AT_FDCWD も 指 定 で き る 。 こ の 値 は 呼 び 出 し 元 の カ レ ン ト ワ ー キ ン グ デ ィ レ ク ト リ を 意 味 す る 。 引 き 数 flags は open(2) と 同 じ で あ る 。 handle が シ ン ボ リ ッ ク リ ン ク を 参 照 し て い る 場 合 、 呼 び 出 し 元 は O_PATH フ ラ グ を 指 定 し な け れ ば な ら ず 、 そ の シ ン ボ リ ッ ク リ ン ク は 展 開 さ れ な い 。 O_NOFOLLOW が 指 定 さ れ た 場 合 は 、 O_NOFOLLOW は 無 視 さ れ る 。
open_by_handle_at() を 呼 び 出 す に は 、 呼 び 出 し 元 が CAP_DAC_READ_SEARCH ケ ー パ ビ リ テ ィ ー を 持 っ て い な け れ ば な ら な い 。
返 り 値
成 功 す る と 、 name_to_handle_at() は 0 を 返 し 、 open_by_handle_at() は 負 で な い フ ァ イ ル デ ィ ス ク リ プ タ ー を 返 す 。 エ ラ ー の 場 合 、 ど ち ら の シ ス テ ム コ ー ル も −1 を 返 し 、 errno に エ ラ ー の 原 因 を 示 す 値 を 設 定 す る 。
エ ラ ー
name_to_handle_at() と open_by_handle_at() は openat(2) と 同 じ エ ラ ー で 失 敗 す る 。 ま た 、 こ れ ら の シ ス テ ム コ ー ル は 以 下 の エ ラ ー で 失 敗 す る こ と も あ る 。
name_to_handle_at() は 以 下 の エ ラ ー で 失 敗 す る こ と が あ る 。
EFAULT |
pathname, mount_id, handle の ど れ か が ア ク セ ス 可 能 な ア ド レ ス 空 間 の 外 を 指 し て い る 。 | ||
EINVAL |
flags に 無 効 な ビ ッ ト 値 が 含 ま れ て い る 。 | ||
EINVAL |
handle−>handle_bytes が MAX_HANDLE_SZ よ り も 大 き い 。 | ||
ENOENT |
pathname が 空 文 字 列 だ が 、 flags に AT_EMPTY_PATH が さ れ て い な か っ た 。 |
ENOTDIR
dirfd で 指 定 さ れ た フ ァ イ ル デ ィ ス ク リ プ タ ー が デ ィ レ ク ト リ を 参 照 し て お ら ず 、 両 方 の flags に AT_EMPTY_PATH が 指 定 さ れ 、 か つ pathname が 空 文 字 列 で あ る 場 合 で も な い 。
EOPNOTSUPP フ
ァ イ ル シ ス テ
ム が パ ス 名 を
フ ァ イ ル ハ ン
ド ル へ の 変 換
を サ ポ ー ト し
て い な い 。
EOVERFLOW 呼 び 出 し に
渡 さ れ た
handle−>handle_bytes の 値
が 小 さ す ぎ た
。 こ の エ ラ ー
が 発 生 し た 際
、 handle−>handle_bytes は
ハ ン ド ル に 必
要 な サ イ ズ に
更 新 さ れ る 。
open_by_handle_at() は 以 下 の エ ラ ー で 失 敗 す る こ と が あ る 。
EBADF |
mount_fd が オ ー プ ン さ れ た フ ァ イ ル デ ィ ス ク リ プ タ ー で な い 。 | ||||||
EFAULT |
handle が ア ク セ ス 可 能 な ア ド レ ス 空 間 の 外 を 指 し て い る 。 | ||||||
EINVAL |
handle−>handle_bytes が MAX_HANDLE_SZ よ り 大 き い か 0 に 等 し い 。 | ||||||
ELOOP |
handle が シ ン ボ リ ッ ク リ ン ク を 参 照 し て い る が 、 flags に O_PATH が さ れ て い な か っ た 。
呼 び 出
し 元 が CAP_DAC_READ_SEARCH
ケ ー パ ビ リ テ
ィ を 持 っ て い
な い 。 が 削 除 さ れ た 場 合 な ど に 発 生 す る 。 バ ー ジ ョ ンこ れ ら の シ ス テ ム コ ー ル は Linux 2.6.39 で 初 め て 登 場 し た 。 ラ イ ブ ラ リ に よ る サ ポ ー ト は バ ー ジ ョ ン 2.14 以 降 の glibc で 提 供 さ れ て い る 。 準 拠こ れ ら の シ ス テ ム コ ー ル は 非 標 準 の Linux の 拡 張 で あ る 。 FreeBSD に は getfh() と openfh() と い う ほ と ん ど 同 じ 機 能 の シ ス テ ム コ ー ル の ペ ア が 存 在 す る 。 注 意あ る プ ロ セ ス で name_to_handle_at() を 使 っ て フ ァ イ ル ハ ン ド ル を 生 成 し て 、 そ の ハ ン ド ル を 別 の プ ロ セ ス の open_by_handle_at() で 使 用 す る こ と が で き る 。 い く つ か の フ ァ イ ル シ ス テ ム で は 、 パ ス 名 か ら フ ァ イ ル ハ ン ド ル へ の 変 換 が サ ポ ー ト さ れ て い な い 。 例 え ば 、 /proc, /sys や 種 々 の ネ ッ ト ワ ー ク フ ァ イ ル シ ス テ ム な ど で あ る 。 フ ァ イ ル ハ ン ド ル は 、 フ ァ イ ル が 削 除 さ れ た り 、 そ の 他 の フ ァ イ ル シ ス テ ム 固 有 の 理 由 で 、 無 効 ("stale") に な る 場 合 が あ る 。 無 効 な ハ ン ド ル で あ る こ と は 、 open_by_handle_at() か ら エ ラ ー ESTALE が 返 る こ と で 通 知 さ れ る 。 こ れ ら の シ ス テ ム コ ー ル は 、 ユ ー ザ ー 空 間 の フ ァ イ ル サ ー バ ー で の 使 用 を 意 図 し て 設 計 さ れ て い る 。 例 え ば 、 ユ ー ザ ー 空 間 NFS サ ー バ ー が フ ァ イ ル ハ ン ド ル を 生 成 し て 、 そ の ハ ン ド ル を NFS ク ラ イ ア ン ト に 渡 す こ と が で き る 。 そ の 後 、 ク ラ イ ア ン ト が フ ァ イ ル を オ ー プ ン し よ う と し た 際 に 、 こ の ハ ン ド ル を サ ー バ ー に 送 り 返 す こ と が で き る 。 こ の よ う な 機 能 に よ り 、 ユ ー ザ ー 空 間 フ ァ イ ル サ ー バ ー は 、 そ の サ ー バ ー が 提 供 す る フ ァ イ ル に 関 し て ス テ ー ト レ ス で (状 態 を 保 持 せ ず に ) 動 作 す る こ と が で き る 。 pathname
が シ ン ボ リ ッ
ク リ ン ク を 参
照 し て い て 、
flags に AT_SYMLINK_FOLLOW が
指 定 さ れ て い
な い 場 合 、
name_to_handle_at() は (シ ン
ボ リ ッ ク が 参
照 す る フ ァ イ
ル で は な く ) リ
ン ク に 対 す る
ハ ン ド ル を 返
す 。 ハ ン ド ル
を 受 け 取 っ た
プ ロ セ ス は 、
open_by_handle_at() の O_PATH フ
ラ グ を 使 っ て
ハ ン ド ル を フ
ァ イ ル デ ィ ス
ク リ プ タ ー に
変 換 し 、 そ の
フ ァ イ ル デ ィ
ス ク リ プ タ ー
を readlinkat(2) や fchownat(2)
な ど の シ ス テ
ム コ ー ル の dirfd
引 き 数 と し て
渡 す こ と で 、
そ の シ ン ボ リ
ッ ク リ ン ク に
対 し て 操 作 を
行 う こ と が で
き る 。 永 続 的
な フ ァ イ ル シ
ス テ ム ID の 取 得
例以 下 の 2 つ の プ ロ グ ラ ム は name_to_handle_at() と open_by_handle_at() の 使 用 例 を 示 し た も の で あ る 。 最 初 の プ ロ グ ラ ム (t_name_to_handle_at.c) は name_to_handle_at() を 使 用 し て 、 コ マ ン ド ラ イ ン 引 き 数 で 指 定 さ れ た フ ァ イ ル に 対 応 す る フ ァ イ ル ハ ン ド ル と マ ウ ン ト ID を 取 得 す る 。 ハ ン ド ル と マ ウ ン ト ID は 標 準 出 力 に 出 力 さ れ る 。 2 つ 目 の プ ロ グ ラ ム (t_open_by_handle_at.c) は 、 標 準 入 力 か ら マ ウ ン ト ID と フ ァ イ ル ハ ン ド ル を 読 み 込 む 。 そ れ か ら 、 open_by_handle_at() を 利 用 し て 、 そ の ハ ン ド ル を 使 っ て フ ァ イ ル を オ ー プ ン す る 。 追 加 の コ マ ン ド ラ イ ン 引 き 数 が 指 定 さ れ た 場 合 は 、 open_by_handle_at() の mount_fd 引 き 数 は 、 こ の 引 き 数 で 渡 さ れ た 名 前 の デ ィ レ ク ト リ を オ ー プ ン し て 取 得 す る 。 そ れ 以 外 の 場 合 、 /proc/self/mountinfo か ら ス キ ャ ン し て 標 準 入 力 か ら 読 み 込 ん だ マ ウ ン ト ID に 一 致 す る マ ウ ン ト ID を 検 索 し 、 そ の レ コ ー ド で 指 定 さ れ て い る マ ウ ン ト デ ィ レ ク ト リ を オ ー プ ン し て 、 mount_fd を 入 手 す る 。 (こ れ ら の プ ロ グ ラ ム で は マ ウ ン ト ID が 永 続 的 で は な い 点 に つ い て の 対 処 は 行 わ な い 。 ) 以 下 の シ ェ ル セ ッ シ ョ ン は 、 こ れ ら 2 つ の プ ロ グ ラ ム の 使 用 例 で あ る 。 $ echo
’Can you please think about it?’ >
cecilia.txt $ stat
−−printf="%i\n" cecilia.txt #
Display inode number #define _GNU_SOURCE #define
errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \ } int if (argc != 2)
{ pathname = argv[1]; /* file_handle 構 造 体 を 確 保 す る */ fhsize =
sizeof(*fhp); /*
name_to_handle_at() を 最 初 に
呼 び 出 し て フ
ァ イ ル ハ ン ド
ル に 必 要 な サ
イ ズ を 入 手 す
る dirfd =
AT_FDCWD; /* For name_to_handle_at() calls */ /* file_handle 構 造 体 を 正 し い サ イ ズ に 確 保 し 直 す */ fhsize =
sizeof(struct file_handle) + fhp−>handle_bytes;
/* コ マ ン ド ラ イ ン で 指 定 さ れ た パ ス 名 か ら フ ァ イ ル ハ ン ド ル を 取 得 */ if
(name_to_handle_at(dirfd, pathname, fhp, &mount_id,
flags) == −1) /*
t_open_by_handle_at.c で 後 で 再
利 用 で き る よ
う に 、 マ ウ ン
ト ID、 フ ァ イ ル
ハ ン ド ル の サ
イ ズ 、 フ ァ イ
ル ハ ン ド ル を
標 準 出 力 に 書
き 出 す printf("%d\n",
mount_id); exit(EXIT_SUCCESS);
} プ ロ グ ラ ム の
ソ ー ス : t_open_by_handle_at.c #define
errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \ } /*
/proc/self/mountinfo を ス キ ャ
ン し て 、 マ ウ
ン ト ID が 'mount_id' に 一
致 す る 行 を 探
す 。 static int fp =
fopen("/proc/self/mountinfo", "r"); found = 0; nread =
sscanf(linep, "%d %*d %*s %*s %s", if (mi_mount_id
== mount_id) fclose(fp); if (!found) {
return open(mount_path, O_RDONLY); } int if ((argc >
1 && strcmp(argv[1], "−−help")
== 0) || argc > 2) { /* マ ウ ン ト ID と フ ァ イ ル ハ ン ド ル 情 報 が 入 っ た 標 準 入 力 : Line 1:
<mount_id> if
((fgets(line1, sizeof(line1), stdin) == NULL) || mount_id = atoi(line1); handle_bytes = strtoul(line2, &nextp, 0); /* handle_bytes
が あ れ ば 、 fhp =
malloc(sizeof(struct file_handle) + handle_bytes); fhp−>handle_bytes = handle_bytes; fhp−>handle_type = strtoul(nextp, &nextp, 0); for (j = 0; j
< fhp−>handle_bytes; j++) /* マ
ウ ン ト ポ イ ン
ト の フ ァ イ ル
デ ィ ス ク リ プ
タ ー を 取 得 す
る 。 取 得 は 、
コ マ ン ド ラ イ
ン で 指 定 さ れ
た パ ス 名 を オ
ー プ ン す る か
、 if (argc >
1) if (mount_fd ==
−1) /* ハ ン ド ル と マ ウ ン ト ポ イ ン ト を 使 っ て フ ァ イ ル を オ ー プ ン す る */ fd =
open_by_handle_at(mount_fd, fhp, O_RDONLY); /* そ の フ ァ イ ル か ら バ イ ト を 読 み 出 す */ nread =
read(fd, buf, sizeof(buf)); printf("Read %zd bytes\n", nread); exit(EXIT_SUCCESS); } 関 連 項 目open(2),
libblkid(3), blkid(8), findfs(8),
mount(8) こ の 文 書 に つ い てこ の man ペ ー ジ は Linux man−pages プ ロ ジ ェ ク ト の リ リ ー ス 3.79 の 一 部 で あ る 。 プ ロ ジ ェ ク ト の 説 明 と バ グ 報 告 に 関 す る 情 報 は http://www.kernel.org/doc/man−pages/ に 書 か れ て い る 。 |