diff options
Diffstat (limited to 'perl-install/fs/mount_options.pm')
| -rw-r--r-- | perl-install/fs/mount_options.pm | 276 | 
1 files changed, 276 insertions, 0 deletions
| diff --git a/perl-install/fs/mount_options.pm b/perl-install/fs/mount_options.pm new file mode 100644 index 000000000..0b63f7260 --- /dev/null +++ b/perl-install/fs/mount_options.pm @@ -0,0 +1,276 @@ +package fs::mount_options; + +use diagnostics; +use strict; + +use common; +use fs::type; +use fs::get; +use log; + +sub list() { +    my %non_defaults = ( +			sync => 'async', noatime => 'atime', noauto => 'auto', ro => 'rw',  +			user => 'nouser', nodev => 'dev', noexec => 'exec', nosuid => 'suid', +			user_xattr => 'nouser_xattr', +		       ); +    my @user_implies = qw(noexec nodev nosuid); +    \%non_defaults, \@user_implies; +} + +sub unpack { +    my ($part) = @_; +    my $packed_options = $part->{options}; + +    my ($non_defaults, $user_implies) = list(); + +    my @auto_fs = fs::type::guessed_by_mount(); +    my %per_fs = ( +		  iso9660 => [ qw(unhide) ], +		  vfat => [ qw(flush umask=0 umask=0022) ], +		  ntfs => [ qw(umask=0 umask=0022) ], +		  nfs => [ qw(rsize=8192 wsize=8192) ], +		  cifs => [ qw(username= password=) ], +		  davfs2 => [ qw(username= password= uid= gid=) ], +		  reiserfs => [ 'notail' ], +		 ); +    push @{$per_fs{$_}}, 'usrquota', 'grpquota' foreach 'ext2', 'ext3', 'ext4', 'xfs'; +    push @{$per_fs{$_}}, 'acl' foreach 'ext2', 'ext3', 'ext4', 'reiserfs'; + +    while (my ($fs, $l) = each %per_fs) { +	member($part->{fs_type}, $fs, 'auto') && member($fs, @auto_fs) or next; +	$non_defaults->{$_} = 1 foreach @$l; +    } + +    $non_defaults->{relatime} = 1 if isTrueLocalFS($part) || $part->{fs_type} eq 'ntfs-3g'; + +    my $defaults = { reverse %$non_defaults }; +    my %options = map { $_ => '' } keys %$non_defaults; +    my @unknown; +    foreach (split(",", $packed_options)) { +	if ($_ eq 'defaults') { +	    #- skip +	} elsif (member($_, 'user', 'users')) { +	    $options{$_} = 1 foreach $_, @$user_implies; +	} elsif (exists $non_defaults->{$_}) { +	    $options{$_} = 1; +	} elsif ($defaults->{$_}) { +	    $options{$defaults->{$_}} = 0; +	} elsif (/(.*?=)(.*)/) { +	    $options{$1} = $2; +	} else { +	    push @unknown, $_; +	} +    } +    # merge those, for cleaner help +    $options{'rsize=8192,wsize=8192'} = delete $options{'rsize=8192'} && delete $options{'wsize=8192'} +      if exists $options{'rsize=8192'}; + +    my $unknown = join(",", @unknown); +    \%options, $unknown; +} + +sub pack_ { +    my ($_part, $options, $unknown) = @_; + +    my ($non_defaults, $user_implies) = list(); +    my @l; + +    my @umasks = map { +	if (/^umask=/) { +	    my $v = delete $options->{$_}; +	    /^umask=(.+)/ ? if_($v, $1) : $v; +	} else { () } +    } keys %$options; +    if (@umasks) { +	push @l, 'umask=' . min(@umasks); +    } + +    if (my $user = find { delete $options->{$_} } 'users', 'user') { +	push @l, $user; +	delete $options->{user}; +	foreach (@$user_implies) { +	    if (!delete $options->{$_}) { +		# overriding +		$options->{$non_defaults->{$_}} = 1; +	    } +	} +    } +    push @l, map_each { if_($::b, $::a =~ /=$/ ? "$::a$::b" : $::a) } %$options; +    push @l, $unknown; + +    join(",", uniq(grep { $_ } @l)); +} +sub pack { +    my ($part, $options, $unknown) = @_; +    $unknown =~ s/ /,/g; +    $part->{options} = pack_($part, $options, $unknown) || 'defaults'; +    noreturn(); +} + +# update me on each util-linux new release: +sub help() { +    ( +	'acl' => N("Enable POSIX Access Control Lists"), + +	'flush' => N("Flush write cache on file close"), + +	'grpquota' => N("Enable group disk quota accounting and optionally enforce limits"), + +	'noatime' => N("Do not update inode access times on this filesystem +(e.g, for faster access on the news spool to speed up news servers)."), + +	'relatime' => N("Update inode access times on this filesystem in a more efficient way +(e.g, for faster access on the news spool to speed up news servers)."), + +	'noauto' => N("Can only be mounted explicitly (i.e., +the -a option will not cause the filesystem to be mounted)."), + +	'nodev' => N("Do not interpret character or block special devices on the filesystem."), + +	'noexec' => N("Do not allow execution of any binaries on the mounted +filesystem. This option might be useful for a server that has filesystems +containing binaries for architectures other than its own."), + +	'nosuid' => N("Do not allow set-user-identifier or set-group-identifier +bits to take effect. (This seems safe, but is in fact rather unsafe if you +have suidperl(1) installed.)"), + +	'ro' => N("Mount the filesystem read-only."), + +	'sync' => N("All I/O to the filesystem should be done synchronously."), + +	'users' => N("Allow every user to mount and umount the filesystem."),          + +	'user' => N("Allow an ordinary user to mount the filesystem."),          + +	'usrquota' => N("Enable user disk quota accounting, and optionally enforce limits"), + +        'user_xattr' => N("Support \"user.\" extended attributes"), + +        'umask=0' => N("Give write access to ordinary users"), + +        'umask=0022' => N("Give read-only access to ordinary users"), +    ); +} + + +sub rationalize { +    my ($part) = @_; + +    my ($options, $unknown) = &unpack($part); + +    if ($part->{fs_type} ne 'reiserfs') { +	$options->{notail} = 0; +    } +    if (!fs::type::can_be_one_of_those_fs_types($part, 'vfat', 'cifs', 'iso9660', 'udf')) { +	delete $options->{'codepage='}; +    } +    if (member($part->{mntpoint}, fs::type::directories_needed_to_boot())) { +	foreach (qw(users user noauto)) { +	    if ($options->{$_}) { +		$options->{$_} = 0; +		$options->{$_} = 0 foreach qw(nodev noexec nosuid); +	    } +	} +    } + +    &pack($part, $options, $unknown); +} + +sub set_default { +    my ($part, %opts) = @_; +    #- opts are: security iocharset codepage ignore_is_removable + +    my ($options, $unknown) = &unpack($part); + +    if (!$opts{ignore_is_removable} && $part->{is_removable}  +	  && !member($part->{mntpoint}, fs::type::directories_needed_to_boot())  +	  && (!$part->{fs_type} || $part->{fs_type} eq 'auto' || $part->{fs_type} =~ /:/)) { +	$part->{fs_type} = 'auto'; +	$options->{flush} = 1 if $part->{media_type} ne 'cdrom'; +    } + +    if ($part->{media_type} eq 'cdrom') { +	$options->{ro} = 1; +    } + +    if ($part->{media_type} eq 'fd') { +	# slow device so do not loose time, write now! +	$options->{flush} = 1; +    } + +    if (isTrueLocalFS($part)) { +	#- noatime on laptops (do not wake up the hd) +	#- otherwise relatime (wake up the hd less often / better performances) +	#- Do  not  update  inode  access times on this +	#- filesystem (e.g, for faster access  on  the +	#- news spool to speed up news servers). +	$options->{relatime} = $options->{noatime} = 0; +	$options->{ detect_devices::isLaptop() ? 'noatime' : 'relatime' } = 1 if !$opts{force_atime}; +    } +    if ($part->{fs_type} eq 'nfs') { +	put_in_hash($options, {  +			       nosuid => 1, 'rsize=8192,wsize=8192' => 1, soft => 1, +			      }); +    } +    if ($part->{fs_type} eq 'cifs') { +	add2hash($options, { 'username=' => '%' }) if !$options->{'credentials='}; +    } +    if (fs::type::can_be_this_fs_type($part, 'vfat')) { + +	put_in_hash($options, { +			       users => 1, noexec => 0, +			      }) if $part->{is_removable}; + +	put_in_hash($options, { +			       'umask=0' => $opts{security} <= 1 && !isESP($part), +			       'iocharset=' => $opts{iocharset}, 'codepage=' => $opts{codepage}, +			      }); +    } +    if ($part->{fs_type} eq 'ntfs') { +	put_in_hash($options, { ro => 1, 'nls=' => $opts{iocharset}, +				'umask=0' => $opts{security} < 1, 'umask=0022' => $opts{security} < 2, +			      }); +    } +    if (fs::type::can_be_this_fs_type($part, 'iso9660')) { +	put_in_hash($options, { users => 1, noexec => 0, 'iocharset=' => $opts{iocharset} }); +    } +    if ($part->{fs_type} eq 'reiserfs') { +	$options->{notail} = 1; +	$options->{user_xattr} = 1; +    } +    if (member($part->{fs_type}, qw(ext2 ext3 ext4))) { +	$options->{acl} = 1; +    } +    if (isLoopback($part) && !isSwap($part)) { #- no need for loop option for swap files +	$options->{loop} = 1; +    } + +    # rationalize: no need for user +    if ($options->{autofs}) { +	$options->{users} = $options->{user} = 0; +    } + +    if ($options->{user} || $options->{users}) { +        # have noauto when we have user +        $options->{noauto} = 1; +	# ensure security  (user_implies - noexec as noexec is not a security matter) +	$options->{$_} = 1 foreach 'nodev', 'nosuid'; +    } + +    &pack($part, $options, $unknown); + +    rationalize($part); +} + +sub set_all_default { +    my ($all_hds, %opts) = @_; +    #- opts are: security iocharset codepage + +    foreach my $part (fs::get::really_all_fstab($all_hds)) { +	set_default($part, %opts); +    } +} + +1; | 
