Skip to content
Snippets Groups Projects
Commit 98ad146c authored by Mark Harrison's avatar Mark Harrison
Browse files

Remove the sysv IPC shared memory code in favor of using files instead.

This fixes an issue with resmon not correctly cleaning up the shared memory
segments when it dies.

Currently no locking is done on the file to prevent reading of a partial
status dump. This needs fixing.

Also, the file is deleted immediately after opening. This deals with the issue
of having a stale file around if resmon dies and also limits the ability of
somebody to inject invalid data into the file.

git-svn-id: https://labs.omniti.com/resmon/branches/resmon2@367 8c0face9-b7db-6ec6-c4b3-d5f7145c7d55
parent 1ae78969
No related branches found
No related tags found
No related merge requests found
...@@ -8,50 +8,53 @@ use IO::File; ...@@ -8,50 +8,53 @@ use IO::File;
use IO::Socket; use IO::Socket;
use Socket; use Socket;
use Fcntl qw/:flock/; use Fcntl qw/:flock/;
use IPC::SysV qw /IPC_PRIVATE IPC_CREAT IPC_RMID S_IRWXU S_IRWXG S_IRWXO/;
use Data::Dumper; use Data::Dumper;
my $SEGSIZE = 1024*256;
my $KEEPALIVE_TIMEOUT = 5; my $KEEPALIVE_TIMEOUT = 5;
my $REQUEST_TIMEOUT = 60; my $REQUEST_TIMEOUT = 60;
sub new { sub new {
my $class = shift; my $class = shift;
my $file = shift; my $file = shift;
my $fh = IO::File->new(".$file.state", "+>");
# Delete the just opened file - it stays open, but doesn't show on disk
unlink ".$file.state";
return bless { return bless {
file => $file file => $file,
shared_state => $fh
}, $class; }, $class;
} }
sub get_shared_state { sub get_shared_state {
my $self = shift; my $self = shift;
my $blob; my $fh = $self->{shared_state};
my $len; if (defined $fh) {
return unless(defined($self->{shared_state})); my $VAR1;
# Lock shared segment $fh->seek(0, 0);
# Read in my $blob;
shmread($self->{shared_state}, $len, 0, length(pack('i', 0))); {
$len = unpack('i', $len); local $/ = undef;
shmread($self->{shared_state}, $blob, length(pack('i', 0)), $len); $blob = <$fh>;
# unlock }
my $VAR1; eval $blob;
eval $blob; die $@ if ($@);
die $@ if ($@); $self->{store} = $VAR1;
$self->{store} = $VAR1; } else {
die "Unable to read shared state";
};
return $self->{store}; return $self->{store};
} }
sub store_shared_state { sub store_shared_state {
my $self = shift; my $self = shift;
return unless(defined($self->{shared_state})); my $fh = $self->{shared_state};
my $blob = Dumper($self->{store}); if (defined($fh)) {
$fh->truncate(0);
# Lock shared segment $fh->seek(0,0);
# Write state and flush print $fh Dumper($self->{store});
shmwrite($self->{shared_state}, pack('i', length($blob)), $fh->flush();
0, length(pack('i', 0))) || die "$!"; } else {
shmwrite($self->{shared_state}, $blob, length(pack('i', 0)), die "Unable to store shared state";
length($blob)) || die "$!"; };
# unlock
} }
sub xml_kv_dump { sub xml_kv_dump {
...@@ -467,11 +470,6 @@ sub open { ...@@ -467,11 +470,6 @@ sub open {
$self->{swap_on_close} = 1; # move this to a non .swap version on close $self->{swap_on_close} = 1; # move this to a non .swap version on close
chmod 0644, "$self->{file}.swap"; chmod 0644, "$self->{file}.swap";
unless(defined($self->{shared_state})) {
$self->{shared_state} = shmget(IPC_PRIVATE, $SEGSIZE,
IPC_CREAT|S_IRWXU|S_IRWXG|S_IRWXO);
die "$0: $!" unless (defined $self->{shared_state});
}
return 1; return 1;
} }
...@@ -530,8 +528,5 @@ sub DESTROY { ...@@ -530,8 +528,5 @@ sub DESTROY {
kill 9, $child if(kill 0, $child); kill 9, $child if(kill 0, $child);
waitpid(-1,WNOHANG); waitpid(-1,WNOHANG);
} }
if(defined($self->{shared_state})) {
shmctl($self->{shared_state}, IPC_RMID, 0);
}
} }
1; 1;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment