tar展開時にCannot utime: Operation not permittedが発生

Summary

tar ボールを展開した時に

  • tar: foo: Cannot utime: Operation not permitted
  • tar: foo: Cannot change mode to rwxrwxr-x: Operation not permitted

というエラーが発生した時の解決方法をメモ

再現条件

オーナーが他ユーザのディレクトリを tar で展開したディレクトリで上書きしようとすると

  • 更新日時の更新
  • パーミッションの変更

で上記エラーが発生する

再現手順

$ mkdir foo
$ chmod a+w foo/
$ sudo chown root:root foo
$ ls -l
total 4
drwxrwxrwx 2 root root 4096 Jul 13 20:55 foo

foo ディレクトリはその他ユーザに "w" のフラグが立っているので、ファイル作成できる。

$ touch foo/bar

foo ディレクトリ以下を tar で固める

$ tar cvzf /tmp/foo.tgz foo/
foo/
foo/bar

カレントディレクトリに展開して、上書きしてみる

$ tar zxfv /tmp/foo.tgz
foo/
foo/bar
tar: foo: Cannot utime: Operation not permitted
tar: foo: Cannot change mode to rwxrwxr-x: Operation not permitted
tar: Exiting with failure status due to previous errors
  • Cannot utime: Operation not permitted
  • Cannot change mode to rwxrwxr-x: Operation not permitted

というの2つのエラーが発生している。

以下で、これらエラーを順に解決していく。

Cannot utime: Operation not permitted 対応

utime(2) はアクセス/更新日時を設定するシステムコール。

man の utime(2) を読むと

  •  utime で現在時刻に更新する場合は、オーナー(or root)であるか effective user に write パーミションが必要
  •  ttime で特定時刻に更新する場合は、オーナー(or root)である必要

がある。

http://pubs.opengroup.org/onlinepubs/9699919799/functions/utime.html
The utime() function shall set the access and modification times of the file named by the path argument.
If times is a null pointer, the access and modification times of the file shall be set to the current time. The effective user ID of the process shall match the owner of the file, or the process has write permission to the file or has appropriate privileges, to use utime() in this manner.
If times is not a null pointer, times shall be interpreted as a pointer to a utimbuf structure and the access and modification times shall be set to the values contained in the designated structure. Only a process with the effective user ID equal to the user ID of the file or a process with appropriate privileges may use utime() this way.

tar の場合、ディレクトリを tar されたディレクトリのタイムスタンプで更新しようとしているため、Cannot utime: Operation not permitted というエラーが発生している。

この問題は touch コマンドでも簡単に再現できる。

$ touch foo
$ echo $?
0
$ touch -t 201301230123.45 foo
touch: setting times of `foo': Operation not permitted
$ echo $?
1
$ sudo chmod o-w foo
$ ll
total 12
drwxrwxr-x  3 jsmith jsmith 4096 Jul 13 21:20 ./
drwxrwxrwt 26 root   root   4096 Jul 13 21:20 ../
drwxrwxr-x  2 root   root   4096 Jul 13 21:04 foo/
$ touch foo/
touch: setting times of `foo/': Permission denied

write 権限があるので、オーナーでなくても現在時刻に更新できるが、特定時刻に更新しようとするとエラーになる。
write 権限を取ると、現在時刻の更新もエラーになる。

解決策

tar に -m/--touch オプションをつければ OK

-m, –touch : don’t extract file modified time

$ tar zxfvm /tmp/foo.tgz
foo/
foo/bar
tar: foo: Cannot change mode to rwxrwxr-x: Operation not permitted
tar: Exiting with failure status due to previous errors

“tar: foo: Cannot utime: Operation not permitted” は発生しなくなった。

Cannot change mode to rwxrwxr-x: Operation not permitted 対応

tarumask に合わせてディレクトリのパーミッションが設定される
drwxrwxrwx から rwxrwxr-x にパーミッションを変更しようとするが、オーナーでないため Cannot change mode to rwxrwxr-x: Operation not permitted というエラーが発生している。

解決策

tar したディレクトリのパーミッションを展開時にも保持する場合、 tar-p/--preserve-permissions/--same-permissions オプションをつければ OK

-p, –preserve-permissions, –same-permissions preserve access times on dumped files, either by restoring the times

$ tar zxfvmp /tmp/foo.tgz
foo/
foo/bar
$ echo $?
0

ということで、2つのエラーが消え、無事成功

References

Leave a comment