You are viewing a read-only archive of the Blogs.Harvard network. Learn more.

~ Archive for rlucasStories ~

Migrating to new rlucas.net domain for most blogging

1

Gentle reader,

This server has gotten so slow,
probably thanks to Philip’s blog, that
I have finally decided to put up my own server elsewhere.  Other
reasons are:

  • I can’t use vim here to edit my entries.
  • I hate the HTML munging that this blog software uses.
  • Despite
    the PageRank boost of the .harvard.edu domain, I have decided to opt
    for the branding aspect of my long-time username, rlucas, which has
    been the local part of my Internet email address since 1993 or
    so.

And so, I am putting on hold this, my
Berkman blog.  I do intend to keep using it for Harvard-specific
things, on occasion, but my technical notes and, newly, my startup and
VC related dispatches, will be found from now on at my rlucas.net blog.

Migrating to new rlucas.net domain for most blogging …

[FIX] Perl DBI / DBD::Pg bind values rely on Perl’s automatic numeric/string scalar conversion

ø

Scenario: you are using DBD::Pg to interface with your database (perhaps directly through DBI, or through an abstraction layer like Class::DBI or DBIx::ContextualFetch) when you get an odd result:

DBD::Pg::st execute failed: ERROR: parser: parse error at or near [your string, or the part of your string that doesn’t begin with leading digits] at …

or

DBD::Pg::db selectrow_array failed: ERROR: Attribute “yourstring” not found at …

If you look at the PostgreSQL query log, you’ll see that “yourstring” was not properly quoted as a literal in the SQL delivered to the parser.

Since you’ve either been relying upon your abstraction layer or personally doing the Right Thing and binding your values with the “WHERE thing=? AND otherthing=?” syntax, you’re quite confused — this should all be quoted.

The problem is that Perl has flagged that scalar as a numeric value, possibly because you used a numeric operator on it (like > or == instead of gt or eq). The solution is to upgrade to DBD::Pg 1.32 or to explicitly stringify your string as “$yourstring”.

Below is the bug filed with CPAN.

Mac OS X 10.2, Perl 5.6.0, DBD::Pg 1.22, DBI 1.45

Bind values appear to rely upon Perl’s automatic numeric/string scalar conversion in order to determine whether or not to quote.

This bug was discussed on
http://aspn.activestate.com/ASPN/Mail/Message/perl-DBI-dev/1607287

my $dbh = DBI->connect(…); #connect to Postgres; no errors with SQLite
my $scalar = “abc”;
warn “scalar is greater than zero (and now considered numeric)” if $scalar > 0;
warn “dbh->quote(scalar) works ok: ” . $dbh->quote($scalar);
warn “but bind values do not:” . $dbh->selectrow_array(
“SELECT 1 WHERE 1=?”,
undef,
($scalar)
);

Using a numeric operator on the scalar makes Perl auto-convert it to a number; this is interpreted by the magic in Pg.xs as rendering the scalar ineligible for quoting.

One solution is to bind those variables that must be text but might have been numberified with “$varname”, thereby stringifying them in the eyes of Perl.

[FIX] Perl DBI / DBD::Pg bind values rely on Perl’s automatic numeric/string scalar conversion …

[FIX] Apache/OpenSSL won’t talk to some browsers, with SSL3_GET_CLIENT_HELLO:no shared cipher

ø

If you are finding that some browsers are talking to your new Apache/OpenSSL install,
while some are pulling a total blank (looks like a connection refused
or server not found), and you are getting this error:

OpenSSL: error:1408A0C1:SSL routines:SSL3_GET_CLIENT_HELLO:no shared cipher [Hint: Too restrictive SSLCipherSuite or using DSA server certificate?]


then heed the warning.  You are likely using the DSA server
certificate that comes with some fresh installs.  Check your cert
directories:

ls -l /etc/httpd/conf/ssl.crt
ls -l /etc/httpd/conf/ssl.key

Do you see that your server.crt (or whatever your httpd.conf defines as
your cert) and your server.key (or whatever is your key) are symbolic
links to the default “snakeoil” certs?

server.crt -> snakeoil-dsa.crt
server.key -> snakeoil-dsa.key



Ok, then you might have better luck in using the RSA versions, which play nice with more browsers:

