Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 7 Dec 1998 13:40:01 -0500
From:      Brian Cully <shmit@kublai.com>
To:        freebsd-arch@FreeBSD.ORG
Subject:   Sysconfig, or, the SysV vs. BSD init wars
Message-ID:  <19981207134001.A1794@rcn.com>

next in thread | raw e-mail | index | archive | help
[Originally sent to freebsd-hackers, and re-sent here by the author,
with apologies to those that have already seen it. -EE]


(I hope I manage to state myself clearly in this message, but I'm a
little confused as to how to relate everything.)

I've spent the last few weeks working on and off on a replacement for
/etc/rc, and given the recent traffic regarding such, I figured now's a
good time to tell the world.

The program itself, sysconfig (probably should be called sysinit, given
it's functionality), should be called from init instead of /etc/rc,
and sysconfig reads it's data out of /etc/system (or something). The
syntax of the file looks like this:

service = {
	enabled = "YES";
	supplies = [ "service_1"; ...; "service_n"; ];
	requires = [ "requirement_1; ...; "requirement_n"; ];
	load = "startup script";
	unload = "teardown script";
};

The supplies and requires nodes can be regular strings, too, instead of
arrays, or even another dictionary (but that hasn't been written yet,
it's of dubious value to me). The syntax should look like your everyday
dictionary, and can have dictionaries or arrays nested indefinately
within other dictionaries or arrays (which could be useful).

The load and unload nodes can reference other nodes like this:

load = "ifconfig $address $netmask";

or, if you want to leave local scope, you can reference an element in
another node:

load = "ifconfig $root.address $super.netmask";

So, if you want to config your ethernet interfaces:

network = {
	enabled = "YES";
	supplies = "network";
	load = "ifconfig $address $netmask $media $options";
	unload = "ifconfig $key down";
	interfaces = [ "fxp0"; "lo0"; ];
	fxp0 = {
		address = "207.172.25.236";
		netmask = "255.255.255.0";
		media = "media 100BaseTX mediaopt full-duplex";
	};
	lo0 = {
		address = "127.0.0.1";
		netmask = "255.0.0.0";
	};
};

As you can see, the name of the service is arbitrary for now,
eventually, I want to have the service name be a module that can be
loaded at run-time for third-party extension. If there is no module
it'll use default behaviour (which will fail with the network example
above). This requires ld.so and libc.so to be on the root partition,
which is something we'll probably eventually need anyway, as the system
becomes more and more dynamic.

You can source other files, to assist in ease-of-maintenance for
centralised distribution.

The dictionary parsing stuff is sufficiently high-level as to allow
for a menu-driven configurator for newbies (and random other uses,
I'm using it in my RADIUS daemon, for example). The dictionary code
is really only up to the task of parsing the config file and printing
it out again right now, because that's as much functionality as I
need for the moment (but it's very good about failure modes, giving
you a nice stack backtrace). In the future, though, I want to make
it more robust.

I'm of two minds about the /etc/init.d/service start|stop functionality
in SysV init, I want to implement it, but am not sure how, here's the
way I see it:

	1) Have the `load' and `unload' nodes just call external
	   scripts to do the dirty work, that you can call yourself
	   when you want to, or,
	2) Have a `telinit' style program where you can say:
		telinit module unload
		telinit module load
	   The perks here being that you could theoretically replace
	   init eventually, and you can have sysinit do all the
	   dependency tracking information so you can't easily unload
	   a service that's in use by another service that's still
	   up (which I think would be way cool, and worth the
	   confusion over having to use a `telinit' style program).

I've got my code to a point where it tracks down who supplies what,
and with a little more work (in my copious spare time), it'll be
able to track down dependencies and load programs. It doesn't do
the object referencing I talked about above, because it's not useful
to do that when I can't even load a program. :-)

So in about a man-day or two, I should have it to the point where
I can actually replace /etc/rc with it.

Oh, yes, and it's also done completely in Objective C, because it made
my life really easy while I was developing this.

I'd really like feedback on this, because I'd like this to be used,
or I'd at least like to stop wasting my time on it if it won't be. If
you want the code send me mail, it's not very functional, but you
will probably be able to see where I'm going.

-- 
Brian Cully						<shmit@rcn.com>
Macintosh -- we might not get everything right, but at least we
knew the century was going to end.
                                -- Douglas Adams, on the Y2K problem.

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-arch" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?19981207134001.A1794>