In the coming sections, interactions with the database are going
to be much more direct and detailed than they have been to this
point. As a result, it will be handy to be able to readily view the
structure of the database tables, and to view the records stored
within them. As I develop the database itself further it is likely
that I will add some additional tools to this bag of tricks, but for
now I would suggest that if an Xserver is available, the graphical
pgaccess tool provides a handy way to keep the database tables
visible as the development process is on-going.
As always with a
package for which a pre-compiled binary is available, pgaccess can be
installed with a simple “apt-get install pgaccess”. Once
the utility has been started by typing “pgaccess” in a
terminal window (again, assuming that some type of Xwindows display
capability is present) the main widget for the utility is displayed.
Clicking on “database” and then “open” will
display the widget at right, in which connection details are
specified.
Once the connection has been established double-clicking
on a table name will initiate a browse widget on that table, as shown
below.


One difficulty with pgaccess is that it would not work with the version of postgresql (7.1.2) that I had installed at that point, because that binary had not been compiled with unicode support. I then did something that is never a good idea, and would in fact have been a cardinal sin if this had involved a production database. That is, I completely blew away my working environment before I had an available replacement. In this context the only real downside was that I had to invest a few more hours getting the replacement working when I might have preferred to continue with the development process, while in a production environment that down time would have more critical consequences. In any event, my rationale for doing so revolved around the devlopmental status of the database. Given the scripts that I had on hand, I felt that reconstructing the database would be trivial. What actually happened, however, reminded me to be humble <grin>. After installing the postgresql package that is current as of 10/31/2003 in the stable (woody) distribution, version 7.2.1, I had some difficulty connecting to it. In this specific context it took me a while to recognize that a blanket deny statement in the pg_hba.conf file was masking the access that I had granting to the machines in the cluster subnet, as in the following excerpt
#host all 0.0.0.0 0.0.0.0 reject host all 192.1.1.0 255.255.255.0 trust
(The commented line is, of course, the one that created the difficulty. As I have said before, the structure implemented here represents a relatively loose security implementation on the database server. Currently, anyone who can gain access to the cluster controller could gain access to the database, if they knew where to look. I will be tightening that down somewhat in a later section.)
Once I upgraded postgresql to version 7.2.1, pgaccess was able to talk to the database server. Even if this upgrade had not been applied, however, the existing database tables should be dropped and repopulated by piping the lastest bbdb_create script and the new db_populate.script into the psql utility, The db_populate.script file loads a slightly more complete set of test data into the database tables, and will get more complete as time goes on as well, but one should never discount how boring constructing a coherent set of test data can be.<grin>
The changes required to the recs_insert.pl script came as a response to problems what quite frankly took me by surprise, largely because I had not had reason to check the flow of the entry process for some time. In some of these changes, I am not quite sure what precipitated the problems that required the change, but this is not unusual in a system with several interlocking components., especially after upgrading libraries in some component of the system. This is just the way things are. Generally, a working system is not upgraded until all of the changes have been applied to a working system and system functionality verified. I have take a somewhat more cavalier approach in this development process, and the changes required here represent an illustration of the resultant price to be paid.
Regardless, the first change came as a result of the fact that at some point I had decided that it was appropriate to turn on the strict switch for this script. As a result, the gethostbyaddr() function used in the number_config() subroutine called from the BB_UTIL module would fail. Its original form
@host=gethostbyaddr($address,AF_INET);will fail because a text string alone (a "bareword") cannot be used as a function argument under the strict pragma. As a result the hostname is not determined, and the whole process of determining appropriate locations for log files collapses. Once I tracked that down, it was a relatively simple fix. While storing the "AF_INET" string inside a scalar and passing that to the subroutine should have worked, it did not, so I simply stored the mode number in the scalar, which did work. This is not generally considered to be good form, however, so at some point I am likely to revisit that.
I next discovered that the manner in which the intermediate working files were written in the same number_config() subroutine could lead to problems. Specifically, this subroutine relies on the order of the lines written to the files as a control element, and if it does not behave appropriately the operation of the subroutine is affected. While this is a little clunky, as long as I control the manner in which the files are created it is workable. Unfortunately, however, there were apparently some holes in that control, which is what led to the difficulty. As an example, the file /home/www/host_addr serves as the controlling list of TCP/IP addresses of the machines in the cluster. The number_config subroutine will generate a list of hostnames that is of the same number of lines as the host_addr file when its construction is finished. The problem arises when the hash_assign() subroutine, again located in BB_UTIL, is used to create a hash of mosix numbers and hosts.
sub hash_assign {
my %hostnum;
open(NUMBERS,"/home/www/numbers");
open(HOSTS,"/home/www/hosts");
my @mos_num=;
my @hosts=;
my $mos_num;
my $i=0;
foreach $mos_num(@mos_num) {
chomp $mos_num;
$hostnum{$mos_num}=$hosts[$i];
$i++;
}
return \%hostnum;
}
Since the construction is predicated on line order, if there are more lines in the file /home/www/numbers the @mos_num array will be larger than the @hosts array. Therfore, the initial value for the hostname in a hash slice keyed to a given mosix number will be overwritten with undef as the subroutine passes the end of the array holding the hostnames. As a result, when that hash is used in the free_space() subroutine to determine the host name to be used in a remote shell execution and undefined value will be passed to the rsh command. (Note that there would be no problem if the situation were reversed and the hosts file had been written to several times, as long as the order of the lines was appropriate.)While in previous versions I had used pre-existing copies of these files to avoid unnecessary processing, the first step I took in resolving the problem was simply to recreate the files each time. This measure also serves to preclude the unusual circumstance in which an out-of-date file might be used. The /home/www/numbers and /home/www/hosts files are now written by opening the filehandles on those files in overwrite mode
my $out_numbers="/home/www/numbers"; my $out_hosts="/home/www/hosts"; open(OUT,">$out_numbers"); open(OUT_HOSTS,">$out_hosts");thus assuring that the files are created anew on each execution. In the case of the host_addr file, however, this will not work because that file is create by successive executions of an external command (mosctl). Therefore, if the filehandle is in overwrite mode the final version of the file will have only one line, each successive iteration having opened the fule and overwritten what was created on the previous iteration. Obviously, I cannot have that, but just as obviously I cannot leave the potential for the file to grow across successive iterations of the script. Therefore, on each execution of the script I delete the file written previously,
system("rm /home/www/host_addr");
and when I do write to the file I write to it in append mode. system("mosctl whois $machine >> $out_host_addr");
Therefore, each invocation of mosctl within the loop appends another line to the file.So there it is ... recs_insert.pl now once again behaves as it should. That being said, I do feel some dissatisfaction with certain elements of the way the script works in light of other elements of the system that have been developed since I first put this together. I have therefore put upgrading this script into my mental to-do list as something to get involved with after the major elements of the system are in place.
Next, I will put together the framework under which the editing function will be executed.