mv server.crt server.crt.orig
ln -s snakeoil-rsa.crt server.crt

mv server.key server.key.orig

ln -s snakeoil-rsa.key server.key

apachectl stop && apachectl start



(Remembering that with Apache, when playing with SSL stuff, do a full stop and start upon making changes — a HUP won’t cut it)


As per all recommendations, do away with the snakeoil stuff ASAP and certainly before putting anything up on a public network.


CAVEAT: Do not use this advice for production.  This advice should
only be used for your own dev or testing, in order to get a fresh
install at least nominally working.  If you want real SSL and
can’t figure it out, pay someone, because your security is worth it.

Concentrating in History and Science at Harvard

1

Having had a not entirely satisfactory experience in the History and Science department at Harvard, I have been making notes ever since on how things might have been improved, and on things I wish I’d known before starting out.

Prospective concentrators in the department of History of Science at Harvard may want to check my notes, linked below:

http://blogs.law.harvard.edu/rlucas/history_and_science_at_harvard

These notes are not intended to be universally applicable — caveat lector — but would help someone like me who was considering, or struggling with, a concentration in History and Science.

Concentrating in History and Science at Harvard …

[SANITY CHECK] Apache 2 hangs with lots of STDERR output from CGI

1

You are not crazy. It is not an infinite recursion in your logic. Your code doesn’t take that long to execute.

If
you output to STDERR (in Perl, this means Carp or warn or the venerable
print STDERR among others) from a CGI script under Apache 2.0, and you
end up dumping more than approximately 4k (note that if you are using
“warn” or “Carp” you may have extra stuff on there so that you only
output 3k or so but the extras bring it up to 4k), Apache 2 will hang
forever (as of today, 30 March 2004).

See this bug report: http://nagoya.apache.org/bugzilla/show_bug.cgi?id=22030

There are some patches proposed in the link above on the Apache project bugzilla, but they are not production releases.

In
case you were wondering,
http://blogs.law.harvard.edu/rlucas/2003/08/26#a13 shows some helpful
hints on how you can back down to version 1.3.

Question to all:
what are folks’ recommendations for an Apache 1.3 packaged install? I
would tend to prefer statically linked with SSL and mod_perl, but the
only one I’ve seen folks using is from n0i.net which isn’t entirely
satisfying because I don’t speak Romanian.

Update: Using Apachetoolbox
(see Google), you can fairly simply compile apache 1.3 + mod_ssl + mod_perl
+ php and whatever 3rd party modules you like.  This makes for a fine alternative to RPM
versioning hell, or even to traipsing around your src tree typing make.  Be sure that if you do this, you specify
mod_perl 1.29 rather than 1.99, if you compile mod_perl in.

[SANITY CHECK] Apache 2 hangs with lots of STDERR output from CGI …

[FIX] XFree86 stuck at 640 x 480 under Linux with Dell Dimension or Optiplex

ø

With a fresh install of Red Hat 9 on a Dell Dimension 4600, the only video mode that would work with XFree86 was 640 x 480, which is ludicrously big on a decent-sized monitor.  Changing the config didn’t do anything, even though the config was well within my monitor’s limits.


The solution was to go into the BIOS setup and change the Integrated Devices (LegacySelect Options) / Onboard Video Buffer setting from 1 MB to 8 MB.  I’m not sure what the tradeoff with other aspects of the system is, but X nicely starts up at 1280 x 1024.  Apparently, this is the solution for other Dell models as well, including the Optiplex GX260; mine had Dell BIOS Revision A08.  Also, it seems to be the case that the problem is general to XFree86, although it manifested for me under Red Hat 9.


Thanks to Erick Tonnel at Dell, who kindly provided the solution here:


http://lists.ze-linux.org/2004-02/msg00154.html


 

FIX: Can’t locate object method “select_val” via package “DBI::st” under Class::DBI 0.95

ø

[warning: see updates below]


Between Class::DBI 0.94 and 0.95, something changed causing my classes that override db_Main() to set the db connection (instead of, e.g. using set_db) to stop working.  Specifically, when their sequence functions were invoked, I got an error of:


 


Can’t locate object method “select_val” via package “DBI::st” (perhaps you forgot to load “DBI::st”?) at /usr/lib/perl5/site_perl/5.6.1/Class/DBI.pm line …


 


