helpers: lockfree lookup of nobody user on unix systems (#14866)
* helpers: lockfree lookup of nobody user on linux and darwin This PR continues the nobody user lookup saga, by making the nobody user lookup lock-free on linux and darwin. By doing the lookup in an init block this originally broke on Windows, where we must avoid doing the lookup at all. We can get around that breakage by only doing the lookup on linux/darwin where the nobody user is going to exist. Also return the nobody user by value so that a copy is created that cannot be modified by callers of Nobody(). * helper: move nobody code into unix file
This commit is contained in:
parent
1593963cd1
commit
ba1e337f8b
|
@ -1,4 +1,4 @@
|
|||
//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
|
||||
//go:build unix
|
||||
|
||||
package allocdir
|
||||
|
||||
|
@ -40,17 +40,14 @@ func dropDirPermissions(path string, desired os.FileMode) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
nobody, err := users.Nobody()
|
||||
nobody := users.Nobody()
|
||||
|
||||
uid, err := getUid(&nobody)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
uid, err := getUid(nobody)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
gid, err := getGid(nobody)
|
||||
gid, err := getGid(&nobody)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -9,23 +9,6 @@ import (
|
|||
// some NSS implementations are not concurrency safe
|
||||
var lock sync.Mutex
|
||||
|
||||
// nobody is a cached copy of the nobody user, which is going to be looked-up
|
||||
// frequently and is unlikely to be modified on the underlying system.
|
||||
var nobody *user.User
|
||||
|
||||
// Nobody returns User data for the "nobody" user on the system, bypassing the
|
||||
// locking / file read / NSS lookup.
|
||||
func Nobody() (*user.User, error) {
|
||||
lock.Lock()
|
||||
defer lock.Unlock()
|
||||
if nobody != nil {
|
||||
return nobody, nil
|
||||
}
|
||||
u, err := user.Lookup("nobody")
|
||||
nobody = u
|
||||
return u, err
|
||||
}
|
||||
|
||||
// Lookup username while holding a global process lock.
|
||||
func Lookup(username string) (*user.User, error) {
|
||||
lock.Lock()
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
//go:build unix
|
||||
|
||||
package users
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os/user"
|
||||
)
|
||||
|
||||
// nobody is a cached copy of the nobody user, which is going to be looked-up
|
||||
// frequently and is unlikely to be modified on the underlying system.
|
||||
var nobody user.User
|
||||
|
||||
// Nobody returns User data for the "nobody" user on the system, bypassing the
|
||||
// locking / file read / NSS lookup.
|
||||
func Nobody() user.User {
|
||||
return nobody
|
||||
}
|
||||
|
||||
func init() {
|
||||
u, err := Lookup("nobody")
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("failed to lookup nobody user: %v", err))
|
||||
}
|
||||
nobody = *u
|
||||
}
|
Loading…
Reference in New Issue