Merge branch 'master' into raman/master_ports
diff --git a/asterix-events/src/main/resources/events/cc_start/cc_start.sh b/asterix-events/src/main/resources/events/cc_start/cc_start.sh
index 003d9cf..bbea4dc 100755
--- a/asterix-events/src/main/resources/events/cc_start/cc_start.sh
+++ b/asterix-events/src/main/resources/events/cc_start/cc_start.sh
@@ -3,4 +3,4 @@
   mkdir -p $LOG_DIR
 fi
 cd $WORKING_DIR
-$ASTERIX_HOME/bin/asterixcc -client-net-ip-address $CLIENT_NET_IP -client-net-port 1098 -cluster-net-ip-address $CLUSTER_NET_IP -cluster-net-port 1099 -http-port 8888  &> $LOG_DIR/cc.log
+$ASTERIX_HOME/bin/asterixcc -client-net-ip-address $CLIENT_NET_IP -client-net-port $CLIENT_NET_PORT -cluster-net-ip-address $CLUSTER_NET_IP -cluster-net-port $CLUSTER_NET_PORT -http-port $HTTP_PORT  &> $LOG_DIR/cc.log
diff --git a/asterix-events/src/main/resources/events/events.xml b/asterix-events/src/main/resources/events/events.xml
index f85e3ea..068367e 100644
--- a/asterix-events/src/main/resources/events/events.xml
+++ b/asterix-events/src/main/resources/events/events.xml
@@ -70,6 +70,13 @@
     <daemon>false</daemon>
   </event>
   <event>
+    <type>directory_copy</type>
+    <script>file/dir_copy.sh</script>
+    <description>Copies a directory (and its contents) from the remove file system to the local file system</description>
+    <args>destination_node destination_path local_source_path</args>
+    <daemon>false</daemon>
+  </event>
+  <event>
     <type>file_delete</type>
     <script>file/delete.sh</script>
     <description>Deletes a file on the local file system to a remote node</description>
diff --git a/asterix-events/src/main/resources/events/file/dir_copy.sh b/asterix-events/src/main/resources/events/file/dir_copy.sh
new file mode 100755
index 0000000..6015dca
--- /dev/null
+++ b/asterix-events/src/main/resources/events/file/dir_copy.sh
@@ -0,0 +1,7 @@
+USERNAME=$1
+SRC_HOST=$2
+SRC_DIR=$3
+DEST_DIR=$4
+mkdir -p $DEST_DIR
+echo "scp -r $USERNAME@$SRC_HOST:$SRC_DIR $DEST_DIR"
+scp -r $USERNAME@$SRC_HOST:$SRC_DIR $DEST_DIR 
diff --git a/asterix-events/src/main/resources/events/node_join/nc_join.sh b/asterix-events/src/main/resources/events/node_join/nc_join.sh
index d8bbbd2..efbfd40 100755
--- a/asterix-events/src/main/resources/events/node_join/nc_join.sh
+++ b/asterix-events/src/main/resources/events/node_join/nc_join.sh
@@ -6,4 +6,4 @@
   mkdir -p $LOG_DIR
 fi
 cd $WORKING_DIR
-$ASTERIX_HOME/bin/asterixnc -node-id $NC_ID -cc-host $CC_HOST -cc-port 1099 -cluster-net-ip-address $IP_LOCATION  -data-ip-address $IP_LOCATION -iodevices $IO_DEVICES -result-ip-address $IP_LOCATION &> $LOG_DIR/${NC_ID}.log
+$ASTERIX_HOME/bin/asterixnc -node-id $NC_ID -cc-host $CC_HOST -cc-port $CLUSTER_NET_PORT  -cluster-net-ip-address $IP_LOCATION  -data-ip-address $IP_LOCATION -iodevices $IO_DEVICES -result-ip-address $IP_LOCATION &> $LOG_DIR/${NC_ID}.log
diff --git a/asterix-events/src/main/resources/schema/cluster.xsd b/asterix-events/src/main/resources/schema/cluster.xsd
index 718d7b0..c0cd309 100644
--- a/asterix-events/src/main/resources/schema/cluster.xsd
+++ b/asterix-events/src/main/resources/schema/cluster.xsd
@@ -17,6 +17,10 @@
 	<xs:element name="iodevices" type="xs:string" />
 	<xs:element name="java_home" type="xs:string" />
 	<xs:element name="username" type="xs:string" />