I was able to replicate this on Mac OS X 10.2 with Perl 5.6.0 and Red Hat 9 with 5.6.1 (don’t ask about the latter version magic…).


 


If you get select_val errors with Class::DBI 0.95, here are two workarounds:


 



 


I am not sure why this is (comments are welcome) and have submitted a bug to the developers as CPAN #5522.


Update: Thanks to Tony Bowden, maintainer of Class::DBI, for his reply:


 



Full context and any attached attachments can be found at:
http://rt.cpan.org/NoAuth/Bug.html?id=5522 >


On Mon, Mar 01, 2004 at 06:42:38PM -0500, Guest via RT wrote:
> In Class::DBI 0.95, setting up the DB connection by overriding db_Main
> breaks Ima::DBI->select_val and the methods that rely on it (like sequence
> and count_all)


You need to call Ima::DBI->connect rather than DBI->connect in your
overriden db_Main.


Tony


 


Still not certain, though, why it is that it breaks in 0.95 and not 0.94.


Update: Thanks again to Tony, who writes:



The reason this broke in going from 0.94 to 0.95, btw, is that the
select_val stuff was only added to Ima::DBI recently, so Class::DBI .94
didn’t use these, but instead rolled its own long winded versions.


0.95 uses the new methods in Ima::DBI and is a lot better off for it! 🙂


Tony


Update 23 April 2004: Things are all wacky now.  You should be careful and should probably NOT do any of the above.  See the 06 April 2004 exchanges on the CDBI mailing list.  If you do what is described above you stand to get reconnections that will mess up things like auto_increments in MySQL.  At present the issue of how to deal with db_Main() seems unresolved.

FIX: GIMP can’t open PostScript (PS, EPS, PDF) files under Windows

1

The GIMP (GNU Image Manipulation Program) is a neat tool for people with needs too casual or cheap for PhotoShop, but too much for various paintbrush type tools.


However, if you install the GIMP under Windows 2000, like me, EPS or PS PostScript files will not open properly, instead barfing with:


Error opening file: C:\\temp\\myfile.eps


PS: Can’t interprete file [sic]


You’ll need to do the following to make it work:


1. Install GhostScript for Windows.


http://www.cs.wisc.edu/~ghost/doc/AFPL/get811.htm


2. Install the GIMP.


http://www2.arnes.si/~sopjsimo/gimp/


3. Set your environment variables to include:


GS_PROG=c:\\path\\to\\and\\filename.exe


GS_LIB=c:\\just\\the\\path\\lib


Typical paths in which to find your GS stuff after a default install might be C:\\gs\\gs8.11\\bin\\gswin32c.exe and C:\\gs\\gs8.11\\lib


(One way to get your environment set in Windows is Start: Settings:Control Panel:System:Advanced:Environment Variables.  In non-NT versions you might need to change AUTOEXEC.BAT to include SET directives)


4. Restart the GIMP and you should be up and running.

FIX: GIMP can’t open PostScript (PS, EPS, PDF) files under Windows …

FIX: Suppress Perl “uninitialized value” warnings (strongish medicine for clueful users only)

ø

If you have written any Perl of moderate complexity, and especially if your Perl of moderate complexity has included CGI and Database interactions, (or any time you have to deal with undef or NULL vs. a blank string, and you might have either of the two), you have run across warnings like this (maybe to STDERR, or maybe in your /etc/httpd/logs/error_log):


Use of uninitialized value in concatenation (.) or string at …


Use of uninitialized value in numeric gt (>) at …


etc.  How can you stop these error messages (warnings, really) from blocking up your logs and your STDERR?


In fact, you should be somewhat concerned at your uninitialized value warnings.  After all, they are there for a reason.  A really good piece of code ought not to generate them, at least in theory.  However, sometimes you want the benefit of use strict and -w warnings, and you have at once good reason not to want to know about uninitialized values.  What might these be?



  • You are doing string interpolation into something where undef and “” are equivalent for your purposes (most web page work)
  • You are doing some conditionals or string comparisons based upon data that come in from one crufty source or another, like CGI, and you don’t want to make a separate case for undef and “”.
  • Relative quick-and-dirtiness where you want at least use strict in order to prevent egregious code but you don’t need to hear about the semantic difference between undefined and the emtpy string.

