On Jun 23, 2009, at 6:20 PM, Greg Shenaut wrote:
Until recently, it was possible to put arbitrary code into /etc/ rc.server to perform scripted maintenance activities in the early boot context (i.e., system disk still write-only, limited driver access, etc). In the version distributed with 10.5.7, rc.server shows up later in the sequence (i.e., system disk mounted read- write). In any case, adding code to rc.server always was a kludge.
What exactly are you doing that requires a read-only filesystem (I assume that's what you meant). What do you mean by "limited driver access"? Single-user mode doesn't stop the kernel from loading kexts as needed.
Now, the cleanest way to do it seems to be to put code into /.env and use "nvram boot-args=-s ; reboot" to run it. This is actually a much cooler kludge, because /.env (the value of ENV in single-user mode) is normally run only in single-user mode, because otherwise the HOME variable will be set, and for root that will cause ENV normally to be defined as /var/root/.env. Because /.env only gets run in single-user mode, you can put in fairly elaborate checks to make sure you're in in the right place without negatively impacting startup time for normal root shell scripts.
But I'm concerned that this method, like rc.server, will someday be seen by the launchd developers as a bug (that is, HOME not being defined in single-user mode); in this case, it too will suddenly disappear and some other kludge will have to be found.
.env is a feature of the shell, not launchd. Though it's not mentioned in bash(1). Perhaps you're referring to /etc/profile? If that's the case, I suppose we could someday invoke the shell with --noprofile or something in the future, but I don't see a compelling reason to do that. Also, we don't set ENV when invoking the shell for single-user mode. Also, the existence of rc.server is considered to be more of a necessary evil than a bug. :)
So what I'm wondering is whether it might not be a good idea to provide a conventional hook for early-boot maintenance. It could simply be a shell script in a standard location such as /etc/ rc.earlyboot which gets executed by launchd if present, owned by root, and not writable except by root. This would keep people who insist on doing this kind of thing from having to keep finding new and better kludges.
Or, of course, the /.env thing and the HOME-less single-user shell could become a feature of launchd that is reserved for this purpose.
This might come in the future, but not in the form you're expecting. -- Damien Sorresso BSD Engineering Apple Inc.