[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