This service is available only in Japanese-language.

wic(wks)で作成したFSイメージのルートディレクトリにSGIDを付与する方法

wic(wks)を使用してSDカードイメージ(wicファイル)を構築しています。
ファイルシステムを2つ持つような構成にしており、片方のルートにSGIDをつけたいのですが、
そのようなイメージを構築することはできますか?

下記にうまくいっていない例をしめします。

wks.inのファイルシステムの記述部分は下記のような設定をしています。

```
part / --source rootfs --ondisk mmcblk --fstype=ext4 --label root --align 8192 --fixed-size 1024 --exclude-path=share/
part /share --source rootfs --ondisk mmcblk --fstype=ext4 --label share --align 8192 --fixed-size 1024 --rootfs-dir=${IMAGE_ROOTFS}/share"
```

rootfsのイメージレシピで下記のようにSGIDを付与しようと試みました。

```
do_rootfs[postfuncs] = "add_sgid_to_share"
add_sgid_to_share() {
chmod 2775 ${IMAGE_ROOTFS}/share
}
```

上記では/shareにSGIDが付与されていませんでした。
原因を探ると、mkfs.ext4でext4のイメージファイルを作成するときにSGIDが消失してしまっているように見えます。
出来上がったwicファイルをkpartxコマンドでループバックマウントしてみるとSGIDが付与されていません。
逆に、tar形式のイメージファイルではSGIDが付与されています。

上記の例で/shareにSGIDを付与するには、どのような解決方法がスマートでしょうか?
以上、よろしくお願いします。

wic ですが、Yoctoのバージョンによって変更されている箇所があります。
現在使用中のBSPに含まれるYoctoのバージョンをお知らせいただけると、解決策が見つかる可能性が有ります。

はい。do_image_tar で作成されたイメージにはSGIDが残り、do_image_wic で作成されたイメージではSGIDがクリアされる状況です。

使用しているYoctoのバージョンは 3.0(Zeus) です。
使用しているコードは NXP の i.MX8 シリーズのものになります。
下記でDLできるものをベースにしています。

```
repo init -u https://source.codeaurora.org/external/imx/imx-manifest -b imx-linux-zeus -m imx-5.4.3-1.0.1.xml
```

do_image_wic タスク内では、ディレクトリ構成の生成はtarを使用したsrcからのコピーではなく、srcのディレクトリ構成に準じて、mkdir でディレクトリを生成するため、SUID/SGIDといった属性は消えてしまっています。

do_image_wic 実行後に変更を行うのであれば、
https://www.yoctoproject.org/docs/3.0.4/overview-manual/overview-manual....
の記述から、IMAGE_POSTPROCESS_COMMAND で、指定する方法がスマートと考えますが、ちょっと難物ですね。

返信ありがとうございます。

IMAGE_POSTPROCESS_COMMAND でやるとなると、`*.wic.bz2` ができた後に変更するという理解であっていますか?
そうなるとだいぶ難しそうです。
wicのコマンドラインヘルプや、そのpythonコードも見てみましたが、
イメージ中のディレクトリにSGIDを付与できそうなコマンドを見つけられなかったです。

また、イメージを作成する前のディレクトリの状態を詳しく調べたところ、
mkfs.ext4で消えている確証がとれたので、現状のツールでは無理なのかなと思いました。

以下調べたこと:

https://git.yoctoproject.org/cgit/cgit.cgi/poky/tree/scripts/lib/wic/par...
の前後に下記のようなログを入れてビルド。

観察のための改造:
```
+ logger.warning("@@@@ {}".format(mkfs_cmd))
exec_native_cmd(mkfs_cmd, native_sysroot, pseudo=pseudo)
+ _,debugout = exec_native_cmd("/bin/ls -la {}".format(rootfs_dir),native_sysroot, pseudo=pseudo)
+ logger.warning("@@@@ {}".format(debugout))
```

上記の結果(do_image_wicのログ):

