Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 29 Oct 1998 22:21:40 -0800
From:      Terry Lambert <terry@whistle.com>
To:        "Andrzej Bialecki terry@whistle.com" <abial@nask.pl>
Cc:        Bryan Mann <bmann@whistle.com>, small@FreeBSD.ORG
Subject:   Re: Unified Configuration Interface
Message-ID:  <36395AF4.7614@whistle.com>
References:  <Pine.BSF.4.02A.9810292344200.3317-100000@korin.warman.org.pl>

next in thread | previous in thread | raw e-mail | index | archive | help
Andrzej Bialecki wrote:

[ ... ]

] Now, yet another idea occured to me: in fact, the initial
] startup could just try to start some highest level function
] of the system, and this function (since it has multiple
] dependencies) would try to satisfy its needs by requesting
] an "INIT" action from all service providers it is dependent
] upon.

Yes.  You could, in fact, define a "service" that consisted
only of dependencies, for example "run_state_three", and
then "ask for run_state_three".  A "service cluster".

] > So I think the problem is resolvable; it's just an issue of
] > establishing that you're really dependent on services, not
] > daemons, and then using a sufficient granularity for your
] > definition of services to avoid starvation deadlocks.
] 
] Hmmm... I don't think this resolves the issue of deadlocks -
] it just moves it to more abstract level of services, instead
] of real objects/processes.
] The real problem (i.e. mutual "critical" dependency, like
] 
]                 depends on
]                1<----------2<--------3
]                |                    /|\
]                +---------------------+
] 
] ) still exists.

Yes; but this abstract level has a lot less clutter in it,
and even though it's an O(3) problem, you can detect loops
in "critical dependencies" rather quickly.  In fact, if you
go to /usr/src/usr.bin/yacc/warshall.c, you can see the code
you would need to link in to make this work.  8-).


> > Of course, we are ignoring the real issue here, which is that
> > most services only exist in the first place because we insist
> > on having a procedurally abstracted configuration space.  Why
> 
> ??? I can't parse it...

OK; I'll elaborate... it's a fun topic, anyway.  8-).

The reason you have a lot of these dependencies is because
the services you depend upon have some information you need,
and they have to be there for you to ask them.

You have other dependencies that need monitoring (or SNMP
traps, etc.) because most programs are written to call a
function to get configuration data at startup, and if you
make changes after that, you have to signal them that the
information has changed, and that their cached copy of the
data is stale (for example, "the hostname has changed", or
"the IP address assigned to interface ed0 has changed", etc.).

The configuration data is stale because the programs operate
on a cached copy of the configuration space, instead of on
the real configuration space.

A good example of this is errno.  In FreeBSD-current, it's
defined as a dereference of a integer pointer return from
a function that gets called when you reference "errno".

Consider if the hostname, or any other information that
could become stale was accessed the same way.  If it was,
you would never need to restart your daemons because when
they referenced the data *it would always be the right data*.


Now say you don't want to take the procedure call hit every
time you reference "hostname".  How do you accomplish this?

One way you could accomplish this is by defining hostname
to be something like this:

#define	hostname	((char *)(*(baseaddress)[ HOSTNAME]))

Where baseaddress is the base address of a memory mapped
file that contained your configuration space, and starting
at position 0 in the file, you have an array of void *
pointers that point to the configuration data, somewhere
else in the memory mapped file.

When I access "hostname", what I get is a char * pointer to
wherever the hostname is in the memory mapped file (we just
need to agree that the void * pointer that points to the
hostname is at offset 3, and that HOSTNAME is defined to be
3 -- or whatever agreed upon offset).  Like the IRQ vector
table in low memory.  Yeah, I take a pointer dereference
overhead that I wouldn't have on a cached copy, but I never
have to take a restart overhead from getting signalled.

So crt0.o or a CTOR (runtime constructor function) mmap's
this file for me magically when my program starts up, and
I just access things as if they're local variables.  When
I want to change something, I call a function that changes
the copy in the real file, with whatever necessary interlocks
to make sure no one is modifying the same thing at the same
time.

A configuration space.

This gets rid of the need to monitor most of the things
you would ever want to monitor, since the reason you are
trying to monitor them is to catch changes so you can
update your cached copy (i.e., you are doing an awful lot
of work once in a while to avoid having to do a little
work each time, but those aren't your only choices for
solving the problem you want to solve, which is to avoid
function call overhead each time you want to use some
configuration data that may have changed on you).


-- Terry Lambert
-- Whistle Communications, Inc.
-- terry@whistle.com

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



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