[pve-devel] r5995 - pve-common/trunk/data/PVE

svn-commits at proxmox.com svn-commits at proxmox.com
Wed May 18 12:35:57 CEST 2011


Author: dietmar
Date: 2011-05-18 12:35:57 +0200 (Wed, 18 May 2011)
New Revision: 5995

Modified:
   pve-common/trunk/data/PVE/INotify.pm
Log:
read/write /etc/network/interfaces


Modified: pve-common/trunk/data/PVE/INotify.pm
===================================================================
--- pve-common/trunk/data/PVE/INotify.pm	2011-05-18 09:46:09 UTC (rev 5994)
+++ pve-common/trunk/data/PVE/INotify.pm	2011-05-18 10:35:57 UTC (rev 5995)
@@ -25,7 +25,9 @@
 my $inotify;
 my $inotify_pid = 0;
 my $versions;
-my $shadowfiles = {};
+my $shadowfiles = {
+    '/etc/network/interfaces' => '/etc/network/interfaces.new',
+};
 
 # to enable cached operation, you need to call 'inotify_init'
 # inotify handles are a limited resource, so use with care (only
@@ -660,4 +662,230 @@
 	      \&read_active_workers,
 	      \&write_active_workers);
 
+
+my $bond_modes = { 'balance-rr' => 0,
+		   'active-backup' => 1,
+		   'balance-xor' => 2,
+		   'broadcast' => 3,
+		   '802.3ad' => 4,
+		   'balance-tlb' => 5,
+		   'balance-alb' => 6,
+	       };
+
+#sub get_bond_modes {
+#    return $bond_modes;
+#}
+
+sub read_etc_network_interfaces {
+    my ($filename, $fh) = @_;
+
+    my $ifaces = {};
+
+    my $line;
+
+    if (my $fd2 = IO::File->new("/proc/net/dev", "r")) {
+	while (defined ($line = <$fd2>)) {
+	    if ($line =~ m/^\s*(eth[0-9]):.*/) {
+		$ifaces->{$1}->{exists} = 1;
+	    }
+	}
+	close($fd2);
+    }
+
+    # always add the vmbr0 bridge device
+    $ifaces->{vmbr0}->{exists} = 1;
+
+    if (my $fd2 = IO::File->new("/proc/net/if_inet6", "r")) {
+	while (defined ($line = <$fd2>)) {
+	    if ($line =~ m/^[a-f0-9]{32}\s+[a-f0-9]{2}\s+[a-f0-9]{2}\s+[a-f0-9]{2}\s+[a-f0-9]{2}\s+(lo|eth\d+|vmbr\d+|bond\d+)$/) {
+		$ifaces->{$1}->{active} = 1;
+	    }
+	}
+	close ($fd2);
+    }
+
+    my $gateway = 0;
+
+    while (defined ($line = <$fh>)) {
+	chomp ($line);
+	next if $line =~ m/^#/;
+ 
+	if ($line =~ m/^auto\s+(.*)$/) {
+	    my @aa = split (/\s+/, $1);
+
+	    foreach my $a (@aa) {
+		$ifaces->{$a}->{autostart} = 1;
+	    }
+
+	} elsif ($line =~ m/^iface\s+(\S+)\s+inet\s+(\S+)\s*$/) {
+	    my $i = $1;
+	    $ifaces->{$i}->{method} = $2;
+	    my $d = $ifaces->{$i};
+	    while (defined ($line = <$fh>) && ($line =~ m/^\s+((\S+)\s+(.+))$/)) {
+		my $option = $1;
+		my ($id, $value) = ($2, $3);
+		if (($id eq 'address') || ($id eq 'netmask') || ($id eq 'broadcast')) {
+		    $d->{$id} = $value;
+		} elsif ($id eq 'gateway') {
+		    $d->{$id} = $value;
+		    $gateway = 1;
+		} elsif ($id eq 'slaves' || $id eq 'bridge_ports') {
+		    my $devs = {};
+		    foreach my $p (split (/\s+/, $value)) {
+			next if $p eq 'none';
+			$devs->{$p} = 1;
+		    }
+		    my $str = join (' ', sort keys %{$devs});
+		    $d->{$id} = $str || '';
+		} elsif ($id eq 'bridge_stp') {
+		    if ($value =~ m/^\s*(on|yes)\s*$/i) {
+			$d->{$id} = 'on';
+		    } else {
+			$d->{$id} = 'off';
+		    }
+		} elsif ($id eq 'bridge_fd') {
+		    $d->{$id} = $value;
+		} elsif ($id eq 'bond_miimon') {
+		    $d->{$id} = $value;
+		} elsif ($id eq 'bond_mode') {
+		    # always use names
+		    foreach my $bm (keys %$bond_modes) {
+			my $id = $bond_modes->{$bm};
+			if ($id eq $value) {
+			    $value = $bm;
+			    last;
+			}
+		    }
+		    $d->{$id} = $value;
+		} else {
+		    push @{$d->{options}}, $option;
+		}
+	    }
+	}
+    }
+
+    if (!$gateway) {
+	$ifaces->{vmbr0}->{gateway} = '';
+    }
+
+    if (!$ifaces->{lo}) {
+	$ifaces->{lo}->{method} = 'loopback';
+	$ifaces->{lo}->{autostart} = 1;
+    }
+
+    foreach my $iface (keys %$ifaces) {
+	my $d = $ifaces->{$iface};
+	if ($iface =~ m/^bond\d+$/) {
+	    $d->{type} = 'bond';
+	} elsif ($iface =~ m/^vmbr\d+$/) {
+	    $d->{type} = 'bridge';
+	    if (!defined ($d->{bridge_fd})) {
+		$d->{bridge_fd} = 0;
+	    }
+	    if (!defined ($d->{bridge_stp})) {
+		$d->{bridge_stp} = 'off';
+	    }
+	} elsif ($iface =~ m/^(\S+):\d+$/) {
+	    $d->{type} = 'alias';
+	    if (defined ($ifaces->{$1})) {
+		$d->{exists} = $ifaces->{$1}->{exists};
+	    } else {
+		$ifaces->{$1}->{exists} = 0;
+		$d->{exists} = 0;
+	    }
+	} elsif ($iface =~ m/^eth[0-9]$/) {
+	    $d->{type} = 'eth';
+	} else {
+	    $d->{type} = 'unknown';
+	}
+
+	$d->{method} = 'manual' if !$d->{method};
+    }
+
+    return $ifaces;
+}
+
+sub __interface_to_string {
+    my ($iface, $d) = @_;
+
+    return '' if !($d && $d->{method});
+
+    my $raw = '';
+
+    if ($d->{autostart}) {
+	$raw .= "auto $iface\n";
+    }
+    $raw .= "iface $iface inet $d->{method}\n";
+    $raw .= "\taddress  $d->{address}\n" if $d->{address};
+    $raw .= "\tnetmask  $d->{netmask}\n" if $d->{netmask};
+    $raw .= "\tgateway  $d->{gateway}\n" if $d->{gateway};
+    $raw .= "\tbroadcast  $d->{broadcast}\n" if $d->{broadcast};
+
+    if ($d->{bridge_ports} || ($iface =~ m/^vmbr\d+$/)) {
+	my $ports = $d->{bridge_ports} || 'none';
+	$raw .= "\tbridge_ports $ports\n";
+    }
+
+    if ($d->{bridge_stp} || ($iface =~ m/^vmbr\d+$/)) {
+	my $v = $d->{bridge_stp};
+	$v = defined ($v) ? $v : 'off';
+	$raw .= "\tbridge_stp $v\n";
+    }
+
+    if (defined ($d->{bridge_fd}) || ($iface =~ m/^vmbr\d+$/)) {
+	my $v = $d->{bridge_fd};
+	$v = defined ($v) ? $v : 0;
+	$raw .= "\tbridge_fd $v\n";
+    }
+
+    if ($d->{slaves} || ($iface =~ m/^bond\d+$/)) {
+	my $slaves = $d->{slaves} || 'none';
+	$raw .= "\tslaves $slaves\n";
+    }
+
+    if (defined ($d->{'bond_miimon'}) || ($iface =~ m/^bond\d+$/)) {
+	my $v = $d->{'bond_miimon'};
+	$v = defined ($v) ? $v : 100;
+	$raw .= "\tbond_miimon $v\n";
+    }
+
+    if (defined ($d->{'bond_mode'}) || ($iface =~ m/^bond\d+$/)) {
+	my $v = $d->{'bond_mode'};
+	$v = defined ($v) ? $v : 'balance-rr';
+	$raw .= "\tbond_mode $v\n";
+    }
+
+    foreach my $option (@{$d->{options}}) {
+	$raw .= "\t$option\n";
+    }
+
+    return $raw;
+}
+
+sub write_etc_network_interfaces {
+    my ($filename, $fh, $ifaces) = @_;
+
+    my $raw = "# network interface settings\n";
+
+    my $printed = {};
+
+    foreach my $t (('lo', 'eth', '')) {
+	foreach my $iface (sort keys %$ifaces) {
+	    my $d = $ifaces->{$iface};
+
+	    next if $printed->{$iface};
+	    next if $iface !~ m/^$t/;
+
+	    $printed->{$iface} = 1;
+	    $raw .= __interface_to_string($iface, $d);
+	}
+    }
+    
+    PVE::Tools::safe_print($filename, $fh, $raw);
+}
+
+register_file('interfaces', "/etc/network/interfaces",
+	      \&read_etc_network_interfaces,
+	      \&write_etc_network_interfaces);
+
 1;




More information about the pve-devel mailing list