// Returns true if there is a failure due to missing computed files. func (sub *Sub) buildUpdateRequest(image *image.Image, request *subproto.UpdateRequest, deleteMissingComputedFiles bool, logger *log.Logger) bool { sub.requiredFS = image.FileSystem sub.filter = image.Filter request.Triggers = image.Triggers sub.requiredInodeToSubInode = make(map[uint64]uint64) sub.inodesChanged = make(map[uint64]bool) sub.inodesCreated = make(map[uint64]string) sub.subObjectCacheUsage = make(map[hash.Hash]uint64, len(sub.ObjectCache)) // Populate subObjectCacheUsage. for _, hash := range sub.ObjectCache { sub.subObjectCacheUsage[hash] = 0 } if !filesystem.CompareDirectoriesMetadata(&sub.FileSystem.DirectoryInode, &sub.requiredFS.DirectoryInode, nil) { makeDirectory(request, &sub.requiredFS.DirectoryInode, "/", false) } if sub.compareDirectories(request, &sub.FileSystem.DirectoryInode, &sub.requiredFS.DirectoryInode, "/", deleteMissingComputedFiles, logger) { return true } // Look for multiply used objects and tell the sub. for obj, useCount := range sub.subObjectCacheUsage { if useCount > 1 { if request.MultiplyUsedObjects == nil { request.MultiplyUsedObjects = make(map[hash.Hash]uint64) } request.MultiplyUsedObjects[obj] = useCount } } return false }
// Returns true if no update needs to be performed. func (sub *Sub) buildUpdateRequest(request *subproto.UpdateRequest) bool { var state state state.subFS = &sub.fileSystem.FileSystem requiredImage := sub.herd.getImage(sub.requiredImage) state.requiredFS = requiredImage.FileSystem filter := requiredImage.Filter request.Triggers = requiredImage.Triggers state.requiredInodeToSubInode = make(map[uint64]uint64) state.inodesChanged = make(map[uint64]bool) state.inodesCreated = make(map[uint64]string) state.subObjectCacheUsage = make(map[hash.Hash]uint64, len(sub.fileSystem.ObjectCache)) var rusageStart, rusageStop syscall.Rusage syscall.Getrusage(syscall.RUSAGE_SELF, &rusageStart) // Populate subObjectCacheUsage. for _, hash := range sub.fileSystem.ObjectCache { state.subObjectCacheUsage[hash] = 0 } compareDirectories(request, &state, &state.subFS.DirectoryInode, &state.requiredFS.DirectoryInode, "/", filter) // Look for multiply used objects and tell the sub. for obj, useCount := range state.subObjectCacheUsage { if useCount > 1 { if request.MultiplyUsedObjects == nil { request.MultiplyUsedObjects = make(map[hash.Hash]uint64) } request.MultiplyUsedObjects[obj] = useCount } } syscall.Getrusage(syscall.RUSAGE_SELF, &rusageStop) sub.lastComputeUpdateCpuDuration = time.Duration( rusageStop.Utime.Sec)*time.Second + time.Duration(rusageStop.Utime.Usec)*time.Microsecond - time.Duration(rusageStart.Utime.Sec)*time.Second - time.Duration(rusageStart.Utime.Usec)*time.Microsecond computeCpuTimeDistribution.Add(sub.lastComputeUpdateCpuDuration) if len(request.FilesToCopyToCache) > 0 || len(request.InodesToMake) > 0 || len(request.HardlinksToMake) > 0 || len(request.PathsToDelete) > 0 || len(request.DirectoriesToMake) > 0 || len(request.InodesToChange) > 0 { sub.herd.logger.Printf( "buildUpdateRequest(%s) took: %s user CPU time\n", sub.hostname, sub.lastComputeUpdateCpuDuration) return false } return true }