MCPcopy
hub / github.com/cloudflare/cloudflared / acquireLockFile

Function acquireLockFile

token/token.go:111–165  ·  view source on GitHub ↗

acquireLockFile loops until it successfully creates a lock file for the given token file path. The lock file is created at tokenPath + ".lock". On each iteration: 1. Try to create the file atomically with O_CREATE|O_EXCL. If that succeeds, write our PID + start time and return nil. 2. If the file a

(tokenPath string, log *zerolog.Logger)

Source from the content-addressed store, hash-verified

109// retry the O_EXCL create. No sleep (the atomic create is the
110// tiebreaker if multiple processes race to reclaim).
111func acquireLockFile(tokenPath string, log *zerolog.Logger) error {
112 lockPath := tokenPath + ".lock"
113 deadline := time.Now().Add(lockTimeout)
114 lastURL := ""
115 for {
116 if time.Now().After(deadline) {
117 return fmt.Errorf("timed out waiting for lock file %s", lockPath)
118 }
119 err := tryCreateLockFile(lockPath)
120 if err == nil {
121 log.Debug().Str("path", lockPath).Msg("lock file acquired")
122 return nil
123 }
124 if !os.IsExist(err) {
125 return errors.Wrapf(err, "failed to create lock file %s", lockPath)
126 }
127
128 // lock file exists, so check if the owner is still alive
129 stale, content, checkErr := isLockFileStale(lockPath)
130 if checkErr != nil {
131 // file may be mid-write by another racer, or was removed
132 // between our O_EXCL attempt and this read
133 log.Debug().Err(checkErr).Str("path", lockPath).
134 Msg("could not read lock file, retrying")
135 time.Sleep(lockRetryInterval)
136 continue
137 }
138
139 if !stale {
140 // try to display the auth URL so the user can open a browser
141 // manually if the original window is not visible
142 if authURL := readAuthURL(tokenPath); authURL != "" && authURL != lastURL {
143 fmt.Fprintf(os.Stderr, "\nAnother cloudflared process (pid %d) "+
144 "is already waiting for authentication.\n\n"+
145 "If a browser window did not open, please visit "+
146 "the following URL:\n\n%s\n\n", content.PID, authURL)
147 lastURL = authURL
148 }
149 log.Debug().Str("path", lockPath).
150 Msg("lock file is held by another process, retrying")
151 time.Sleep(lockRetryInterval)
152 continue
153 }
154
155 // stale, so remove and immediately retry
156 log.Debug().Str("path", lockPath).Int32("stale_pid", content.PID).
157 Msg("reclaiming stale lock file")
158 if removeErr := os.Remove(lockPath); removeErr != nil && !os.IsNotExist(removeErr) {
159 log.Debug().Err(removeErr).Str("path", lockPath).
160 Msg("could not remove stale lock file, retrying")
161 time.Sleep(lockRetryInterval)
162 continue
163 }
164 }
165}
166
167// readAuthURL reads the auth URL companion file for the given token path.
168// Returns the URL string, or empty string if the file doesn't exist or

Callers 1

getTokenFunction · 0.85

Calls 7

tryCreateLockFileFunction · 0.85
isLockFileStaleFunction · 0.85
readAuthURLFunction · 0.85
ErrorfMethod · 0.80
AddMethod · 0.65
RemoveMethod · 0.65
ErrMethod · 0.45

Tested by

no test coverage detected