Closed vroad closed 1 year ago
報告ありがとうございます.
基本的にdockerを使わない場合の動作確認はしていません.私自身がdocker環境しか実際に使っていないため,それ以外の環境で動作確認する必要性がないためです.
これは私個人の話であり,mirakc自体をdocker以外で使用することを阻害するものではありません.ただ,問題が出た場合には自力で解決してもらう必要があります.
問題を解決したら,PRを送っていただければ(余程のことがない限り)基本マージします.これはドキュメントについても同じです.
議論することを拒否しているわけではありません.自身が困っていることは,多くの場合他の人も困ることが多いと考えています.
fuseのマウントオプションについては,少し確認に時間が必要です.fuserというcrateを使っているのですが,これは私が書いたものではないため,どういう動作だったのかすぐには思い出せないためです.fusermount
の動作についても,おそらくfuserの実装に依存するものと思われます.
-o allow_other
が動作しないのは,mirakc-timeshift-fsのオプション処理に問題があるからかもしれません.
現実装では,すべてfuser::MountOption::CUSTOM
として追加しているのですが,
cberner/fuserでは
parse_options_from_args()
を使っています.また,allow_other
に対応するMountOption::AllowOther
というenumがあります.
parse_options_from_args()
は&[&OsStr]
を処理するようなので,この関数を使うならOpt::options
の型を変更したほうが良さそうな気がしますね.
rootユーザーは何故かfusermountがPATHに無くても動きます。
この辺の実装を見れば,理解できそうな気がします. https://github.com/cberner/fuser/tree/master/src/mnt
さっき MountOption::AllowOther
を追加して試してみたら実行ユーザー以外もアクセスできるようになったので、allow_otherが効かないのは
全てCUSTOMオプションとして渡しているせいかと思います。
https://github.com/vroad/mirakc/commit/aab6775ce7283ff3bd1f8b2b152a9cfd294c22d7
parse_options_from_args()
を使えば解決ですが,これ外から呼べないですね..pub(crate)
になっていますね..
mirakc-timeshift-fs
はfuser::mount2()
を呼び出していますが,fuser::mount()
を呼び出すようにしないといけないですね.この場合,fuser::MountOption::FSName
なども文字列化して渡す必要がありますね.
-o allow_other
が動けば,なんとかなりそうですか?
確かリンク時の問題を回避するために,libfuseを使わないようにしました. https://github.com/mirakc/mirakc/commit/7f9d58085a8e78c34e247109a1eaf9824f36c12c
なので,fusermount
(or fusermount3
)を常に利用するようになっていた気がします.
この場合 https://github.com/cberner/fuser/blob/master/src/mnt/fuse_pure.rs の実装に入りますが,detect_fusermount_bin()
でコマンドを探しています.
rootユーザーは何故かfusermountがPATHに無くても動きます
多分これが原因ではないかと思います.この関数は一般ユーザーでも同様に呼び出されるので,rootでコマンドが見つかっているなら一般ユーザーでも見つかっているはず.
mirakc/timeshift-fs
イメージではfuser3
をインストールしています.
-o allow_otherが動けば,なんとかなりそうですか?
これはなんとかなりそうです。 uidやgidを設定していないからか、 一般ユーザーでmirakc-timeshift-fsを起動してもファイルシステム内のファイルのユーザーとグループがrootになるのはちょっと変に見えますが、 ファイルへのアクセスがbindfsなしで出来るようにするのは達成できて、今の所は実用上問題なさそうです。
多分これが原因ではないかと思います.この関数は一般ユーザーでも同様に呼び出されるので,rootでコマンドが見つかっているなら一般ユーザーでも見つかっているはず.
これはどういう意味でしょうか?
一般ユーザーの場合しかfusemountコマンドの検索はしてないんじゃないかと思います。rootユーザーの場合、bash上で export PATH=
して手動実行しても動きます。
PATHからだけでなく、
/bin/fusemount
、 /bin/fusemount3
も探すようですが
NixOSはこの場所にはコマンドが置かれていないですね。
https://github.com/cberner/fuser/issues/126 に、Linux上でrootでfuseを使う場合はlibfuseは不要と書かれているので Linuxでrootの場合は実行のされ方が変わるのではないかと思います。
NixOSはこの場所にはコマンドが置かれていないですね
確かに,/bin/に置かれていることは稀みたいですね.普通は/usr/bin/ですか.
Linuxでrootの場合は実行のされ方が変わるのではないかと思います
直接開くパスもあるみたいですね. https://github.com/cberner/fuser/blob/6b76fd1f9cc8caef0ffa057f3e0879c940c9aab8/src/mnt/fuse_pure.rs#L316
uidやgidを設定していないからか
即値で0を指定していますね. https://github.com/mirakc/mirakc/blob/main/mirakc-timeshift-fs/src/filesystem.rs#L238
mirakc-timeshift-fs
を実行しているユーザーのuid/gidを設定したほうが良さそうですね.
今までの内容をまとめると..
fuser::mount()
を使うのが楽だが,deprecatedのようだ..parse_options_from_args()
はprivateなので,どうするか少し考える必要がある..mirakc-timeshift-fs
を実行したユーザーのuid/gid (or euid/egid? このあたりはfusermount
など既存実装を調べて決める)fusermount
(or fusermount3
)が必要追加があればお願いします
追加
- uid/gidを
mirakc-timeshift-fs
を実行したユーザーのuid/gid (or euid/egid? このあたりはfusermount
など既存実装を調べて決める)
goofysはファイルのユーザー・グループの初期値が実行ユーザーのuid、gidですね。こちらがデフォルトでも良いかと思います。 https://github.com/kahing/goofys/blob/5661a83f953a6a2352b13e782fbcf99e92089d3a/internal/perms.go#L25 s3fs-fuseは初期値はrootでした。
mirakc-timeshift-fsの実行ファイル自体にsetuidビットを設定しなければeuid/egidは同じではないでしょうか? fusermountにはsetuidビットは必要ですが、 mirakc-timeshift-fs自体は通常rootしかアクセスできないファイルを扱う必要があるわけではないので、setuidビットは使われず、EUID/EGIDは同じになるかと思います。
↓のsetuid設定してない場合の動作と同じになります https://mudongliang.github.io/2020/09/17/ruid-euid-suid-usage-in-linux.html
$ ./test
EUID: 1000, RUID: 1000, SUID: 1000
cat: file-read-only-by-root: Permission denied
EUID: 1000, RUID: 1000, SUID: 1000
cat: file-read-only-by-root: Permission denied
ドキュメントに書いたほうがよい
fusermount
(orfusermount3
)が必要
エラー内容(Error: IoError(Os { code: 2, kind: NotFound, message: "No such file or directory" }
)も書いたほうが良いと思います。fuser側の問題かと思いますが、このエラーメッセージでは何が見つからないか分かりにくいです。
mirakc-timeshift-fsの実行ファイル自体にsetuidビットを設定しなければeuid/egidは同じではないでしょうか?
確かにmirakc-timeshift-fsにsetuidビットを設定するわけではないですね.
fuser側の問題かと思いますが、このエラーメッセージでは何が見つからないか分かりにくいです。
了解です.これを表示しているのはmirakc-timeshift-fsなので,可能ならメッセージを書き換えることにします.
以下,対応済み
--uid
および--gid
の追加
chunk-sizeの既定値の変更も別途行う
@vroad 対応内容に不足がなければ,クローズしてください.関連する別問題があるなら,クローズ後に再オープンしても問題ありません.
chnun-size変更. 875ec95b0e95ff235d6e4a85f505d367f71fc33a
timeshift-fsの修正内容は問題ないと思います。
ドキュメントの言い回しは少し変えても良いかと思いますが、このissueのタイトルで示した問題は解決したので 別のissueにしようかと思います。 ありがとうございました。
ドキュメントのPRも受け付けているので,直接修正してPRを送ってくれるとありがたいです.
できるmirakcではDocker上でmirakc-timeshift-fsを動かしていますが Docker上でなくても正常に動くでしょうか? 私の環境ではNixOSのsystemdで動かしていますが、systemd unitのユーザーがrootだとroot以外ではアクセス不可能になります。マウントしたディレクトリの親ディレクトリでlsすらできません。 mirakc-timeshift-fsに
-o allow_other
をつけて実行しても同じでした。systemd unitを一般ユーザーで動かすとそのユーザーはファイルを見れますが、root含む他ユーザーはファイルを見れないようです。
/etc/fuse.conf
にuser_allow_other
を追加の上、mirakc-timeshift-fsに-o allow_other
をつけて実行しても同じです。systemd unit内では明示的にパスを通さないと動かないコマンドが多く、一般ユーザーで動かすのには手間がかかりました。結局、他ユーザーはファイルを参照できなかったですが。
一般ユーザーでの動作にはPATHに
fusermount
が必要でした。ないと、Error: IoError(Os { code: 2, kind: NotFound, message: "No such file or directory" }
のエラーが出ます。(何が見つからなかったのかはログに出ない) さらに、setuidを設定したバイナリでないと一般ユーザーでfusermount動かないらしく (Error: IoError(Custom { kind: Other, error: "fusermount: mount failed: Operation not permitted\n" })
のエラーが起きる)、NixOSではsetuidが設定されたfusermountのラッパーが/run/wrappers/bin
に存在するのでそちらにパスを通すようにしました。rootユーザーは何故か
fusermount
がPATHに無くても動きます。今のところはbindfsを
-u username -g groupname
オプション付きで起動して、ユーザー、グループを変更した同じディレクトリを別の場所に作って問題を回避していますが、 bindfs(またはDocker)を使わずに動かす方法はありますか?