コード例 #1
0
ファイル: revelo.go プロジェクト: muthu-r/horcrux
// 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
}