cmd/syncthing: Environment handling for upgrade restarts (fixes #3970)

This commit is contained in:
Jakob Borg 2017-02-07 20:48:53 +01:00
parent 9fda9642d3
commit 204f125ab3
2 changed files with 54 additions and 6 deletions

View File

@ -412,6 +412,34 @@ func main() {
return
}
// ---BEGIN TEMPORARY HACK---
//
// Remove once v0.14.21-v0.14.22 are rare enough. Those versions,
// essentially:
//
// 1. os.Setenv("STMONITORED", "yes")
// 2. os.Setenv("STNORESTART", "")
//
// where the intention was for 2 to cancel out 1 instead of setting
// STNORESTART to the empty value. We check for exactly this combination
// and pretend that neither was set. Looking through os.Environ lets us
// distinguish. Luckily, we weren't smart enough to use os.Unsetenv.
matches := 0
for _, str := range os.Environ() {
if str == "STNORESTART=" {
matches++
}
if str == "STMONITORED=yes" {
matches++
}
}
if matches == 2 {
innerProcess = false
}
// ---END TEMPORARY HACK---
if innerProcess || options.noRestart {
syncthingMain(options)
} else {

View File

@ -35,7 +35,6 @@ const (
)
func monitorMain(runtimeOptions RuntimeOptions) {
os.Setenv("STMONITORED", "yes")
l.SetPrefix("[monitor] ")
var dst io.Writer = os.Stdout
@ -69,6 +68,8 @@ func monitorMain(runtimeOptions RuntimeOptions) {
sigHup := syscall.Signal(1)
signal.Notify(restartSign, sigHup)
childEnv := childEnv()
first := true
for {
if t := time.Since(restarts[0]); t < loopThreshold {
l.Warnf("%d restarts in %v; not retrying further", countRestarts, t)
@ -79,6 +80,7 @@ func monitorMain(runtimeOptions RuntimeOptions) {
restarts[len(restarts)-1] = time.Now()
cmd := exec.Command(args[0], args[1:]...)
cmd.Env = childEnv
stderr, err := cmd.StderrPipe()
if err != nil {
@ -96,10 +98,6 @@ func monitorMain(runtimeOptions RuntimeOptions) {
l.Fatalln(err)
}
// Let the next child process know that this is not the first time
// it's starting up.
os.Setenv("STRESTART", "yes")
stdoutMut.Lock()
stdoutFirstLines = make([]string, 0, 10)
stdoutLastLines = make([]string, 0, 50)
@ -149,7 +147,6 @@ func monitorMain(runtimeOptions RuntimeOptions) {
// Restart the monitor process to release the .old
// binary as part of the upgrade process.
l.Infoln("Restarting monitor...")
os.Setenv("STNORESTART", "")
if err = restartMonitor(args); err != nil {
l.Warnln("Restart:", err)
}
@ -161,6 +158,13 @@ func monitorMain(runtimeOptions RuntimeOptions) {
l.Infoln("Syncthing exited:", err)
time.Sleep(1 * time.Second)
if first {
// Let the next child process know that this is not the first time
// it's starting up.
childEnv = append(childEnv, "STRESTART=yes")
first = false
}
}
}
@ -409,3 +413,19 @@ func (f *autoclosedFile) closerLoop() {
}
}
}
// Returns the desired child environment, properly filtered and added to.
func childEnv() []string {
var env []string
for _, str := range os.Environ() {
if strings.HasPrefix("STNORESTART=", str) {
continue
}
if strings.HasPrefix("STMONITORED=", str) {
continue
}
env = append(env, str)
}
env = append(env, "STMONITORED=yes")
return env
}