Syndicate
Site (RSS, Atom)
Contact
Weblog status
Total entries: 78
Last entry: 2022-10-16 13:52:24
Last updated: 2022-10-16 14:12:58
powered by vim, bash, cat, grep, sed, and nb 3.4.2

2019-09-20 23:22:47

Workaround for Unity installation issue "not enough space"

Some days ago my son told me that he had an issue on installing Unity via UnityHubSetup on Linux: Even with specifying TMPDIR and selecting home partition as installation target the installer did still show the (low) free disk space of the root partition.

There are several pages about this topic but apparently there's no easy solution for this issue. I told him that (assuming that you actually have enough free disk space) the disk space can be "faked" by pre-loading a shared library where the statfs() calls are wrapping the system calls and are "faking" the results.

As Proof-of-Concept and for educational purposes I wrote this fake library and a small shell script to control the Unity installer and the lib. A small issue is that the executable UnityHubSetup.AppImage is actually unpacking some kind of image and then starting the actual installer from this image. As a solution my script will launch UnityHubSetup.AppImage to get the image unpacked, then terminate UnityHubSetup.AppImage and finally start the real installer with the fake library preloaded. That causes the installer window flashing one time and then opening up finally.

Script and fake lib as archive: unityhubsetup-fake-diskspace.tar.gz

Content of the archive:

$ ls -1 unityhubsetup-fake-diskspace
README
launch-uhs-with-faked-increased-diskspace.sh
wrap_statfs.c
wrap_statfs.so

Some technical details: The actual free space is multiplied with a constant factor...

$ grep -B3 'resize_factor =' wrap_statfs.c 
/**
 * multiply free space with resize_factor
 */
static const int resize_factor = 16;

... and this is an implementation of a faked call:

$ fgrep -A9 'int statfs(' wrap_statfs.c 
int statfs(const char *path, struct statfs *buf) {
  int result;
  write(2, MESSAGE_STATFS, (sizeof MESSAGE_STATFS) - 1);
  actual_statfs = dlsym(RTLD_NEXT, "statfs");
  result = actual_statfs(path, buf);
  if (result == 0) {
    SET(buf->f_blocks, buf->f_bfree, buf->f_bavail);
  }
  return result;
}

Posted by Frank W. Bergmann | Permanent link | File under: c, shell