Unmount local FS before stopping jail

This commit is contained in:
yo
2022-04-02 14:17:10 +02:00
parent 30209d2890
commit 349ea12979
3 changed files with 145 additions and 3 deletions

View File

@ -1,9 +1,15 @@
package cmd
import (
"os"
"fmt"
"sort"
"bufio"
"errors"
"os/exec"
"reflect"
"strings"
"strconv"
)
/*****************************************************************************
@ -57,6 +63,102 @@ func executeCommandInJail(jail *Jail, cmdline string) (string, error) {
return string(out), err
}
/*****************************************************************************
* Parse an fstab file, returning an array of Mount
*****************************************************************************/
func getFstab(path string) ([]Mount, error) {
var mounts []Mount
f, err := os.Open(path)
if err != nil {
return mounts, err
}
defer f.Close()
scan := bufio.NewScanner(f)
for scan.Scan() {
res := strings.Fields(scan.Text())
if len(res) != 6 {
return mounts, fmt.Errorf("Incorrect format for fstab line %s", scan.Text())
}
freq, err := strconv.Atoi(res[4])
if err != nil {
return mounts, fmt.Errorf("Incorrect format for fstab line %s: Dump is not an integer\n", scan.Text())
}
pass, err := strconv.Atoi(res[5])
if err != nil {
return mounts, fmt.Errorf("Incorrect format for fstab line %s: Pass is not an integer\n", scan.Text())
}
m := Mount{
Device : res[0],
Mountpoint : res[1],
Type : res[2],
Options : strings.Split(res[3], ","),
Fs_Freq : freq,
Fs_Passno : pass,
}
mounts = append(mounts, m)
}
return mounts, nil
}
/*****************************************************************************
* Get a specific jail source reference, to update properties after a range loop
*****************************************************************************/
func getJailFromArray(internalName string, jarray []Jail) (*Jail, error) {
for _, j := range jarray {
if internalName == j.InternalName {
return &j, nil
}
}
return &Jail{}, errors.New("Jail not found")
}
/*
*/
// Recurse into structure, returning reflect.Kind of named field.
// Nested fields are named with a dot (ex "MyStruct.MyField")
func getStructFieldKind(parentStruct interface{}, fieldName string) (reflect.Kind, string, error) {
v := reflect.ValueOf(parentStruct)
if v.Kind() == reflect.Ptr {
v = v.Elem()
}
// For debugging
if false {
for i := 0 ; i < v.NumField(); i++ {
f := v.Field(i)
if f.Kind() == reflect.String {
fmt.Printf("%v=%v\n", v.Type().Field(i).Name, f.Interface())
}
}
}
if strings.Contains(fieldName, ".") {
fs := strings.Split(fieldName, ".")
f := v.FieldByName(fs[0])
if f.Kind() == reflect.Struct {
return getStructFieldKind(f.Interface(), strings.Join(fs[1:], "."))
} else {
return reflect.Kind(0), fieldName, errors.New(fmt.Sprintf("%s is not a struct: %s\n", fs[0], f.Kind().String()))
}
} else {
f := v.FieldByName(fieldName)
if f.IsValid() {
return f.Kind(), fieldName, nil
} else {
return reflect.Kind(0), fieldName, errors.New(fmt.Sprintf("Field not found: %s", fieldName))
}
}
return reflect.Kind(0), fieldName, errors.New(fmt.Sprintf("Field not found: %s", fieldName))
}
/*****************************************************************************
*