Change:
klog.Errorf("%s: error determining whether payload should be written to disk: %v", w.logContext, err) return err } else if !should && len(pathsToRemove) == 0 { <del> klog.V(4).Infof("%s: no update required for target directory %v", w.logContext, w.targetDir) return nil </del> <ins> klog.V(4).Infof("%s: write not required for data directory %v", w.logContext, oldTsDir) // data directory is already up to date, but we need to make sure that // the user-visible symlinks are created. // See https://github.com/kubernetes/kubernetes/issues/121472 for more details. // Reset oldTsDir to empty string to avoid removing the data directory. shouldWrite = false oldTsDir = "" </ins> } else { klog.V(4).Infof("%s: write required for target directory %v", w.logContext, w.targetDir) } } <del> // (5) tsDir, err := w.newTimestampDir() if err != nil { klog.V(4).Infof("%s: error creating new ts data directory: %v", w.logContext, err) return err } tsDirName := filepath.Base(tsDir) // (6) if err = w.writePayloadToDir(cleanPayload, tsDir); err != nil { klog.Errorf("%s: error writing payload to ts data directory %s: %v", w.logContext, tsDir, err) return err } klog.V(4).Infof("%s: performed write of new data to ts data directory: %s", w.logContext, tsDir) </del> <ins> if shouldWrite { // (5) tsDir, err := w.newTimestampDir() if err != nil { klog.V(4).Infof("%s: error creating new ts data directory: %v", w.logContext, err) return err } tsDirName := filepath.Base(tsDir) </ins> <del> // (7) if setPerms != nil { if err := setPerms(tsDirName); err != nil { klog.Errorf("%s: error applying ownership settings: %v", w.logContext, err) </del> <ins> // (6) if err = w.writePayloadToDir(cleanPayload, tsDir); err != nil { klog.Errorf("%s: error writing payload to ts data directory %s: %v", w.logContext, tsDir, err) </ins> return err } <del> } </del> <ins> klog.V(4).Infof("%s: performed write of new data to ts data directory: %s", w.logContext, tsDir) </ins> <del> // (8) newDataDirPath := filepath.Join(w.targetDir, newDataDirName) if err = os.Symlink(tsDirName, newDataDirPath); err != nil { os.RemoveAll(tsDir) klog.Errorf("%s: error creating symbolic link for atomic update: %v", w.logContext, err) return err } </del> <ins> // (7) if setPerms != nil { if err := setPerms(tsDirName); err != nil { klog.Errorf("%s: error applying ownership settings: %v", w.logContext, err) return err } } </ins> <del> // (9) if runtime.GOOS == "windows" { os.Remove(dataDirPath) err = os.Symlink(tsDirName, dataDirPath) os.Remove(newDataDirPath) } else { err = os.Rename(newDataDirPath, dataDirPath) } if err != nil { os.Remove(newDataDirPath) os.RemoveAll(tsDir) klog.Errorf("%s: error renaming symbolic link for data directory %s: %v", w.logContext, newDataDirPath, err) return err </del> <ins> // (8) newDataDirPath := filepath.Join(w.targetDir, newDataDirName) if err = os.Symlink(tsDirName, newDataDirPath); err != nil { if err := os.RemoveAll(tsDir); err != nil { klog.Errorf("%s: error removing new ts directory %s: %v", w.logContext, tsDir, err) } klog.Errorf("%s: error creating symbolic link for atomic update: %v", w.logContext, err) return err } // (9) if runtime.GOOS == "windows" { if err := os.Remove(dataDirPath); err != nil { klog.Errorf("%s: error removing data dir directory %s: %v", w.logContext, dataDirPath, err) } err = os.Symlink(tsDirName, dataDirPath) if err := os.Remove(newDataDirPath); err != nil { klog.Errorf("%s: error removing new data dir directory %s: %v", w.logContext, newDataDirPath, err) } } else { err = os.Rename(newDataDirPath, dataDirPath) } if err != nil { if err := os.Remove(newDataDirPath); err != nil && err != os.ErrNotExist { klog.Errorf("%s: error removing new data dir directory %s: %v", w.logContext, newDataDirPath, err) } if err := os.RemoveAll(tsDir); err != nil { klog.Errorf("%s: error removing new ts directory %s: %v", w.logContext, tsDir, err) } klog.Errorf("%s: error renaming symbolic link for data directory %s: %v", w.logContext, newDataDirPath, err) return err } </ins> } // (10)

Discussion:
When kubelet is creating configmap volume for a pod, it finished writing dir and made symlink to . At the same time, the kubelet is restarted, unfortunately the configmap item symlink is not created. The restarted kubelet will try to configmap, . Kubelet should create absent symlink for configmap volume. can hack kubelet to help reproduce it: sleep some time before ` kubelet and start official kubelet will skip to create symlink for UserVisibleFiles No response_ <details</details<details</details<details</details<details</details<details</details<details</details
This issue is currently awaiting triage. If a SIG or subproject determines this is a relevant issue, they will accept it by applying the label and provide further guidance. The label can be by org members by writing in a comment. <detailsInstructions for interacting with me using PR comments are available . If you have questions or suggestions related to my behavior, please file an issue against the repository. </details
/sig node
/sig storage This seems like an issue for sig storage. Can someone take a look and confirm?
Can you please add the version details as well?
/remove-sig node
/assign