+	<xs:element name="web_port" type="xs:string" />
+	<xs:element name="client_port" type="xs:string" />
+	<xs:element name="cluster_port" type="xs:string" />
+	<xs:element name="http_port" type="xs:string" />
 
 	<!-- definition of complex elements -->
 	<xs:element name="working_dir">
@@ -49,6 +53,17 @@
 		</xs:complexType>
 	</xs:element>
 
+	<xs:element name="ports">
+		<xs:complexType>
+			<xs:sequence>
+				<xs:element ref="cl:web_port"  />
+				<xs:element ref="cl:client_port"  />
+				<xs:element ref="cl:cluster_port"  />
+				<xs:element ref="cl:http_port"  />
+			</xs:sequence>
+		</xs:complexType>
+	</xs:element>
+
 	<xs:element name="env">
 		<xs:complexType>
 			<xs:sequence>
@@ -82,6 +97,7 @@
 				<xs:element ref="cl:txn_log_dir" minOccurs="0" />
 				<xs:element ref="cl:store" minOccurs="0" />
 				<xs:element ref="cl:iodevices" minOccurs="0" />
+				<xs:element ref="cl:ports" />
 				<xs:element ref="cl:working_dir" />
 				<xs:element ref="cl:master_node" />
 				<xs:element ref="cl:node" maxOccurs="unbounded" />
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/CommandHandler.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/CommandHandler.java
index 7fc3884..91a7ee5 100644
--- a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/CommandHandler.java
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/CommandHandler.java
@@ -52,6 +52,9 @@
             case CONFIGURE:
                 cmd = new ConfigureCommand();
                 break;
+            case LOG:
+                cmd = new LogCommand();
+                break;
             case SHUTDOWN:
                 cmd = new ShutdownCommand();
                 break;
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/HelpCommand.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/HelpCommand.java
index 3bc700d..76e40fa 100644
--- a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/HelpCommand.java
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/HelpCommand.java
@@ -58,6 +58,9 @@
             case ALTER:
                 helpMessage = new AlterCommand().getUsageDescription();
                 break;
+            case LOG:
+                helpMessage = new LogCommand().getUsageDescription();
+                break;
             default:
                 helpMessage = "Unknown command " + command;
         }
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/ICommand.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/ICommand.java
index 979c414..0b29850 100644
--- a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/ICommand.java
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/ICommand.java
@@ -27,6 +27,7 @@
         ALTER,
         VALIDATE,
         CONFIGURE,
