I have a java project which one of its components is to monitor a specific folder which is mounted to my machine.
My linux version is OpenSUSE 42.1
For monitoring the folder I'm using java's Watch Service.
Attached is the main code for folder monitoring we found online and modified to our on need.
(sorry for the lack of copy rights, can't find where it was taken from) .
Constructor:
/**
* Creates a WatchService and registers the given directory
*/
public WatchDir(Path dir, Kind<?>... dirWatchKinds) throws IOException {
this.watcher = FileSystems.getDefault().newWatchService();
this.keys = new HashMap<WatchKey,Path>();
register(dir, dirWatchKinds);
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
try {
watcher.close();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
Run method (implemented as runnable):
/**
* Process all events for keys queued to the watcher
*/
public void run() {
while (shouldRun) {
// wait for key to be signalled
WatchKey key;
try {
key = watcher.take();
} catch (Exception x) {
return;
}
Path dir = keys.get(key);
if (dir == null) {
log.error("WatchKey not recognized!!");
continue;
}
for (WatchEvent<?> event: key.pollEvents()) {
WatchEvent.Kind<?> kind = event.kind();
if (kind == OVERFLOW) {
continue;
}
// Context for directory entry event is the file name of entry
WatchEvent<Path> ev = cast(event);
Path name = ev.context();
Path child = dir.resolve(name);
handleDirEvent(child, ev.kind());
}
// reset key and remove from set if directory no longer accessible
boolean valid = key.reset();
if (!valid) {
// Check that dir path still exists. If not, notify user and whoever run the thread
if (Files.notExists(dir)){
//log.error(String.format("Directory ", arg1));
fireFileChangedEvent(dir.getFileName().toString(), FileState.Deleted);
}
keys.remove(key);
// all directories are inaccessible
if (keys.isEmpty()) {
break;
}
}
}
}
Now for my problem.
The mounted folder is prone to disconnections which probably will be handled out side of my program scope (from terminal I guess).
Currently when it happens, the watcher.take()
is getting notified, without any events to handle,
and on the boolean valid = key.reset()
it gets value false which then results in thread termination eventually.
From that point I don't really know when the folder will be mounted again - for re-running the monitor thread.
What is the best way to monitor mount / unmount of the folder?
Please note: the monitored endpoint folder not necessarily is the mounting point, it (the mounted folder) could be one of its ancestors.
Any help would be appreciated!
Your could look at the /proc/mounts
file to see if the mount still exist or not.
Not sure about OpenSUSE but I assume they work the same as Redhat style linux. https://www.centos.org/docs/5/html/5.2/Deployment_Guide/s2-proc-mounts.html