Transform tar into cpio without rooting

archivecpionot-root-usertar

I have a tarball containing many files with root:root owner and/or special device inodes. cpio only accepts paths existing in the file system when it is creating a cpio archive. And I don't want to have to sudo in order to transform tar into cpio, while I want to preserve all the permissions, owners, and special inodes.

Is there some clean way of handling this?

EDIT1:

I believe that fakeroot can be seen as somewhat clean way. However it does not scale as expected – nearly 1,000x speed difference:

[user@computer root]$ ls -l ../fanbox.tar
-rw-rw-r-- 1 user user 56555520 May 22 03:33 ../fanbox.tar
[user@computer root]$ time tar -x --delay-directory-restore -f ../fanbox.tar
tar: dev/null: Cannot mknod: Operation not permitted
tar: dev/random: Cannot mknod: Operation not permitted
tar: dev/urandom: Cannot mknod: Operation not permitted
tar: Exiting with failure status due to previous errors

real    0m0.255s
user    0m0.062s
sys 0m0.193s
[user@computer root]$ rm -rf *
[user@computer root]$ time fakeroot tar -x --delay-directory-restore -f ../fanbox.tar

real    3m49.381s
user    0m0.812s
sys 0m2.760s
[user@computer root]$ 

Based on the output of time command I guess it is because of the communication between fakeroot and faked.

For reference, there is no much difference between a 2M tarball and 50M tarball when I changed fakeroot into sudo bash in my script. And also I believe that the problem is the number of files in the tarball, not the size: I used the same script on a ~10M tarball with two 5M binaries, and the script is not so slow.

Best Answer

You can use fakeroot. As the name says, it fakes the root user, by intercepting serveral syscalls with a LD_LIBRARY_PATH/LD_PRELOAD library wrapper, to have the process believe it's running as root. This has been created for the purpose of building and packaging applications without having to be root, including using make install which typically would be run as root. It's especially well suited to create archives.

During this, a forked daemon faked will run in order to remember all faked file ownership rights or informations on special files the child processes believes they made. So all operations have to be done in the same "instance", or faked will exit and forget what it was remembering.

$ fakeroot
# tar xf ...
# find foo ... | cpio -o ...
# exit
$ 

Other example showing faked's interaction:

$ mknod /tmp/vaporware b 8 0
mknod: /tmp/vaporware: Operation not permitted
$ fakeroot
# mknod /tmp/vaporware b 8 0
# ls -l /tmp/vaporware
brw-r--r-- 1 root root 8, 0 May 18 08:33 /tmp/vaporware
# exit
$ ls -l /tmp/vaporware
-rw-r--r--. 1 user user 0 May 18 08:33 /tmp/vaporware
Related Question