Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 558608 - sys-apps/portage cannot install files to filesystems not supporting chown()
Summary: sys-apps/portage cannot install files to filesystems not supporting chown()
Status: UNCONFIRMED
Alias: None
Product: Portage Development
Classification: Unclassified
Component: Core (show other bugs)
Hardware: All Linux
: Normal normal (vote)
Assignee: Portage team
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-08-24 15:57 UTC by Stuart Shelton
Modified: 2015-08-24 16:04 UTC (History)
0 users

See Also:
Package list:
Runtime testing required: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Stuart Shelton 2015-08-24 15:57:01 UTC
I'm working on an updated sys-boot/raspberrypi-firmware ebuild, and found that portage reproducibly fails when attempting to write the firmware data files to the RPi /boot partition which is, of necessity, FAT32-formatted.

What actually happens is that the 'merge' stage progresses until the first file is copied to /boot, at which point the process fails with "copy <src> -> <dest>#new failed", and a file named <dest>#new ('bcm2709-rpi-2-b.dtb#new ', in this case) is left in the destination filesystem.  Note that the '#new' has been added by portage.

The problem is that the pym/portage/util/movefile.py file unconditionally calls _apply_stat when the source and destination filesystems differ, and the implementation of this is simply:

def _apply_stat(src_stat, dest):
        _os.chown(dest, src_stat.st_uid, src_stat.st_gid)
        _os.chmod(dest, stat.S_IMODE(src_stat.st_mode))

On FAT32, however, from shell `chmod` silently fails whilst `chown` fails with 'Operation not permitted'.  I do note, however, that if the filesystem is mounted with 'root:root' ownership and 'chown root:root x' is executed, then this does succeed - so there may be some userpriv-type issue here?

By changing movefile.py as follows:

def _apply_stat(src_stat, dest):
        try:
                _os.chmod(dest, stat.S_IMODE(src_stat.st_mode))
        except SystemExit as e:
                raise
        except Exception as e:
                writemsg("!!! %s\n" % _('chmod %(dest)s failed.') %
                        {"dest": dest}, noiselevel=-1)
                writemsg("!!! %s\n" % (e,), noiselevel=-1)
                return None
        try:
                _os.chown(dest, src_stat.st_uid, src_stat.st_gid)
        except SystemExit as e:
                raise
        except Exception as e:
                writemsg("!!! %s\n" % _('chown %(dest)s failed.') %
                        {"dest": dest}, noiselevel=-1)
                writemsg("!!! %s\n" % (e,), noiselevel=-1)
                return None

... the result is then:

...
>>> /lib/modules/4.1.6-v7+/modules.alias
>>> /lib/modules/4.1.6-v7+/modules.alias.bin
>>> /lib/modules/4.1.6-v7+/modules.devname
>>> /lib/modules/4.1.6-v7+/modules.dep
>>> /lib/modules/4.1.6-v7+/modules.order
>>> /lib/modules/4.1.6-v7+/modules.symbols
--- /boot/
!!! chown /boot/bcm2709-rpi-2-b.dtb#new failed.
!!! [Errno 1] Operation not permitted: '/boot/bcm2709-rpi-2-b.dtb#new'
>>> /boot/bcm2709-rpi-2-b.dtb
!!! chown /boot/config.txt#new failed.
!!! [Errno 1] Operation not permitted: '/boot/config.txt#new'
>>> /boot/config.txt
!!! chown /boot/start_x.elf#new failed.
!!! [Errno 1] Operation not permitted: '/boot/start_x.elf#new'
>>> /boot/start_x.elf
!!! chown /boot/start.elf#new failed.
!!! [Errno 1] Operation not permitted: '/boot/start.elf#new'
>>> /boot/start.elf
!!! chown /boot/bcm2708-rpi-cm.dtb#new failed.
!!! [Errno 1] Operation not permitted: '/boot/bcm2708-rpi-cm.dtb#new'
>>> /boot/bcm2708-rpi-cm.dtb
!!! chown /boot/bootcode.bin#new failed.
!!! [Errno 1] Operation not permitted: '/boot/bootcode.bin#new'
>>> /boot/bootcode.bin
!!! chown /boot/start_db.elf#new failed.
!!! [Errno 1] Operation not permitted: '/boot/start_db.elf#new'
>>> /boot/start_db.elf
!!! chown /boot/start_cd.elf#new failed.
!!! [Errno 1] Operation not permitted: '/boot/start_cd.elf#new'
>>> /boot/start_cd.elf
!!! chown /boot/System.map-4.1.6-v7+#new failed.
!!! [Errno 1] Operation not permitted: '/boot/System.map-4.1.6-v7+#new'
>>> /boot/System.map-4.1.6-v7+
!!! chown /boot/fixup.dat#new failed.
!!! [Errno 1] Operation not permitted: '/boot/fixup.dat#new'
>>> /boot/fixup.dat
!!! chown /boot/bcm2708-rpi-b.dtb#new failed.
!!! [Errno 1] Operation not permitted: '/boot/bcm2708-rpi-b.dtb#new'
>>> /boot/bcm2708-rpi-b.dtb
!!! chown /boot/fixup_db.dat#new failed.
!!! [Errno 1] Operation not permitted: '/boot/fixup_db.dat#new'
>>> /boot/fixup_db.dat
!!! chown /boot/fixup_cd.dat#new failed.
!!! [Errno 1] Operation not permitted: '/boot/fixup_cd.dat#new'
>>> /boot/fixup_cd.dat
Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/portage/dbapi/_MergeProcess.py", line 235, in _spawn
    prev_mtimes=self.prev_mtimes, counter=counter)
  File "/usr/lib/python2.7/site-packages/portage/dbapi/vartree.py", line 5006, in merge
    counter=counter)
  File "/usr/lib/python2.7/site-packages/portage/dbapi/vartree.py", line 4165, in treewalk
    rval = self._merge_contents(srcroot, destroot, cfgfiledict)
  File "/usr/lib/python2.7/site-packages/portage/dbapi/vartree.py", line 4445, in _merge_contents
    self.settings["EPREFIX"].lstrip(os.sep), cfgfiledict, mymtime):
  File "/usr/lib/python2.7/site-packages/portage/dbapi/vartree.py", line 4800, in mergeme
    os.chown(mydest, mystat[4], mystat[5])
  File "/usr/lib/python2.7/site-packages/portage/__init__.py", line 259, in __call__
    rval = self._func(*wrapped_args, **wrapped_kwargs)
OSError: [Errno 1] Operation not permitted: '/boot/overlays'

... so it appears that directory creation is likewise affected.