@Test
 public void testConsoleCtrlHandler() {
   if (Constants.WINDOWS) {
     assertNotNull(JNAKernel32Library.getInstance());
     assertThat(JNAKernel32Library.getInstance().getCallbacks().size(), equalTo(1));
   } else {
     assertNotNull(JNAKernel32Library.getInstance());
     assertThat(JNAKernel32Library.getInstance().getCallbacks().size(), equalTo(0));
   }
 }
示例#2
0
  /** initialize native resources */
  public static void initializeNatives(
      Path tmpFile, boolean mlockAll, boolean seccomp, boolean ctrlHandler) {
    final ESLogger logger = Loggers.getLogger(Bootstrap.class);

    // check if the user is running as root, and bail
    if (Natives.definitelyRunningAsRoot()) {
      if (Boolean.parseBoolean(System.getProperty("es.insecure.allow.root"))) {
        logger.warn("running as ROOT user. this is a bad idea!");
      } else {
        throw new RuntimeException("don't run elasticsearch as root.");
      }
    }

    // enable secure computing mode
    if (seccomp) {
      Natives.trySeccomp(tmpFile);
    }

    // mlockall if requested
    if (mlockAll) {
      if (Constants.WINDOWS) {
        Natives.tryVirtualLock();
      } else {
        Natives.tryMlockall();
      }
    }

    // listener for windows close event
    if (ctrlHandler) {
      Natives.addConsoleCtrlHandler(
          new ConsoleCtrlHandler() {
            @Override
            public boolean handle(int code) {
              if (CTRL_CLOSE_EVENT == code) {
                logger.info("running graceful exit on windows");
                try {
                  Bootstrap.stop();
                } catch (IOException e) {
                  throw new ElasticsearchException("failed to stop node", e);
                }
                return true;
              }
              return false;
            }
          });
    }

    // force remainder of JNA to be loaded (if available).
    try {
      JNAKernel32Library.getInstance();
    } catch (Throwable ignored) {
      // we've already logged this.
    }

    // init lucene random seed. it will use /dev/urandom where available:
    StringHelper.randomId();
  }
示例#3
0
  static void windowsImpl() {
    if (!Constants.WINDOWS) {
      throw new IllegalStateException(
          "bug: should not be trying to initialize ActiveProcessLimit for an unsupported OS");
    }

    JNAKernel32Library lib = JNAKernel32Library.getInstance();

    // create a new Job
    Pointer job = lib.CreateJobObjectW(null, null);
    if (job == null) {
      throw new UnsupportedOperationException("CreateJobObject: " + Native.getLastError());
    }

    try {
      // retrieve the current basic limits of the job
      int clazz = JNAKernel32Library.JOBOBJECT_BASIC_LIMIT_INFORMATION_CLASS;
      JNAKernel32Library.JOBOBJECT_BASIC_LIMIT_INFORMATION limits =
          new JNAKernel32Library.JOBOBJECT_BASIC_LIMIT_INFORMATION();
      limits.write();
      if (!lib.QueryInformationJobObject(job, clazz, limits.getPointer(), limits.size(), null)) {
        throw new UnsupportedOperationException(
            "QueryInformationJobObject: " + Native.getLastError());
      }
      limits.read();
      // modify the number of active processes to be 1 (exactly the one process we will add to the
      // job).
      limits.ActiveProcessLimit = 1;
      limits.LimitFlags = JNAKernel32Library.JOB_OBJECT_LIMIT_ACTIVE_PROCESS;
      limits.write();
      if (!lib.SetInformationJobObject(job, clazz, limits.getPointer(), limits.size())) {
        throw new UnsupportedOperationException(
            "SetInformationJobObject: " + Native.getLastError());
      }
      // assign ourselves to the job
      if (!lib.AssignProcessToJobObject(job, lib.GetCurrentProcess())) {
        throw new UnsupportedOperationException(
            "AssignProcessToJobObject: " + Native.getLastError());
      }
    } finally {
      lib.CloseHandle(job);
    }

    logger.debug("Windows ActiveProcessLimit initialization successful");
  }