func (d *Daemon) regenerateEndpoint(ep *endpoint.Endpoint) error { // This is the temporary directory to store the generated headers, // the original existing directory is not overwritten until all // generation has succeeded. origDir := filepath.Join(".", strconv.Itoa(int(ep.ID))) tmpDir := origDir + "_update" backupDir := origDir + "_backup" if err := d.regenerateBPF(ep, tmpDir); err != nil { return err } // Attempt to move the original endpoint directory to a backup location if err := os.Rename(origDir, backupDir); err != nil { os.RemoveAll(tmpDir) return fmt.Errorf("Unable to create backup of endpoint directory: %s", err) } // Move new endpoint directory in place, upon failure, restore backup if err := os.Rename(tmpDir, origDir); err != nil { os.RemoveAll(tmpDir) if err2 := os.Rename(backupDir, origDir); err2 != nil { log.Warningf("Restoring the backup directory for %s for endpoint "+ "%s did not succeed, the endpoint is now in an inconsistent state", backupDir, ep.String()) return err2 } return fmt.Errorf("Restored original endpoint directory, atomic replace failed: %s", err) } os.RemoveAll(backupDir) log.Infof("Successfully regenerated program for endpoint %s", ep.String()) return nil }