Hello Corbin,
> 1) It seems that many times copy is a better replacement for a hard
> link than symbolic link. For example, in managing the group.lock
> file, they create a link of group.lock (turned into a symlink) to
> another temporary file group.#### . When they delete the temporary
> file group.###, group.lock is left as a hanging symlink and this
> causes things to fail later on that test for the existence of and
> contents of the group.lock file.
>
> A) Can you think of a more robust way to emulate a hard link,
> because neither a copy nor a symlink is a great answer?
> A binding is actually a good answer, but it would be a binding
> from within the rootfs to another file within the rootfs. Maybe
> these could be created when a hard link is created and get
> deleted when the file (that is now a binding) is removed. The
> list of these could be written to a file, for launching in the
> future. This feels like it could work, but maybe is a little
> clunky. Any better ideas? Currently my initial rootfs have no
> hard links (I replace them with copies initially)
As you said, hardlinks and symlinks are not semantically equivalent:
* for the hardlink "A <-> B", A and B points to the same content.
If one of them is removed, the other one is still valid.
* for the symlink "A -> B ", A points to B. If the latter is
removed, the former will be invalid.
To keep the original semantic, an intermediate file could be used: the
hardlink "A <-> B" can be translated into two symlinks ""A -> C" and
"B -> C", where C is the original content. What do you think about
this solution?
> B) There is no system call to do a copy by itself, so if I wanted a
> hard link to be a copy, how do I replace the one system call
> with multiple, or just drop it and then do some code to perform
> the copy?
Syscall chaining is a new feature that will be included in PRoot v3.2:
https://github.com/cedric-vincent/PRoot/commit/7cd0c919545a867f4df77446750ab5ebfd9b7055
To cancel a syscall use "set_sysnum(tracee, PR_void)" in the sysenter
stage.
> 2) This is something that proot could do well, would help Android
> users a lot, but might be outside the scope of what you want to do.
> If you take a normal linux rootfs, say debian, 90% of the files are
> non-executable and 10% are executable. Android often has a small
> partition that supports symlinks and executables and a larger
> partition (sometimes external) that is mounted noexec and may be
> formatted such that it does not support symlinks. So, what if the
> rootfs is split into 3 pieces... the rootfs itself has every file
> replaced with links to one of two bindings exec and noexec which
> contain a mirror of the directories used (as needed), but one has
> the files that are marked as executable and the other has the rest.
> I have proven that splitting a rootfs this way provides a
> functional rootfs in the end, but I have only done this as a
> preprocessed step, so it cannot handle properly adding or removing
> files or changing permissions. So, what if proot intercepted
> attempts to create a file or change a files permissions with code
> that made sure that the file is created or moved to the correct
> binding and that the link in the rootfs points at the correct one.
This could be done in a dedicated extension. For instance, my
teammates write and use such kind of extensions. I could help you to
write your own extension if you wish. Do you have some pseudo-code to
start with?
It looks awesome! I don't own an Android device but I'm really proud
you based this project on PRoot! I took a quick look at the sources,
please could you remind me why you use QEMU?
Cédric.