github.com/minio/minio@v0.0.0-20240328213742-3f72439b8a27/internal/lock/lock_solaris.go (about) 1 //go:build solaris 2 // +build solaris 3 4 // Copyright (c) 2015-2021 MinIO, Inc. 5 // 6 // This file is part of MinIO Object Storage stack 7 // 8 // This program is free software: you can redistribute it and/or modify 9 // it under the terms of the GNU Affero General Public License as published by 10 // the Free Software Foundation, either version 3 of the License, or 11 // (at your option) any later version. 12 // 13 // This program is distributed in the hope that it will be useful 14 // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 // GNU Affero General Public License for more details. 17 // 18 // You should have received a copy of the GNU Affero General Public License 19 // along with this program. If not, see <http://www.gnu.org/licenses/>. 20 21 package lock 22 23 import ( 24 "os" 25 "syscall" 26 ) 27 28 // lockedOpenFile is an internal function. 29 func lockedOpenFile(path string, flag int, perm os.FileMode, rlockType int) (*LockedFile, error) { 30 var lockType int16 31 switch flag { 32 case syscall.O_RDONLY: 33 lockType = syscall.F_RDLCK 34 case syscall.O_WRONLY: 35 fallthrough 36 case syscall.O_RDWR: 37 fallthrough 38 case syscall.O_WRONLY | syscall.O_CREAT: 39 fallthrough 40 case syscall.O_RDWR | syscall.O_CREAT: 41 lockType = syscall.F_WRLCK 42 default: 43 return nil, &os.PathError{ 44 Op: "open", 45 Path: path, 46 Err: syscall.EINVAL, 47 } 48 } 49 50 lock := syscall.Flock_t{ 51 Start: 0, 52 Len: 0, 53 Pid: 0, 54 Type: lockType, 55 Whence: 0, 56 } 57 58 f, err := os.OpenFile(path, flag, perm) 59 if err != nil { 60 return nil, err 61 } 62 63 if err = syscall.FcntlFlock(f.Fd(), rlockType, &lock); err != nil { 64 f.Close() 65 if err == syscall.EAGAIN { 66 err = ErrAlreadyLocked 67 } 68 return nil, err 69 } 70 71 st, err := os.Stat(path) 72 if err != nil { 73 f.Close() 74 return nil, err 75 } 76 77 if st.IsDir() { 78 f.Close() 79 return nil, &os.PathError{ 80 Op: "open", 81 Path: path, 82 Err: syscall.EISDIR, 83 } 84 } 85 86 return &LockedFile{f}, nil 87 } 88 89 // TryLockedOpenFile - tries a new write lock, functionality 90 // it is similar to LockedOpenFile with with syscall.LOCK_EX 91 // mode but along with syscall.LOCK_NB such that the function 92 // doesn't wait forever but instead returns if it cannot 93 // acquire a write lock. 94 func TryLockedOpenFile(path string, flag int, perm os.FileMode) (*LockedFile, error) { 95 return lockedOpenFile(path, flag, perm, syscall.F_SETLK) 96 } 97 98 // LockedOpenFile - initializes a new lock and protects 99 // the file from concurrent access across mount points. 100 // This implementation doesn't support all the open 101 // flags and shouldn't be considered as replacement 102 // for os.OpenFile(). 103 func LockedOpenFile(path string, flag int, perm os.FileMode) (*LockedFile, error) { 104 return lockedOpenFile(path, flag, perm, syscall.F_SETLKW) 105 } 106 107 // Open - Call os.OpenFile 108 func Open(path string, flag int, perm os.FileMode) (*os.File, error) { 109 return os.OpenFile(path, flag, perm) 110 }