JNIEXPORT void JNICALL
Java_org_apache_hadoop_io_nativeio_SharedFileDescriptorFactory_deleteStaleTemporaryFiles0(
  JNIEnv *env, jclass clazz, jstring jprefix, jstring jpath)
{
  const char *prefix = NULL, *path = NULL;
  char target[PATH_MAX];
  jthrowable jthr;
  DIR *dp = NULL;
  struct dirent *de;

  prefix = (*env)->GetStringUTFChars(env, jprefix, NULL);
  if (!prefix) goto done; // exception raised
  path = (*env)->GetStringUTFChars(env, jpath, NULL);
  if (!path) goto done; // exception raised

  dp = opendir(path);
  if (!dp) {
    int ret = errno;
    jthr = newIOException(env, "opendir(%s) error %d: %s",
                          path, ret, terror(ret));
    (*env)->Throw(env, jthr);
    goto done;
  }
  while ((de = readdir(dp))) {
    if (strncmp(prefix, de->d_name, strlen(prefix)) == 0) {
      int ret = snprintf(target, PATH_MAX, "%s/%s", path, de->d_name);
      if ((0 < ret) && (ret < PATH_MAX)) {
        unlink(target);
      }
    }
  }

done:
  if (dp) {
    closedir(dp);
  }
  if (prefix) {
    (*env)->ReleaseStringUTFChars(env, jprefix, prefix);
  }
  if (path) {
    (*env)->ReleaseStringUTFChars(env, jpath, path);
  }
}
Beispiel #2
0
JNIEXPORT jint JNICALL
Java_org_apache_hadoop_net_unix_DomainSocketWatcher_doPoll0(
JNIEnv *env, jclass clazz, jint checkMs, jobject fdSet)
{
  struct fd_set_data *sd;
  int ret, err;

  sd = (struct fd_set_data*)(intptr_t)(*env)->
      GetLongField(env, fdSet, fd_set_data_fid);
  ret = poll(sd->pollfd, sd->used_size, checkMs);
  if (ret >= 0) {
    return ret;
  }
  err = errno;
  if (err != EINTR) { // treat EINTR as 0 fds ready
    (*env)->Throw(env, newIOException(env,
            "poll(2) failed with error code %d: %s", err, terror(err)));
  }
  return 0;
}
JNIEXPORT jobject JNICALL
Java_org_apache_hadoop_io_nativeio_SharedFileDescriptorFactory_createDescriptor0(
  JNIEnv *env, jclass clazz, jstring jprefix, jstring jpath, jint length)
{
  const char *prefix = NULL, *path = NULL;
  char target[PATH_MAX];
  int ret, fd = -1, rnd;
  jthrowable jthr;
  jobject jret = NULL;

  prefix = (*env)->GetStringUTFChars(env, jprefix, NULL);
  if (!prefix) goto done; // exception raised
  path = (*env)->GetStringUTFChars(env, jpath, NULL);
  if (!path) goto done; // exception raised

  pthread_mutex_lock(&g_rand_lock);
  rnd = rand();
  pthread_mutex_unlock(&g_rand_lock);
  while (1) {
    ret = snprintf(target, PATH_MAX, "%s/%s_%d",
                   path, prefix, rnd);
    if (ret < 0) {
      jthr = newIOException(env, "snprintf error");
      (*env)->Throw(env, jthr);
      goto done;
    } else if (ret >= PATH_MAX) {
      jthr = newIOException(env, "computed path was too long.");
      (*env)->Throw(env, jthr);
      goto done;
    }
    fd = open(target, O_CREAT | O_EXCL | O_RDWR, 0700);
    if (fd >= 0) break; // success
    ret = errno;
    if (ret == EEXIST) {
      // Bad luck -- we got a very rare collision here between us and 
      // another DataNode (or process).  Try again.
      continue;
    } else if (ret == EINTR) {
      // Most of the time, this error is only possible when opening FIFOs.
      // But let's be thorough.
      continue;
    }
    jthr = newIOException(env, "open(%s, O_CREAT | O_EXCL | O_RDWR) "
            "failed: error %d (%s)", target, ret, terror(ret));
    (*env)->Throw(env, jthr);
    goto done;
  }
  if (unlink(target) < 0) {
    jthr = newIOException(env, "unlink(%s) failed: error %d (%s)",
                          path, ret, terror(ret));
    (*env)->Throw(env, jthr);
    goto done;
  }
  if (ftruncate(fd, length) < 0) {
    jthr = newIOException(env, "ftruncate(%s, %d) failed: error %d (%s)",
                          path, length, ret, terror(ret));
    (*env)->Throw(env, jthr);
    goto done;
  }
  jret = fd_create(env, fd); // throws exception on error.

done:
  if (prefix) {
    (*env)->ReleaseStringUTFChars(env, jprefix, prefix);
  }
  if (path) {
    (*env)->ReleaseStringUTFChars(env, jpath, path);
  }
  if (!jret) {
    if (fd >= 0) {
      close(fd);
    }
  }
  return jret;
}