Repository: metalbear-co/mirrord (language: rust)

Issue:
mirrord fails when sniffer fails on old kernel
was supposed to be fixed in 3.124.1 thanks to https://github.com/metalbear-co/mirrord/pull/2897 but apparently not


Discussion / hints:
<p><a href="https://linear.app/metalbear/issue/MBE-514/mirrord-fails-when-sniffer-fails-on-old-kernel">MBE-514 mirrord fails when sniffer fails on old kernel</a></p>
https://github.com/metalbear-co/mirrord/blob/81315899855bc742a7c7a094f44d737005429501/mirrord/agent/src/sniffer.rs#L167

Don't we need to change this to just log the error instead of `?`.

Fix patch:
diff --git a/changelog.d/2909.fixed.md b/changelog.d/2909.fixed.md
new file mode 100644
index 00000000000..23ac39d2c75
--- /dev/null
+++ b/changelog.d/2909.fixed.md
@@ -0,0 +1,1 @@
+Fix agent crash on sniffer failure
diff --git a/mirrord/agent/src/entrypoint.rs b/mirrord/agent/src/entrypoint.rs
index 78affd80407..28eb5f26634 100644
--- a/mirrord/agent/src/entrypoint.rs
+++ b/mirrord/agent/src/entrypoint.rs
@@ -514,17 +514,29 @@ async fn start_agent(args: Args) -> Result<()> {
     } else {
         let cancellation_token = cancellation_token.clone();
         let is_mesh = args.is_mesh();
-
+        // We're using this to avoid crashing on old kernels when initializing the
+        // `RawSocketTcpCapture`. failed task causes the agent to exit
+        // so we just check that initialization was successful
+        // then decide whether to store the task or drop it
+        // https://github.com/metalbear-co/mirrord/pull/2910
+        let (sniffer_init_tx, sniffer_init_rx) = tokio::sync::oneshot::channel::<bool>();
         let watched_task = WatchedTask::new(
             TcpConnectionSniffer::<RawSocketTcpCapture>::TASK_NAME,
             async move {
-                let res =
+                if let Ok(sniffer) =
                     TcpConnectionSniffer::new(sniffer_command_rx, args.network_interface, is_mesh)
-                        .and_then(|sniffer| sniffer.start(cancellation_token))
-                        .await;
-
-                if let Err(error) = res {
-                    tracing::error!(%error, "Sniffer failed");
+                        .await
+                {
+                    if let Err(error) = sniffer_init_tx.send(true) {
+                        tracing::error!(%error, "Failed to send sniffer init result");
+                    };
+                    // will block from this point on
+                    let res = sniffer.start(cancellation_token).await;
+                    if let Err(err) = res {
+                        error!(%err, "Sniffer failed");
+                    }
+                } else if let Err(error) = sniffer_init_tx.send(false) {
+                    tracing::error!(%error, "Failed to send sniffer init result");
                 }
 
                 Ok(())
@@ -538,7 +550,14 @@ async fn start_agent(args: Args) -> Result<()> {
             "net",
         );
 
-        (Some(task), Some(status))
+        match sniffer_init_rx.await {
+            Ok(true) => (Some(task), Some(status)),
+            Ok(false) => (None, None),
+            Err(error) => {
+                tracing::error!(%error, "unexpected error while waiting for sniffer init");
+                (None, None)
+            }
+        }
     };
 
     let (stealer_task, stealer_status) = if args.mode.is_targetless() {


Test patch: