/** * Link event triggered by FUSE. * * @param pid PID of the triggering process. * @param originalFilePath The original file path. * @param linkPath Path to link to. */ public void link(int pid, String originalFilePath, String linkPath) { checkProgramTree(Integer.toString(pid)); originalFilePath = sanitizePath(originalFilePath); linkPath = sanitizePath(linkPath); long now = System.currentTimeMillis(); File link = createLinkVertex(linkPath); putVertex(link); File original = createFileVertex(originalFilePath); putVertex(original); WasDerivedFrom linkEdge = new WasDerivedFrom(original, link); linkEdge.addAnnotation("operation", "link"); linkEdge.addAnnotation("endtime", Long.toString(now)); putEdge(linkEdge); // Add the link to the links map. links.put(linkPath, originalFilePath); }
/** * ReadLink event triggered by FUSE. * * @param pid PID of the triggering process. * @param iotime IO time of the operation. * @param path Path indicating target file. */ public void readlink(int pid, int iotime, String path) { checkProgramTree(Integer.toString(pid)); path = sanitizePath(path); // Create the file artifact and populate the annotations with file information. long now = System.currentTimeMillis(); File linkFile = createLinkVertex(path); putVertex(linkFile); Used edge = new Used((Program) localCache.get(Integer.toString(pid)), linkFile); edge.addAnnotation("endtime", Long.toString(now)); edge.addAnnotation("operation", "readlink"); putEdge(edge); // If the given path represents a link, then perform the same operation on the // artifact to which the link points. if (links.containsKey(path)) { read(pid, iotime, links.get(path), 0); } }
/** * Rename event triggered by FUSE. * * @param pid PID of the triggering process. * @param iotime IO time of the operation. * @param pathfrom The source path. * @param pathto The destination path. * @param link An integer used to indicate whether the target was a link or not. * @param done An intiger used to indicate whether this event was triggered before or after the * rename operation. */ public void rename(int pid, int iotime, String pathfrom, String pathto, int link, int done) { checkProgramTree(Integer.toString(pid)); pathfrom = sanitizePath(pathfrom); pathto = sanitizePath(pathto); long now = System.currentTimeMillis(); // 'done' is used to indicate whether this is a pre-rename or a post-rename // call. In pre-rename, a Used edge is created from the process to the old // file. In post-rename, a WasGeneratedBy edge is created from the process // to the new file and a WasDerivedEdge created between the two file // artifacts. if (done == 0) { // Create file artifact depending on whether this is a link or not. // Link artifacts are created differently to avoid recursion that may // cause FUSE to crash. File fileVertex = (link == 1) ? createLinkVertex(pathfrom) : createFileVertex(pathfrom); putVertex(fileVertex); // Put the file artifact in the localCache to be removed on post-rename. localCache.put(pathfrom, fileVertex); Used edge = new Used((Program) localCache.get(Integer.toString(pid)), fileVertex); edge.addAnnotation("endtime", Long.toString(now)); putEdge(edge); } else { // Create file artifact depending on whether this is a link or not. // Link artifacts are created differently to avoid recursion that may // cause FUSE to crash. File fileVertex = (link == 1 ? createLinkVertex(pathto) : createFileVertex(pathto)); putVertex(fileVertex); WasGeneratedBy writeEdge = new WasGeneratedBy(fileVertex, (Program) localCache.get(Integer.toString(pid))); writeEdge.addAnnotation("endtime", Long.toString(now)); putEdge(writeEdge); WasDerivedFrom renameEdge = new WasDerivedFrom(fileVertex, (File) localCache.remove(pathfrom)); renameEdge.addAnnotation("iotime", Integer.toString(iotime)); renameEdge.addAnnotation("endtime", Long.toString(now)); renameEdge.addAnnotation("operation", "rename"); putEdge(renameEdge); if (links.containsKey(pathfrom)) { // If the rename is on a link then update the link name. String linkedLocation = links.get(pathfrom); links.remove(pathfrom); links.put(pathto, linkedLocation); } } }
/** * Read event triggered by FUSE. * * @param pid PID of the triggering process. * @param iotime IO time of the operation. * @param path Path indicating target file. * @param link An integer used to indicate whether the target was a link or not. */ public void read(int pid, int iotime, String path, int link) { checkProgramTree(Integer.toString(pid)); path = sanitizePath(path); long now = System.currentTimeMillis(); // Create file artifact depending on whether this is a link or not. // Link artifacts are created differently to avoid recursion that may // cause FUSE to crash. File fileVertex = (link == 1) ? createLinkVertex(path) : createFileVertex(path); putVertex(fileVertex); Used edge = new Used((Program) localCache.get(Integer.toString(pid)), fileVertex); edge.addAnnotation("iotime", Integer.toString(iotime)); edge.addAnnotation("endtime", Long.toString(now)); putEdge(edge); // If the given path represents a link, then perform the same operation on the // artifact to which the link points. if (link == 1 && links.containsKey(path)) { read(pid, iotime, links.get(path), 0); } }
@Override public boolean launch(String arguments) { if (arguments == null) { return false; } try { localHostAddress = InetAddress.getLocalHost().getHostAddress(); localHostName = InetAddress.getLocalHost().getHostName(); } catch (Exception ex) { localHostAddress = null; localHostName = null; Logger.getLogger(LinuxFUSE.class.getName()).log(Level.WARNING, null, ex); } try { BufferedReader confReader = new BufferedReader(new FileReader("/etc/fuse.conf")); String line; boolean found = false; while ((line = confReader.readLine()) != null) { // Check if the line "user_allow_other" exists in the config file. if (line.trim().equalsIgnoreCase("user_allow_other")) { found = true; break; } } if (!found) { // File /etc/fuse.conf not configured correctly. return false; } } catch (Exception ex) { // File /etc/fuse.conf does not exist or is configured incorrectly. Logger.getLogger(LinuxFUSE.class.getName()).log(Level.WARNING, null, ex); return false; } try { // The argument to this reporter is the mount point for FUSE. mountPoint = arguments; localCache = Collections.synchronizedMap(new HashMap<String, AbstractVertex>()); links = Collections.synchronizedMap(new HashMap<String, String>()); // Create a new directory as the mount point for FUSE. java.io.File mount = new java.io.File(mountPoint); if (mount.exists()) { return false; } else { int exitValue = Runtime.getRuntime().exec("mkdir " + mountPoint).waitFor(); if (exitValue != 0) { return false; } } mountPath = (new java.io.File(mountPoint)).getAbsolutePath(); myPID = ManagementFactory.getRuntimeMXBean().getName().split("@")[0].trim(); // Load the native library. System.loadLibrary("LinuxFUSE"); // Get the system boot time from the proc filesystem. boottime = 0; try { BufferedReader boottimeReader = new BufferedReader(new FileReader("/proc/stat")); String line; while ((line = boottimeReader.readLine()) != null) { StringTokenizer st = new StringTokenizer(line); if (st.nextToken().equals("btime")) { boottime = Long.parseLong(st.nextToken()) * 1000; break; } else { continue; } } boottimeReader.close(); } catch (Exception exception) { Logger.getLogger(LinuxFUSE.class.getName()).log(Level.SEVERE, null, exception); } // Create an initial root vertex which will be used as the root of the // process tree. Program rootVertex = new Program(); rootVertex.addAnnotation("pidname", "System"); rootVertex.addAnnotation("pid", "0"); rootVertex.addAnnotation("ppid", "0"); String stime_readable = new java.text.SimpleDateFormat(simpleDatePattern).format(new java.util.Date(boottime)); String stime = Long.toString(boottime); rootVertex.addAnnotation("boottime_unix", stime); rootVertex.addAnnotation("boottime_simple", stime_readable); localCache.put("0", rootVertex); putVertex(rootVertex); String path = "/proc"; String currentProgram; java.io.File folder = new java.io.File(path); java.io.File[] listOfFiles = folder.listFiles(); // Build the process tree using the directories under /proc/. Directories // which have a numeric name represent processes. for (int i = 0; i < listOfFiles.length; i++) { if (listOfFiles[i].isDirectory()) { currentProgram = listOfFiles[i].getName(); try { Integer.parseInt(currentProgram); Program processVertex = createProgramVertex(currentProgram); String ppid = (String) processVertex.getAnnotation("ppid"); localCache.put(currentProgram, processVertex); putVertex(processVertex); if (Integer.parseInt(ppid) >= 0) { if (((Program) localCache.get(ppid) != null) && (processVertex != null)) { WasTriggeredBy triggerEdge = new WasTriggeredBy(processVertex, (Program) localCache.get(ppid)); putEdge(triggerEdge); } } } catch (Exception exception) { continue; } } } Runnable FUSEThread = new Runnable() { public void run() { try { // Launch FUSE from the native library. launchFUSE(mountPoint); } catch (Exception exception) { Logger.getLogger(LinuxFUSE.class.getName()).log(Level.SEVERE, null, exception); } } }; new Thread(FUSEThread, "LinuxFUSE-Thread").start(); } catch (Exception exception) { Logger.getLogger(LinuxFUSE.class.getName()).log(Level.SEVERE, null, exception); return false; } return true; }