Friday Feb 15, 2008

We just integrated the CIFS client (Phase 1) into Nevada for build 84. It feels great to see this finally happen. Sun processes require that a project team "jump through many hoops" before integration, all to ensure a high-quality delivery, avoid legal exposure, etc. etc. etc. but finally, we've arrived at the finish line for phase 1. This was possible thanks to hard work by many people, and cooperation from many more. Thanks, everyone.

Another key to getting this done was management support for defending against the inevitable requests for things that could lead to feature creep. It was a tough judgement call sometimes, but the guiding principle we followed for Phase 1 was: "Just get the essential features working first." Of course, opinions vary on what is "essential", but I hope we got it about right.

The features we defined as "essential" included basically: whatever it takes to allow access to CIFS shares with Unix commands: mount, cp, mv, mkdir, rmdir, ...

Some features we called non-essential were slightly controversial. For example, mmap(2) support (for mapped-file access) is required for running programs on an "smbfs" mount, and for opening files in many Gnome applications. Another is automatic reconnect, which would let a mount continue to work after a server disconnect. While users might wish for these features now, the CIFS client is quite usable without them, and provides more than what we had before. I hope we'll be able to add some of these desirable features soon. Help from the OpenSolaris community is welcome!

If you'd like to help with follow-on work on the CIFS client, please see the CIFS Client Project page for suggestions on how you might get involved.

Thanks, Gordon Ross

Wednesday Nov 14, 2007

It's such a relief to reach our "functionality complete" milestone. We've all been working very hard on this project - long hours.

Personally, I've been struggling for a long time to come up with a reasonable approach for making our smbfs/netsmb code thread-safe. If we were starting from scratch, I would be temped to just use one big "perimeter" lock, but the NFS code we started with already had a fairly sophisticated locking design that I didn't want to rip out. Then the "netsmb" code (the part we took from Darwin) had some locking code but was apparently not designed for a fully preemptive kernel.

For the NFS-derived "smbfs" code, I basically just extended the NFS design a little so we would serialize state changes to (shared) file handles, directory search handles, etc.

The "netsmb" code was harder. After a couple attempts at this, I settled on a fairly typical locking hierarchy that follows the data structures in this module: globals, virtual circuits (VC), share connections. The main complication here is that "tear down" can be initiated from any level in this hierarchy, i.e. smbfs umount drops a share connection, or a VC may be closed when the server drops our connection. In all cases, we have to track reference counts and "prune" the tree of data structures for elements that lose their last reference. Of course, when the last reference on a share goes away, it may in turn cause the last reference on a VC to go away. All of this has to be implemented while taking locks in a well-defined order (top to bottom) and preventing concurrent activity from trying to use objects that are in the process of being torn down. (That last bit is the hard part:)

One "invention" I'm proud of in this work is the idea to use a "two phase" destruction approach. The first stage marks an object as "going away", which prevents any new references. Once an object is so marked, we can drop its lock if needed to satisfy lock ordering rules (i.e. when we want to go decrement the parent reference count). The second stage actually destroys the object, but only happens after all the references go away. The first stage destroy also causes termination of any backing state, i.e. the tree connect for a share object, or the connection for a VC object. The clever part of this was the realization that we could have a generic "kill" function for these objects that forces the first stage destruction to happen before all the references are gone. We use this for things like zone shutdown. The result is that we can reliably initiate tear-down, and as long as reference counts are honest, we don't have dangling references to destroyed objects.

One case where reference counts were not "honest" was the "IOD thread". In the Darwin code, the IOD thread was started and stopped synchronously with creation/destruction of a VC object. We found it difficult to force termination of the IOD thread (due to limitations on the type of kernel thread we use). The solution we used is to let the IOD thread terminate when it finds that it's connection has closed, or when it discovers (after receiving nothing for a while) that it holds the last reference on the VC. Forced shutdown of a VC ("kill") just closes the connection, and the IOD thread notices the local close and terminates. This makes VC release cleanup asynchronous!

It's a lot of work to get thread-safe locking in place, and hard to be sure you've got things 100% covered. There are lots of asserts in there now about locking conditions. We hit a few during initial tests, but it looks pretty good now. I really hope people will download the beta and beat on it to help us find whatever we might have missed.

Enjoy!

Wednesday Apr 11, 2007

I'm "Mr. Mom" this week, with my wife out of town.

My wife is a very good cook. I enjoy her creations, and our boys (2 & 4 yrs) will usually eat what she prepares. I don't mind cooking, but I mostly keep to the basics, and I sometimes take shortcuts with the recipes.

My wife, knowing my cooking style, and fearing that our kids would go hungry while she's away was careful to leave out some recipes, and even shopped for the week. Monday night was Sauteed Chicken with Lemon and Capers.

It started out OK. Heat some olive oil in the skillet, add some cloves of garlic... Didn't see those, so I just threw in a generous spoonful of chopped garlic from the big jar I found in the fridge. Interrupted then by the boys who needed some "guidance"... Then... What's that smell? Oh yeah, the garlic, now somewhat dark brown. Guess the pan was turned up a little too high. Oh well, looks OK to me, so I start to throw in the chicken, realizing then that's it's not quite thawed. OK, so I put 'em in the microwave for a bit (They're thawed when the plastic bags explode, right?) then into the pan with the burned garlic.

After another interruption from the boys, I return to flip the now slightly "blackened" chicken, and look for the lemon and capers. Didn't find capers or lemons, but found one of those little plastic lemon-shaped bottles of lemon juice, way in the back of the fridge. It looked old, but lemon juice doesn't go bad, does it? Squirted some in. Set the table, came back, and decreed the chicken "done".

The boys gave their plates very suspicious looks and turned up their noses. "I want mac-n-cheese!" they announce. "No, it's this or nothing." I respond, not wanting to encourage picky eating. The four yr. old ate a little of his chicken, carefully peeling off the dark parts, and lots of rice. The two yr. old did not touch the chicken, and hardly ate any of the rice, which had unfortunately come into contact with the highly suspect chicken. The broccoli disappeared, but was later found (all of it) on the floor.

So there I was, relaxing after cleaning up the mess in the kitchen, and I see the 2 yr. old wander past me, gnawing on a big hunk of stale looking bread. "Huh?" I wonder, where did he get that? Then I see the kitchen garbage pail open... "Oh, yuck!" I realize, that's the stale bread I threw out at breakfast time, long before the coffee grounds, banana peels, chicken wrappers, and who knows what else had been thrown in on top. Ashamed for being such a big meanie, I took the bread away from him and gave him a clean piece.

So to the point of this story: It's now clear that my youngest would rather eat garbage than my cooking! They really miss their mother... and her cooking.

This blog copyright 2008 by gwr