As promised!

Attached is another patch against r1127, this one adds a new server
plugin which changes the behaviour of cmd_create_open.  You can
configure server settings (more!) so that when a new file is written to
mogile, it will first go to specific networks.  Details in the POD.

This patch doesn't duplicate any of my previous 2, so if you want
everything, you'd best apply all three.

cheers.

diff -urP trunk_r1127/server/lib/MogileFS/Config.pm trunk_r1127_plugin_only/server/lib/MogileFS/Config.pm
--- trunk_r1127/server/lib/MogileFS/Config.pm	2007-05-17 10:42:53.000000000 +0100
+++ trunk_r1127_plugin_only/server/lib/MogileFS/Config.pm	2007-10-04 18:43:46.000000000 +0100
@@ -315,6 +315,8 @@
         return $v;
     }}
 
+    if ($key =~ /^put_class_/) { return $any }
+
     return 0;
 }
 
diff -urP trunk_r1127/server/lib/MogileFS/Worker/Query.pm trunk_r1127_plugin_only/server/lib/MogileFS/Worker/Query.pm
--- trunk_r1127/server/lib/MogileFS/Worker/Query.pm	2007-09-04 15:05:53.000000000 +0100
+++ trunk_r1127_plugin_only/server/lib/MogileFS/Worker/Query.pm	2007-10-04 18:40:53.000000000 +0100
@@ -240,9 +240,22 @@
     $self->wait_for_monitor;
 
     # find suitable device(s) to put this file on.
-    my @dests; # MogileFS::Device objects which are suitabke
+    my @dests; # MogileFS::Device objects which are suitable
 
     $profstart->("find_deviceid");
+
+    my @possible_devices = MogileFS::Device->devices;
+    
+    my $hook_result;    
+    eval {$hook_result = MogileFS::run_global_hook('cmd_create_open_find_dev',
+                                                   $args,
+                                                   [EMAIL PROTECTED]
+                                                  )
+         };
+    if ($hook_result) { # with no plugin the default is undef
+        @possible_devices = @{$hook_result};
+    }
+    
     while (scalar(@dests) < ($multi ? 3 : 1)) {
         my $ddev = first {
             $_->should_get_new_files &&
@@ -251,7 +264,7 @@
             [$_, 100 * $_->percent_free]
         } grep {
             $_->exists
-        } MogileFS::Device->devices;
+        } @possible_devices; 
 
         last unless $ddev;
         push @dests, $ddev;
diff -urP trunk_r1127/server-plugins/MogileFS-Plugin-ClassPutNetwork/lib/MogileFS/Plugin/ClassPutNetwork.pm trunk_r1127_plugin_only/server-plugins/MogileFS-Plugin-ClassPutNetwork/lib/MogileFS/Plugin/ClassPutNetwork.pm
--- trunk_r1127/server-plugins/MogileFS-Plugin-ClassPutNetwork/lib/MogileFS/Plugin/ClassPutNetwork.pm	1970-01-01 01:00:00.000000000 +0100
+++ trunk_r1127_plugin_only/server-plugins/MogileFS-Plugin-ClassPutNetwork/lib/MogileFS/Plugin/ClassPutNetwork.pm	2007-10-04 18:38:17.000000000 +0100
@@ -0,0 +1,101 @@
+package MogileFS::Plugin::ClassPutNetwork;
+
+use strict;
+use warnings;
+
+use MogileFS::Util qw(weighted_list);
+
+use Net::Netmask;
+
+sub load {
+     MogileFS::register_global_hook( 'cmd_create_open_find_dev', sub {
+         my ($args, $possible_devices) = @_;
+               
+         my $key_name = key_name($args->{domain},$args->{class});
+         # look for put_class_$domain_$class => location1,location2
+         my $zone_string = MogileFS::Config->server_setting($key_name);
+
+         # leave early 
+         return undef unless $zone_string;
+
+         # then lookup zone_location => netmask
+         my @netmasks;
+         foreach my $zone_name (split(",",$zone_string)) {
+             my $network = MogileFS::Config->server_setting('zone_'.$zone_name);
+             next if not $network;
+
+             my $netmask = Net::Netmask->new2($network);
+             if (Net::Netmask::errstr()) {
+                 warn "couldn't parse <$netmask> as a netmask. error was <".
+                     Net::Netmask::errstr().
+                     ">. check your server settings";
+                 next;
+             }
+
+             push @netmasks, $netmask;
+         }
+
+         # filter out devices on the wrong networks
+         my @approved_devices;
+         foreach my $possible_dev (@{$possible_devices}) {
+             foreach my $netmask (@netmasks) {
+                 if ($netmask->match($possible_dev->host->ip)) {
+                     push @approved_devices, $possible_dev;
+                 }
+             }
+         }
+
+         if (not @approved_devices) {
+             warn "ClassPutNetwork can't find a suitable device for <<$key_name>>";
+             @approved_devices = @{$possible_devices};                 
+         }
+
+         return [EMAIL PROTECTED];
+     });
+                                        
+    return 1;
+}
+
+sub unload {
+    MogileFS::unregister_global_hook( 'cmd_create_open' );
+    
+    return 1;
+}
+
+sub key_name {
+    my ($domain, $class) = @_;
+
+    return 'put_class_'.$domain.'_'.$class;
+}
+
+# 
+1;
+
+# Local Variables:
+# mode: perl
+# c-basic-indent: 4
+# indent-tabs-mode: nil
+# End:
+
+__END__
+
+=head1 NAME
+
+MogileFS::Plugin::ClassPutNetwork - aim to write classes to a specific network
+
+=head1 DESCRIPTION
+
+This plugin is closely related to the MultipleNetworks replication policy.  For that you'll have defined network masks for various network "zones", e.g.
+
+ mogadm settings set zone_location1 192.168.0.0/24
+ mogadm settings set zone_location2 10.0.0.0/24
+
+This plugin lets you control where a file is initially put when it's saved into mogile.  Where your networks don't have uber fast connections this allows for quick puts, while replicating at leisure. For each class that you want to control the destination of, you'll need to make another server setting defining which devices it should be saved to, by defining which zone the class should be saved to. The key is in the form put_class_$domain_$class, e.g.
+
+ mogadm settings set put_class_mydomain_myclass location1,location2
+
+If we can't find a device on your ideal network(s), we'll target anywhere else.
+
+=head1 SEE ALSO
+
+L<MogileFS::ReplicationPolicy::MultipleNetworks>

Reply via email to