Archive for the ‘Linux’ Category

perl modules

Sunday, August 15th, 2010

Adderall onlineLevitra

I am a complete Perl novice.  But there are occasions when I need to install perl modules.  I have learned that

perl -MCPAN -e ‘install (module-name)’

will allow you to install a perl module from the CPAN respository.

Ruby on Rails Performance Tuning -a beginners perspective

Sunday, August 15th, 2010

Adderall onlineLevitra

So I have been developing MemoryMiner (as my introduction to Rails) for almost six months now, and performance issues are starting to become recognizable. In a desperate attempt to kill two birds with one stone, I upgraded my Linux server (bmw) to Fedora Core 5 this past weekend. It was not uneventful but I finished with MySQL 5.0.22 installed and running for my Rails apps. I also now have ruby 1.8.5 and Edge Rails.   Unfortunately, the performance is still inadequate, and while I’m perfectly willing to suffer due to limited hardware, I’m pretty sure there is some bloat that needs to be trimmed -particularly in the area of database query tuning.

The first order of business was to get a handle on where my application was spending time. The classic solution, a profiler, applies to Rails as well. I tried the built-in profiler (script/performance/profiler) but was not blown away. Then I found ruby-prof and its graph profiles. I installed the gem and added a real simple around filter in the controller to generate an HTML Graph Profile. Cool -I could exercise a method/URL in a controller and immediately (in another browser) see the results in an easy-to-digest format.

Unfortunately, I could not find a smoking gun.
References:

  1. http://ruby-prof.rubyforge.org/graph.txt
  2. http://ruby-prof.rubyforge.org/
  3. http://glu.ttono.us/articles/2006/06/23/stefen-kaes-optimizing-rails
  4. http://www.thoughtstoblog.com/articles/2006/10/24/rails-performance-tool-box
  5. http://blog.kovyrin.net/2006/08/28/ruby-performance-results/
  1. Good example of benchmarking -with useful server-vs-server results.

Why can’t stinit get the attention it deserves?

Friday, September 14th, 2007

I’ve been frustrated by tape drives for years.  They are the most finicky, unreliable, least-documented and most expensive components of most of the computer systems I have had the pleasure of administering.  I’m no longer an “up-to-date” sysadmin, but I still try to take care of my own stuff and, not surprisingly, tape drives still are the the top of my bitch list.

Today’s bitch is brought to you by stinit -a great idea that needs some love.

With stinit, you have a means of enforcing a configuration set on a device.  Since each tape drive (in the default Linux st configuration) is represented by four devices, you can easily define four different configuration modes for each drive.  Simply by using a different device (/dev/st0, /dev/st0a, /dev/st0l, /dev/st0m, for example) you can ensure your apps see the tape drive just so.

Unfortunately, stinit is weakly documented (just try the mode= syntax) and full of bugs that make tracking down simple errors costly.  Here’s the one I hit today…see if you can tell what the hell is wrong.

[Background: I have two tape drives connected to this server, one is a Compaq SuperDLT, the other an ancient Archive DDS drive for which I have no documentation]

[root@aprilia amanda]# stinit
Warning: No modes in definition for (’COMPAQ’, ‘SuperDLT1′, ”).
Can’t find defaults for tape number 1.
Initialized 1 tape device.

Hmmm…seems like I left out the modes in the definition of Compaq drive.  Let’s go to the file:


# Archive Python
manufacturer=ARCHIVE model=”Python 28388-XXX” {
        timeout=3600
}

# Compaq SuperDLT1
manufacturer=COMPAQ model=”SuperDLT1″ {
        timeout=3600
        mode1 blocksize=0
        mode2 blocksize=0
        mode3 blocksize=0
        mode4 blocksize=0
}

Puzzling.  The modes are clearly in there.  I try the stinit command again, this time with the verbose option:


[root@aprilia amanda]# stinit -v

stinit, processing tape 0
The manufacturer is ‘COMPAQ’, product is ‘SuperDLT1′, and revision ‘5F5F’.

stinit, processing tape 1
The manufacturer is ‘ARCHIVE’, product is ‘Python 28388-XXX’, and revision ‘4.45′.
Warning: No modes in definition for (’COMPAQ’, ‘SuperDLT1′, ”).
Can’t find defaults for tape number 1.
Initialized 1 tape device.

