Skip to content

Commit 43fc41d

Browse files
committed
feat(mount): add data field to MountSpec
1 parent 776de30 commit 43fc41d

3 files changed

Lines changed: 41 additions & 3 deletions

File tree

src/config.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,9 @@ pub struct MountSpec {
250250

251251
/// Whether the mount point should be mounted readonly.
252252
pub read_only: bool,
253+
254+
/// Optional mount data (e.g., "size=64m" for tmpfs).
255+
pub data: Option<String>,
253256
}
254257

255258
pub trait Mountable {

src/mount.rs

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,29 @@ impl Mountable for MountSpec {
146146
let target_p = target.as_ptr();
147147

148148
if self.create_mountpoint {
149-
fs::create_dir_all(&self.target)?;
149+
if self.bind {
150+
// For bind mounts, match the source type: if the source is a
151+
// file/device, create an empty file at the target (not a directory).
152+
// Bind-mounting a file onto a directory fails with EINVAL.
153+
if let Some(ref src) = self.source {
154+
let is_dir = std::path::Path::new(src)
155+
.metadata()
156+
.map(|m| m.is_dir())
157+
.unwrap_or(true);
158+
if is_dir {
159+
fs::create_dir_all(&self.target)?;
160+
} else {
161+
if let Some(parent) = std::path::Path::new(&self.target).parent() {
162+
fs::create_dir_all(parent)?;
163+
}
164+
fs::File::create(&self.target)?;
165+
}
166+
} else {
167+
fs::create_dir_all(&self.target)?;
168+
}
169+
} else {
170+
fs::create_dir_all(&self.target)?;
171+
}
150172
}
151173

152174
let mut flags: c_ulong = libc::MS_SILENT;
@@ -163,10 +185,17 @@ impl Mountable for MountSpec {
163185
flags |= libc::MS_REC;
164186
}
165187

188+
let data_cstr = self.data.as_ref().map(|d| CString::new(d.as_str()).unwrap());
189+
let data_ptr = data_cstr.as_ref().map(|c| c.as_ptr() as *const libc::c_void).unwrap_or(ptr::null());
190+
166191
unsafe {
167-
let rc = libc::mount(source_p, target_p, fstype_p, flags, ptr::null());
192+
let rc = libc::mount(source_p, target_p, fstype_p, flags, data_ptr);
168193
if rc < 0 {
169-
bail!("unable to mount");
194+
let err = io::Error::last_os_error();
195+
bail!(
196+
"unable to mount: source={:?} target={:?} fstype={:?} bind={} flags=0x{:x}: {}",
197+
self.source, self.target, self.fstype, self.bind, flags, err
198+
);
170199
}
171200
}
172201

src/wrap.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,7 @@ impl CreateRequest {
321321
safe: false,
322322
create_mountpoint: false,
323323
read_only: false,
324+
data: None,
324325
};
325326

326327
oldroot
@@ -345,6 +346,7 @@ impl CreateRequest {
345346
safe: true,
346347
create_mountpoint: true,
347348
read_only: false,
349+
data: None,
348350
};
349351
stage_tmpfs
350352
.mount()
@@ -365,6 +367,7 @@ impl CreateRequest {
365367
safe: false,
366368
create_mountpoint: false,
367369
read_only: false,
370+
data: None,
368371
};
369372
stage_bind
370373
.mount()
@@ -384,6 +387,7 @@ impl CreateRequest {
384387
safe: false,
385388
create_mountpoint: false,
386389
read_only: false,
390+
data: None,
387391
};
388392

389393
newroot
@@ -407,6 +411,7 @@ impl CreateRequest {
407411
safe: true,
408412
create_mountpoint: false,
409413
read_only: false,
414+
data: None,
410415
};
411416

412417
procfs
@@ -426,6 +431,7 @@ impl CreateRequest {
426431
safe: mount.safe,
427432
create_mountpoint: mount.create_mountpoint,
428433
read_only: mount.read_only,
434+
data: None,
429435
};
430436

431437
parented_mount

0 commit comments

Comments
 (0)