[launchd-dev] early boot hook in launchd/launchctl?

Greg Shenaut gkshenaut at ucdavis.edu
Wed Jun 24 07:49:47 PDT 2009


On Jun 23, 2009, at 9:08 PM, Damien Sorresso wrote:

> 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.

I clone the system disk to a firewire drive using hdiutil -srcdevice.

>> 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.

I think bash(1) is slightly inaccurate in its discussion of ENV. From  
observation, it appears that ENV is always defined (as $HOME/.env),  
but it will be sourced only if the file exists. Root's home directory  
is /var/root, so HOME would normally be defined as that, but in single- 
user mode, at least currently, HOME is not defined. For shells run by  
root, ENV would normally be /var/root/.env, but since HOME is  
undefined in single-user mode, it comes out as /.env.

In any case, it sounds like from the launchd point of view, this  
method (which depends on HOME not getting defined in single-user mode)  
appears reasonably stable, which suits me OK.

> Also, the existence of rc.server is considered to be more of a  
> necessary evil than a bug. :)

Gotcha.

>> 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.

I'm sure that's true.

Thanks,
Greg Shenaut

> -- 
> Damien Sorresso
> BSD Engineering
> Apple Inc.
>



More information about the launchd-dev mailing list