Interesting that the error message appears after stinit trys to initialize the Archive drive.  After a little googling, I find that an stinit bug was reported in the debian mailing lists (here) for the numbering of the modes.  On a hunch that the programmer couldn’t get his zero-based and one-based numbering straight for the tape drives either, I add a garbage mode for the Archive drive

# Archive Python
manufacturer=ARCHIVE model=”Python 28388-XXX” {
        timeout=3600
        mode1 blocksize=0
}

# Compaq SuperDLT1
manufacturer=COMPAQ model=”SuperDLT1″ {
        timeout=3600
        mode1 blocksize=0
        mode2 blocksize=0
        mode3 blocksize=0
        mode4 blocksize=0
}

…and ABRACADABRA, the problem goes away:

[root@aprilia amanda]# stinit
Initialized 2 tape devices.

Full Circle REST

Friday, August 3rd, 2007

viagra online
XANAXadderall onlineLevitraPuppies for sale

The support that Rails has provided for developing RESTful applications is nothing short of amazing considering it was added on long after Rails had an established URL-mapping mechanism (Routes.draw).? But I want more.? Specifically, I want my resources to have a more complete life.

Warning: I am not an expert in Rails or REST.

Background: in the current (late summer 2007) Edge Rails, RESTful resources (ActionController::Resources) are defined primarily for the purpose of creating named routes with a DSL (map.resource …).? A very important by-product of generating named routes is the helper methods available to generate routes in views and controllers.? The net result is a tidy means of generating and recognizing RESTful URIs.? A typical exploitation of these features looks like this:

  1. Define Routes per Resource
  2. Recognize Incoming Request’s Route
  3. (process request in controller)
  4. Generate view, typically with one or more links

Repeat steps 2 through 4 as required.

In step one, the Rails programmer does the hard work: modeling the resources, the interface to those resources, the mapping of resources to controllers, etc.? Rails honors our work and uses these abstract resources to recognize routes (in step two) and to help up generate routes (in step four).? But what about step three?? Can we exploit our abstract resource model here?? Let’s recast the typical methods in a controller that backs a resource:

def index
? identify resource
? manipulate resource
end

def destroy
? identify resource
? manipulate resource
end

def create
? identify resource
? manipulate resource
end

For the index action, the identified resource is a collection represented by a Class or an association.? For the destroy (and show and edit) actions, the identified resource is a member represented by an ActiveRecord model instance.? For the create (and new) actions, the resource is a new, unsaved, AR model instance.? Every controller action that handles a REST request starts with the identification of the resource.? For the following examples, let’s define some resources:

map.resources users do |user|
? user.resources groups, :controller => ‘groups’ do |group|
??? group.resources tags, :controller => ‘tags’
? end
end

map.resources groups do |group|
? group.resources users, :controller => ‘users’ do |user|
??? user.resources tags, :controller => ‘tags’
? end
end

map.resources vehicles do |vehicle|
? vehicle.resources wheels, :controller => ‘wheels’
end

map.resources unicycles do |unicycle|
? vehicle.resource wheel, :controller => ‘wheels’
end

As these resource definitions show, sometimes resource identification is trivial and sometimes it’s not…

  1. /vehicles/567/wheels
  2. /unicycle/234/wheel
  3. /users/17/groups/2/tags
  4. /groups/2/users/17/tags

In example #1, wheels is a has_many association of a vehicle instance.? It would be nice if Rails helped us find the vehicle instance and pointed us towards its has_many association.? What we get is the params hash, which indicates the vehicle instance, and the invocation of WheelsController.index, which implies the wheels collection association.? Indirect, but adequate.

In example #2, wheel is a has_one association of a unicycle instance.? Rails should help us find the vehicle instance and point us towards the association.? Much as in the first example, Rails gives us a params hash and invokes the WheelsController.show method.? Again, indirect but adequate.?

Examples one and two together illustrate the first ugly problem with resource identification:

Problem One: The arity of resources is implied by the invoked controller method instead of being explicit.

In example #3, tags is a has_many association of a Group instance.? In example #4, tags is a has_many association of a User instance.? The params hash and invoked method? are identical for these two requests.? Rails really lets us down here: short of parsing the request path, there is nothing to distinguish these two requests.

Problem Two: The hierarchy of the request’s resource chain is not preserved.

