@@ -160,33 +160,41 @@ pass on lo0 all
160160 // Write rules to temp file for debugging
161161 fs:: write ( & self . pf_rules_path , rules) . context ( "Failed to write PF rules file" ) ?;
162162
163- // Load rules into anchor using stdin to avoid -f flag issues in CI
164- info ! ( "Loading PF rules into anchor {}" , PF_ANCHOR_NAME ) ;
165- let mut child = Command :: new ( "pfctl" )
166- . args ( [ "-a" , PF_ANCHOR_NAME , "-f" , "-" ] )
167- . stdin ( std:: process:: Stdio :: piped ( ) )
168- . stdout ( std:: process:: Stdio :: piped ( ) )
169- . stderr ( std:: process:: Stdio :: piped ( ) )
170- . spawn ( )
171- . context ( "Failed to spawn pfctl" ) ?;
172-
173- // Write rules to stdin
174- use std:: io:: Write ;
175- if let Some ( mut stdin) = child. stdin . take ( ) {
176- stdin
177- . write_all ( rules. as_bytes ( ) )
178- . context ( "Failed to write rules to pfctl" ) ?;
179- }
180-
181- let output = child
182- . wait_with_output ( )
163+ // Try to load rules using file first (standard approach)
164+ info ! ( "Loading PF rules from {}" , self . pf_rules_path) ;
165+ let output = Command :: new ( "pfctl" )
166+ . args ( [ "-a" , PF_ANCHOR_NAME , "-f" , & self . pf_rules_path ] )
167+ . output ( )
183168 . context ( "Failed to load PF rules" ) ?;
184169
185- if !output. status . success ( ) {
186- anyhow:: bail!(
187- "Failed to load PF rules: {}" ,
188- String :: from_utf8_lossy( & output. stderr)
189- ) ;
170+ // Check for actual errors vs warnings
171+ let stderr = String :: from_utf8_lossy ( & output. stderr ) ;
172+
173+ // The -f warning is not fatal, but resource busy is
174+ if stderr. contains ( "Resource busy" ) {
175+ // Try to flush the anchor first and retry
176+ warn ! ( "PF anchor busy, attempting to flush and retry" ) ;
177+ let _ = Command :: new ( "pfctl" )
178+ . args ( [ "-a" , PF_ANCHOR_NAME , "-F" , "rules" ] )
179+ . output ( ) ;
180+
181+ // Retry loading rules
182+ let retry_output = Command :: new ( "pfctl" )
183+ . args ( [ "-a" , PF_ANCHOR_NAME , "-f" , & self . pf_rules_path ] )
184+ . output ( )
185+ . context ( "Failed to load PF rules on retry" ) ?;
186+
187+ let retry_stderr = String :: from_utf8_lossy ( & retry_output. stderr ) ;
188+ if !retry_output. status . success ( ) && !retry_stderr. contains ( "Use of -f option" ) {
189+ anyhow:: bail!( "Failed to load PF rules after retry: {}" , retry_stderr) ;
190+ }
191+ } else if !output. status . success ( ) && !stderr. contains ( "Use of -f option" ) {
192+ anyhow:: bail!( "Failed to load PF rules: {}" , stderr) ;
193+ }
194+
195+ // Log if we got the -f warning but continued
196+ if stderr. contains ( "Use of -f option" ) {
197+ debug ! ( "PF rules loaded (ignoring -f flag warning in CI)" ) ;
190198 }
191199
192200 // Enable PF if not already enabled
0 commit comments