[pve-devel] [PATCH container] lxc: read-only bind mounts
Wolfgang Bumiller
w.bumiller at proxmox.com
Fri Feb 12 11:40:35 CET 2016
Factored the bind-mounting into a bindmount() function since
we don't want to leave a writable bind-mount behind if the
read-only remount fails.
The read-only flag is now also removed from the initial
mount flags and is added only for the remount command and is
added separately the non-bind mounts.
---
src/PVE/LXC.pm | 33 ++++++++++++++++++---------------
1 file changed, 18 insertions(+), 15 deletions(-)
diff --git a/src/PVE/LXC.pm b/src/PVE/LXC.pm
index e701202..d4b6d8b 100644
--- a/src/PVE/LXC.pm
+++ b/src/PVE/LXC.pm
@@ -2256,6 +2256,19 @@ sub run_with_loopdev {
return $device;
}
+sub bindmount {
+ my ($dir, $dest, $ro, @extra_opts) = @_;
+ PVE::Tools::run_command(['mount', '-o', 'bind', @extra_opts, $dir, $dest]);
+ if ($ro) {
+ eval { PVE::Tools::run_command(['mount', '-o', 'bind,remount,ro', $dest]); };
+ if (my $err = $@) {
+ warn $err;
+ # don't leave writable bind-mounts behind...
+ PVE::Tools::run_command(['umount', $dest]);
+ }
+ }
+}
+
# use $rootdir = undef to just return the corresponding mount path
sub mountpoint_mount {
my ($mountpoint, $rootdir, $storage_cfg, $snapname) = @_;
@@ -2286,10 +2299,7 @@ sub mountpoint_mount {
if (defined($mountpoint->{acl})) {
$optstring .= ($mountpoint->{acl} ? 'acl' : 'noacl');
}
- if ($mountpoint->{ro}) {
- $optstring .= ',' if $optstring;
- $optstring .= 'ro';
- }
+ my $readonly = $mountpoint->{ro};
my @extra_opts = ('-o', $optstring);
@@ -2314,10 +2324,7 @@ sub mountpoint_mount {
die "cannot mount subvol snapshots for storage type '$scfg->{type}'\n";
}
} else {
- if ($mountpoint->{ro}) {
- die "read-only bind mounts not supported\n";
- }
- PVE::Tools::run_command(['mount', '-o', 'bind', @extra_opts, $path, $mount_path]);
+ bindmount($path, $mount_path, $readonly, @extra_opts);
warn "cannot enable quota control for bind mounted subvolumes\n" if $quota;
}
}
@@ -2334,6 +2341,7 @@ sub mountpoint_mount {
if ($quota) {
push @extra_opts, '-o', 'usrjquota=aquota.user,grpjquota=aquota.group,jqfmt=vfsv0';
}
+ push @extra_opts, '-o', 'ro' if $readonly;
PVE::Tools::run_command(['mount', @extra_opts, $path, $mount_path]);
}
}
@@ -2354,18 +2362,13 @@ sub mountpoint_mount {
die "unsupported image format '$format'\n";
}
} elsif ($type eq 'device') {
+ push @extra_opts, '-o', 'ro' if $readonly;
PVE::Tools::run_command(['mount', @extra_opts, $volid, $mount_path]) if $mount_path;
return wantarray ? ($volid, 0, $volid) : $volid;
} elsif ($type eq 'bind') {
- if ($mountpoint->{ro}) {
- die "read-only bind mounts not supported\n";
- # Theoretically we'd have to execute both:
- # mount -o bind $a $b
- # mount -o bind,remount,ro $a $b
- }
die "directory '$volid' does not exist\n" if ! -d $volid;
&$check_mount_path($volid);
- PVE::Tools::run_command(['mount', '-o', 'bind', @extra_opts, $volid, $mount_path]) if $mount_path;
+ bindmount($volid, $mount_path, $readonly, @extra_opts) if $mount_path;
warn "cannot enable quota control for bind mounts\n" if $quota;
return wantarray ? ($volid, 0, undef) : $volid;
}
--
2.1.4
More information about the pve-devel
mailing list