I believe these two problems stem from the outdated perception of the URL only as a means of triggering a specific controller action and providing some unordered key-value parameters.? In the RESTful world, however, the URL has become a resource specifier.? And that means hierarchy matters and parameters are not limited to key-value pairs.? In a nutshell, Rails needs to help us match a concrete request with our abstract resource model.? Until it does, identification of RESTful resources will continue to be a pain in the ass.

In the meantime, I have taken two steps to help the programmer match an abstract resource to the concrete request by providing some extra information to the controller.? First, I have made the matched route available to the controller as an attribute of the request by monkey patching ActionController::Routing::RouteSet and ActionController::AbstractRequest.? Now I can see the specific components of the request in an abstract way instead of as a string.

But once I had made that change, I realized I was getting very close to the holy grail of the actual abstract resource definition (from routes.rb) used to generate the route.? It was only a couple of more monkey patches before I had the source ActionController::Resources::Resource instance available to the controller as well.

Now in my controllers I can see which of my abstract resources (as defined in routes.rb) matches the incoming request.? That goes a long way towards getting the matching AR model instances instantiated.?

My only remaining beef is that the abstract route definitions (in routes.rb) do not store any meaningful hierarchy information.? In my example above, the subordinate collection resource beneath a group and called ‘users’ is only aware of its parent resource (a group) though a couple of strings (name_prefix and one other).? That means that even when I know the abstract resource that matches the incoming request, I can’t really see its enclosing resources with inferring them from string pattern matching.? Rails should store the parent resource for any nested resources.

Resources
??? Jamis Buck’s awesome tutorial on Rails Routing
??? Discussion of some of these issues from a different angle

Full Circle REST

Friday, August 3rd, 2007

XANAXADDERALL ONLINELevitraCialis onlinePuppies for sale

The support that Rails has provided for developing RESTful applications is nothing short of amazing considering it was added on long after Rails had an established URL-mapping mechanism (Routes.draw).? But I want more.? Specifically, I want my resources to have a more complete life.

Warning: I am not an expert in Rails or REST.

Background: in the current (late summer 2007) Edge Rails, RESTful resources (ActionController::Resources) are defined primarily for the purpose of creating named routes with a DSL (map.resource …).? A very important by-product of generating named routes is the helper methods available to generate routes in views and controllers.? The net result is a tidy means of generating and recognizing RESTful URIs.? A typical exploitation of these features looks like this:

  1. Define Routes per Resource
  2. Recognize Incoming Request’s Route
  3. (process request in controller)
  4. Generate view, typically with one or more links

Repeat steps 2 through 4 as required.

In step one, the Rails programmer does the hard work: modeling the resources, the interface to those resources, the mapping of resources to controllers, etc.? Rails honors our work and uses it to recognize routes (in step two) and to help up generate routes (in step four).? But what about step three?? Can we exploit our resource model here?? Let’s recast the typical methods in a controller that backs a resource:

def index
? identify resource
? manipulate resource
end

def destroy
? identify resource
? manipulate resource
end

def create
? identify resource
? manipulate resource
end

For the index action, the identified resource is a collection represented by a Class or an association.? For the destroy (and show and edit) actions, the identified resource is a member represented by an ActiveRecord model instance.? For the create (and new) actions, the resource is a new, unsaved, AR model instance.? Every controller action that handles a REST request starts with the identification of the resource.? For the following examples, let’s define some resources:

map.resources users do |user|
? user.resources groups, :controller => ‘groups’ do |group|
??? group.resources tags, :controller => ‘tags’
? end
end

map.resources groups do |group|
? group.resources users, :controller => ‘users’ do |user|
??? user.resources tags, :controller => ‘tags’
? end
end

map.resources vehicles do |vehicle|
? vehicle.resources wheels, :controller => ‘wheels’
end

map.resources unicycles do |unicycle|
? vehicle.resource wheel, :controller => ‘wheels’
end

As these resource definitions show, sometimes resource identification is trivial and sometimes it’s not…

  1. /vehicles/567/wheels
  2. /unicycle/234/wheel
  3. /users/17/groups/2/tags
  4. /groups/2/users/17/tags

In example #1, wheels is a has_many association of a vehicle instance.? It would be nice if Rails helped us find the vehicle instance and pointed us towards its has_many association.? What we get is the params hash, which indicates the vehicle instance, and the invocation of WheelsController.index, which implies the wheels collection association.? Indirect, but adequate.

