Friday, October 30, 2009

Determining 64-bitness of your CPU

It looks like /proc/cpuinfo isn't the only way to find out whether your CPU is 64bit capable. In an effort to determine the most reliable way to find out this information I came across this page. A quick summary:

If you see any output from the following command, you're running a 64-bit capable CPU.
grep ^flags /proc/cpuinfo | grep ' lm '
The following command, if it exists on your system, will tell you the width of your physical and logical CPUs:
lshw -C cpu | grep width
The lshw command is available natively on my Ubuntu 9.04 system and is available from rpmforge.org for RHEL5 and CentOS5 systems.

Friday, October 9, 2009

More Fun with PostgreSQL Date/Time

I got a number of comments from sasha2048 about the modulo, division and remainder operators for the interval data types in a previous blog entry. After playing with all the suggestions I figured it would be best to devote another blog post to the revised code for the functions and operators. The main quibble sasha2048 had with the functions was their precision - they were only good for intervals expressed in seconds and weren't able to handle more precise intervals e.g. in the millisecond range. Here, then, are the updated functions that have the following features:

  1. The concept of a modulo operator for double precision numbers where a % b = (a - floor(a/b)*b)
  2. Updated interval_divide and interval_modulo functions that store the extracted epoch from a timestamp into a double precision variable instead of an integer
  3. Made all functions immutable and "return null on null input"
  4. Added a default value for the "precision" argument in the round function - it's now set to 1 second so unless you specify a precision level, all round calls will round an interval to the nearest second.

-- Functions

create function interval_divide (interval, interval) returns double precision as $$

declare

firstEpoch constant double precision := extract(epoch from $1);

secondEpoch constant double precision := extract(epoch from $2);

begin

return firstEpoch / secondEpoch;

end

$$ language plpgsql immutable returns null on null input;

create function double_precision_modulo (double precision, double precision) returns integer as $$

begin

return ($1 - floor($1 / $2) * $2);

end

$$ language plpgsql immutable returns null on null input;

create function interval_modulo (interval, interval) returns interval as $$

declare

firstEpoch constant double precision := extract(epoch from $1);

secondEpoch constant double precision := extract(epoch from $2);

begin

return (firstEpoch % secondEpoch) * '1 second'::interval;

end

$$ language plpgsql immutable returns null on null input;

create function round (interval, interval default '1 second'::interval) returns interval as $$

declare

quantumNumber constant double precision := round($1 / $2);

begin

return $2 * quantumNumber;

end

$$ language plpgsql immutable returns null on null input;

-- Operators

create operator % (

leftarg = double precision,

rightarg = double precision,

procedure = double_precision_modulo

);

create operator / (

leftarg = interval,

rightarg = interval,

procedure = interval_divide

);

create operator % (

leftarg = interval,

rightarg = interval,

procedure = interval_modulo

);

Thursday, October 1, 2009

NFS Error Messages

As part of a disaster-recovery exercise I needed to make available an NFS share to various machines that needed it. It turns out the Solaris machine designated to be the NFS server had the NFS service deleted from it for some reason. We ended up getting an error while mounting the NFS share that indicated we needed to restart /etc/init.d/nfs.server on the Solaris machine.

While looking for a concise guide to NFS error messages I found this guide. It's short and sweet and would make a great cheat-sheet when printed out.

Saturday, September 19, 2009

International Talk Like a Pirate Day

Avast! It be that time of yearrrr when all me pirrate chums and I gatherr 'rround and celebrate our inner pirrates! Arrrr! Thank ye Cap'n Slappy and ol' Chumbucket for this rroisterous day! Enjoy!

The 5 A's


I'm a pirrate!


More from the Pirate Guys here.

Sunday, August 23, 2009

CentOS 5.3 Upgrade Woes

I ran yum upgrade on a development box running CentOS 5.3 and came across this error message:

--> Processing Dependency: /usr/lib/python2.4 for package: gamin-python
--> Processing Dependency: /usr/lib/python2.4 for package: libxslt-python
--> Processing Dependency: /usr/lib/python2.4 for package: libxml2-python
--> Finished Dependency Resolution
gamin-python-0.1.7-8.el5.i386 from installed has depsolving problems
--> Missing Dependency: /usr/lib/python2.4 is needed by package gamin-python-0.1.7-8.el5.i386 (installed)
libxslt-python-1.1.17-2.el5_2.2.i386 from installed has depsolving problems
--> Missing Dependency: /usr/lib/python2.4 is needed by package libxslt-python-1.1.17-2.el5_2.2.i386 (installed)
libxml2-python-2.6.26-2.1.2.8.i386 from updates has depsolving problems
--> Missing Dependency: /usr/lib/python2.4 is needed by package libxml2-python-2.6.26-2.1.2.8.i386 (updates)
Error: Missing Dependency: /usr/lib/python2.4 is needed by package gamin-python-0.1.7-8.el5.i386 (installed)
Error: Missing Dependency: /usr/lib/python2.4 is needed by package libxslt-python-1.1.17-2.el5_2.2.i386 (installed)
Error: Missing Dependency: /usr/lib/python2.4 is needed by package libxml2-python-2.6.26-2.1.2.8.i386 (updates)
Some searching on Google resulted in this post from April 2009 which indicated a yum clean all would do the trick. All is well now :)

Sunday, August 16, 2009

Partially extracting a tarball

I've never had to extract just a small part of a tarball before so it took a little bit of digging to determine how to do that. It's simple with other archivers e.g. zip, rar et al but tar requires just a couple of extra options to make it happen.

Let's say you have a gzipped tarball that contains all your logs from /var/log with fully qualified paths. One thing to remember is that tar will always remove any leading / from all paths it processes. This means if you ran the tar command as follows:

tar zcf /tmp/logs.tar.gz /var/log


you will have a gzipped tarball containing files such as:

var/log/httpd/access.log
var/log/httpd/error.log
var/log/messages
var/log/dmesg


With this in mind, if you want to extract just your web server log files located in var/log/httpd, you can use the following commandline:

tar zxf /tmp/logs.tar.gz --wildcards 'var/log/httpd/*'


The quotes are necessary so the wildcard doesn't get extrapolated. That command will result in the var/log/httpd directory structure being created in your current dir and you will find that directory populated with the access.log and error.log files.

Tuesday, June 30, 2009

Fun with PostgreSQL and Date/Time

I've been playing around with PostgreSQL 8.3.7 lately and while manipulating intervals realized a few key operators were missing. It turns out it's fairly easy to define operators in PostgreSQL as long as you have an existing function in the database. As a proof of concept I loaded up pl/PgSQL in a working database and created the following functions and operators:
  • interval_divide (used to power the / operator for intervals): Divides one interval by another and returns a real. Its purpose is to tell you how many interval2-sized chunks of time exist in interval1.
  • interval_modulo (used to power the % operator for intervals): Divides one interval by another and returns the remainder as an interval. Its purpose is to tell you how much time would be left over if you fit in as many interval2 sized chunks of time in interval1. You can also use it to determine whether interval1 can perfectly fit a whole number of interval2-size chunks of time.
  • round: Rounds one interval to the nearest value that will fit a whole number of interval2-sized chunks of time.
The actual code is fairly simple but quite useful. I'm sure it'll perform better if written as a C function but that's a bridge I'll cross when I have to.

Code
Here's the code for the functions:

create function interval_divide (interval, interval) returns double precision as $$
declare
firstEpoch constant integer := extract(epoch from $1);
secondEpoch constant integer := extract(epoch from $2);
begin
return firstEpoch::double precision / secondEpoch::double precision;
end
$$ language plpgsql;

create function interval_modulo (interval, interval) returns interval as $$
declare
firstEpoch constant integer := extract(epoch from $1);
secondEpoch constant integer := extract(epoch from $2);
begin
return (firstEpoch % secondEpoch) * '1 second'::interval;
end
$$ language plpgsql;

create function round (interval, interval) returns interval as $$
declare
quantumNumber constant real := round($1 / $2);
begin
return $2 * quantumNumber;
end
$$ language plpgsql;
Here's how to create the appropriate operators using these functions:

create operator / (
leftarg = interval,
rightarg = interval,
procedure = interval_divide
);

create operator % (
leftarg = interval,
rightarg = interval,
procedure = interval_modulo
);
Usage Examples
=> select '1 hour'::interval / '5 minutes'::interval;
?column?
----------
12
(1 row)

=> select '1 hour'::interval / '7 minutes'::interval;
?column?
----------
8.57143
(1 row)

=> select '1 hour'::interval % '7 minutes'::interval;
?column?
----------
00:04:00
(1 row)

=> select '1 hour'::interval % '5 minutes'::interval;
?column?
----------
00:00:00
(1 row)

=> select round('1 hour'::interval, '7 minutes'::interval);
round
----------
01:03:00
(1 row)

=> select '1 hour 3 minutes'::interval / '7 minutes'::interval;
?column?
----------
9
(1 row)