From a049329467d3e01cfc53dab50a61136f0da91583 Mon Sep 17 00:00:00 2001 From: Marius Tolzmann Date: Mon, 14 Nov 2011 14:17:32 +0100 Subject: [PATCH] added tag to help keep original /etc/export entries.. --- Makefile | 17 ++++ mxmount | 240 ++++++++++++++++++++++++++++++++++++++++++++++++ mxmount.service | 11 +++ 3 files changed, 268 insertions(+) create mode 100644 Makefile create mode 100755 mxmount create mode 100644 mxmount.service diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..1d3bd58 --- /dev/null +++ b/Makefile @@ -0,0 +1,17 @@ + +PREFIX=/usr +BINDIR=/usr/bin +SYSCONFDIR=/etc +SYSTEMDSYSTEMDIR=${SYSCONFDIR}/systemd/system + +DESTDIR= + +clean: + +all: + +install: + install -d -m 0755 ${DESTDIR}${BINDIR} + install -m 0755 mxmount ${DESTDIR}${BINDIR} + install -d -m 0755 ${DESTDIR}${SYSTEMDSYSTEMDIR} + install -m 0644 mxmount.service ${DESTDIR}${SYSTEMDSYSTEMDIR} diff --git a/mxmount b/mxmount new file mode 100755 index 0000000..87c66d9 --- /dev/null +++ b/mxmount @@ -0,0 +1,240 @@ +#!/usr/bin/perl + +use Sys::Hostname; +use Data::Dumper; +use Socket; + +######################################## + +my $configfile="/etc/mxmounts"; +my $exports="/etc/exports"; + +######################################## + +my $tag = "# DO NOT EDIT BELOW THIS LINE # created by /usr/bin/mxmount #"; + +my $fullhostname, $hostname; +my @lines,@exports; +my %V, %D; + +$fullhostname = hostname(); +($hostname) = $fullhostname =~ /^(.*?)\./; + +%D = (); +%V = ( + DEFAULT_MOUNT_FS => '', + DEFAULT_MOUNT_OPTIONS => '', + DEFAULT_EXPORT_OPTIONS => '', + DEFAULT_MOUNT_PREFIX => '/', + + SHORTHOST => $hostname, + FULLHOST => $fullhostname, + + NONE => '', + NULL => '' +); + +@lines = read_file($configfile); +@exports = read_file_raw($exports); + +@lines = parse_variables(@lines); + +@lines = parse_data(@lines); + +foreach(@lines) { + print STDERR "skipping: '$_'\n"; +} + +#print Dumper \%D; + +mount_all(); +create_exports(); + +system(exportfs -ra); + +sub create_exports { + my $allmp = $D{$hostname}; + my @CMD; + + open(EXPORTS, '>', $exports) or die "can't open $exports: $!"; + + foreach my $exp (@exports) { + chomp($exp); + next if($exp =~ /^\s*$/); + last if($exp eq $tag); + print EXPORTS "$exp\n"; + } + + print EXPORTS "\n$tag\n\n# auch du nicht, donald 8)\n\n"; + + foreach my $mp (@$allmp) { + next if($mp->{noexport}); + @CMD = ($mp->{mountpoint}, $mp->{exportopts}); + + print join " ", "$exports: ", @CMD, "\n"; + print EXPORTS join " ", @CMD, "\n"; + + } + + close EXPORTS; +} + + +sub mount_all { + my $allmp = $D{$hostname}; + my @CMD; + foreach my $mp (sort { $a->{mountpoint} <=> $b->{mountpoint} } @$allmp) { + + @CMD = (); + + push @CMD, 'mount', "LABEL=$mp->{label}", $mp->{mountpoint}; + + if($mp->{fs}) { + push @CMD, '-t', $mp->{fs}; + } + if($mp->{mountopts}) { + push @CMD, '-o', $mp->{mountopts}; + } + system('mkdir','-p',$mp->{mountpoint}); + print STDERR join " ", @CMD, "\n"; + system(@CMD); + } +} + +sub parse_data { + my @lines = @_; + my @invalid = (); + my @data; + + my $rest; + + foreach(@lines) { + @data = split /\s+/, $_; + + unless($data[1]) { + push @invalid, $_; + next; + } + + my $D = {}; + + $D->{line} = $_; + + $D->{host} = $data[0]; + + + $D->{label} = $data[1]; + if($D->{label} =~ /^!(.*)/) { + $D->{noexport} = 1; + $D->{label} = $1; + } + + if($D->{label} =~ /(.*):(.*)/) { + $D->{label} = $1; + $D->{mountpoint} = $2; + } else { + if($D->{label} =~ /^X/) { + $D->{mountpoint} = 'X/' . $D->{label}; + $D->{label} = lc($D->{label}); + } else { + $D->{mountpoint} = $D->{label}; + } + } + if($D->{mountpoint} !~ m(^\/)) { + $D->{mountpoint} = "$V{DEFAULT_MOUNT_PREFIX}/" . $D->{mountpoint}; + } + + $D->{fs} = 'auto'; + $D->{mountopts} = $data[2] ? $data[2] : $V{DEFAULT_MOUNT_OPTIONS}; + if($D->{mountopts} =~ /\[(.*)\](.*)/) { + $D->{fs} = $1; + $D->{mountopts} = $2; + } + + $D->{exportopts} = $data[3] ? $data[3] : $V{DEFAULT_EXPORT_OPTIONS}; + + foreach(qw(host label mountpoint fs mountopts exportopts )) { + $D->{$_} = expand_variables($D->{$_}); + } + + + push @{$D{$D->{host}}}, $D; + } + return @invalid; +} + +sub expand_variables { + my $s = shift; + + foreach my $k (keys %V) { + $s =~ s/$k/$V{$k}/g; + } + + return $s; +} + + +sub parse_variables { + my @lines = @_; + my @invalid = (); + + my $key, $value; + + foreach(@lines) { + if(($key, $value) = /^(\S+)=\s*(.*)$/) { + $V{$key} = $value; + } else { + push @invalid,expand_variables($_); + } + } + return @invalid; +} + +sub read_file { + my $file = shift; + open F, "$file" or die "can't open $file: $!\n"; + + my @lines=(); + my $line=""; + my $cont=0; + + while() { + chomp; + next if(/^\s*#/ or /^\s*$/); + + $cont=0; + + s/#.*$//; # remove comments.. + + $_ = $line . $_; + + if(s/\\\s*$//) { + # line continous in next line.. + $cont=1; + } + + $line = $_; + + unless($cont) { + $line =~ s/\s+/ /g; + $line =~ s/^\s+//; + $line =~ s/\s+$//; + push @lines, $line; + $line=""; + } + } + + close F; + return @lines; +} + +sub read_file_raw { + my $file = shift; + my @lines; + + open F, "$file" or return; + @lines = ; + close F; + + return @lines; +} diff --git a/mxmount.service b/mxmount.service new file mode 100644 index 0000000..2409b49 --- /dev/null +++ b/mxmount.service @@ -0,0 +1,11 @@ +[Unit] +Description=MX mount local data filessystems +ConditionPathExists=/etc/mxmounts + +[Service] +Type=oneshot +ExecStart=/usr/bin/mxmount +RemainAfterExit=yes + +[Install] +WantedBy=local-fs.target