In example #2, wheel is a has_one association of a unicycle instance.? Rails should help us find the vehicle instance and point us towards the association.? Much as in the first example, Rails gives us a params hash and invokes the WheelsController.show method.? Again, indirect but adequate.?

Examples one and two together illustrate the first ugly problem with resource identification:

Problem One: The arity of resources is implied by the invoked controller method instead of being explicit.

In example #3, tags is a has_many association of a Group instance.? In example #4, tags is a has_many association of a User instance.? The params hash and invoked method? are identical for these two requests.? Rails really lets us down here: short of parsing the request path, there is nothing to distinguish these two requests.

Problem Two: The hierarchy of the request’s resource chain is not preserved.

I believe these two problems stem from a common failing in Rails: the outdated perception of the URL as a means of triggering a specific controller action and providing some unordered key-value parameters.? In the RESTful world, however, the URL has become a resource specifier.? And that means hierarchy counts and parameters are not limited to key-value pairs.? Until Rails embraces those realities, identification of RESTful resources will continue to be a pain in the ass.

I

Resources
??? Jamis Buck’s awesome tutorial on Rails Routing
??? Discussion of some of these issues from a different angle

Full Circle REST

Thursday, August 2nd, 2007

XANAXADDERALL ONLINELevitraCialis online

The support that Rails has provided for developing RESTful applications is nothing short of amazing considering it was added on long after Rails had an established URL-mapping mechanism (Routes.draw).? But I want more.? Specifically, I want my resources to have a more complete life.

Warning: I am not an expert in Rails or REST.

Background: in the current (late summer 2007) Edge Rails, RESTful resources (ActionController::Resources) are defined primarily for the purpose of creating named routes with a DSL (map.resource …).? A very important by-product of generating named routes is the helper methods available to generate routes in views and controllers.? The net result is a tidy means of generating and recognizing RESTful URIs.? A typical exploitation of these features looks like this:

  1. Define Routes per Resource
  2. Recognize Incoming Request’s Route
  3. (process request in controller)
  4. Generate view, typically with one or more links

Repeat steps 2 through 4 as required.

In step one, the Rails programmer does the hard work: modeling the resources, the interface to those resources, the mapping of resources to controllers, etc.? Rails honors our work and uses it to recognize routes (in step two) and to help up generate routes (in step four).? But what about step three?? Can we exploit our resource model here?? Let’s recast the typical methods in a controller that backs a resource:

def index
? identify resource
? manipulate resource
end

def destroy
? identify resource
? manipulate resource
end

def create
? identify resource
? manipulate resource
end

For the index action, the identified resource is a collection represented by a Class or an association.? For the destroy (and show and edit) actions, the identified resource is a member represented by an ActiveRecord model instance.? For the create (and new) actions, the resource is a new, unsaved, AR model instance.? Every controller action that handles a REST request starts with the identification of the resource.? For the following examples, let’s define some resources:

map.resource account do |account|
? account.resource vehicle, :controller => ‘vehicles’
end

map.resources users do |user|
? user.resources groups, :controller => ‘groups’ do |group|
??? group.resources tags, :controller => ‘tags’
? end
end

map.resources groups do |group|
? group.resources users, :controller => ‘users’ do |user|
??? user.resources tags, :controller => ‘tags’
? end
end

map.resources vehicles do |vehicle|
? vehicle.resources wheels, :controller => ‘wheels’
end

map.resources unicycles do |unicycle|
? vehicle.resource wheel, :controller => ‘wheels’
end

As these resource definitions show, sometimes resource identification is trivial and sometimes it’s not…

  1. /vehicles/567/wheels
  2. /unicycle/234/wheel
  3. /users/17/groups/2/tags
  4. /groups/2/users/17/tags

In example #1, wheels is a has_many association of a vehicle instance.? It would be nice if Rails helped us find the vehicle instance and pointed us towards its has_many association.? What we get is the params hash, which indicates the vehicle instance, and the invocation of WheelsController.index, which implies the wheels collection association.? Indirect, but adequate.

In example #2, wheel is a has_one association of a unicycle instance.? Rails should help us find the vehicle instance and point us towards the association.? Much as in the first example, Rails gives us a params hash and invokes the WheelsController.show method.? Again, indirect but adequate.?

Examples one and two together illustrate the first ugly problem with resource identification:

Problem One: The arity of child resources is implied by the invoked controller method instead of being explicit.

