@@ -812,12 +812,65 @@ fn main() -> i32 {
812812 - ** Cgroup** : target = cgroup path ("/sys/fs/cgroup/test"), flags = unused (0)
813813- Returns 0 on success, negative error code on failure
814814
815+ ** ` detach(handle: ProgramHandle) -> void ` **
816+ - Detaches the program from its current attachment point using its handle
817+ - Automatically determines the correct detachment method based on program type:
818+ - ** XDP** : Uses ` bpf_xdp_detach() ` with stored interface and flags
819+ - ** TC** : Uses ` bpf_tc_detach() ` with stored interface and direction
820+ - ** Kprobe/Tracepoint** : Destroys the stored ` bpf_link ` handle
821+ - No return value (void) - logs errors to stderr if detachment fails
822+ - Safe to call multiple times on the same handle (no-op if already detached)
823+ - Automatically cleans up internal attachment tracking
824+
815825** Safety Benefits:**
816826- ** Compile-time enforcement** : Cannot call ` attach() ` without first calling ` load() ` - the type system prevents this
817827- ** Implementation abstraction** : Users work with ` ProgramHandle ` instead of raw file descriptors
818828- ** Resource safety** : Program handles abstract away the underlying resource management
829+ - ** Automatic cleanup** : ` detach() ` handles all program types uniformly and cleans up tracking data
830+ - ** Idempotent operations** : Safe to call ` detach() ` multiple times without side effects
831+
832+ #### 3.5.3 Lifecycle Best Practices
833+
834+ ** Proper Cleanup Patterns:**
835+ ``` kernelscript
836+ fn main() -> i32 {
837+ var prog1 = load(filter)
838+ var prog2 = load(monitor)
839+
840+ // Attach programs
841+ var result1 = attach(prog1, "eth0", 0)
842+ var result2 = attach(prog2, "eth0", 1)
843+
844+ // Error handling with partial cleanup
845+ if (result1 != 0 || result2 != 0) {
846+ // Clean up any successful attachments before returning
847+ if (result1 == 0) detach(prog1)
848+ if (result2 == 0) detach(prog2)
849+ return 1
850+ }
851+
852+ // Normal operation...
853+ print("Programs running...")
854+
855+ // Proper shutdown: detach in reverse order
856+ detach(prog2) // Last attached, first detached
857+ detach(prog1)
858+
859+ return 0
860+ }
861+ ```
862+
863+ ** Multi-Program Detachment Order:**
864+ - Always detach programs in ** reverse order** of attachment
865+ - This ensures dependencies are cleaned up properly
866+ - Example: if ` filter ` depends on ` monitor ` , detach ` monitor ` first
867+
868+ ** Error Recovery:**
869+ - Use conditional detachment for partial failure scenarios
870+ - Safe to call ` detach() ` multiple times on the same handle
871+ - Always clean up successful attachments before returning error codes
819872
820- #### 3.5.3 Advanced Usage Patterns
873+ #### 3.5.4 Advanced Usage Patterns
821874
822875** Configuration Between Load and Attach:**
823876``` kernelscript
@@ -855,6 +908,13 @@ fn main(args: Args) -> i32 {
855908
856909 if (result == 0) {
857910 print("Filter attached successfully")
911+
912+ // Simulate running the program (in real usage, this might be an event loop)
913+ print("Filter is processing packets...")
914+
915+ // Proper cleanup when shutting down
916+ detach(prog_handle)
917+ print("Filter detached successfully")
858918 } else {
859919 print("Failed to attach filter")
860920 return 1
@@ -2749,6 +2809,14 @@ fn main() -> i32 {
27492809 attach(filter_handle, "eth0", 0)
27502810 attach(monitor_handle, "eth0", 1)
27512811
2812+ print("Multiple programs attached to eth0")
2813+ print("Running packet processing pipeline...")
2814+
2815+ // Proper cleanup - detach in reverse order (best practice)
2816+ detach(monitor_handle)
2817+ detach(filter_handle)
2818+ print("All programs detached successfully")
2819+
27522820 return 0
27532821}
27542822```
@@ -3196,7 +3264,7 @@ fn main() -> i32 {
31963264fn main() -> i32 {
31973265 try {
31983266 var prog = load(packet_filter)
3199- attach(prog, "eth0", 0)
3267+ attach(prog, "eth0", 0)
32003268 print("Program attached successfully")
32013269 return 0
32023270
@@ -4085,6 +4153,13 @@ fn main(args: Args) -> i32 {
40854153
40864154 if (filter_result != 0 || monitor_result != 0) {
40874155 print("Failed to attach programs to interface: ", args.interface)
4156+ // Clean up any successful attachments
4157+ if (filter_result == 0) {
4158+ detach(filter_handle)
4159+ }
4160+ if (monitor_result == 0) {
4161+ detach(monitor_handle)
4162+ }
40884163 return 1
40894164 }
40904165
@@ -4099,13 +4174,21 @@ fn main(args: Args) -> i32 {
40994174 }
41004175
41014176 // Monitor system health using config stats
4102- while (true) {
4177+ var iteration_count = 0
4178+ while (iteration_count < 100) { // Run for limited time in example
41034179 if (system.packets_dropped > 1000 && !args.quiet_mode) {
41044180 print("High drop rate detected: ", system.packets_dropped)
41054181 }
41064182 sleep(10000)
4183+ iteration_count += 1
41074184 }
41084185
4186+ // Proper cleanup when shutting down
4187+ print("Shutting down, detaching programs...")
4188+ detach(monitor_handle) // Detach in reverse order
4189+ detach(filter_handle)
4190+ print("All programs detached successfully")
4191+
41094192 return 0
41104193}
41114194```
0 commit comments