[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