In example #3, tags is a has_many association of a Group instance.? In example #4, tags is a has_many association of a User instance.? The params hash and invoked method? are identical for these two requests.? Rails really lets us down here: short of parsing the request path, there is nothing to distinguish these two requests.

Problem Two: The hierarchy of the request’s resource chain is not preserved.

a relationship between a parent resource (vehicle or unicycle instance
in this example) and a child resource (wheels or wheel) is not
available.? relationship of resources is .? To do so will require a
more explicit representation of the parent resource (unicycle instance
or vehicle instance) and the child resource (wheel or wheels).

Does Rails exploit our resource modelling effort to help us identify the request’s resource?? No!? Are going to take that insult lying down?? No!? We’re going to carp and bitch!? Okay, I got a bit ahead of myself…but I maintain that Rails does a poor job of helping the programmer identify the resources in

Resources
??? Jamis Buck’s awesome tutorial on Rails Routing

Full Circle REST

Wednesday, August 1st, 2007

XANAXADDERALL ONLINELevitraAdderall onlineadderall without prescriptionPhentermine onlinetramadol onlinevalium online

The support that Rails has provided for developing RESTful applications is nothing short of amazing considering it was added on long after Rails had an established URL-mapping mechanism (Routes.draw).? But I want more.? Specifically, I want my resources to have a more complete life.

Warning: I am not an expert in Rails or REST.

Background: in the current (late summer 2007) Edge Rails, RESTful resources (ActionController::Resources) are defined primarily for the purpose of creating named routes with a DSL (map.resource …).? A very important by-product of generating named routes are the helper methods available to generate routes in views and controllers.? The net result is a tidy means of generating and recognizing RESTful URIs.? A typical exploitation of these features looks like this:

  1. Define Routes per Resource
  2. Recognize Incoming Request’s Route
  3. (process request in controller)
  4. Generate view, typically with one or more links

Repeat steps 2 through 4 as required.

In step one, the Rails programmer does the hard work: modeling the resources, the interface to those resources, the mapping of resources to controllers, etc.? Rails honors our work and uses it to recognize routes (in step two) and to help up generate routes (in step four).? But what about step three?? Can we exploit our resource model here?? Let’s recast the typical methods in a controller that backs a resource:

def index
? identify resource
? manipulate resource
end

def destroy
? identify resource
? manipulate resource
end

def create
? identify resource
? manipulate resource
end

For the index action, the identified resource is a collection represented by a Class or an association.? For the destroy (and show and edit) actions, the identified resource is a member represented by an ActiveRecord model instance.? For the create (and new) actions, the resource is an unsaved AR model instance.? Every controller action that handles a REST request must start with the identification of the resource.? Sometimes the resource identification is trivial…

/vehicles/234

sometimes it’s not…

/vehicles/567/wheels
/vehicles/234/wheel
/account/vehicle

Does Rails exploit our resource modelling effort to help us identify the request’s resource?

Resources
??? Jamis Buck’s awesome tutorial on Rails Routing

Native NSIS installer builds under Linux -a HOWTO

Saturday, March 3rd, 2007

Today I decided to create a build system for NSIS under Linux. Here is how I did it.

 

Download and unzip latest NSIS source from sourceforge and the corresponding zip file with libraries and such:

 

$ mkdir nsis;cd nsis
$ wget http://prdownloads.sourceforge.net/nsis/nsis-2.24-src.tar.bz2?download
$ wget http://prdownloads.sourceforge.net/nsis/nsis-2.24.zip?download
$ unzip nsis-2.24.zip
$ bunzip2 nsis-2.24-src.tar.bz2
$ tar -xf nsis-2.24-src.tar

To build makensis, the NSIS installer generator, you need scons (a replacement for make). You may be able to install it with your platforms package manager -but I couldn’t. The Fedora Core 5 yum package for was not quite up-to-date enough (0.96.1 available via yum versus 0.96.93 required). Here is how I manually installed it:

$ mkdir scons;cd scons
$ wget http://prdownloads.sourceforge.net/scons/scons-0.96.95-1.noarch.rpm
$ sudo rpm -ivh scons-0.96.95-1.noarch.rpm

The rpm is not signed, so you can’t use the yum localinstall <package> trick.

Now use scons to build makensis (but none of the other components -we’ll be using the pre-built ones since they don’t need to run under Linux anyway):