```
WARNING: @@@@ mkfs.ext4 -F -i 8192 /mnt/ssd2/trees/work1/imxbsp/build/tmp/work/imx8mmevk-poky-linux/core-image-minimal/1.0-r0/deploy-core-image-minimal-image-complete/core-image-minimal-imx8mmevk-20210105121634/tmp.wic.nrkpggo8/rootfs_share.4.ext4 -L share -U 78806533-3e12-4dea-abac-a8bb4c109ea4 -d /mnt/ssd2/trees/work1/imxbsp/build/tmp/work/imx8mmevk-poky-linux/core-image-minimal/1.0-r0/rootfs/share
WARNING: @@@@ total 16
drwxrwsr-x 3 root root 4096 Jan 5 12:02 . ★SGID消えてない
drwxr-xr-x 18 root root 4096 Jan 5 12:02 ..
-rw-r--r-- 1 root root 4 Jan 5 12:02 bar
drwxrwsr-x 2 root root 4096 Jan 5 12:02 hoge
```

do_devshellを起動し上記のmkfs.ext4コマンドを参考にext4イメージを作成したところ、wicイメージに入っているパーティションと同じくルートのSGIDが欠落したのイメージになったので、mkfs.ext4コマンドのところが悪いという結論になりました。
mkfs.ext4でrootのパーミッションを引き継いだり指定したりするオプションはなさそうなので、何らかの方法でマウントした後に変えるしかないのではないかと思います。

https://patches.openembedded.org/patch/170464/
で議論されており、Yocto3.2以降では、0001-misc-create_inode.c-set-dir-s-mode-correctly.patch は含まれていません。

以下の行のみ含むe2fsprogs_1.45.3.bbappend を作成してお試しいただければ良いかと。
SRC_URI_remove = "file://0001-misc-create_inode.c-set-dir-s-mode-correctly.patch"

若しくは、Yocto3.2.1 の meta/recipes-devtools/e2fsprogs/ 以下を新規レイヤーにコピーして、バックポートすれば良いかと。

Yocto3.0を使用しているので、0001-misc-create_inode.c-set-dir-s-mode-correctly.patch はすでに存在していますね。
do_patchの状況も確認して、パッチがあたっていることを確認しました。

提示のURLでUpstreamはパッチと異なる修正をしたとのことなので、Yocto.3.2相当の1.45.6まで上げてみましたが、
アップグレードしても状況は変わりませんでした(/shareのパーティションのルートFSにSGUIDは設定されないまま)

e2fsprogsのコードを読んでみての推測ですが、ルートへの権限はコピーされないのかもしれません。

main => populate_fs : src_root_dirが-dで渡されたパス
https://git.kernel.org/pub/scm/fs/ext2/e2fsprogs.git/tree/misc/mke2fs.c?...
populate_fs => populate_fs2 => __populate_fs : source_dirが-dで渡されたパス
https://git.kernel.org/pub/scm/fs/ext2/e2fsprogs.git/tree/misc/create_in...
: source_dirが-dで渡されたパス。ということは、__populate_fsでrootは無視している。(804行~824行)
https://git.kernel.org/pub/scm/fs/ext2/e2fsprogs.git/tree/misc/create_in...

初期化スクリプトの中で、/share の属性をチェックしてSGIDが付与されていなければ付与するものを追加するのが
一番影響が少なさそうですね。

現時点のツールではbitbakeでwicのファイルシステムのルートディレクトリの権限変更は難しいということがわかりましたので、
今回は、起動後の初期化スクリプトでやることにしました。

もしread onlyなシステムで、権限を変える必要が出てきたときはそのときに考えることにします。
(loopbackマウントをつかう変換スクリプトを書くか、e2progfsの-E root_ownerをヒントにパッチを作るか、初回マウント時に書き換えを許すか...)

お付き合いいただきありがとうございました。

本来の趣旨とは異なるかもしれませんが、/share の下にディレクトリを作成し、そのディレクトリにSGIDを設定した場合は、SGIDが残る可能性があるかと。