|
@@ -75,6 +75,10 @@ public class ShellBasedIdMapping implements IdMappingServiceProvider {
|
|
|
|
|
|
private final File staticMappingFile;
|
|
|
private StaticMapping staticMapping = null;
|
|
|
+ // Last time the static map was modified, measured time difference in
|
|
|
+ // milliseconds since midnight, January 1, 1970 UTC
|
|
|
+ private long lastModificationTimeStaticMap = 0;
|
|
|
+
|
|
|
private boolean constructFullMapAtInit = false;
|
|
|
|
|
|
// Used for parsing the static mapping file.
|
|
@@ -88,7 +92,6 @@ public class ShellBasedIdMapping implements IdMappingServiceProvider {
|
|
|
// Maps for id to name map. Guarded by this object monitor lock
|
|
|
private BiMap<Integer, String> uidNameMap = HashBiMap.create();
|
|
|
private BiMap<Integer, String> gidNameMap = HashBiMap.create();
|
|
|
-
|
|
|
private long lastUpdateTime = 0; // Last time maps were updated
|
|
|
|
|
|
/*
|
|
@@ -118,7 +121,7 @@ public class ShellBasedIdMapping implements IdMappingServiceProvider {
|
|
|
conf.get(IdMappingConstant.STATIC_ID_MAPPING_FILE_KEY,
|
|
|
IdMappingConstant.STATIC_ID_MAPPING_FILE_DEFAULT);
|
|
|
staticMappingFile = new File(staticFilePath);
|
|
|
-
|
|
|
+ updateStaticMapping();
|
|
|
updateMaps();
|
|
|
}
|
|
|
|
|
@@ -290,20 +293,42 @@ public class ShellBasedIdMapping implements IdMappingServiceProvider {
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
- private synchronized void initStaticMapping() throws IOException {
|
|
|
- staticMapping = new StaticMapping(
|
|
|
- new HashMap<Integer, Integer>(), new HashMap<Integer, Integer>());
|
|
|
+ private synchronized void updateStaticMapping() throws IOException {
|
|
|
+ final boolean init = (staticMapping == null);
|
|
|
+ //
|
|
|
+ // if the static mapping file
|
|
|
+ // - was modified after last update, load the map again;
|
|
|
+ // - did not exist but was added since last update, load the map;
|
|
|
+ // - existed before but deleted since last update, clear the map
|
|
|
+ //
|
|
|
if (staticMappingFile.exists()) {
|
|
|
- LOG.info("Using '" + staticMappingFile + "' for static UID/GID mapping...");
|
|
|
- staticMapping = parseStaticMap(staticMappingFile);
|
|
|
+ // check modification time, reload the file if the last modification
|
|
|
+ // time changed since prior load.
|
|
|
+ long lmTime = staticMappingFile.lastModified();
|
|
|
+ if (lmTime != lastModificationTimeStaticMap) {
|
|
|
+ LOG.info(init? "Using " : "Reloading " + "'" + staticMappingFile
|
|
|
+ + "' for static UID/GID mapping...");
|
|
|
+ lastModificationTimeStaticMap = lmTime;
|
|
|
+ staticMapping = parseStaticMap(staticMappingFile);
|
|
|
+ }
|
|
|
} else {
|
|
|
- LOG.info("Not doing static UID/GID mapping because '" + staticMappingFile
|
|
|
- + "' does not exist.");
|
|
|
+ if (init) {
|
|
|
+ staticMapping = new StaticMapping(new HashMap<Integer, Integer>(),
|
|
|
+ new HashMap<Integer, Integer>());
|
|
|
+ }
|
|
|
+ if (lastModificationTimeStaticMap != 0 || init) {
|
|
|
+ // print the following log at initialization or when the static
|
|
|
+ // mapping file was deleted after prior load
|
|
|
+ LOG.info("Not doing static UID/GID mapping because '"
|
|
|
+ + staticMappingFile + "' does not exist.");
|
|
|
+ }
|
|
|
+ lastModificationTimeStaticMap = 0;
|
|
|
+ staticMapping.clear();
|
|
|
}
|
|
|
- }
|
|
|
+ }
|
|
|
|
|
|
/*
|
|
|
- * Reset the maps to empty.
|
|
|
+ * Refresh static map, and reset the other maps to empty.
|
|
|
* For testing code, a full map may be re-constructed here when the object
|
|
|
* was created with constructFullMapAtInit being set to true.
|
|
|
*/
|
|
@@ -314,15 +339,16 @@ public class ShellBasedIdMapping implements IdMappingServiceProvider {
|
|
|
|
|
|
if (constructFullMapAtInit) {
|
|
|
loadFullMaps();
|
|
|
+ // set constructFullMapAtInit to false to allow testing code to
|
|
|
+ // do incremental update to maps after initial construction
|
|
|
+ constructFullMapAtInit = false;
|
|
|
} else {
|
|
|
+ updateStaticMapping();
|
|
|
clearNameMaps();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
synchronized private void loadFullUserMap() throws IOException {
|
|
|
- if (staticMapping == null) {
|
|
|
- initStaticMapping();
|
|
|
- }
|
|
|
BiMap<Integer, String> uMap = HashBiMap.create();
|
|
|
if (OS.startsWith("Mac")) {
|
|
|
updateMapInternal(uMap, "user", MAC_GET_ALL_USERS_CMD, "\\s+",
|
|
@@ -336,9 +362,6 @@ public class ShellBasedIdMapping implements IdMappingServiceProvider {
|
|
|
}
|
|
|
|
|
|
synchronized private void loadFullGroupMap() throws IOException {
|
|
|
- if (staticMapping == null) {
|
|
|
- initStaticMapping();
|
|
|
- }
|
|
|
BiMap<Integer, String> gMap = HashBiMap.create();
|
|
|
|
|
|
if (OS.startsWith("Mac")) {
|
|
@@ -353,7 +376,6 @@ public class ShellBasedIdMapping implements IdMappingServiceProvider {
|
|
|
}
|
|
|
|
|
|
synchronized private void loadFullMaps() throws IOException {
|
|
|
- initStaticMapping();
|
|
|
loadFullUserMap();
|
|
|
loadFullGroupMap();
|
|
|
}
|
|
@@ -443,9 +465,7 @@ public class ShellBasedIdMapping implements IdMappingServiceProvider {
|
|
|
}
|
|
|
|
|
|
boolean updated = false;
|
|
|
- if (staticMapping == null) {
|
|
|
- initStaticMapping();
|
|
|
- }
|
|
|
+ updateStaticMapping();
|
|
|
|
|
|
if (OS.startsWith("Linux")) {
|
|
|
if (isGrp) {
|
|
@@ -481,9 +501,7 @@ public class ShellBasedIdMapping implements IdMappingServiceProvider {
|
|
|
}
|
|
|
|
|
|
boolean updated = false;
|
|
|
- if (staticMapping == null) {
|
|
|
- initStaticMapping();
|
|
|
- }
|
|
|
+ updateStaticMapping();
|
|
|
|
|
|
if (OS.startsWith("Linux")) {
|
|
|
if (isGrp) {
|
|
@@ -547,6 +565,15 @@ public class ShellBasedIdMapping implements IdMappingServiceProvider {
|
|
|
this.uidMapping = new PassThroughMap<Integer>(uidMapping);
|
|
|
this.gidMapping = new PassThroughMap<Integer>(gidMapping);
|
|
|
}
|
|
|
+
|
|
|
+ public void clear() {
|
|
|
+ uidMapping.clear();
|
|
|
+ gidMapping.clear();
|
|
|
+ }
|
|
|
+
|
|
|
+ public boolean isNonEmpty() {
|
|
|
+ return uidMapping.size() > 0 || gidMapping.size() > 0;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
static StaticMapping parseStaticMap(File staticMapFile)
|