+        LOG,
         SHUTDOWN,
         HELP
     }
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/LogCommand.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/LogCommand.java
new file mode 100644
index 0000000..3f99ab0
--- /dev/null
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/LogCommand.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2009-2012 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package edu.uci.ics.asterix.installer.command;
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.util.Date;
+
+import org.apache.commons.io.FileUtils;
+import org.kohsuke.args4j.Option;
+
+import edu.uci.ics.asterix.event.management.EventrixClient;
+import edu.uci.ics.asterix.event.schema.pattern.Patterns;
+import edu.uci.ics.asterix.installer.driver.InstallerDriver;
+import edu.uci.ics.asterix.installer.driver.InstallerUtil;
+import edu.uci.ics.asterix.installer.error.InstallerException;
+import edu.uci.ics.asterix.installer.events.PatternCreator;
+import edu.uci.ics.asterix.installer.model.AsterixInstance;
+import edu.uci.ics.asterix.installer.model.AsterixInstance.State;
+
+public class LogCommand extends AbstractCommand {
+
+    @Override
+    protected void execCommand() throws Exception {
+        InstallerDriver.initConfig(true);
+        String asterixInstanceName = ((LogConfig) config).name;
+        AsterixInstance instance = InstallerUtil.validateAsterixInstanceExists(asterixInstanceName, State.INACTIVE,
+                State.UNUSABLE, State.ACTIVE);
+        PatternCreator pc = new PatternCreator();
+        EventrixClient client = InstallerUtil.getEventrixClient(instance.getCluster());
+        String outputDir = ((LogConfig) config).outputDir == null ? InstallerDriver.getManagixHome() + File.separator + "logdump"
+                : ((LogConfig) config).outputDir;
+        File f = new File(outputDir);
+        String outputDirPath = f.getAbsolutePath();
+        if (!f.exists()) {
+            boolean success = f.mkdirs();
+            if (!success) {
+                throw new InstallerException("Unable to create output directory:" + outputDirPath);
+            }
+        }
+        Patterns transferLogPattern = pc.getGenerateLogPattern(asterixInstanceName, instance.getCluster(), outputDirPath);
+        client.submit(transferLogPattern);
+        File outputDirFile = new File(outputDirPath);
+        final String destFileName = "log_" + new Date().toString().replace(' ', '_') + ".zip";
+        File destFile = new File(outputDirFile, destFileName);
+        InstallerUtil.zipDir(outputDirFile, destFile);
+
+        String[] filesToDelete = outputDirFile.list(new FilenameFilter() {
+            @Override
+            public boolean accept(File dir, String name) {
+                return !name.equals(destFileName);
+            }
+
+        });
+        for (String fileS : filesToDelete) {
+             f = new File(outputDirFile, fileS);
+            if (f.isDirectory()) {
+                FileUtils.deleteDirectory(f);
+            } else {
+                f.delete();
+            }
+        }
+        LOGGER.info("Log zip archive created at " + destFile.getAbsolutePath());
+    }
+
+    @Override
+    protected CommandConfig getCommandConfig() {
+        return new LogConfig();
+    }
+
+    @Override
+    protected String getUsageDescription() {
+        return "\nCreates a tar ball containing log files corresponding to each worker node (NC) and the master (CC)  for an ASTERIX instance"
+                + "\n\nAvailable arguments/options"
+                + "\n-n name of the ASTERIX instance. \n-d destination directory for producing the tar ball (defaults to) "
+                + InstallerDriver.getManagixHome();
+    }
+}
+
+class LogConfig extends CommandConfig {
+
+    @Option(name = "-n", required = true, usage = "Name of Asterix Instance")
+    public String name;
+
+    @Option(name = "-d", required = false, usage = "Destination directory for producing log tar ball")
+    public String outputDir;
+
+}
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/driver/InstallerDriver.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/driver/InstallerDriver.java
index a9ab53b..1c2ec0a 100644
--- a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/driver/InstallerDriver.java
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/driver/InstallerDriver.java
@@ -135,6 +135,8 @@
         buffer.append("describe " + ":" + " Describes an existing asterix instance" + "\n");
         buffer.append("validate " + ":" + " Validates the installer/cluster configuration" + "\n");
         buffer.append("configure" + ":" + " Configure the Asterix installer" + "\n");
+        buffer.append("log      " + ":"
+                + " Produce a tar archive contianing log files from the master and worker nodes" + "\n");
         buffer.append("shutdown " + ":" + " Shutdown the installer service" + "\n");
         buffer.append("help     " + ":" + " Provides usage description of a command" + "\n");
         buffer.append("\nTo get more information about a command, use managix help -cmd <command>");
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/driver/InstallerUtil.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/driver/InstallerUtil.java
index abf0420..38be234 100644
--- a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/driver/InstallerUtil.java
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/driver/InstallerUtil.java
@@ -69,6 +69,10 @@
     public static final String TXN_LOG_DIR_KEY_SUFFIX = "txnLogDir";
     public static final String ASTERIX_CONFIGURATION_FILE = "asterix-configuration.xml";
     public static final String TXN_LOG_CONFIGURATION_FILE = "log.properties";
+    public static final int CLUSTER_NET_PORT_DEFAULT = 1098;
+    public static final int CLIENT_NET_PORT_DEFAULT = 1099;
+    public static final int HTTP_PORT_DEFAULT = 8888;
+    public static final int WEB_INTERFACE_PORT_DEFAULT = 19001;
 
     public static AsterixInstance createAsterixInstance(String asterixInstanceName, Cluster cluster,
             AsterixConfiguration asterixConfiguration) throws FileNotFoundException, IOException {
@@ -106,11 +110,22 @@
         }
         clusterProperties.add(new Property("ASTERIX_HOME", cluster.getWorkingDir().getDir() + File.separator
                 + "asterix"));
-        clusterProperties.add(new Property("CLUSTER_NET_IP", cluster.getMasterNode().getClusterIp()));
-        clusterProperties.add(new Property("CLIENT_NET_IP", cluster.getMasterNode().getClientIp()));
         clusterProperties.add(new Property("LOG_DIR", cluster.getLogDir()));
         clusterProperties.add(new Property("JAVA_HOME", cluster.getJavaHome()));
         clusterProperties.add(new Property("WORKING_DIR", cluster.getWorkingDir().getDir()));
+        clusterProperties.add(new Property("CLIENT_NET_IP", cluster.getMasterNode().getClientIp()));
+        clusterProperties.add(new Property("CLUSTER_NET_IP", cluster.getMasterNode().getClusterIp()));
+
+        int clusterNetPort = cluster.getPorts() != null && cluster.getPorts().getClusterPort() != null ? Integer
+                .parseInt(cluster.getPorts().getClusterPort()) : CLUSTER_NET_PORT_DEFAULT;
+        int clientNetPort = cluster.getPorts() != null && cluster.getPorts().getClientPort() != null ? Integer
+                .parseInt(cluster.getPorts().getClientPort()) : CLIENT_NET_PORT_DEFAULT;
+        int httpPort = cluster.getPorts() != null && cluster.getPorts().getHttpPort() != null ? Integer
+                .parseInt(cluster.getPorts().getHttpPort()) : HTTP_PORT_DEFAULT;
+        clusterProperties.add(new Property("CLIENT_NET_PORT", "" + clientNetPort));
+        clusterProperties.add(new Property("CLUSTER_NET_PORT", "" + clusterNetPort));
+        clusterProperties.add(new Property("HTTP_PORT", "" + httpPort));
+
         cluster.setEnv(new Env(clusterProperties));
     }
 
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/events/PatternCreator.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/events/PatternCreator.java
index 0f382f9..7330c67 100644
--- a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/events/PatternCreator.java
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/events/PatternCreator.java
@@ -16,8 +16,10 @@
 
 import java.io.File;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import edu.uci.ics.asterix.event.driver.EventDriver;
@@ -183,7 +185,7 @@
             txnLogDir = node.getTxnLogDir() == null ? instance.getCluster().getTxnLogDir() : node.getTxnLogDir();
             store = node.getStore() == null ? cluster.getStore() : node.getStore();
             pargs = workingDir + " " + instance.getName() + " " + iodevices + " " + store + " "
-                    + BackupCommand.ASTERIX_ROOT_METADATA_DIR + " " + txnLogDir + " " + backupId + " " + backupDir
+                    + BackupCommand.ASTERIX_ROOT_METADATA_DIR  + " " + txnLogDir + " " + backupId + " " + backupDir
                     + " " + "local" + " " + node.getId();
             Event event = new Event("backup", nodeid, pargs);
             patternList.add(new Pattern(null, 1, null, event));
