[pve-devel] r4957 - pve-common/trunk
svn-commits at proxmox.com
svn-commits at proxmox.com
Tue Aug 10 11:32:12 CEST 2010
Author: dietmar
Date: 2010-08-10 09:32:12 +0000 (Tue, 10 Aug 2010)
New Revision: 4957
Modified:
pve-common/trunk/INotify.pm
Log:
improved inotify class
Modified: pve-common/trunk/INotify.pm
===================================================================
--- pve-common/trunk/INotify.pm 2010-08-10 07:53:42 UTC (rev 4956)
+++ pve-common/trunk/INotify.pm 2010-08-10 09:32:12 UTC (rev 4957)
@@ -13,6 +13,7 @@
my $ccache;
my $ccachemap;
+my $ccacheregex;
my $inotify;
my $inotify_pid = 0;
my $versions;
@@ -23,6 +24,7 @@
# Note: please close the inotify handle after you fork
+# fixme: remove somehow
my $shadowfiles = {
'/etc/network/interfaces' => '/etc/network/interfaces.new',
};
@@ -57,15 +59,32 @@
return $diff;
}
-sub write_file {
- my ($filename, $data, $full) = @_;
+sub ccache_info {
+ my ($filename) = @_;
+ foreach my $uid (keys %$ccacheregex) {
+ my $ccinfo = $ccacheregex->{$uid};
+ my $dir = $ccinfo->{dir};
+ my $regex = $ccinfo->{regex};
+ if ($filename =~ m|^$dir/+$regex$|) {
+ return ($ccinfo, $filename);
+ }
+ }
+
$filename = $ccachemap->{$filename} if defined ($ccachemap->{$filename});
die "file '$filename' not added :ERROR" if !defined ($ccache->{$filename});
+
+ return ($ccache->{$filename}, $filename);
+}
- my $writer = $ccache->{$filename}->{writer};
+sub write_file {
+ my ($fileid, $data, $full) = @_;
+ my ($ccinfo, $filename) = ccache_info($fileid);
+
+ my $writer = $ccinfo->{writer};
+
my $realname = $filename;
my $shadow;
@@ -82,7 +101,7 @@
$res = &$writer ($filename, $fh, $data);
};
- $ccache->{$filename}->{version} = undef;
+ $ccinfo->{version} = undef;
my $err = $@;
$fh->detach() if $err;
@@ -103,11 +122,11 @@
}
sub update_file {
- my ($filename, $data, @args) = @_;
+ my ($fileid, $data, @args) = @_;
- $filename = $ccachemap->{$filename} if defined ($ccachemap->{$filename});
+ my ($ccinfo, $filename) = ccache_info($fileid);
- my $update = $ccache->{$filename}->{update};
+ my $update = $ccinfo->{update};
die "unable to update/merge data" if !$update;
@@ -150,12 +169,10 @@
}
sub discard_changes {
- my ($filename, $full) = @_;
+ my ($fileid, $full) = @_;
- $filename = $ccachemap->{$filename} if defined ($ccachemap->{$filename});
+ my ($ccinfo, $filename) = ccache_info($fileid);
- die "file '$filename' not added :ERROR" if !defined ($ccache->{$filename});
-
if (my $copy = $shadowfiles->{$filename}) {
unlink $copy;
}
@@ -164,22 +181,13 @@
}
sub read_file {
- my ($filename, $full) = @_;
+ my ($fileid, $full) = @_;
my $parser;
-# fixme: allow regex to register parsers
-# if ($filename =~ m|^/etc/qemu-server/\d+\.conf$|) {
-# $parser = \&read_qmconfig;
-# } elsif ($filename =~ m|^/etc/vz/conf/\d+\.conf$|) {
-# $parser = \&read_vzconfig;
-# } else {
-
- $filename = $ccachemap->{$filename} if defined ($ccachemap->{$filename});
-
- die "file '$filename' not added :ERROR" if !defined ($ccache->{$filename});
-
- $parser = $ccache->{$filename}->{parser};
+ my ($ccinfo, $filename) = ccache_info($fileid);
+
+ $parser = $ccinfo->{parser};
my $fd;
my $shadow;
@@ -200,32 +208,32 @@
$fd = IO::File->new ($filename, "r");
}
- my $acp = $ccache->{$filename}->{always_call_parser};
+ my $acp = $ccinfo->{always_call_parser};
if (!$fd) {
- $ccache->{$filename}->{version} = undef;
- $ccache->{$filename}->{data} = undef;
- $ccache->{$filename}->{diff} = undef;
+ $ccinfo->{version} = undef;
+ $ccinfo->{data} = undef;
+ $ccinfo->{diff} = undef;
return undef if !$acp;
}
- my $noclone = $ccache->{$filename}->{noclone};
+ my $noclone = $ccinfo->{noclone};
# file unchanged?
- if (!$ccache->{$filename}->{nocache} &&
+ if (!$ccinfo->{nocache} &&
$inotify && $versions->{$filename} &&
- defined ($ccache->{$filename}->{data}) &&
- defined ($ccache->{$filename}->{version}) &&
- ($ccache->{$filename}->{readonce} ||
- ($ccache->{$filename}->{version} == $versions->{$filename}))) {
+ defined ($ccinfo->{data}) &&
+ defined ($ccinfo->{version}) &&
+ ($ccinfo->{readonce} ||
+ ($ccinfo->{version} == $versions->{$filename}))) {
my $ret;
- if (!$noclone && ref ($ccache->{$filename}->{data})) {
- $ret->{data} = dclone ($ccache->{$filename}->{data});
+ if (!$noclone && ref ($ccinfo->{data})) {
+ $ret->{data} = dclone ($ccinfo->{data});
} else {
- $ret->{data} = $ccache->{$filename}->{data};
+ $ret->{data} = $ccinfo->{data};
}
- $ret->{changes} = $ccache->{$filename}->{diff};
+ $ret->{changes} = $ccinfo->{diff};
return $full ? $ret : $ret->{data};
}
@@ -238,61 +246,93 @@
my $res = &$parser ($filename, $fd);
- if (!$ccache->{$filename}->{nocache}) {
- $ccache->{$filename}->{version} = $cver;
+ if (!$ccinfo->{nocache}) {
+ $ccinfo->{version} = $cver;
}
# we cache data with references, so we always need to
# dclone this data. Else the original data may get
# modified.
- $ccache->{$filename}->{data} = $res;
+ $ccinfo->{data} = $res;
# also store diff
- $ccache->{$filename}->{diff} = $diff;
+ $ccinfo->{diff} = $diff;
my $ret;
- if (!$noclone && ref ($ccache->{$filename}->{data})) {
- $ret->{data} = dclone ($ccache->{$filename}->{data});
+ if (!$noclone && ref ($ccinfo->{data})) {
+ $ret->{data} = dclone ($ccinfo->{data});
} else {
- $ret->{data} = $ccache->{$filename}->{data};
+ $ret->{data} = $ccinfo->{data};
}
- $ret->{changes} = $ccache->{$filename}->{diff};
+ $ret->{changes} = $ccinfo->{diff};
return $full ? $ret : $ret->{data};
}
-sub add_file {
- my ($id, $filename, $parser, $writer, $update, %options) = @_;
+sub parse_ccache_options {
+ my ($ccinfo, %options) = @_;
- die "file '$filename' already added :ERROR" if defined ($ccache->{$filename});
- die "ID '$id' already used :ERROR" if defined ($ccachemap->{$id});
-
- $ccachemap->{$id} = $filename;
- $ccache->{$filename}->{id} = $id;
-
- $ccache->{$filename}->{parser} = $parser || \&ccache_default_parser;
- $ccache->{$filename}->{writer} = $writer || \&ccache_default_writer;
- $ccache->{$filename}->{update} = $update;
-
foreach my $opt (keys %options) {
my $v = $options{$opt};
if ($opt eq 'readonce') {
- $ccache->{$filename}->{$opt} = $v;
+ $ccinfo->{$opt} = $v;
} elsif ($opt eq 'nocache') {
- $ccache->{$filename}->{$opt} = $v;
+ $ccinfo->{$opt} = $v;
} elsif ($opt eq 'noclone') {
# noclone flag for large read-only data chunks like aplinfo
- $ccache->{$filename}->{$opt} = $v;
+ $ccinfo->{$opt} = $v;
} elsif ($opt eq 'always_call_parser') {
# when set, we call parser even when the file does not exists.
# this allows the parser to return some default
- $ccache->{$filename}->{$opt} = $v;
+ $ccinfo->{$opt} = $v;
} else {
die "internal error - unsupported option '$opt'";
}
}
}
+sub register_file {
+ my ($id, $filename, $parser, $writer, $update, %options) = @_;
+
+ die "can't register file after initify_init" if $inotify;
+
+ die "file '$filename' already added :ERROR" if defined ($ccache->{$filename});
+ die "ID '$id' already used :ERROR" if defined ($ccachemap->{$id});
+
+ my $ccinfo = {};
+
+ $ccinfo->{id} = $id;
+ $ccinfo->{parser} = $parser || \&ccache_default_parser;
+ $ccinfo->{writer} = $writer || \&ccache_default_writer;
+ $ccinfo->{update} = $update;
+
+ parse_ccache_options($ccinfo, %options);
+
+ $ccachemap->{$id} = $filename;
+ $ccache->{$filename} = $ccinfo;
+}
+
+sub register_regex {
+ my ($dir, $regex, $parser, $writer, $update, %options) = @_;
+
+ die "can't register regex after initify_init" if $inotify;
+
+ my $uid = "$dir/$regex";
+ die "regular expression '$uid' already added :ERROR" if defined ($ccacheregex->{$uid});
+
+ my $ccinfo = {};
+
+ $ccinfo->{dir} = $dir;
+ $ccinfo->{regex} = $regex;
+ $ccinfo->{parser} = $parser || \&ccache_default_parser;
+ $ccinfo->{writer} = $writer || \&ccache_default_writer;
+ $ccinfo->{update} = $update;
+
+ parse_ccache_options($ccinfo, %options);
+
+ $ccacheregex->{$uid} = $ccinfo;
+}
+
sub poll {
return if !$inotify;
@@ -341,9 +381,11 @@
}
}
- # also get versions of qemu and openvz config files
- $dirhash->{"/etc/qemu-server"}->{_regex} = '\d+\.conf';
- $dirhash->{"/etc/vz/conf"}->{_regex} = '\d+\.conf';
+ foreach my $uid (keys %$ccacheregex) {
+ my $ccinfo = $ccacheregex->{$uid};
+ #$dirhash->{$ccinfo->{dir}}->{_regex} = $ccinfo->{regex};
+ $dirhash->{$ccinfo->{dir}}->{_regex} = 1;
+ }
$inotify_pid = $$;
@@ -377,17 +419,22 @@
$inotify = undef;
}
- my $re = $dirhash->{$dir}->{_regex};
- if ($re && ($name =~ m|^$re$|)) {
+ if ($dirhash->{$dir}->{_regex}) {
+ foreach my $uid (keys %$ccacheregex) {
+ my $ccinfo = $ccacheregex->{$uid};
+ next if $dir ne $ccinfo->{dir};
+ my $regex = $ccinfo->{regex};
+ if ($regex && ($name =~ m|^$regex$|)) {
- my $fn = "$dir/$name";
- $versions->{$fn}++;
- #print "VERSION:$fn:$versions->{$fn}\n";
-
+ my $fn = "$dir/$name";
+ $versions->{$fn}++;
+ print "VERSION:$fn:$versions->{$fn}\n";
+ }
+ }
} elsif (my $fn = $dirhash->{$dir}->{$name}) {
$versions->{$fn}++;
- #print "VERSION:$fn:$versions->{$fn}\n";
+ print "VERSION:$fn:$versions->{$fn}\n";
}
});
}
@@ -395,20 +442,24 @@
foreach my $dir (keys %$dirhash) {
foreach my $name (keys %{$dirhash->{$dir}}) {
if ($name eq '_regex') {
- my $re = $dirhash->{$dir}->{_regex};
- if (my $fd = IO::Dir->new ($dir)) {
- while (defined(my $de = $fd->read)) {
- if ($de =~ m/^$re$/) {
- my $fn = "$dir/$de";
- $versions->{$fn}++; # init with version
- #print "init:$fn:$versions->{$fn}\n";
+ foreach my $uid (keys %$ccacheregex) {
+ my $ccinfo = $ccacheregex->{$uid};
+ next if $dir ne $ccinfo->{dir};
+ my $re = $ccinfo->{regex};
+ if (my $fd = IO::Dir->new ($dir)) {
+ while (defined(my $de = $fd->read)) {
+ if ($de =~ m/^$re$/) {
+ my $fn = "$dir/$de";
+ $versions->{$fn}++; # init with version
+ print "init:$fn:$versions->{$fn}\n";
+ }
}
}
}
} else {
my $fn = $dirhash->{$dir}->{$name};
$versions->{$fn}++; # init with version
- #print "init:$fn:$versions->{$fn}\n";
+ print "init:$fn:$versions->{$fn}\n";
}
}
}
More information about the pve-devel
mailing list