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>