In these cases, if you are using Perl 5.6+, you are in luck.  You can carefully wrap the specific section of code that has a good reason for not caring about undef values in a block (curly braces) and write:


{
no warnings ‘uninitialized’;
if ( CGI::param(‘name’) ) {
print “Hello, ” . CGI::param(‘name’);
}
else {
print “Hi there.”;
}
}

INFO: What happens to ssh every 2:11:15?

ø

I was getting a weird artifact in my logs.  A daemon process that was in charge of keeping an ssh connection open to a remote host was restarting ssh every two hours eleven minutes:


myuser 15208 0.0 0.0 0 0 Z 02:01 0:00 [ssh
myuser 15511 0.0 0.0 0 0 Z 04:12 0:00 [ssh
myuser 15548 0.0 0.0 0 0 Z 06:24 0:00 [ssh
myuser 15584 0.0 0.0 0 0 Z 08:35 0:00 [ssh
myuser 15619 0.0 0.3 3408 1704 S 10:46 0:00 ssh -T myhost …


What the heck is going on? I was running this from behind a DSL modem, and I had experienced some intermittent problems with it before. Was it the modem? Googling on the model # indicated nothing similar reported by others. Was it my ISP or Telco? Phone calls to them indicated that 2 hours was the median time between dropped connections for some old modems, but not mine and not my circuit type. Hmm. Many people pointed to the TCP KeepAlive default of 7200 seconds — two hours — but my problem had a period of over two hours. Almost exactly, consistently, two hours eleven minutes.


As it turns out, the TCP KeepAlive time of 7200 seconds plus the default KeepAlive probe interval (75) times the default probe count (9) add up to 2:11:15.


If you want to change this for one reason or another, try:


echo “30” > /proc/sys/net/ipv4/tcp_keepalive_time


… or likewise (remember that you’ll still have 11:15 worth of probe * count; lower those too if you need to know sooner). Better yet, read http://av.stanford.edu/books/tcpip/tcp_keep.htm for some actual theory on the subject.


One good use for this information is if you want to keep a persistent connection open between two machines using, e.g., Net::SSH::sshopen2 for a bidirectional remote connection to a process executed on a remote machine, but you’re on a kind of flaky connection that can cause the connection to get dropped often but briefly, and the nature of the stuff you’re doing is such that you want it to re-connect and try again rather than obliviously sit through the blip.


(The reason I ramble so lengthily on what particularly one might use this for is because you do NOT want to follow these directions if you’re having a more common “momentarily flaky” connection sequela, such as you have terminal sessions that you wish to keep open despite a moment of flakiness — in that case, you do NOT want to enable short TCP keepalives, since they are really “detect deads,” and they will increase the likelihood that your blip in the connection will kill your terminal session.  In that case, you pretty much want to do the OPPPOSITE of this, excepting that 1. if you are behind a NAT router and your connection isn’t actually flaky, you might really be seeing a timeout of the NAT table, not connection flakeage, and so you DO want to put a keepalive in shorter than the NAT table timeout [it’s all a bit much, isn’t it?] 2. you are probably best off just using “screen” and doing a screen -r to reconnect to an old screen when you get reconnected [screen is awesome for all sorts of reasons, and wth screen, if you can divorce yourself from the graphical burden, you’ve essentially got a total multitasking virtual desktop with persistent state as long as you’ve got a vt100 terminal].)


The way I would recommend would be the following:


1. Set up your local ssh_config to make sure you’re using KeepAlive yes.


2. Set up your local tcp settings to have a short keepalive time and probe interval/count.  (Some kernels apparently don’t behave with less than 90 seconds as the keepalive time but I have had success with much lower numbers.)


3. Set up your remote sshd_config to use the ClientAliveInterval and ClientAliveCountMax with reasonable values.  What this does is sort of a reverse and in-band version of what the TCP keepalive is doing on the local machine; the ssh daemon will send an encrypted signal across every ClientAliveInterval seconds and will hang up the connection if it misses CountMax of them in a row; this makes sure that the process you run on the remote machine gets hung up OK.


4. Make sure that your sshopen2 call and the sending and receiving of things along it recognizes when the SSH connection gets closed out and deals with it, such as by an eval loop and a reconnection in the event of $@ .


 

INFO: What happens to ssh every 2:11:15? …