$ cd ../nsis-2.24-src
$ scons SKIPSTUBS=all SKIPPLUGINS=all SKIPUTILS=all SKIPMISC=all NSIS_CONFIG_CONST_DATA_PATH=no

That last step should take a bit. When it finishes, you have a native Linux
version of makensis in ./build/release/makensis/makensis.

Now for the tricky part… NSIS installers are built with makensis. This output of makensis includes (in compressed form) many libraries that are used at install time. These libraries could be built as part of our build process -in fact the default scons configuration tries to do just that. But without a really good cross-compiler, we can’t do better than just taking the pre-built libraries from the same NSIS version as built for Win32. That is why we downloaded the zip file in step one. Now we need to meld the Linux version of makensis with the zip file into a coherent whole:

$ sudo scons install-compiler
$ cd ..
$ sudo unzip nsis-2.24 -d /usr/local/share
$ sudo mv /usr/local/share/nsis-2.24/ /usr/local/share/nsis

The first step puts makensis into the right location (/usr/local/bin on my system). The remaining steps put the contents of the zip file in a standard location where its libraries can be found by makensis.  Done!

 

NB: Ideally, you should be able to install the makensis executable and support libraries/configs from the zip to appropriate locations on the Linux filesystem using scons install, but this is not possible. Admittedly, that is asking a lot given that the manual process shown above is so simple. Still, it is ironic that a program whose sole focus is installers has a relatively limited installer itself (under Linux only). I posted on this subject on the Nullsoft forum. Kudos to kichik over there for confirming the problem as well as helping me get through this last step. Not to mention posting other stuff on the forum that got me through the first steps as well.

Regardless, it is amazing that the whole thing works under Linux. My build system is now completely hands off (tied into subversion via CruiseControl.rb). All I do is check in a new revision, and a couple of minutes later I have a new installer that is automatically put into the ftp repository.

Benchmarking Rails

Wednesday, January 10th, 2007

I decided to take a detour and look at benchmarking my Rails application. Some background: I am running on a Compaq Proliant 3000 2×550 Pentium III Xeon with 2GB of RAM and a RAID 5 array using the old-style (white) Compaq drives. Software is Fedora Core 5 (Linux kernel 2.6.18-1.2200.fc5smp) with Apache 2.2.2 balancing across a mongrel cluster (v0.2.1) of two mongrel servers (v0.13.4). I am running on Edge Rails (r5875), and the database is MySQL 5.0.27.

To start, I used standard apache benchmark tools to get a feel for performance:

# ab -n 100 -C _MemoryMiner=b2b53b4c3141af2ed7e871291f9959f8 http://bmw.hapgoods.com/login

# ab -n 100 -C _MemoryMiner=b2b53b4c3141af2ed7e871291f9959f8 http://bmw.hapgoods.com/people/b7a2d7c0-4b49-11db-bf36-0011855ee3ff

# ab -n 100 -C _MemoryMiner=b2b53b4c3141af2ed7e871291f9959f8 http://bmw.hapgoods.com/places

Note that I am providing a session cookie to ensure that the expensive authentication methods are not run. To test the authentication code, I use this:

# ab -n 100 -A alice:XXX http://bmw.hapgoods.com/places

To get the cookie, you can either cheat (use the Rails console, look in the session store or examine the log files) or you can build a session dynamically with wget and get the session key:

# wget –save-cookies cookies.txt –keep-session-cookies -O /dev/null –post-data ‘user[login]=alice&user[password]=XXX’ http://bmw.hapgoods.com/sessions

Results from the testing show that even a simple (no DB access) GET request like the first one in the list above takes about 100ms. During the benchmarking run the CPU on the server is pegged at nearly 100% running the ruby process; this respresents the Rails overhead for instantiating a controller instance and rendering a simple view. Pretty disappointing. Interestingly, Rails log file shows the request being processed in about 35ms. Why the big discrepancy?

Moving to more complex requests like the second one show that mysql quickly gets hit hard. The response time jumps up to nearly 1700ms and mysqld starts to claim a substantial chunk of CPU. Based on the SQL query info in the Rails log file, I presume my authorization-enabled finds (using nasty joins) are the likely culprit.

Doubling the concurrency from one to two (-c 2) almost doubles the response time. Conclusion -few resources are available to service extra queries.

Next Step: Rails Benchmarking.

ip_conntrack_amanda on Fedora Core

