You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by te...@apache.org on 2012/06/24 18:20:28 UTC

svn commit: r1353289 - in /hbase/trunk: bin/ hbase-server/ hbase-server/src/main/native/ hbase-server/src/main/native/src/ hbase-server/src/main/native/src/mlockall_agent/ src/assembly/

Author: tedyu
Date: Sun Jun 24 16:20:28 2012
New Revision: 1353289

URL: http://svn.apache.org/viewvc?rev=1353289&view=rev
Log:
HBASE-4391 Add ability to start RS as root and call mlockall (Matteo Bertozzi)


Added:
    hbase/trunk/hbase-server/src/main/native/
    hbase/trunk/hbase-server/src/main/native/CMakeLists.txt
    hbase/trunk/hbase-server/src/main/native/src/
    hbase/trunk/hbase-server/src/main/native/src/mlockall_agent/
    hbase/trunk/hbase-server/src/main/native/src/mlockall_agent/mlockall_agent.c
Modified:
    hbase/trunk/bin/hbase-config.sh
    hbase/trunk/hbase-server/pom.xml
    hbase/trunk/src/assembly/all.xml

Modified: hbase/trunk/bin/hbase-config.sh
URL: http://svn.apache.org/viewvc/hbase/trunk/bin/hbase-config.sh?rev=1353289&r1=1353288&r2=1353289&view=diff
==============================================================================
--- hbase/trunk/bin/hbase-config.sh (original)
+++ hbase/trunk/bin/hbase-config.sh Sun Jun 24 16:20:28 2012
@@ -63,6 +63,21 @@ do
     hosts=$1
     shift
     HBASE_REGIONSERVERS=$hosts
+  elif [ "--mlock" = "$1" ]
+  then
+    shift
+    mlock_opts=$1
+    shift
+    mlock_agent="$HBASE_HOME/native/libmlockall_agent.so"
+    echo $mlock_agent
+    if [ -e $mlock_agent ]; then
+        HBASE_REGIONSERVER_OPTS="$HBASE_REGIONSERVER_OPTS -agentpath:$mlock_agent=$mlock_opts"
+    else
+        cat 1>&2 <<EOF
+Unable to find mlockall_agent, hbase must be compiled with -Pnative
+EOF
+        exit 1
+    fi
   else
     # Presume we are at end of options and break
     break

Modified: hbase/trunk/hbase-server/pom.xml
URL: http://svn.apache.org/viewvc/hbase/trunk/hbase-server/pom.xml?rev=1353289&r1=1353288&r2=1353289&view=diff
==============================================================================
--- hbase/trunk/hbase-server/pom.xml (original)
+++ hbase/trunk/hbase-server/pom.xml Sun Jun 24 16:20:28 2012
@@ -515,6 +515,39 @@
         </dependency>
       </dependencies>
     </profile>
+    <profile>
+      <id>native</id>
+      <activation>
+        <activeByDefault>false</activeByDefault>
+      </activation>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-antrun-plugin</artifactId>
+            <executions>
+              <execution>
+                <id>make</id>
+                <phase>compile</phase>
+                <goals><goal>run</goal></goals>
+                <configuration>
+                  <target>
+                    <mkdir dir="${project.build.directory}/native"/>
+                    <exec executable="cmake" dir="${project.build.directory}/native" 
+                        failonerror="true">
+                      <arg line="${basedir}/src/main/native -DJVM_ARCH_DATA_MODEL=${sun.arch.data.model}"/>
+                    </exec>
+                    <exec executable="make" dir="${project.build.directory}/native" failonerror="true">
+                      <arg line="VERBOSE=1"/>
+                    </exec>
+                  </target>
+                </configuration>
+              </execution>
+            </executions>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
     <!-- Profiles for building against different hadoop versions -->
     <!-- There are a lot of common dependencies used here, should investigate
     if we can combine these profiles somehow -->

Added: hbase/trunk/hbase-server/src/main/native/CMakeLists.txt
URL: http://svn.apache.org/viewvc/hbase/trunk/hbase-server/src/main/native/CMakeLists.txt?rev=1353289&view=auto
==============================================================================
--- hbase/trunk/hbase-server/src/main/native/CMakeLists.txt (added)
+++ hbase/trunk/hbase-server/src/main/native/CMakeLists.txt Sun Jun 24 16:20:28 2012
@@ -0,0 +1,35 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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 at
+#
+#     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.
+#
+
+cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
+
+# If JVM_ARCH_DATA_MODEL is 32, compile all binaries as 32-bit.
+# This variable is set by maven.
+if (JVM_ARCH_DATA_MODEL EQUAL 32)
+    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32")
+    set(CMAKE_LD_FLAGS "${CMAKE_LD_FLAGS} -m32")
+    if (CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "amd64")
+        set(CMAKE_SYSTEM_PROCESSOR "i686")
+    endif ()
+endif (JVM_ARCH_DATA_MODEL EQUAL 32)
+
+FIND_PACKAGE(JNI REQUIRED)
+INCLUDE_DIRECTORIES(${JAVA_INCLUDE_PATH})
+INCLUDE_DIRECTORIES(${JAVA_INCLUDE_PATH2})
+
+add_library (mlockall_agent SHARED src/mlockall_agent/mlockall_agent.c)