@@ -479,4 +481,35 @@
         return new Pattern(null, 1, null, event);
     }
 
+    public Patterns getGenerateLogPattern(String asterixInstanceName, Cluster cluster, String outputDir) {
+        List<Pattern> patternList = new ArrayList<Pattern>();
+        Map<String,String> nodeLogs = new HashMap<String,String>();
+        
+        String username = cluster.getUsername() == null ? System.getProperty("user.name") : cluster.getUsername();
+        String srcHost = cluster.getMasterNode().getClientIp();
+        Nodeid nodeid = new Nodeid(new Value(null, EventDriver.CLIENT_NODE.getId()));
+        String srcDir = cluster.getMasterNode().getLogDir() == null ? cluster.getLogDir() : cluster.getMasterNode()
+                .getLogDir();
+        String destDir = outputDir + File.separator + "cc";
+        String pargs = username + " " + srcHost + " " + srcDir + " " + destDir;
+        Event event = new Event("directory_copy", nodeid, pargs);
+        Pattern p = new Pattern(null, 1, null, event);
+        patternList.add(p);
+        nodeLogs.put(cluster.getMasterNode().getClusterIp(),srcDir);
+        for (Node node : cluster.getNode()) {
+            srcHost = node.getClusterIp();
+            srcDir = node.getLogDir() == null ? cluster.getLogDir() : node.getLogDir();
+            if(nodeLogs.get(node.getClusterIp()) != null && nodeLogs.get(node.getClusterIp()).equals(srcDir)){
+                continue;
+            }
+            destDir = outputDir + File.separator + node.getId();
+            pargs = username + " " + srcHost +  " " + srcDir + " "  + destDir;
+            event = new Event("directory_copy", nodeid, pargs);
+            p = new Pattern(null, 1, null, event);
+            patternList.add(p);
+        }
+        Patterns patterns = new Patterns(patternList);
+        return patterns;
+    }
+
 }
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/model/AsterixInstance.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/model/AsterixInstance.java
index 9839b90..e074fad 100644
--- a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/model/AsterixInstance.java
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/model/AsterixInstance.java
@@ -19,6 +19,7 @@
 import java.util.Date;
 import java.util.List;
 
+import edu.uci.ics.asterix.common.config.AsterixExternalProperties;
 import edu.uci.ics.asterix.common.configuration.AsterixConfiguration;
 import edu.uci.ics.asterix.common.configuration.Property;
 import edu.uci.ics.asterix.event.schema.cluster.Cluster;
@@ -28,7 +29,6 @@
 
     private static final long serialVersionUID = 2874439550187520449L;
 
-  
     public enum State {
         ACTIVE,
         INACTIVE,
@@ -60,7 +60,13 @@
         this.asterixVersion = asterixVersion;
         this.createdTimestamp = new Date();
         this.backupInfo = new ArrayList<BackupInfo>();
-        this.webInterfaceUrl = "http://" + cluster.getMasterNode().getClientIp() + ":" + 19001;
+        int webPort = 19001;
+        for (Property p : asterixConfiguration.getProperty()) {
+            if (p.getName().equalsIgnoreCase("web.port")) {
+                webPort = Integer.parseInt(p.getValue());
+            }
+        }
+        this.webInterfaceUrl = "http://" + cluster.getMasterNode().getClientIp() + ":" + webPort;
     }
 
     public Date getModifiedTimestamp() {
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/model/EventList.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/model/EventList.java
index b605889..33f489e 100644
--- a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/model/EventList.java
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/model/EventList.java
@@ -28,6 +28,7 @@
         FILE_TRANSFER,
         FILE_CREATE,
         DIRECTORY_TRANSFER,
+        DIRECTORY_COPY,
         NODE_INFO
     }
 }