Monday, November 20th, 2006

After working with my NFS server and successfully getting it to work nicely with iptables, I disabled an overly-permissive hole in the firewall of my NFS server -which is also my tape host for amanda. It turns out that amanda was also relying on that hole to backup networked clients. Instead of just opening the hole back up, I experimented a bit. What I found is not good.

First, some background. I have ports 10082 and 10083 opened on the server to support amrecover operation. On the clients, I have 10080 opened to allow the incoming backup requests to connect.

The ip_conntrack_amanda kernel module is supposed to allow the backup daemon running on the client (amandad) to establish a new TCP connection back to the server by marking the incoming packets as RELATED. It is apparently failing:

amandad: debug 1 pid 29550 ruid 33 euid 33: start at Mon Nov 20 09:05:11 2006
amandad: version 2.4.5p1
amandad: build: VERSION=”Amanda-2.4.5p1″
amandad: BUILT_DATE=”Fri Feb 10 21:44:52 EST 2006″
amandad: BUILT_MACH=”Linux hs20-bc1-6.build.redhat.com 2.6.9-22.18.bz155725.ELsmp #1 SMP Thu Nov 17 15:34:08 EST 2005 i686 i686 i386 GNU/Linux”
amandad: CC=”i386-redhat-linux-gcc”
amandad: CONFIGURE_COMMAND=”‘./configure’ ‘–build=i386-redhat-linux’ ‘–host=i386-redhat-linux’ ‘–target=i386-redhat-linux-gnu’ ‘–program-prefix=’ ‘–prefix=/usr’ ‘–exec-prefix=/usr’ ‘–bindir=/usr/bin’ ‘–sbindir=/usr/sbin’ ‘–sysconfdir=/etc’ ‘–datadir=/usr/share’ ‘–includedir=/usr/include’ ‘–libdir=/usr/lib’ ‘–libexecdir=/usr/lib/amanda’ ‘–localstatedir=/var/lib’ ‘–sharedstatedir=/usr/com’ ‘–mandir=/usr/share/man’ ‘–infodir=/usr/share/info’ ‘–enable-shared’ ‘–disable-dependency-tracking’ ‘–with-index-server=localhost’ ‘–with-tape-server=localhost’ ‘–with-config=DailySet1′ ‘–with-gnutar-listdir=/var/lib/amanda/gnutar-lists’ ‘–with-smbclient=/usr/bin/smbclient’ ‘–with-amandahosts’ ‘–with-user=amanda’ ‘–with-group=disk’ ‘–with-tmpdir=/var/log/amanda’ ‘–with-gnutar=/bin/tar’”
amandad: paths: bindir=”/usr/bin” sbindir=”/usr/sbin”
amandad: libexecdir=”/usr/lib/amanda” mandir=”/usr/share/man”
amandad: AMANDA_TMPDIR=”/var/log/amanda”
amandad: AMANDA_DBGDIR=”/var/log/amanda” CONFIG_DIR=”/etc/amanda”
amandad: DEV_PREFIX=”/dev/” RDEV_PREFIX=”/dev/r”
amandad: DUMP=”/sbin/dump” RESTORE=”/sbin/restore” VDUMP=UNDEF
amandad: VRESTORE=UNDEF XFSDUMP=UNDEF XFSRESTORE=UNDEF VXDUMP=UNDEF
amandad: VXRESTORE=UNDEF SAMBA_CLIENT=”/usr/bin/smbclient”
amandad: GNUTAR=”/bin/tar” COMPRESS_PATH=”/usr/bin/gzip”
amandad: UNCOMPRESS_PATH=”/usr/bin/gzip” LPRCMD=”/usr/bin/lpr”
amandad: MAILER=”/usr/bin/Mail”
amandad: listed_incr_dir=”/var/lib/amanda/gnutar-lists”
amandad: defs: DEFAULT_SERVER=”localhost” DEFAULT_CONFIG=”DailySet1″
amandad: DEFAULT_TAPE_SERVER=”localhost”
amandad: DEFAULT_TAPE_DEVICE=”/dev/null” HAVE_MMAP HAVE_SYSVSHM
amandad: LOCKING=POSIX_FCNTL SETPGRP_VOID DEBUG_CODE
amandad: AMANDA_DEBUG_DAYS=4 BSD_SECURITY USE_AMANDAHOSTS
amandad: CLIENT_LOGIN=”amanda” FORCE_USERID HAVE_GZIP
amandad: COMPRESS_SUFFIX=”.gz” COMPRESS_FAST_OPT=”–fast”
amandad: COMPRESS_BEST_OPT=”–best” UNCOMPRESS_OPT=”-dc”
amandad: time 0.001: got packet:
——–
Amanda 2.4 REQ HANDLE 000-30510709 SEQ 1164031511
SECURITY USER amanda
SERVICE noop
OPTIONS features=fffffeff9ffe7f;
——–

