Thursday Sep 25, 2008

The Network Auto-Magic project, which aims to simplify and automate network configuration needs to do a couple of things:

  • catch, handle (and sometimes generate) network-related events, handling transitioning from one network environment to another etc.
  • provide a data repository for configuration preferences for various network environments, with a set of default preferences that lean towards automatic configuration (e.g. use DHCP to get an address)
  • provide a set of user interfaces to allow for manual configuration as well as inspection of network state

This high-level description maps quite nicely onto the set of core components we plan to deliver for phase 1 of NWAM:

  • nwamd - the core daemon at the heart of network autoconfiguration. It is this daemon's job to handle network-related events, assess network conditions and respond to changes in conditions
  • libnwam is the library that provides storage of NWAM-related configuration
  • Finally commandline tools such as nwamcfg and nwamadm and the GUI component of NWAM allow user interaction with network configuration

In a follow-up set of blog posts, I'm going to try and describe these components, starting with the set of events that nwamd needs to monitor and respond to and how that is (and will be) done.

In the meantime, why not give NWAM phase 0.5 a try - it alleviates many of the usability issues that applied to NWAM and works really nicely. Kudos to Jim and Darren (and Michael for his work on spec'ing out a set of candidate solutions to usability issues).

Tuesday Sep 23, 2008

I recently had to make a Windows Vista-installed laptop dual-bootable with OpenSolaris. There's plenty of descriptions of the process around, but just in case here's what I did:

  • Back up any critical data in Windows
  • Burn OpenSolaris 08-05 liveCD
  • Burn system rescue CD with GParted (disk partition management software). It's a Linux-based livecd which allows you to resize partitions dynamically, add new partitions etc. We need to reduce the size of the Windows partition on the disk to make room for a partition for OpenSolaris.
  • Reboot with system rescue cd in drive. When it boots up, type "startx", and when X is running select the GParted icon to run the partition management software. Click on the Vista partition, resize it by clicking and dragging the arrow on the right hand side to the left, and when you've left enough space for OpenSolaris, also add a new partition of type "linux-swap". Resizing/adding the partition should take about an hour. When finished, open a terminal, and type reboot. Video walking through this process can be found here.
  • Boot into windows, allow it to run disk repair, then put the OpenSolaris liveCD in the drive and reboot into OpenSolaris.
  • Click on the install icon on the desktop. When you get to disk partition information, you'll need select the new partition you just added and change the paritition type to solaris from linux-swap before you can install
  • When you reboot (and have removed the liveCD from the drive, you should see Windows and opensolaris in your GRUB menu. Then you can boot into OpenSolaris, run "pkg image-update" etc.

Wednesday Jul 30, 2008

With guidance from Anurag, I've been trying to figure out how the NWAM development process changes with the advent of Mercurial as the source code management tool for OpenSolaris. I've tried to detail the process I'm using here in case it's of use to others. The basic idea is to have a development repository in which we make changes (and will eventually push to the main NWAM repository on opensolaris.org), along with a build repository, to which we pull our changes to build/test. Here are the steps:

  1. clone a development repository
    # hg clone ssh://anon@hg.opensolaris.org/hg/nwam/nwam1 /path2/dev_ws
    
  2. make changes by editing files
  3. commit these changes in the development repository
  4. # hg commit
    
  5. clone/pull the above development changes to a build/test repository
    # hg clone /path2/dev_ws /path2/build_ws
    
    To ensure latest changes are there:
    # cd /path2/build_ws
    # hg update
    
    Or if rather than cloning, you need to update an existing build repository:
    # cd /path2/build_ws
    # hg pull -u /path2/dev_ws
    
  6. clone usr/closed separately, adding it to build repository (external-to-Sun builds need to download the closed binaries at this point instead I believe).
    # cd /path2/build_ws/usr
    # hg clone ssh://elpaso.sfbay//export/clone-hg/usr/closed
    
  7. build/test
  8. push dev changes, replacing yourname with your opensolaris.org account name. SSH keys need to be set up with youro OpenSolaris account for this to work properly, and your account needs to be on the list of contributors.
  9. # cd /path2/dev_ws
    # hg push ssh://yourname@hg.opensolaris.org/hg/nwam/nwam1
    

Friday Jul 25, 2008

One area of SMF that is a bit confusing is the whole notion of snapshots, refresh and how property updates occur. I find this a bit tricky myself, so if there's mistakes below, I'll happily correct them.

A snapshot is essentially a read-only picture of a set of property groups associated with an instance and its parent service. The most important snapshot is the 'running' snapshot, as it is the place applications (including svcprop) and service methods should read their configuration from. Why is this?

My understanding is that the snapshot model is there (in part at least) to allow atomic commit of multiple changes. This is particularly important for services that consume such configuration information. Imagine I want to change two properties in an inetd service. I'd like to change a tcp service from a wait-type (only handling one connection at a time) to a nowait-type service with a specific maximum connection rate. I need to change two properties - the 'wait' property, and the 'max_con_rate' property, since nonzero values for the latter only makes sense for nowait services. The snapshot model allows me to change each individually with svccfg, then refresh. The refresh action updates the running snapshot to contain a read-only picture of the latest values of my properties (it also runs the refresh method associated with the service instance, if there is one). Then entities consuming these values will see both changes at once as the running snapshot is updated atomically.

Sometimes you'll see the actual service and instance property values referred to as the 'configuration' or 'editing' snapshot, but that's not quite accurate, since as we saw above, snapshots are read-only and we make our changes to the actual configuration values, not a frozen picture of them.

If you select an instance using svccfg, you can see there's a bunch of snapshots in addition to 'running':

# svccfg -s nwam
svc:/network/physical:nwam> listsnap
initial
last-import
previous
running
start
svc:/network/physical:nwam> 

Here we see another aspect of snapshots. svccfg(1M) allows us to revert back to earlier snapshots. The names of the various snapshots are pretty self-explanatory. The idea is, if I mess up my configuration, I just need to revert to the initial snapshot, or the one associated with last manifest import, etc.

You'll note something that seems weird - 'refresh' can be carried out both by svcadm and svccfg. Why is this? Well as we saw earlier, refresh has a configuration component - update the running snapshot - and an action component - run the refresh method. Configuration actions belong in svccfg, and actions in svcadm, so it makes sense to have refresh in both. Also, it's possible you may need to update the running snapshot in a SMF repository that's not currently running - maybe you made a configuration change that makes the system unbootable, and it's in the running snapshot, so you can't fix it with svccfg. Having refresh in svccfg makes such problems fixable, since it can operate on an inactive SMF repository. More on this another time.

So finally, why didn't my svccfg property change show up in svcprop? Because svcprop reads from the running snapshot, and until refresh is run, the changes haven't hit that snapshot yet.

Tuesday Jul 22, 2008

With a lot of help from the SMF OpenSolaris community, I recently introduced a change in how the Service Management Framework (SMF) handles property values. I'll try to describe it here.

Service data in SMF is internally represented as groupings of property values (which are named, funnily enough property groups). Some specify dependencies, others the restarter that is responsible for handling starting and stopping the service, while others specify how a service is started, stopped or refreshed. In addition to specifying service data of relevance to the framework, property groups can specify configuration data that is consumed by the service too.

Each property in a property group must be of one specific type - a string, a boolean, an integer etc., but can have multiple values associated with it. Up until recently (before build 95 of OpenSolaris), these values were unordered - i.e. a consumer of the values could assume nothing about the relationship between the order in which they were stored and the order in which they were later retrieved. The putback of 6715372 - SMF repository should store (and allow retrieval of) property values in the order they were added - changes this. Now if property values are specified in a particular order via libscf(3scf) interfaces or via svccfg, they will be stored in that order, and are also retrieved in that order. I'll give a brief description of how this was solved.

Firstly, we need to understand how properties were stored previously. All SMF data is stored in a sqlite database file - in fact there are two database files. The persistent data is stored in /etc/svc/respository.db, and the transient data (temporary property groups and properties that do not survive reboot) is stored in /etc/svc/volative/svc_nonpersist.db. We can examine the content of these databases using /lib/svc/bin/sqlite, but it's not a good idea to do such a thing on a production system of course. Property values are stored in the 'value_tbl' database table. Let's display a single row in that table prior to my putback:

# lib/svc/bin/sqlite /etc/svc/repository.db
SQLite version 2.8.15-repcached-nightly
Enter ".help" for instructions
sqlite> SELECT * FROM value_tbl LIMIT 1; 
16|s|Unstable
sqlite> 

The columns displayed are the associated property id (16), the type ('s' for string) and the value itself ('Unstable'). The value table can have multiple values with the same id - this is how multivalued properties are stored. When property vaues were retrieved in the past, the SMF backend would translate requests into an SQL statement like this 'SELECT * FROM value_tbl WHERE value_id = 16'. Note that there is no ordering here, we just select all values with order unspecified.

Trying the same query on the upgraded repository reveals an extra column:

# lib/svc/bin/sqlite /etc/svc/repository.db
SQLite version 2.8.15-repcached-nightly
Enter ".help" for instructions
sqlite> SELECT * FROM value_tbl LIMIT 1; 
16|s|Unstable|0
sqlite> 

The extra column specifies value_order for a given set of values sharing the same id - the first value is 0, the second 1, etc. When storing a set of values, the backend now specifies a value_order value for each. On retrieval, an exta clause is added to the SQL statement: 'SELECT * FROM value_tbl WHERE value_id = 16 ORDER BY value_order'. This ensures backend retrieval is done in order. Note that this is not the whole story in getting value ordering to work - some libscf(3scf) library changes were needed too, along with some changes to svccfg(1M).

So if you are upgrading to snv_95, and you notice a message like this during boot:

svc.configd: upgrading SMF repository format...
svc.configd: SMF repository upgrade is complete.

...you're seeing the backend database being upgraded as the extra 'value_order' column is being added. It takes a few seconds as the version of sqlite used does not support the 'ADD COLUMN' statement - instead we create a new temporary table with the extra column, import the values from the old table, remove the old table and replace it with the new one.

So finally, what is the practical value of all this? Well, if your service needs to specify configuration data that is order-sensitive - for example a set of nameservices that should be tried in a particular order - you can now specify this using multiple property values, and be sure that you get the values back in the order in which they were set. Here's an example of setting multiple values for a string property, and seeing the order preserved:

# svccfg -s rdisc:default setprop routing/send_address = \( \"A\" \"B\" \"C\" \)
# svccfg -s rdisc:default listprop routing/send_address
routing/send_address  astring  "A" "B" "C" 

In the past, since value ordering was not supported, order-sensitive values had to be stuffed into a single string value with a character separator delimiting each value, which is a pain for consumers to handle, since they had to parse the stored value themselves. A small change, but I suspect it'll come in handy moving forward.

If you want more details, check out the bug report, the ARC case, and the design discussion on smf-discuss.

Friday Oct 19, 2007

We've been working on refreshing the Phase 1 design for NWAM (see here) in the light of what we've learnt during implementation so far. I was tasked with reworking nwamd (1M) to become an SMF delegated restarter, and have tried to describe the design here. As the name suggests, a delegated restarter's job is to take over many of the duties that the master SMF restarter, svc.startd, carries out in managing child instances. In our case, these child instances are Network Configuration Units (NCUs) representing network links and IP interfaces, environments or locations (which specify which name service to use, etc) and External Network Modifiers (which are external-to-NWAM entities that carry out network configuration, such as a VPN client). The reason a delegated restarter is required is that these entitities don't really fit into the standard start/stop/refresh service model - for example a link needs to respond to events such as a WiFi connection dropping, an IP interface needs to respond to events such as acquiring an IP address through DHCP etc. Since it's nwamd's job to monitor for such events, making it a delegated restarter makes sense - it can then handle such events and run appropriate methods and transition the relevant services through appropriate states.

A delegated restarter has to handle events from the master restarter, svc.startd, and these include:

  • Notification from svc.startd of new instances to handle (these will be instances that specify the delegated restarter as their restarter, you can see examples of how this is done in any inetd service manifest, e.g. echo.xml)
  • Notification that an administrator has initiated an action, e.g. disable, enable
  • Notification that the dependencies of an instance are satisfied, i.e. it is ready to run

One area we're particularly interested in is feedback on the naming of instances representing links and IP interfaces. I've put some suggestions in the design doc mentioned above, but nothing is cast in stone at this stage of course, so any feedback on nwam-discuss@opensolaris.org is welcome. At present, my suggestion is to have all NWAM-managed services grouped under the "network/auto" FMRI, with separate services for NCUs, environments and ENMs, i.e.

  • svc:/network/auto/ncu
  • svc:/network/auto/env
  • svc:/network/auto/enm

note that the use of env(ironment) to describe name service and other configuration may change, this is being discussed on nwam-discuss at present.

In terms of NCUs in particular, my suggestion is to prefix the instance names by their type/class, i.e. for link NCUs, the prefix is "link-", for IPv4 interfaces "ipv4-", and for IPv6 "ipv6-". I had been thinking about having different services for links and IP interfaces, but then realized that in order to use the same instance name for IPv4 and IPv6 interface instances, then i'd need separate IPv4 and IPv6 services. So it seems better to have all NCUs grouped by service, and prefix them, allowing the user to run "svcs *bfe" say to see all bfe instances

As an example, here's the service listing for the prototype restarter on my laptop, which has a builtin "iwi" wireless card and a builtin "bfe" wired interface:

# svcs ncu
STATE STIME FMRI
online 7:51:13 svc:/network/auto/ncu:link-bfe0
online 7:51:16 svc:/network/auto/ncu:link-iwi0
online 7:51:21 svc:/network/auto/ncu:ipv4-iwi0
offline 7:51:13 svc:/network/auto/ncu:ipv6-bfe0
offline 7:51:15 svc:/network/auto/ncu:ipv4-bfe0
offline 7:51:16 svc:/network/auto/ncu:ipv6-iwi0

Note that once Clearview vanity naming integrates, the link name ("iwi0" or "bfe0" or whatever) will be dropped in favour of the vanity names for those links.

So, is this reasonable? Is there a better name than "auto"? Let us know!

Friday Aug 24, 2007

Having taken a DTrace course recently, i've been thinking about ways that it can help debugging during development. here's a simple example: nwamd(1M) uses LOG_ERR syslog(3C) messages to log errors when they occur, but they can of course occur for a variety of reasons. We often want access to more information than we record in the log, so here's a simple DTrace script that prints out the syslog() caller's stack on getting a LOG_ERR (3) message:

#!/usr/sbin/dtrace -s

pid$target:libc:syslog:entry
/ arg0 == 3 /
{
ustack();
}

This can be enhanced to match to a specific syslog() error message (using strstr(copyinstr(arg1), "errmsg") as an additional predicate clause), but even better is speculative tracing - we pick a starting point in the code to start a speculation, and if we hit the error condition, we commit the data we've recorded, otherwise discard it. This is particularly handy in cases where functions have void return values, since if the return value indicates the error, we just need pid$target::function:return /arg1 == errcode/

Thursday Aug 23, 2007

I've been deep in the bowels of the NWAM implementation for awhile and thought it might be useful to provide a code walkthrough. There's a lot of interactions to juggle in trying to understand what NWAM is doing, so it's probably best to start with a brief introduction and describe what NWAM is up to. I'll follow up with more specifics later. Just to be clear, this is the NWAM implementation currently in Nevada, which represents the first phase of the ongoing project detailed at the NWAM project page.

Firstly, the code for the nwam daemon is here

It's launched by the "nwam" instance of the network/physical service. The "default" instance of this service does traditional network configuration, and to switch on nwam, it should be disabled, and nwam should be enabled, i.e. svcadm disable network/physical:default
svcadm enable network/physical:nwam

The nwam method script launches the NWAM daemon, nwamd.

The general design of nwamd is a set of threads that listen for and feed events into a state machine which alters system state. Signal handling is carried out by a dedicated thread, which blocks on SIGWAIT and handles various signal- driven events for the daemon as a whole (as otherwise we would have to ensure each thread does signal handling as there are no guarantees which thread gets the signal delivered to it). When forking child processes, we restore the signal mask.

The key concepts NWAM phase 0 introduces are:

Link Layer Profiles (LLPs): these specify, for each IP interface, how it attains an address ("static"'ally or via "dhcp"). In the former case, the static address must be specified. The /etc/nwam/llp file is used to store LLPs, and it can either be hand-crafted, where the IP interfaces are listed in preferred order, or it is created automatically by nwamd (in this case, wired interfaces are ordered first). For the first phase of NWAM (what we call phase 0), only one LLP can be active at a time.

Upper Layer Profiles (ULPs): these are tied to LLPs, and once an LLP is active, nwamd looks for the file /etc/nwam/ulp/check-conditions. If this file exists and is executable, it is run. This should print a single line of output, which is the name of the profile that the user wishes to activate based on the current conditions. If such a line is read successfully (foo in this example), then /etc/nwam/ulp/foo/bringup is executed. Likewise, when the interface gets torn down for whatever reason, /etc/nwam/ulp/foo/teardown is executed. The "bringup" and "teardown" scripts are invoked via pfexec(1) with default basic privileges. Such scripts can be used to initiate VPN connection, etc. No upper layer profiles are provided by default.

For more details, see nwamd(1M).

Files:

main.c: initialization, signal handling, main event loop
events.c: code to enqueue/dequeue events, routing events thread
interface.c: IP interface handling, bringing up/down interfaces etc.
llp.c: code for creating/manipulating /etc/nwam/llp file, switching LLPs, finding the best available LLP, etc.
state_machine.c: code to handle events dequeued by the event handler
util.c: general utility functions, logging etc.
wireless.c: wireless handling code

Threads:

The program consists of a number of threads:

the main event loop thread: takes events off the event queue and calls state_machine() to process them.

the signal handling thread: signals are blocked everywhere else, and it handles SIGALARM timers, shutdown and SIGHUP (refresh) signals.

routing event thread: opens a RTSOCK AF_UNIX socket and read()s from it to get RTM_IFINFO (interface flag changes) and RTM_NEWADDR (new address for interface) events.

periodic wireless scan thread: checks if the signal level has dropped below the minimum acceptable or if the AP has disconnected, and initiates wireless scans.

gather interface info thread: run when a cable is plugged in or a wireless interface is being configured. runs DHCP on wired interfaces or does a wireless scan.

Timers:

A timer is initialized when DHCP is started on an interface. Timers are started via the alarm() system call, and on expiry, the SIGALRM signal is caught in the signal handling thread. From here we walk all interfaces to find which interfaces timer expiry occured for, and we create EV_TIMER events for those interfaces that expiry occured for. When a timer expires on an interface, we check if DHCP has succeeded - if not, we select the best available interface (one which DHCP has not failed on), and make that the active LLP.

Example

To get an idea of what NWAM is up to, let's take a simple example: a laptop running NWAM for the first time, with a wireless interface and a wired interface that is not plugged in.

All IP interfaces will be brought down by initialize_interfaces(), and dhcpagent is killed. Then "ifconfig -a plumb" is carried out to plumb all interfaces. We then add these interfaces to our interfaces list. The /etc/nwam/llp file is initialized to contain the wired and wireless interfaces, with wired appearing before wireless, and specifying address sources for both as "dhcp". We then start event collection, creating the routing event thread and the periodic wireless scan thread. Then the gather_interface_info() thread is fired off for each IP interface that is IFF_RUNNING or wireless. Note that some drivers will show IFF_RUNNING even if a cable is not plugged in - they do not support DL_NOTE_LINK_UP notifications. If the wired driver supports link state notifications, nothing is done with it, and the wireless scan kicks in and initiates a scan on the interface. We will be prompted with a list of wireless networks, and select one, possibly entering a WEP key if required. If connection succeeds, we generate a "newif" event, which the event handling thread uses to evaluate the best LLP given the current scenario.

If the driver does not support link state notifications, it will show IFF_RUNNING regardless of whether a cable is plugged in or not, and an attempt to start DHCP on the interface will be made. A timer is started, and we add a "newif" (new interface) event to the event queue. In response to this, the state machine gets the preferred LLP of those available (in this case the wired one), and compares it to the current LLP, and swaps if necessary, making the wired profile active. From here the Upper Layer Profile conditions are evaluated, and the appropriate ULP is activated.

I'll follow up with more details about initialization and the main event loop.

Wednesday Jun 14, 2006

OpenSolaris is 1 today. My first forays into Solaris development coincided with the release of OpenSolaris, so I've been lucky enough to benefit from the amazing resource that the OpenSolaris community is from the start. So, to everyone involved in making OpenSolaris a success, inside and especially outside Sun, a huge thank you, and here's to the future!

Monday Apr 03, 2006

proposed ON changes for quagga project

Note: this is a guide to the changes as they are today, and things may of course change - we're still a bit way from code review. The following is a guide to help people navigate the code and get up to speed on what we're trying to do. Referring to the design document will probably be helpful.

The ON changes involve a number of different components:

  1. changes to routeadm.c to support SMF services
  2. addition of ipv4(6)-routing(forwarding) SMF services
  3. addition of value/manage authorizations for routing services
  4. service conversions for in.routed, in.ripngd, in.rdisc and in.ndpd

changes to routeadm.c to support SMF services

These changes involved:

  • extending the functionality of the enable/disable (-e/-d) flags for routeadm to cover SMF services as well as the keywords ipv4-routing, ipv6-routing etc. In the former case, the named SMF service is checked to ensure if it is indeed a routing daemon service (identified by the presence of the "routing" application property group), and if so it is enabled disabled as specified immediately. If ipv4-routing/ipv6-routing etc is specified, the appropriate value is enabled/disabled in routing.conf as before. When "routeadm -u" (update) is run, these state changes are applied.
  • adding list/modify functionality for SMF routing services. In the case of "list", we check if the SMF service is a routing service (see above), and if so, list all the "routing" application properties. For modify, the user specifies a list of key=value properties (that must already exist - no routing properties can be created) along with the routing service FMRI.
  • adding the list of routing daemon services and their states to the routeadm output. Again, these are identified by presence of a "routing" application property group.
  • interacting with ipv4(6)-routing(forwarding) SMF services. When update (routeadm -u) is run, the states of the ipv4(6)-routing(forwarding) services are updated to match those specified in routing.conf. If a service is already enabled, it is restarted (to get updates to daemon arguments for example).
  • supporting upgrade. The new SMF commands will not run during upgrade, so instead they append themselves to /var/svc/profile/upgrade to be run post-upgrade. Upgrade is detected by specification of an alternate root (routeadm -R ) and by the fact that the SMF repository door is not present.

routeadm.c

addition of ipv4(6)-routing(forwarding) SMF services

These services need to set ip forwarding flags in the case of ip forwarding services, and for ip routing, they needed to support legacy behaviour. So, for routing services, they check the contents of the ipv4(6)-routing-daemon ipv4(6)-daemon-args and ipv4(6)-daemon-stop-cmd fields in routing.conf. If the contents of these are upgradeable (either to SMF versions of in.routed etc, or to quagga equivalents for zebra daemons), the fields are blanked and the appropriate SMF routing service is enabled. For quagga services, the zebra configuration files are also migrated to /etc/quagga. If the daemon invokations are not upgradeable, for enable, the appropriate daemon is invoked and it's pidfile created. For disable, the stop command is run.

forwarding.xml routing.xml

addition of value/manage authorizations for routing services

We create 2 new authorizations in connection with SMF routing services - one covers the changing of routing service states, solaris.smf.modify.routing. All routing-related services should specify this authorization in the "general" property group, to let SMF know it is needed to run the methods for that service. The other new authorization, solaris.smf.manage.routing covers changing of routing service properties (needed for "routeadm -m" to work - see above). We need to augment the network management rights profile to include these new authorizations, as routing management is a part of network management.

prof_attr.txt auth_attr.txt

Examples of converted services are below.

service conversions for in.routed, in.ripngd, in.rdisc and in.ndpd

All the above are converted to SMF. Each has to have a "routing" property group of type "application" to identify itself as a routing service. Within this, each specifies daemon_args - the arguments to run the daemon with. Since this property is within the routing property group, it is available to "routeadm -m" to modify. We ensure each service method specifies it requires the routing authorization (so the user requires this auth to update state of routing services), and that the routing property group specifies the routing value authorization (so the user requires this auth to change values).

in.ndpd conversion: ndp.xml svc-ndp

in.ripngd conversion: ripng.xml svc-ripng

in.rdisc conversion: rdisc.xml svc-rdisc

in.routed conversion: route.xml svc-route

Wednesday Oct 26, 2005

We've posted the design document for the quagga/routing management design review over at opensolaris , and are really hoping people will have comments and suggestions. I might discuss some of the rationale behind the current SMF routing management design here in depth if it would be helpful, but the basic idea was to retool routeadm(1M) to both support SMF routing services and to take advantage of the framework SMF provides in it's own architecture.

The former involved extending routeadm's syntax in an inteadm-like manner to allow enabling and disabling of SMF routing dameon services, and setting/retrieval of SMF routing daemon service properties.

The latter involved creating services to match each routeadm option (ipv4(6)-routing, ipv4(6)-forwarding) which routing daemons can depend on, and creating an overall "routing-manager" service. Creating services to match these options allows SMF routing daemons to depend on global routing/forwarding settings through SMF dependencies, and creating a routing-manager service allows routing management to be split out from the network-initial service to further parallelism during boot. More details in the pdf itself of course, and to reiterate, we really want to hear what you think.

And as is mentioned, there will also be opportunities to collaborate further down the line, if people are interested - maybe, for example, you'd like to provide an SMF manifest for in.routed. But for now, as meem points out for Clearview, you've got a chance to influence the design whether you work in Sun or not, and are seeing the design document at the same time as internal folks are.

Tuesday Apr 19, 2005

so the other day i was talking about eye movements and how visual processing is non-uniform across the visual field. it's hard to see these in action without investing in some expensive equipment, or without staring at someone else's eyes for a long time. so to save on romantic misunderstandings, check out the following demo, or this one's even more infuriating. what you notice is the grey dots at the intersections appear and disappear the whole time. what's going on? you can read about why here too, but for our purposes the demo shows two things. first, your eyes really are moving the whole time (unless you make a concerted effort not to move them of course. even then, there's a slight jitter, due to an imbalance in the antagonistic muscles controlling the eye), since the dots and dot-free zone keep shifting, and second that processing in central vision is different, since no dots appear where you're looking directly.

Thursday Apr 14, 2005

I've done a bit of vision research work (not in Sun) and still do from time to time so i might blog about this a bit.

Human Computer Interaction is a research area that's always interested me peripherally, but I'm too lazy to investigate it in any depth. I've often wondered if any of the more recent vision research work has had a big impact, I imagine so. The upshot of all of this research can be summarized pretty succinctly - vision is nothing like what you think it is (and i don't mean this smugly - vision is nothing like what i thought it was either). I might blog about this a little, but i'm no expert, so forgive me if get some details wrong. And much of this is old news, but i think it's fascinating stuff, and can bear retelling, even if badly.

Try the following experiment - hold your thumb out at arms length, and look at the size of your fingernail. That's the size of the area in your central visual field within which you do vision well. By "well" i mean you can see fine detail clearly, perceive colour etc. Outside this, these abilities fall off rapidly. Having said this your peripheral vision - what you see "with the corner of your eye" - kicks in in low light conditions, and it's good at detecting movement.

So how come it appears i can see everything in front of me perfectly? If only a small part of the visual field is processed with "high fidelity", why don't i see a blurred, black-and-white mess elsewhere? Part of the answer - you move your eyes. About 3 times a second. There are a few different types of eye movement, but the exploratory type are known as saccades, and these are rapid jumps, followed by pauses - known as fixations - where you take in information (I seem to recall that the early experiments with eye movements were done by attaching a probe to your eyeball, which along with the Stanford Prison Experiment, goes to show that the 60s was a dangerous time to participate in a psychology study). So you engage in this "jump - fixate -jump" cycle the whole time, and actively construct a picture of the world. It's kind of shocking to realise that even the serene contemplation of a painting in an art gallery involves all this frantic movement (i defy you to move any part of your body 3 times a second without attracting concerned glances).

The next question is why does the visual system opt for this approach? Well, i seem to recall that to support "high-fidelity vision" throughout the visual field, it's been calculated that you would need a brain 100 (i think?) times the size. Speaking as the owner of a rather large head as it is, i'm somewhat glad Nature compromised on this one.

So what's the point of all this for HCI? Well, if visual processing is non-uniform across the visual field (and it is), it clearly matters where you look (and where you don't). maybe i'll get to this tomorrow :-)

Hi, my name's Alan Maguire, I work in Sun out of the Dublin office. previous projects have included a smf webmin module, (see here), which allows basic management of SMF services via webmin. More details on Liane's blog and on at the Clingan zone (thanks folks!). As it stands it displays the service list (with filtering options), allowing you to view/modify service state(s) in the main window. It also provides property (group) editing facilities, just click on the FMRI in the main window and follow the link. You can also view the dependency tree for a service (it's unexpanded by default though). There's clickable links to allow you to read manpages, view logs etc too, and as Liane mentions, there's basic service creation functionality. All comments are welcome!

This blog copyright 2008 by amaguire