Skip to content

Commit 16ed150

Browse files
committed
refactor: simplify sa_file monitoring with early binding approach
- Add PTP_SEC_FOLDER constant for /etc/ptp-secret-mount/ - Watch security mount folder from daemon startup instead of per-profile - Remove saFileTracker, saFileMutex, and saFileInfo (no longer needed) - Remove checkSaFileChanges, updateSaFileTracking, extractSaFileFromConf - Simplify fsnotify handler: any file change triggers PTP restart - Eliminates late binding complexity since mount path is known ahead of time
1 parent 7cbf06b commit 16ed150

File tree

1 file changed

+20
-173
lines changed

1 file changed

+20
-173
lines changed

pkg/daemon/daemon.go

Lines changed: 20 additions & 173 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ const (
5757
MessageTagSuffixSeperator = ":"
5858
TBC = "T-BC"
5959
TGM = "T-GM"
60+
PTP_SEC_FOLDER = "/etc/ptp-secret-mount/"
6061
)
6162

6263
var (
@@ -76,13 +77,6 @@ var ptpProcesses = []string{
7677
phc2sysProcessName, // there can be only one phc2sys process in the system
7778
}
7879

79-
// saFileInfo tracks authentication file information for a profile
80-
type saFileInfo struct {
81-
profileName string
82-
filePath string
83-
fileHash string
84-
}
85-
8680
var ptpTmpFiles = []string{
8781
ts2phcProcessName,
8882
syncEProcessName,
@@ -316,10 +310,6 @@ type Daemon struct {
316310

317311
// Allow vendors to include plugins
318312
pluginManager plugin.PluginManager
319-
320-
// Track sa_file (authentication) files for monitoring changes
321-
saFileTracker map[string]*saFileInfo
322-
saFileMutex sync.Mutex
323313
saFileWatcher *fsnotify.Watcher
324314
}
325315

@@ -351,6 +341,7 @@ func New(
351341
}
352342
tracker.processManager = pm
353343

344+
// Initialize fsnotify watcher for sa_file change detection
354345
// Initialize fsnotify watcher for sa_file change detection
355346
watcher, err := fsnotify.NewWatcher()
356347
if err != nil {
@@ -359,6 +350,12 @@ func New(
359350
watcher = nil
360351
} else {
361352
glog.Info("fsnotify watcher initialized for sa_file change detection")
353+
// Watch the known security mount folder from startup
354+
if err := watcher.Add(PTP_SEC_FOLDER); err != nil {
355+
glog.Warningf("Failed to watch %s (may not exist yet): %v", PTP_SEC_FOLDER, err)
356+
} else {
357+
glog.Infof("Watching %s for sa_file changes", PTP_SEC_FOLDER)
358+
}
362359
}
363360

364361
return &Daemon{
@@ -374,7 +371,6 @@ func New(
374371
processManager: pm,
375372
readyTracker: tracker,
376373
stopCh: stopCh,
377-
saFileTracker: make(map[string]*saFileInfo),
378374
saFileWatcher: watcher,
379375
}
380376
}
@@ -425,23 +421,24 @@ func (dn *Daemon) Run() {
425421
continue // Ignore hidden files like ..data
426422
}
427423

428-
glog.Infof("File system event: %s (op: %s)", event.Name, event.Op.String())
429-
430-
// Prevent restart flooding from multiple rapid events
431-
// Check if any tracked sa_file actually changed
432-
if dn.checkSaFileChanges() {
433-
glog.Info("sa_file authentication file changed, restarting PTP processes")
434-
err := dn.applyNodePTPProfiles()
435-
if err != nil {
436-
glog.Errorf("linuxPTP apply node profile failed after sa_file change: %v", err)
437-
}
424+
glog.Infof("Security file changed: %s (op: %s), restarting PTP processes", event.Name, event.Op.String())
425+
err := dn.applyNodePTPProfiles()
426+
if err != nil {
427+
glog.Errorf("linuxPTP apply node profile failed after security file change: %v", err)
438428
}
439429

440430
case err, ok := <-watcherErrors:
441431
// fsnotify watcher error
442432
if !ok {
443433
watcherErrors = nil
444-
continue
434+
// recreate the watcher
435+
dn.saFileWatcher, err = fsnotify.NewWatcher()
436+
if err != nil {
437+
glog.Errorf("Failed to recreate fsnotify watcher for sa_file monitoring: %v", err)
438+
continue
439+
}
440+
glog.Info("fsnotify watcher reinitialized for sa_file change detection")
441+
445442
}
446443
glog.Errorf("fsnotify watcher error: %v", err)
447444

@@ -471,152 +468,6 @@ func computeFileHash(filePath string) (string, error) {
471468
return fmt.Sprintf("%x", hash.Sum(nil)), nil
472469
}
473470

474-
// extractSaFileFromConf extracts sa_file path from ptp4lConf if present
475-
func extractSaFileFromConf(ptp4lConf *string) string {
476-
if ptp4lConf == nil {
477-
return ""
478-
}
479-
480-
// Parse the config to extract sa_file from [global] section
481-
for _, line := range strings.Split(*ptp4lConf, "\n") {
482-
line = strings.TrimSpace(line)
483-
// Skip comments
484-
if strings.HasPrefix(line, "#") {
485-
continue
486-
}
487-
// Look for sa_file option
488-
if strings.HasPrefix(line, "sa_file") {
489-
parts := strings.Fields(line)
490-
if len(parts) >= 2 {
491-
return parts[1]
492-
}
493-
}
494-
}
495-
return ""
496-
}
497-
498-
// checkSaFileChanges checks if any tracked sa_file has changed
499-
// When a Secret is updated in Kubernetes, the mounted file is automatically updated
500-
// This function detects those changes via hash comparison and returns true if any file changed
501-
// This triggers a PTP process restart (not pod restart) - same as ConfigMap changes
502-
func (dn *Daemon) checkSaFileChanges() bool {
503-
dn.saFileMutex.Lock()
504-
defer dn.saFileMutex.Unlock()
505-
506-
changed := false
507-
for _, info := range dn.saFileTracker {
508-
if info.filePath == "" {
509-
continue
510-
}
511-
512-
// Check if file exists
513-
if _, err := os.Stat(info.filePath); os.IsNotExist(err) {
514-
if info.fileHash != "" {
515-
glog.Warningf("sa_file %s for profile %s was deleted (had hash: %.16s...)",
516-
info.filePath, info.profileName, info.fileHash)
517-
changed = true
518-
}
519-
continue
520-
}
521-
522-
// Compute current hash
523-
currentHash, err := computeFileHash(info.filePath)
524-
if err != nil {
525-
glog.Errorf("Failed to compute hash for sa_file %s: %v", info.filePath, err)
526-
continue
527-
}
528-
529-
// Compare with stored hash
530-
if currentHash != info.fileHash {
531-
glog.Infof("sa_file %s for profile %s has changed (old hash: %.16s... -> %.16s...)",
532-
info.filePath, info.profileName, info.fileHash, currentHash)
533-
info.fileHash = currentHash
534-
changed = true
535-
}
536-
}
537-
538-
return changed
539-
}
540-
541-
// updateSaFileTracking updates the tracking information for sa_files from current profiles
542-
// Called after profiles are applied to initialize or update sa_file monitoring
543-
// Extracts sa_file paths from ptp4lConf and sets up fsnotify watches for instant change detection
544-
// Reuses existing hashes when file path hasn't changed to avoid redundant computation
545-
func (dn *Daemon) updateSaFileTracking() {
546-
dn.saFileMutex.Lock()
547-
defer dn.saFileMutex.Unlock()
548-
549-
// Save old tracking to reuse hashes for unchanged files
550-
oldTracker := dn.saFileTracker
551-
552-
// Remove all existing watches first
553-
if dn.saFileWatcher != nil {
554-
for _, info := range oldTracker {
555-
if info.filePath != "" {
556-
dirPath := filepath.Dir(info.filePath)
557-
dn.saFileWatcher.Remove(dirPath)
558-
}
559-
}
560-
}
561-
562-
// Create new tracking
563-
dn.saFileTracker = make(map[string]*saFileInfo)
564-
watchedDirs := make(map[string]bool)
565-
566-
// Add tracking for each profile that has sa_file configured
567-
for _, profile := range dn.ptpUpdate.NodeProfiles {
568-
if profile.Name == nil {
569-
continue
570-
}
571-
572-
saFilePath := extractSaFileFromConf(profile.Ptp4lConf)
573-
if saFilePath == "" {
574-
continue
575-
}
576-
577-
glog.Infof("Tracking sa_file %s for profile %s", saFilePath, *profile.Name)
578-
579-
// Optimize: Reuse hash if same file path in old tracker (avoid recomputation)
580-
hash := ""
581-
if oldInfo, exists := oldTracker[*profile.Name]; exists && oldInfo.filePath == saFilePath {
582-
// File path unchanged, reuse existing hash
583-
hash = oldInfo.fileHash
584-
glog.Infof("Reusing existing hash for sa_file %s (hash: %.16s...)", saFilePath, hash)
585-
} else {
586-
// New file or path changed, compute hash
587-
if _, err := os.Stat(saFilePath); err == nil {
588-
if h, err := computeFileHash(saFilePath); err == nil {
589-
hash = h
590-
glog.Infof("Computed new hash for sa_file %s (hash: %.16s...)", saFilePath, h)
591-
} else {
592-
glog.Warningf("Failed to compute hash for sa_file %s: %v", saFilePath, err)
593-
}
594-
} else {
595-
glog.Warningf("sa_file %s does not exist yet for profile %s", saFilePath, *profile.Name)
596-
}
597-
}
598-
599-
dn.saFileTracker[*profile.Name] = &saFileInfo{
600-
profileName: *profile.Name,
601-
filePath: saFilePath,
602-
fileHash: hash,
603-
}
604-
605-
// Setup fsnotify watch on directory (not file, due to Kubernetes symlinks)
606-
if dn.saFileWatcher != nil {
607-
dirPath := filepath.Dir(saFilePath)
608-
if !watchedDirs[dirPath] {
609-
if err := dn.saFileWatcher.Add(dirPath); err != nil {
610-
glog.Errorf("Failed to watch directory %s for sa_file changes: %v", dirPath, err)
611-
} else {
612-
glog.Infof("Watching directory %s for instant sa_file change detection", dirPath)
613-
watchedDirs[dirPath] = true
614-
}
615-
}
616-
}
617-
}
618-
}
619-
620471
func printWhenNotNil(p interface{}, description string) {
621472
switch v := p.(type) {
622473
case *string:
@@ -750,10 +601,6 @@ func (dn *Daemon) applyNodePTPProfiles() error {
750601
dn.pluginManager.PopulateHwConfig(dn.hwconfigs)
751602
*dn.refreshNodePtpDevice = true
752603
dn.readyTracker.setConfig(true)
753-
754-
// Update sa_file tracking after profiles are applied
755-
dn.updateSaFileTracking()
756-
757604
return nil
758605
}
759606

0 commit comments

Comments
 (0)