2023-08-31 16:17:46 +01:00
package storage
import (
"fmt"
"os"
"path/filepath"
"strconv"
"strings"
"github.com/AlexSSD7/linsk/nettap"
"github.com/pkg/errors"
)
const tapAllocPrefix = "tap_alloc_"
func ( s * Storage ) getAllocFilePath ( tapName string ) ( string , error ) {
err := nettap . ValidateTapName ( tapName )
if err != nil {
return "" , errors . Wrap ( err , "validate tap name" )
}
return filepath . Join ( s . path , tapAllocPrefix + tapName ) , nil
}
func ( s * Storage ) SaveNetTapAllocation ( tapName string , pid int ) error {
allocFilePath , err := s . getAllocFilePath ( tapName )
if err != nil {
return errors . Wrap ( err , "get alloc file path" )
}
err = os . WriteFile ( allocFilePath , [ ] byte ( fmt . Sprint ( pid ) ) , 0400 )
if err != nil {
return errors . Wrap ( err , "write alloc file" )
}
return nil
}
func ( s * Storage ) ReleaseNetTapAllocation ( tapName string ) error {
allocFilePath , err := s . getAllocFilePath ( tapName )
if err != nil {
return errors . Wrap ( err , "get alloc file path" )
}
err = os . Remove ( allocFilePath )
if err != nil {
2023-08-31 20:17:55 +01:00
if errors . Is ( err , os . ErrNotExist ) {
s . logger . Warn ( "Attempted to remove non-existent tap allocation" , "tap-name" , tapName )
return nil
}
2023-08-31 16:17:46 +01:00
return errors . Wrap ( err , "remove alloc file" )
}
return nil
}
2023-09-02 12:07:30 +01:00
func ( s * Storage ) ListNetTapAllocations ( ) ( [ ] nettap . Alloc , error ) {
2023-08-31 16:17:46 +01:00
dirEntries , err := os . ReadDir ( s . path )
if err != nil {
return nil , errors . Wrap ( err , "read data dir" )
}
2023-09-02 12:07:30 +01:00
var ret [ ] nettap . Alloc
2023-08-31 16:17:46 +01:00
for _ , entry := range dirEntries {
if strings . HasPrefix ( entry . Name ( ) , tapAllocPrefix ) {
entryPath := filepath . Join ( s . path , entry . Name ( ) )
tapName := strings . TrimPrefix ( entry . Name ( ) , tapAllocPrefix )
err := nettap . ValidateTapName ( tapName )
if err != nil {
s . logger . Error ( "Failed to validate network tap name in tap allocation file, skipping. External interference?" , "error" , err . Error ( ) , "name" , tapName , "path" , entryPath )
continue
}
data , err := os . ReadFile ( entryPath )
if err != nil {
return nil , errors . Wrapf ( err , "read tap alloc file '%v'" , entryPath )
}
pid , err := strconv . ParseUint ( string ( data ) , 10 , strconv . IntSize - 1 ) // We're aiming for `int` PID.
if err != nil {
return nil , errors . Wrapf ( err , "parse pid (alloc file '%v')" , entryPath )
}
2023-09-02 12:07:30 +01:00
ret = append ( ret , nettap . Alloc {
2023-08-31 16:17:46 +01:00
TapName : tapName ,
PID : int ( pid ) ,
} )
}
}
return ret , nil
}