amandad: time 0.001: sending ack:
—-
Amanda 2.4 ACK HANDLE 000-30510709 SEQ 1164031511
—-

amandad: time 0.006: bsd security: remote host triumph.hapgoods.com user amanda local user amanda
amandad: time 0.007: amandahosts security check passed
amandad: time 0.007: running service “noop”
amandad: time 0.008: sending REP packet:
—-
Amanda 2.4 REP HANDLE 000-30510709 SEQ 1164031511
OPTIONS features=fffffeff9ffe7f;
—-

amandad: time 9.979: got packet:
—-
Amanda 2.4 REQ HANDLE 000-30510709 SEQ 1164031511
SECURITY USER amanda
SERVICE noop
OPTIONS features=fffffeff9ffe7f;
—-

amandad: time 9.979: it is not an ack
amandad: time 9.979: sending REP packet:
—-
Amanda 2.4 REP HANDLE 000-30510709 SEQ 1164031511
OPTIONS features=fffffeff9ffe7f;
—-

amandad: time 19.979: got packet:
—-
Amanda 2.4 REQ HANDLE 000-30510709 SEQ 1164031511
SECURITY USER amanda
SERVICE noop
OPTIONS features=fffffeff9ffe7f;
—-

amandad: time 19.979: it is not an ack
amandad: time 19.979: sending REP packet:
—-
Amanda 2.4 REP HANDLE 000-30510709 SEQ 1164031511
OPTIONS features=fffffeff9ffe7f;
—-

amandad: time 29.976: dgram_recv: timeout after 10 seconds
amandad: time 29.976: waiting for ack: timeout, retrying
amandad: time 39.977: dgram_recv: timeout after 10 seconds
amandad: time 39.977: waiting for ack: timeout, retrying
amandad: time 49.978: dgram_recv: timeout after 10 seconds
amandad: time 49.978: waiting for ack: timeout, retrying
amandad: time 59.980: dgram_recv: timeout after 10 seconds
amandad: time 59.980: waiting for ack: timeout, retrying
amandad: time 69.979: dgram_recv: timeout after 10 seconds
amandad: time 69.979: waiting for ack: timeout, giving up!
amandad: time 69.979: pid 29550 finish time Mon Nov 20 09:06:21 2006

On the client, the incoming request correctly spawns an amandad client who immediately attempts to respond to the incoming packet (@0.008). The client sends the response multiple times, but eventually gives up (@69.979).

On the server, the amcheck program logs this:

amcheck: debug 1 pid 5211 ruid 33 euid 0: start at Mon Nov 20 09:05:11 2006
amcheck: dgram_bind: socket bound to 0.0.0.0.626
amcheck: pid 5211 finish time Mon Nov 20 09:05:41 2006

Note how amcheck has bound to port 626 for incoming responses. Now the smoking gun, the iptables log on the tape server:

Nov 20 09:05:11 triumph kernel: Refused local request: IN=eth0 OUT= MAC=00:50:8b:64:23:37:00:08:c7:cf:32:df:08:00 xsrc=192.168.1.12 DST=192.168.1.30 LEN=78 TOS=0×00 PREC=0×00 TTL=64 ID=0 DF PROTO=UDP SPT=10080 DPT=626 LEN=58
Nov 20 09:05:11 triumph kernel: Refused local request: IN=eth0 OUT= MAC=00:50:8b:64:23:37:00:08:c7:cf:32:df:08:00 xsrc=192.168.1.12 DST=192.168.1.30 LEN=111 TOS=0×00 PREC=0×00 TTL=64 ID=0 DF PROTO=UDP SPT=10080 DPT=626 LEN=91

The firewall has blocked these response packets, despite ip_conntrack_iptables being loaded. I am correctly allowing RELATED packets through the firewall, but It Just Doesn’t Work. I gave up and opened the hole back up.