Fix forever waiting on services not properly closing pipes at start

This commit is contained in:
yo 2023-06-10 14:12:53 +02:00
parent 7c3e14f0f1
commit 6f9bb504be
2 changed files with 70 additions and 4 deletions

View File

@ -1423,9 +1423,9 @@ func StartJail(args []string) {
if len(cj.Config.Exec_start) > 0 {
fmt.Printf(" > Start services:\n")
cmd := fmt.Sprintf("/usr/sbin/setfib %s /usr/sbin/jexec %d %s", cj.Config.Exec_fib, cj.JID, cj.Config.Exec_start)
out, err := executeCommand(cmd)
err := executeCommandNonBlocking(cmd)
if err != nil && len(out) > 0 {
fmt.Printf("Error: %v: %s\n", err, out)
fmt.Printf("Error: %v\n", err)
} else {
fmt.Printf(" > Start services: OK\n")
}

View File

@ -215,7 +215,7 @@ func executeCommand(cmdline string) (string, error) {
// else
word = word + string(c)
}
if len(cmd) > 1 {
out, err = exec.Command(cmd[0], cmd[1:]...).CombinedOutput()
} else {
@ -225,6 +225,72 @@ func executeCommand(cmdline string) (string, error) {
return string(out), err
}
/* From iocage:
* # Courtesy of @william-gr
* # service(8) and some rc.d scripts have the bad h*abit of
* # exec'ing and never closing stdout/stderr. This makes
* # sure we read only enough until the command exits and do
* # not wait on the pipe to close on the other end.
* So this function executes process without waiting after completion
*/
func executeCommandNonBlocking(cmdline string) (error) {
var cmd []string
var oCmd *exec.Cmd
var err error
if gUseSudo {
cmd = append(cmd, "sudo")
}
var word string
var in_escaped bool
// Split by words, or " enclosed words
for i, c := range (cmdline) {
if string(c) == "\"" {
if in_escaped {
// This is the closing "
cmd = append(cmd, word)
in_escaped = false
} else {
in_escaped = true
}
continue
}
if string(c) == " " {
if in_escaped {
word = word + string(c)
continue
} else {
cmd = append(cmd, word)
word = ""
continue
}
}
if i == (len(cmdline) - 1) {
word = word + string(c)
cmd = append(cmd, word)
break
}
// else
word = word + string(c)
}
if len(cmd) > 1 {
oCmd = exec.Command(cmd[0], cmd[1:]...)
} else {
oCmd = exec.Command(cmd[0])
}
if err = oCmd.Start(); err != nil {
return err
}
err = oCmd.Wait()
return err
}
// Executed command outputs to stdout in realtime
func executeCommandWithOutputToStdout(cmdline string) (error) {
var cmd []string
@ -616,7 +682,7 @@ func copyDevfsRuleset(ruleset int, srcrs int) error {
/********************************************************************************
* Returns value of parameter as read in /var/run/jail.$InternalName.conf
* Directoves without value will return "true" if found
* Directives without value will return "true" if found
* Returns an error if parameter not found in file
*******************************************************************************/
func getValueFromRunningConfig(jname string, param string) (string, error) {