diff --git a/asterix-installer/src/main/resources/clusters/local/local.xml b/asterix-installer/src/main/resources/clusters/local/local.xml
index 0af8dfc..3f739de 100644
--- a/asterix-installer/src/main/resources/clusters/local/local.xml
+++ b/asterix-installer/src/main/resources/clusters/local/local.xml
@@ -1,21 +1,26 @@
 <cluster xmlns="cluster">
-  <name>local</name>
-  <working_dir>
-    <dir>/tmp/asterix-installer</dir>
-    <NFS>true</NFS>
-  </working_dir>
-  <log_dir>/tmp/asterix/logs</log_dir>
-  <txn_log_dir>/tmp/asterix/logs</txn_log_dir>
-  <iodevices>/tmp</iodevices>
-  <store>asterix/storage</store>
-  <java_home></java_home>
-  <master_node>
-    <id>master</id>
-    <client_ip>127.0.0.1</client_ip>
-    <cluster_ip>127.0.0.1</cluster_ip>
-  </master_node>
-  <node>
-    <id>node1</id>
-    <cluster_ip>127.0.0.1</cluster_ip>
-  </node>
+	<name>local</name>
+	<working_dir>
+		<dir>/tmp/asterix-installer</dir>
+		<NFS>true</NFS>
+	</working_dir>
+	<log_dir>/tmp/asterix/logs</log_dir>
+	<txn_log_dir>/tmp/asterix/logs</txn_log_dir>
+	<ports>
+		<cluster_port>1099</cluster_port>
+		<client_port>1098</client_port>
+		<http_port>8888</http_port>
+	</ports>
+	<iodevices>/tmp</iodevices>
+	<store>asterix/storage</store>
+	<java_home></java_home>
+	<master_node>
+		<id>master</id>
+		<client_ip>127.0.0.1</client_ip>
+		<cluster_ip>127.0.0.1</cluster_ip>
+	</master_node>
+	<node>
+		<id>node1</id>
+		<cluster_ip>127.0.0.1</cluster_ip>
+	</node>
 </cluster>
diff --git a/asterix-transactions/src/main/java/edu/uci/ics/asterix/transaction/management/resource/PersistentLocalResourceRepository.java b/asterix-transactions/src/main/java/edu/uci/ics/asterix/transaction/management/resource/PersistentLocalResourceRepository.java
index a8f129a..d99fa8b 100644
--- a/asterix-transactions/src/main/java/edu/uci/ics/asterix/transaction/management/resource/PersistentLocalResourceRepository.java
+++ b/asterix-transactions/src/main/java/edu/uci/ics/asterix/transaction/management/resource/PersistentLocalResourceRepository.java
@@ -64,7 +64,8 @@
     }
 
     private String prepareRootMetaDataFileName(String mountPoint, String nodeId, int ioDeviceId) {
-        return mountPoint + ROOT_METADATA_DIRECTORY + "_" + nodeId + "_" + "iodevice" + ioDeviceId;
+        return mountPoint + File.separator + ROOT_METADATA_DIRECTORY + File.separator + ROOT_METADATA_DIRECTORY + "_"
+                + nodeId + "_" + "iodevice" + ioDeviceId;
     }
 
     public void initialize(String nodeId, String rootDir, boolean isNewUniverse, ResourceIdFactory resourceIdFactory)
@@ -82,7 +83,13 @@
 
                 File rootMetadataDir = new File(prepareRootMetaDataFileName(mountPoints[i], nodeId, i));
                 if (!rootMetadataDir.exists()) {
-                    rootMetadataDir.mkdir();
+                    boolean success = rootMetadataDir.mkdirs();
+                    if (!success) {
+                        if (LOGGER.isLoggable(Level.SEVERE)) {
+                            LOGGER.severe("Unable to create root metadata directory"
+                                    + rootMetadataDir.getAbsolutePath());
+                        }
+                    }
                     if (LOGGER.isLoggable(Level.INFO)) {
                         LOGGER.info("created the root-metadata-file's directory: " + rootMetadataDir.getAbsolutePath());
                     }