Grant memtrack the capabilities it needs to run without sudo. Best-effort and idempotent: a no-op when running as root or when the caps are already present. Otherwise runs `setcap` (a single sudo prompt) and re-verifies. Failures are surfaced as warnings rather than aborting, since the run-time privilege guard enforces the requirement and reports it clearly.
()
| 54 | /// Failures are surfaced as warnings rather than aborting, since the run-time |
| 55 | /// privilege guard enforces the requirement and reports it clearly. |
| 56 | pub fn ensure_memtrack_capabilities() -> Result<()> { |
| 57 | if is_root_user() { |
| 58 | debug!("Running as root, memtrack does not need file capabilities"); |
| 59 | return Ok(()); |
| 60 | } |
| 61 | |
| 62 | let Some(path) = memtrack_path() else { |
| 63 | warn!("Could not locate {MEMTRACK_COMMAND} to grant capabilities"); |
| 64 | return Ok(()); |
| 65 | }; |
| 66 | |
| 67 | if binary_has_capabilities(&path, memtrack_required_caps_mask()) { |
| 68 | debug!("{MEMTRACK_COMMAND} already has the required capabilities"); |
| 69 | return Ok(()); |
| 70 | } |
| 71 | |
| 72 | info!( |
| 73 | "Granting {MEMTRACK_COMMAND} the capabilities it needs as a one-time setup for the \ |
| 74 | memory instrument (requires sudo)." |
| 75 | ); |
| 76 | let setcap_args = [memtrack_setcap_spec(), path.to_string_lossy().into_owned()]; |
| 77 | if let Err(e) = run_with_sudo("setcap", setcap_args) { |
| 78 | warn!( |
| 79 | "Failed to grant capabilities to {MEMTRACK_COMMAND} ({e}). \ |
| 80 | Memory profiling will require running as root." |
| 81 | ); |
| 82 | return Ok(()); |
| 83 | } |
| 84 | |
| 85 | if !binary_has_capabilities(&path, memtrack_required_caps_mask()) { |
| 86 | warn!( |
| 87 | "Capabilities did not stick on {}. The filesystem may not support file \ |
| 88 | capabilities (e.g. nosuid, overlayfs, NFS). Memory profiling will require running as root.", |
| 89 | path.display() |
| 90 | ); |
| 91 | } |
| 92 | |
| 93 | Ok(()) |
| 94 | } |
| 95 | |
| 96 | pub fn get_memtrack_status() -> ToolStatus { |
| 97 | let tool_name = MEMTRACK_COMMAND.to_string(); |
no test coverage detected