Example #1
1
func main() {
	fd, fd_err := syscall.Open(LOCK_PATH, syscall.O_CREAT, 0)
	if fd_err != nil {
		fmt.Printf("FD ERR:%v\n", fd_err)
		os.Exit(1)
	}
	flock_err := syscall.Flock(fd, syscall.LOCK_EX)
	if flock_err != nil {
		fmt.Printf("LOCK ERR:%v\n", flock_err)
		os.Exit(1)
	}
	// beginning of the code getting the exclusive lock
	fmt.Printf(".")
	time.Sleep(time.Second * 10)
	// end of the code getting the exclusive lock
	funlock_err := syscall.Flock(fd, syscall.LOCK_UN)
	if funlock_err != nil {
		fmt.Printf("UNLOCK ERR:%v\n", funlock_err)
		unlink_err := syscall.Unlink(LOCK_PATH)
		if unlink_err != nil {
			fmt.Printf("UNLINK ERR:%v\n", unlink_err)
		}
		os.Exit(1)
	}
	close_err := syscall.Close(fd)
	if close_err != nil {
		fmt.Printf("CLOSE ERR:%v\n", close_err)
	}
	unlink_err := syscall.Unlink(LOCK_PATH)
	if unlink_err != nil {
		fmt.Printf("UNLINK ERR:%v\n", unlink_err)
	}
}
func setFileLock(f *os.File, lock bool) error {
	how := syscall.LOCK_UN
	if lock {
		how = syscall.LOCK_EX
	}
	return syscall.Flock(int(f.Fd()), how|syscall.LOCK_NB)
}
Example #3
0
/* Append a line to a file f, locking it first.  Will return if f is empty */
func appendLine(fname, line string) {
	if 0 == len(fname) {
		return
	}
	/* Try to open the successes file */
	f, err := os.OpenFile(fname, os.O_WRONLY|os.O_APPEND|os.O_CREATE,
		0644)
	/* Close on return */
	defer f.Close()
	/* Give up if we can't */
	if err != nil {
		log.Printf("Unable to open file %v: %v", f, err)
		return
	}
	/* Acquire an exclusive lock */
	if syscall.Flock(int(f.Fd()), syscall.LOCK_EX) != nil {
		log.Printf("Unable to lock %v: %v", f, err)
		return
	}
	/* Release it when we're done */
	defer syscall.Flock(int(f.Fd()), syscall.LOCK_UN)
	/* Write line to file */
	r, err := f.WriteString(line)
	if err != nil {
		log.Printf("Error writing %\"%v\" to %v: %v", line, f,
			err)
	}
	if r < len(line) {
		log.Printf("Only wrote %v/%v bytes of \"%v\" to %v", r,
			len(line),
			line, f)
	}
}
Example #4
0
func (auth *Authinfo) Store() (err error) {

	authFile, err := os.Open(auth.path)
	auth.daemonLog.LogError(fmt.Sprintf("Unable to open %s for reading.", auth.path), err)

	err = syscall.Flock(int(authFile.Fd()), 2) //2 is exclusive lock
	if err != nil {
		err = errors.New(fmt.Sprintf("Failed to lock %s for reading.", auth.path))
	}

	auth.lock.RLock()
	defer auth.lock.RUnlock()
	data, err := json.Marshal(auth.Users)

	_, err = authFile.Write(data)
	auth.daemonLog.LogError("Unable to write to file .", err)

	err = syscall.Flock(int(authFile.Fd()), 8) //8 is unlock
	if err != nil {
		err = errors.New(fmt.Sprintf("Unable to unlock %s for reading.", auth.path))
	}

	fi, err := authFile.Stat()
	auth.dbstamp = fi.ModTime().Unix()
	authFile.Close()
	return
}
Example #5
0
// AcquireRepoLock opens the lock file and acquires the lock.
// Dies if the lock cannot be successfully acquired.
func AcquireRepoLock() {
	var err error
	// There is of course technically a bit of a race condition between the file & flock operations here,
	// but it shouldn't matter much since we're trying to mutually exclude plz processes started by the user
	// which (one hopes) they wouldn't normally do simultaneously.
	os.MkdirAll(path.Dir(lockFilePath), DirPermissions)
	// TODO(pebers): This doesn't seem quite as intended, I think the file still gets truncated sometimes.
	//               Not sure why since I'm not passing O_TRUNC...
	if lockFile, err = os.OpenFile(lockFilePath, os.O_RDWR|os.O_CREATE, 0644); err != nil && !os.IsNotExist(err) {
		log.Fatalf("Failed to acquire lock: %s", err)
	} else if lockFile, err = os.Create(lockFilePath); err != nil {
		log.Fatalf("Failed to create lock: %s", err)
	}
	// Try a non-blocking acquire first so we can warn the user if we're waiting.
	log.Debug("Attempting to acquire lock %s...", lockFilePath)
	if err := syscall.Flock(int(lockFile.Fd()), syscall.LOCK_EX|syscall.LOCK_NB); err == nil {
		log.Debug("Acquired lock %s", lockFilePath)
	} else {
		log.Warning("Looks like another plz is already running in this repo. Waiting for it to finish...")
		if err := syscall.Flock(int(lockFile.Fd()), syscall.LOCK_EX); err != nil {
			log.Fatalf("Failed to acquire lock: %s", err)
		}
	}

	// Record the operation performed.
	if _, err = lockFile.Seek(0, os.SEEK_SET); err == nil {
		if n, err := lockFile.Write([]byte(strings.Join(os.Args[1:], " ") + "\n")); err == nil {
			lockFile.Truncate(int64(n))
		}
	}
}
Example #6
0
// Checks status of daemonized process.
// Can be used in daemon actions to perate with daemonized process.
func Status() (isRunning bool, pr *os.Process, e error) {
	const errLoc = "daemonigo.Status()"
	var (
		err  error
		file *os.File
	)

	file, err = os.Open(PidFile)
	if err != nil {
		if !os.IsNotExist(err) {
			e = fmt.Errorf(
				"%s: could not open PID file, reason -> %s",
				errLoc, err.Error(),
			)
		}
		return
	}
	defer file.Close()
	fd := int(file.Fd())
	if err = syscall.Flock(
		fd, syscall.LOCK_EX|syscall.LOCK_NB,
	); err != syscall.EWOULDBLOCK {
		if err == nil {
			syscall.Flock(fd, syscall.LOCK_UN)
		} else {
			e = fmt.Errorf(
				"%s: PID file locking attempt failed, reason -> %s",
				errLoc, err.Error(),
			)
		}
		return
	}

	isRunning = true
	var n, pid int
	content := make([]byte, 128)
	n, err = file.Read(content)
	if err != nil && err != io.EOF {
		e = fmt.Errorf(
			"%s: could not read from PID file, reason -> %s",
			errLoc, err.Error(),
		)
		return
	}
	pid, err = strconv.Atoi(string(content[:n]))
	if n < 1 || err != nil {
		e = fmt.Errorf(
			"%s: bad PID format, PID file is possibly corrupted", errLoc,
		)
		return
	}
	pr, err = os.FindProcess(pid)
	if err != nil {
		e = fmt.Errorf(
			"%s: cannot find process by PID, reason -> %s", errLoc, err.Error(),
		)
	}

	return
}
Example #7
0
func (config *ConfigInfo) load() (err error) {
	configFile, err := os.Open(config.path)
	config.daemonLog.LogError(fmt.Sprintf("Cannot open %s for reading", config.path), err)
	if err != nil {
		os.Exit(1)
	}
	err = syscall.Flock(int(configFile.Fd()), 2)
	config.daemonLog.LogError("Error: Cannot read file for configurations", err)

	configContents, err := ioutil.ReadAll(configFile)
	config.daemonLog.LogError(fmt.Sprintf("Cannot read data from %s", config.path), err)

	err = syscall.Flock(int(configFile.Fd()), 8)
	if err != nil {
		config.daemonLog.LogError("Cannot unlock the config file for reading.", errors.New("Flock sys call Failed"))
	}

	fi, err := configFile.Stat()
	config.daemonLog.LogError(fmt.Sprintf("Stat of %s failed", err), err)
	err = configFile.Close()
	config.daemonLog.LogError("Cannot close file", err)

	config.lock.Lock()
	defer config.lock.Unlock()

	err = json.Unmarshal(configContents, &config.Data)
	config.daemonLog.LogError("Cannot unmarshall config.Data", err)
	config.tmstamp = fi.ModTime().Unix()
	return
}
Example #8
0
func readPid(fileName string) (int, error) {
	fd, err := os.OpenFile(fileName, os.O_RDWR|os.O_CREATE, 0644)
	if err != nil {
		return 0, err
	}
	defer fd.Close()
	if err := syscall.Flock(int(fd.Fd()), syscall.LOCK_EX|syscall.LOCK_NB); err != nil {
		return 0, fmt.Errorf("can't lock '%s', lock is held", fd.Name())
	}

	if _, err := fd.Seek(0, 0); err != nil {
		return 0, err
	}

	data, err := ioutil.ReadAll(fd)
	if err != nil {
		return 0, err
	}

	pid, err := strconv.Atoi(string(bytes.TrimSpace(data)))
	if err != nil {
		return 0, fmt.Errorf("error parsing pid from %s: %s", fd.Name(), err)
	}

	if err := syscall.Flock(int(fd.Fd()), syscall.LOCK_UN); err != nil {
		return 0, fmt.Errorf("can't release lock '%s', lock is held", fd.Name())
	}

	return pid, nil

}
Example #9
0
func (r *Samjung) writeDataToFile(rowData []byte) (uint64, error) {
	// open file
	f, err := os.OpenFile(r.baseDir+"/"+tableFile, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0664)
	if err != nil {
		return 0, err
	}
	defer f.Close()

	// file lock
	err = syscall.Flock(int(f.Fd()), syscall.LOCK_EX)
	if err != nil {
		return 0, err
	}
	defer syscall.Flock(int(f.Fd()), syscall.LOCK_UN)

	// seek end offset of file
	offset, err := f.Seek(0, os.SEEK_END)
	if err != nil {
		return 0, err
	}

	// write to file
	_, err = f.WriteAt(rowData, offset)
	if err != nil {
		return 0, err
	}

	return uint64(offset), nil
}
Example #10
0
func setFileLock(fp *os.File, lock bool) error {
	if lock {
		return syscall.Flock(int(fp.Fd()), syscall.LOCK_EX|syscall.LOCK_NB)
	} else {
		return syscall.Flock(int(fp.Fd()), syscall.LOCK_UN|syscall.LOCK_NB)
	}
}
Example #11
0
func storeVols() error {
	log.Info("Storing volume list...")

	VolData.lock.RLock()
	js, err := json.MarshalIndent(VolData, "", "    ")
	VolData.lock.RUnlock()

	volFile, err := os.OpenFile(VolData.volFileName, syscall.O_WRONLY|syscall.O_CREAT, 0600)
	if err != nil {
		log.Error("DV: Cannot open for writing, file: " + DV_VOL_LIST_FILE)
		return err
	}
	defer volFile.Close()

	for err := syscall.Flock(int(volFile.Fd()), syscall.LOCK_EX); err == syscall.EINTR; {
	}
	defer syscall.Flock(int(volFile.Fd()), syscall.LOCK_UN)

	volFile.Truncate(0)

	_, err = volFile.Write(js)
	if err != nil {
		log.Errorf("Cannot write vol file - %v", err)
		return err
	}

	return nil
}
Example #12
0
File: Add.go Project: JustAdam/metl
func (v *Add) Run(c cli.Command) {
	jobName := c.Param("jobname").String()
	var job job.Job
	if _, err := toml.DecodeFile(metl.GetJobFilePath(jobName)+".toml", &job); err != nil {
		log.Fatal(err)
	}

	cronfile := filepath.Join(metl.Etl.GetLocalStoragePath(), crontabFile)

	file, err := os.Open(cronfile)
	if err != nil {
		file, err = os.Create(cronfile)
		if err != nil {
			log.WithFields(
				log.Fields{
					"filename": cronfile,
				},
			).Fatal("Unable to create cronfile: ", err)
		}
	}
	defer file.Close()

	err = syscall.Flock(int(file.Fd()), syscall.LOCK_EX)
	if err != nil {
		log.Fatal("Failed to lock file")
	}

	defer func() {
		err = syscall.Flock(int(file.Fd()), syscall.LOCK_UN)
		if err != nil {
			log.Fatal("Failed to unlock file")
		}
	}()

	buffer := make([]string, 0)
	if err = jobIsInFile(file, jobName, &buffer); err != nil {
		log.Fatal(err)
	}
	buffer = append(buffer, fmt.Sprintf("%s %s >> %s%s.log", cmd, jobName, logDir, jobName))

	tmpf, err := ioutil.TempFile(metl.Etl.GetLocalStoragePath(), "tmp")
	if err != nil {
		log.Fatal("Unable to create temporary file.")
	}

	for _, line := range buffer {
		if _, err := tmpf.WriteString(line + "\n"); err != nil {
			log.Fatal("Unable to write to temporary file")
		}
	}

	if err := os.Rename(tmpf.Name(), cronfile); err != nil {
		log.Fatal("Failed to rename temporary lock file:", err)
	}

	// execute /usr/bin/env crontab cronfile
}
Example #13
0
// writeKeys serializes the given key in the authorized_keys file (of the
// current user).
func writeKey(k *Key) error {
	file, err := fs.Filesystem().OpenFile(authKey(), os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0644)
	if err != nil {
		return err
	}
	defer file.Close()
	syscall.Flock(int(file.Fd()), syscall.LOCK_EX)
	defer syscall.Flock(int(file.Fd()), syscall.LOCK_UN)
	return k.dump(file)
}
Example #14
0
func cat_new_mids() (floor uint64, ceiling uint64, tsh uint64, err error) {
	tsh = uint64(time.Now().Unix() / 3600)
	file, err := OpenFile(TEMPFILE, O_CREATE|O_RDWR, 0664)
	if err != nil {
		return 0, 0, tsh, errors.New("Unable to open temp file")
	}
	defer func() {
		file.Sync()
		file.Close()
		syscall.Flock(int(file.Fd()), syscall.LOCK_UN)
	}()
	share := make([]byte, 16)
	syscall.Flock(int(file.Fd()), syscall.LOCK_EX)
	n, err := file.Read(share)
	if err != nil && err != io.EOF {
		return 0, 0, tsh, errors.New("Unable to read temp file")
	}
	if n == 16 {
		var f uint64 = binary.BigEndian.Uint64(share[:8])
		var l uint64 = binary.BigEndian.Uint64(share[8:])
		if tsh > l {
			floor = 1
			ceiling = 100000
			buf := make([]byte, 8)
			binary.BigEndian.PutUint64(buf, uint64(ceiling))
			file.WriteAt(buf, 0)
			binary.BigEndian.PutUint64(buf, uint64(tsh))
			file.WriteAt(buf, 8)
		} else {
			floor = f
			ceiling = f + 100000
			buf := make([]byte, 8)
			binary.BigEndian.PutUint64(buf, uint64(ceiling))
			file.WriteAt(buf, 0)
		}
	} else if n == 0 {
		floor = 1
		ceiling = 100000
		buf := make([]byte, 8)
		binary.BigEndian.PutUint64(buf, uint64(ceiling))
		n, err = file.WriteAt(buf, 0)
		if err != nil {
			return 0, 0, tsh, errors.New("Unable to write index to temp file")
		}
		binary.BigEndian.PutUint64(buf, uint64(tsh))
		n, err = file.WriteAt(buf, 8)
		if err != nil {
			return 0, 0, tsh, errors.New("Unable to write tsh to temp file")
		}
	} else {
		return 0, 0, tsh, errors.New("Temp file is herpahs corrupted")
	}
	return floor, ceiling, tsh, nil
}
Example #15
0
func (r *Samjung) getAutoIncrement() (uint64, error) {
	isExist := true
	if _, err := os.Stat(r.baseDir + "/" + autoIncFile); os.IsNotExist(err) {
		isExist = false
	}

	// autoIncFile 없으면 파일 생성하면서 1 집어넣음
	if isExist == false {
		f, err := os.OpenFile(r.baseDir+"/"+autoIncFile, os.O_WRONLY|os.O_CREATE, 0664)
		if err != nil {
			return 0, err
		}
		defer f.Close()

		_, err = f.WriteString("1")
		if err != nil {
			return 0, err
		}

		return 1, nil
	}

	// 있으면 + 1 해서 리턴해주고 저장
	f, err := os.OpenFile(r.baseDir+"/"+autoIncFile, os.O_WRONLY, 0664)
	if err != nil {
		return 0, err
	}
	defer f.Close()

	// file lock
	err = syscall.Flock(int(f.Fd()), syscall.LOCK_EX)
	if err != nil {
		return 0, err
	}
	defer syscall.Flock(int(f.Fd()), syscall.LOCK_UN)

	numByte, err := ioutil.ReadFile(r.baseDir + "/" + autoIncFile)
	if err != nil {
		return 0, err
	}

	number, err := strconv.ParseUint(string(numByte), 10, 64)
	if err != nil {
		return 0, err
	}

	number = number + 1
	_, err = f.WriteString(strconv.FormatUint(number, 10))
	if err != nil {
		return 0, err
	}

	return number, nil
}
Example #16
0
// Write writes a json marshalled, base64 encoded string
// to file. `data` must be json serializable.
func (f *Failover) Write(data interface{}) {
	msg, err := json.Marshal(data)
	if err != nil {
		log.Println(err)
		return
	}
	encodedData := string(base64.StdEncoding.EncodeToString(msg))
	fd := int(f.File.Fd())
	syscall.Flock(fd, syscall.LOCK_SH)
	f.File.WriteString(fmt.Sprintf("%s\n", encodedData))
	syscall.Flock(fd, syscall.LOCK_UN)
}
Example #17
0
// Saves Meta data from dirTree to meta File
func saveMeta(data *ReveloData) error {
	var Meta *horcrux.Meta
	var err error

	data.lock.RLock()
	Meta, err = dirTree.GetMeta(data.Root)
	Meta.Config = data.Config
	Meta.CurrVer = data.CurrVer
	data.lock.RUnlock()

	if err != nil {
		log.Error("saveMeta: Cannot get Meta data")
		return err
	}

	js, err := json.MarshalIndent(Meta, "", "    ")
	if err != nil {
		log.WithFields(
			log.Fields{"Meta": Meta, "Error": err}).Error("saveMeta: Cannot marshal meta")
		return err
	}

	metaFile, err := os.OpenFile(data.cacheDir+"/"+data.metaName, os.O_WRONLY|os.O_SYNC, 0600)
	if err != nil {
		log.WithFields(log.Fields{"Meta File": data.metaName, "Error": err}).Error("saveMeta: Cannot open meta file")
		return err
	}
	defer metaFile.Close()

	// XXX Using File EX lock to avoid multiple access
	for err = syscall.Flock(int(metaFile.Fd()), syscall.LOCK_EX); err == syscall.EINTR; {
	}

	if err != nil {
		log.WithFields(log.Fields{"Error": err}).Error("saveMeta: Cannot lock meta file")
		return err
	}

	defer syscall.Flock(int(metaFile.Fd()), syscall.LOCK_UN)

	metaFile.Truncate(0) //XXX: Do Truncate(n) after write succeeds!!
	n, err := metaFile.Write(js)
	if err != nil {
		log.WithFields(log.Fields{
			"Meta file": data.metaName, "Wrote": n, "Size": len(js), "Error": err,
		}).Error("saveMeta: Cannot write to meta file")
		return err
	}

	log.Debug("saveMeta: Done")
	return nil
}
Example #18
0
func deleteReservation(checkUser bool, args []string) {
	if len(args) != 1 {
		fatalf("Invalid arguments")
	}

	user, err := user.Current()
	path := filepath.Join(igorConfig.TFTPRoot, "/igor/reservations.json")
	resdb, err := os.OpenFile(path, os.O_RDWR, 664)
	if err != nil {
		fatalf("failed to open reservations file: %v", err)
	}
	defer resdb.Close()
	err = syscall.Flock(int(resdb.Fd()), syscall.LOCK_EX)
	defer syscall.Flock(int(resdb.Fd()), syscall.LOCK_UN) // this will unlock it later
	reservations := getReservations(resdb)

	var newres []Reservation
	var deletedReservation Reservation
	found := false
	if checkUser {
		for _, r := range reservations {
			if r.ResName == args[0] && r.Owner != user.Username {
				fatalf("You are not the owner of %v", args[0])
			}
		}
	}
	for _, r := range reservations {
		if r.ResName != args[0] {
			newres = append(newres, r)
		} else {
			deletedReservation = r
			found = true
		}
	}

	if !found {
		fatalf("Couldn't find reservation %v", args[0])
	}

	// Truncate the existing reservation file
	resdb.Truncate(0)
	resdb.Seek(0, 0)
	// Write out the new reservations
	enc := json.NewEncoder(resdb)
	enc.Encode(newres)
	resdb.Sync()

	// Delete all the PXE files in the reservation
	for _, pxename := range deletedReservation.PXENames {
		os.Remove(igorConfig.TFTPRoot + "/pxelinux.cfg/" + pxename)
	}
}
Example #19
0
func (l *layerStore) DoLocked(id string, fn func() error) error {
	f, err := os.OpenFile(l.lockPath(id), os.O_CREATE|os.O_RDWR, 0644)
	if err != nil {
		return err
	}
	defer os.Remove(f.Name())
	defer f.Close()
	if err := syscall.Flock(int(f.Fd()), syscall.LOCK_EX); err != nil {
		return err
	}
	defer syscall.Flock(int(f.Fd()), syscall.LOCK_UN)
	return fn()
}
Example #20
0
func realMain() int {
	flag.Parse()

	if filesFlag == 0 || directoryFlag == "" {
		flag.Usage()
		return 1
	}

	fmt.Println("Creating files...")
	var wg sync.WaitGroup
	for i := 1; i <= filesFlag; i++ {
		wg.Add(1)
		go func() {
			filename := fmt.Sprintf("%s/%s.lock", directoryFlag, uuid.NewUUID().String())
			err := ioutil.WriteFile(filename, []byte("foo"), 0644)
			if err != nil {
				log.Fatalln(err)
			}
			wg.Done()
		}()
	}
	wg.Wait()
	defer cleanUp()

	fmt.Println("Getting all files in " + directoryFlag + "...")
	files, err := ioutil.ReadDir(directoryFlag)
	if err != nil {
		log.Fatalln(err)
	}

	fmt.Println("Opening all files and applying locks")
	for i, file := range files {
		fi, err := os.Open(directoryFlag + "/" + file.Name())
		if err != nil {
			log.Fatalln(err)
		}
		defer fi.Close()
		fd := fi.Fd()
		if i%2 == 0 {
			syscall.Flock(int(fd), syscall.LOCK_EX|syscall.LOCK_NB)
		} else {
			syscall.Flock(int(fd), syscall.LOCK_SH)
		}
	}

	time.Sleep(time.Second * 3000)

	return 0
}
Example #21
0
func TestAcquireRepoLock(t *testing.T) {
	// Grab the lock
	AcquireRepoLock()
	// Now we should be able to open the file (ie. it exists)
	lockFile, err := os.Open(lockFilePath)
	assert.NoError(t, err)
	defer lockFile.Close()
	assert.Error(t, syscall.Flock(int(lockFile.Fd()), syscall.LOCK_EX|syscall.LOCK_NB))
	// Let it go again
	ReleaseRepoLock()
	// Now we can get it
	assert.NoError(t, syscall.Flock(int(lockFile.Fd()), syscall.LOCK_EX|syscall.LOCK_NB))
	// Let it go so the following tests aren't confused :)
	assert.NoError(t, syscall.Flock(int(lockFile.Fd()), syscall.LOCK_UN))
}
Example #22
0
func (f *FileLock) performLock(flockHow int) (performErr error) {
	if f.fileH != nil {
		return errors.Newf("FileLock is already acquired!")
	}

	filePath := path.Join(f.path, f.prefix+f.name)
	// GoLang os.OpenFile creates file with FD_CLOEXEC flag already set on it.
	// This means file will get closed automatically once the process exits,
	// thus we dont need to manually set that flag.
	fileH, err := os.Create(filePath)
	if err != nil {
		return err
	}
	defer func() {
		if performErr != nil {
			_ = fileH.Close()
		}
	}()

	if err := syscall.Flock(int(fileH.Fd()), flockHow); err != nil {
		return err
	}

	f.fileH = fileH
	return nil
}
Example #23
0
File: file.go Project: matomesc/rkt
// TrySharedLock takes a co-operative (shared) lock without blocking.
// This is idempotent when the Lock already represents a shared lock,
// and tries demote an exclusive lock to shared atomically.
// It will return ErrLocked if an exclusive lock already exists.
func (l *FileLock) TrySharedLock() error {
	err := syscall.Flock(l.fd, syscall.LOCK_SH|syscall.LOCK_NB)
	if err == syscall.EWOULDBLOCK {
		err = ErrLocked
	}
	return err
}
Example #24
0
File: file.go Project: matomesc/rkt
// TryExclusiveLock takes an exclusive lock without blocking.
// This is idempotent when the Lock already represents an exclusive lock,
// and tries promote a shared lock to exclusive atomically.
// It will return ErrLocked if any lock is already held.
func (l *FileLock) TryExclusiveLock() error {
	err := syscall.Flock(l.fd, syscall.LOCK_EX|syscall.LOCK_NB)
	if err == syscall.EWOULDBLOCK {
		err = ErrLocked
	}
	return err
}
Example #25
0
// PidfileOpen opens new pidfile, locks it, truncates and writes current pid to it
func PidfileOpen(path string) (*Pidfile, error) {

	pf, err := pidfileOpenFile(path)
	if err != nil {
		return nil, err
	}

	defer func() {
		if err != nil {
			pf.Close()
		}
	}()

	err = syscall.Flock(int(pf.Fd()), syscall.LOCK_EX|syscall.LOCK_NB)
	if err != nil {
		return nil, fmt.Errorf("flock failed (other process running?): %s, %v", path, err)
	}

	err = pf.Truncate(0)
	if err != nil {
		return nil, err
	}

	_, err = fmt.Fprintf(pf, "%d\n", os.Getpid())
	if err != nil {
		return nil, err
	}

	// everything is ok
	return &Pidfile{
		f:    pf,
		path: path,
	}, nil
}
func GetLock(file *os.File, locktype int) {
	fmt.Println("Acquiring lock on ", file.Name())
	Info.Println("Acquiring lock on ", file.Name())
	syscall.Flock(int(file.Fd()), locktype)
	Info.Println("Acquired exclusive lock on ", file.Name())
	fmt.Println("Acquired filelock on ", file.Name())
}
Example #27
0
// LockWithErr locks a file as exclusively with error handling.
//
// If you use with blocking mode, Lock waits until obtaining a lock.
// Else if you use with non-blocking mode, Lock doesn't wait to obtain a lock (means Lock makes failure immediately if cannot obtain a lock).
func (l *Locker) LockWithErr() error {
	if l.file != nil {
		return ErrFailedToAcquireLock
	}

	if l.filename == "" {
		return ErrLockFileEmpty
	}

	var flags int
	if l.nonblock {
		flags = syscall.LOCK_EX | syscall.LOCK_NB
	} else {
		flags = syscall.LOCK_EX
	}

	file, err := os.OpenFile(l.filename, syscall.O_RDWR|syscall.O_NONBLOCK|syscall.O_APPEND|syscall.O_CREAT, 0600) // open append
	if err != nil {
		return fmt.Errorf("setlock: fatal: unable to open %s: temporary failure", l.filename)
	}
	defer func() {
		if l.file == nil {
			// Only close if we failed to flock
			file.Close()
		}
	}()

	err = syscall.Flock(int(file.Fd()), flags)
	if err != nil {
		return ErrFailedToAcquireLock
	}

	l.file = file
	return nil
}
Example #28
0
// TryShare is the non-blocking form of Share and will return an error if the
// lock could not be obtained immediately.
func TryShare(file *os.File) error {
	lock := syscall.LOCK_SH | syscall.LOCK_NB
	if err := syscall.Flock(int(file.Fd()), lock); err != nil {
		return err
	}
	return nil
}
Example #29
0
// TryExclusive is the non-blocking form of Exclusive and will return an
// error if the lock could not be obtained immediately.
func TryExclusive(file *os.File) error {
	lock := syscall.LOCK_EX | syscall.LOCK_NB
	if err := syscall.Flock(int(file.Fd()), lock); err != nil {
		return err
	}
	return nil
}
// CreateLockFile tries to create a file with given name and acquire an
// exclusive lock on it. If the file already exists AND is still locked, it will
// fail.
func CreateLockFile(filename string) (*os.File, error) {
	file, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE, 0600)
	if err != nil {
		return nil, err
	}

	err = syscall.Flock(int(file.Fd()), syscall.LOCK_EX|syscall.LOCK_NB)
	if err != nil {
		file.Close()
		return nil, err
	}

	// Write PID to lock file
	contents := strconv.Itoa(os.Getpid())
	if err := file.Truncate(0); err != nil {
		file.Close()
		return nil, err
	}
	if _, err := file.WriteString(contents); err != nil {
		file.Close()
		return nil, err
	}

	return file, nil
}