Added: hbase/trunk/hbase-server/src/main/native/src/mlockall_agent/mlockall_agent.c
URL: http://svn.apache.org/viewvc/hbase/trunk/hbase-server/src/main/native/src/mlockall_agent/mlockall_agent.c?rev=1353289&view=auto
==============================================================================
--- hbase/trunk/hbase-server/src/main/native/src/mlockall_agent/mlockall_agent.c (added)
+++ hbase/trunk/hbase-server/src/main/native/src/mlockall_agent/mlockall_agent.c Sun Jun 24 16:20:28 2012
@@ -0,0 +1,148 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 at
+ *
+ *     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.
+ */
+
+/**
+ * mlockall_agent is a simple VM Agent that allows to lock the address space of 
+ * the process. This avoids the process' memory eviction under pressure.
+ *
+ * One example is when on the same machine you run the Region Server and 
+ * some map-reduce tasks, some unused data in the region server may get swapped 
+ * and this affects the region server performance.
+ * 
+ * You can load the agent by adding it as a jvm option:
+ * export HBASE_REGIONSERVER_OPTS="-agentpath:./libmlockall_agent.so=user=hbase"
+ */
+
+#include <libgen.h>
+#include <grp.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/resource.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include "jvmti.h"
+
+typedef struct opts {
+  char *setuid_user;
+} opts_t;
+
+#define PREFIX "mlockall_agent: "
+#define LOG(fmt, ...) { fprintf(stderr, PREFIX fmt, #__VA_ARGS__); }
+
+static int parse_options (const char *options, opts_t *parsed) {
+  char *optr, *opts_dup;
+  char *save2 = NULL;
+  char *save = NULL;
+  char *key, *val;
+  int ret = 0;
+  char *tok;
+
+  memset(parsed, 0, sizeof(opts_t));
+  if ((opts_dup = strdup(options)) == NULL)
+    return(-1);
+
+  optr = opts_dup;
+  while ((tok = strtok_r(optr, ",", &save)) != NULL) {
+    optr = NULL;
+    save2 = NULL;
+
+    key = strtok_r(tok, "=", &save2);    
+    val = strtok_r(NULL, "=", &save2);
+    if (!strcmp(key, "user")) {
+      parsed->setuid_user = strdup(val);
+    } else {
+      LOG("Unknown agent parameter '%s'\n", key);
+      ret = 1;
+    }
+  }
+
+  free(opts_dup);
+  return(ret);
+}
+
+static void warn_unless_root() {
+  if (geteuid() != 0) {
+    LOG("(this may be because java was not run as root!)\n");
+  }
+}
+
+JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *vm, char *init_str, void *reserved) {
+  struct passwd *pwd = NULL;
+  opts_t opts;
+
+  if (parse_options(init_str, &opts)) {
+    return(1);
+  }
+
+  // Check that the target user for setuid is specified if current user is root
+  if (opts.setuid_user == NULL) {
+    LOG("Unable to setuid: specify a target username as the agent option user=<username>\n");
+    return(1);
+  }
+
+  // Check that this user exists
+  if ((pwd = getpwnam(opts.setuid_user)) == NULL) {
+    LOG("Unable to setuid: could not find user '%s'\n", opts.setuid_user);
+    return(1);
+  }
+
+  // Boost the mlock limit up to infinity
+  struct rlimit lim;
+  lim.rlim_max = RLIM_INFINITY;
+  lim.rlim_cur = lim.rlim_max;
+  if (setrlimit(RLIMIT_MEMLOCK, &lim)) {
+    perror(PREFIX "Unable to boost memlock resource limit");
+    warn_unless_root();
+    return(1);
+  }
+
+  // Actually lock our memory, including future allocations.
+  if (mlockall(MCL_CURRENT | MCL_FUTURE)) {
+    perror(PREFIX "Unable to lock memory.");
+    warn_unless_root();
+    return(1);
+  }
+
+  // Drop down to the user's supplemental group list
+  if (initgroups(opts.setuid_user, pwd->pw_gid)) {
+    perror(PREFIX "Unable to initgroups");
+    warn_unless_root();
+    return(1);
+  }
+ 
+  // And primary group ID
+  if (setgid(pwd->pw_gid)) {
+    perror(PREFIX "Unable to setgid");
+    warn_unless_root();
+    return(1);
+  }
+
+  // And user ID
+  if (setuid(pwd->pw_uid)) {
+    perror(PREFIX "Unable to setuid");
+    warn_unless_root();
+    return(1);
+  }
+
+  LOG("Successfully locked memory and setuid to %s\n", opts.setuid_user);
+  return(0);
+}
+

Modified: hbase/trunk/src/assembly/all.xml
URL: http://svn.apache.org/viewvc/hbase/trunk/src/assembly/all.xml?rev=1353289&r1=1353288&r2=1353289&view=diff
==============================================================================
--- hbase/trunk/src/assembly/all.xml (original)
+++ hbase/trunk/src/assembly/all.xml Sun Jun 24 16:20:28 2012
@@ -90,6 +90,16 @@
       <fileMode>0644</fileMode>
       <directoryMode>0755</directoryMode>
     </fileSet>
+    <!-- Include native libraries -->
+    <fileSet>
+      <directory>hbase-server/target/native</directory>
+      <outputDirectory>native</outputDirectory>
+      <fileMode>0755</fileMode>
+      <directoryMode>0755</directoryMode>
+      <includes>
+        <include>*.so</include>
+      </includes>
+    </fileSet>
     <!-- This is only necessary until maven fixes the intra-project dependency bug 
       in maven 3.0. Until then, we have to include the test jars for sub-projects. When 
       fixed, the below dependencySet stuff is sufficient for pulling in the test jars as