S
Seebs
|What this ends up doing is allowing me to intercept every system call that
|deals with the filesystem and is affected by privileges, and act as though
|you had root privileges, or at least, make it look as though it acted as
Somebody already did this. It's called fakeroot. Terrible duplication of
effort if you reinvented it from scratch
We used to use fakeroot. It was unsuitable for our purposes in a number
of ways.
Among them:
1. Not much persistency. Fakeroot's good at handling a single build run
which completes in a few minutes. Our system has to handle doing dozens or
hundreds. Over a period of months.
2. Extreme vulnerability to database corruption if anything is changed
outside of it.
3. No real database to speak of; on exit, it writes a flat file list of
plain text data, and it can slurp that back in.
4. No file name tracking. This makes it harder to detect other errors.
5. Can get confused enough to, say, report that a directory is a plain
file, or vise versa.
6. Occasionally crashes, breaking programs relying on it.
7. Also, in default configuration, leaves shared memory segments allocated
and not cleaned up.
There were other issues. After careful study, we concluded that it would be
best to write one from scratch, from the ground up, addressing many of these
concerns.
Mine's called pseudo, and we're currently doing a code clean-up pass before
making it more widely available under some GPL variant. Key differences:
* Tracks file names in nearly-all cases. (You can get past it, but it is
very good at finding out file names.)
* Persistent database using sqlite3 maintained by the daemon.
* Database tracks both names and dev/inode pairs.
* Server does consistency checks and correctly handles cases such as, say,
a database entry which has the same inode as an incoming query, but has
a necessarily-incompatible type (e.g., is tagged as a directory but is
not).
* Client code can automatically restart the server if it goes away or isn't
available, so server doesn't need to be encouraged to stay running for a
long time just because a build might be slow.
* Can log every filesystem action it sees.
We used fakeroot in production systems for a couple of product releases.
Typically, if you loaded things up (say, started and stopped it dozens of
times during an extended build series), sooner or later, it would start
yielding garbage like claiming that a plain file was a directory, or giving
arbitrarily wrong results for files, or lose parts of the recorded state.
Or just crash. On average, if you were using the build system heavily, you'd
hit some kind of "fakeroot failed, you have to re-install all target packages"
thing about once or twice a week.
Since we put in pseudo, we've had one customer bug (which was in an area where
we'd decided to not fully implement something in the first release). When the
bug was reported, the report could tell us what file name pseudo expected to
see for a given file, and what file name had shown up, and why this was
surprising, allowing us to fix the bug in five minutes rather than spending
hours trying to figure out when that inode had been created or freed. We've
had a handful of bugs discovered internally during development, but as of this
writing, I have out for review fixes for the last bugs we are aware of that
have ever caused any kind of failure. (In fact, the last bugs we are aware
of. There have been bugs that didn't cause any failures, because pseudo is
extremely aggressive about sanity-checking its results.)
Basically, if you just look at the time that our developers lost to project
directories that got harmed by fakeroot failures, we've gotten the time I put
back on this returned to us about five-fold since I started.
I would not call it a waste of effort. We did research the alternatives
before trying this, and none of them were a good fit for our usage scenario.
(Relevance, such as it is: It's worth noting that there IS such a thing as
a time to rebuild something that already exists.)
-s