예제 #1
0
파일: scr_log.c 프로젝트: LLNL/scr
/* given a username, a jobname, and a start time, lookup (or create) the id for this job */
int scr_log_job(const char* username, const char* jobname, time_t start)
{
  int rc = SCR_SUCCESS;

  if (scr_db_enable) {
    if (username != NULL && jobname != NULL) {
      int rc = scr_mysql_register_job(username, jobname, start, &scr_db_jobid);
      if (rc != SCR_SUCCESS) {
        scr_err("Failed to register job for username %s and jobname %s, disabling database logging @ %s:%d",
                username, jobname, __FILE__, __LINE__
        );
        scr_db_enable = 0;
        rc = SCR_FAILURE;
      }
    } else {
      scr_err("Failed to read username or jobname from environment, disabling database logging @ %s:%d",
              __FILE__, __LINE__
      );
      scr_db_enable = 0;
      rc = SCR_FAILURE;
    }
  }

  return rc;
}
예제 #2
0
파일: scr_util.c 프로젝트: kento/librscr
/* pack an unsigned 64 bit value to specified buffer in network order */
int scr_pack_uint64_t(void* buf, size_t buf_size, size_t* buf_pos, uint64_t val)
{
  /* check that we have a valid pointer to a buffer position value */
  if (buf == NULL || buf_pos == NULL) {
    scr_err("NULL pointer to buffer or buffer position @ %s:%d",
            __FILE__, __LINE__
    );
    return SCR_FAILURE;
  }

  /* get current buffer position */
  size_t pos = *buf_pos;

  /* compute final buffer position */
  size_t pos_final = pos + sizeof(val);

  /* check that we won't overrun the buffer */
  if (pos_final > buf_size) {
    scr_err("Attempting to pack too many bytes into buffer @ %s:%d",
            __FILE__, __LINE__
    );
    return SCR_FAILURE;
  }

  /* convert value to network order */
  uint64_t val_network = scr_hton64(val);

  /* pack value into buffer */
  memcpy(buf + pos, &val_network, sizeof(val_network));

  /* update position */
  *buf_pos = pos_final;

  return SCR_SUCCESS;
}
예제 #3
0
파일: scr_log.c 프로젝트: LLNL/scr
/* connects to the SCR log database */
int scr_mysql_connect()
{
#ifdef HAVE_LIBMYSQLCLIENT
  /* create our type-string-to-id cache */
  scr_db_types = scr_hash_new();
  if (scr_db_types == NULL) {
    scr_err("Failed to create a hash to cache type string to id lookups @ %s:%d",
            __FILE__, __LINE__
    );
    return SCR_FAILURE;
  }

  /* initialize our database structure */
  mysql_init(&scr_mysql);

  /* connect to the database */
  if (! mysql_real_connect(&scr_mysql, scr_db_host, scr_db_user, scr_db_pass, scr_db_name, 0, NULL, 0)) {
    scr_err("Failed to connect to SCR log database %s on host %s @ %s:%d",
            scr_db_name, scr_db_host, __FILE__, __LINE__
    );
    return SCR_FAILURE;
  }

#endif
  return SCR_SUCCESS;
}
예제 #4
0
파일: scr_io.c 프로젝트: cartazio/scr
int scr_file_unlock(const char* file, int fd)
{
  #ifdef SCR_FILE_LOCK_USE_FLOCK
    if (flock(fd, LOCK_UN) != 0) {
      scr_err("Failed to acquire file lock on %s: flock(%d, %d) errno=%d %s @ %s:%d",
              file, fd, LOCK_UN, errno, strerror(errno), __FILE__, __LINE__
      );
      return SCR_FAILURE;
    }
  #endif

  #ifdef SCR_FILE_LOCK_USE_FCNTL
    struct flock lck;
    lck.l_type = F_UNLCK;
    lck.l_whence = 0;
    lck.l_start = 0L;
    lck.l_len = 0L; //locking the entire file

    if(fcntl(fd, F_SETLK, &lck) < 0) {
      scr_err("Failed to acquire file read lock on %s: fnctl(%d, %d) errno=%d %s @ %s:%d",
              file, fd, F_UNLCK, errno, strerror(errno), __FILE__, __LINE__
      );
      return SCR_FAILURE;
    }
  #endif

  return SCR_SUCCESS;
}
예제 #5
0
파일: scr_util.c 프로젝트: kento/librscr
/* given a string, convert it to a double and write that value to val */
int scr_atod(char* str, double* val)
{
  /* check that we have a string */
  if (str == NULL) {
    scr_err("scr_atod: Can't convert NULL string to double @ %s:%d",
            __FILE__, __LINE__
    );
    return SCR_FAILURE;
  }

  /* check that we have a value to write to */
  if (val == NULL) {
    scr_err("scr_atod: NULL address to store value @ %s:%d",
            __FILE__, __LINE__
    );
    return SCR_FAILURE;
  }

  /* convert string to double */
  errno = 0;
  double value = strtod(str, NULL);
  if (errno == 0) {
    /* got a valid double, set our output parameter */
    *val = value;
  } else {
    /* could not interpret value */
    scr_err("scr_atod: Invalid double: %s @ %s:%d",
            str, __FILE__, __LINE__
    );
    return SCR_FAILURE;
  }

  return SCR_SUCCESS;
}
예제 #6
0
파일: scr_log.c 프로젝트: LLNL/scr
/* lookup name in table, insert if it doesn't exist, and return id */
int scr_mysql_read_write_id(const char* table, const char* name, unsigned long* id)
{
  int rc = SCR_SUCCESS;

#ifdef HAVE_LIBMYSQLCLIENT
  /* if the value is already in the database, return its id */
  rc = scr_mysql_read_id(table, name, id);
  if (rc == SCR_SUCCESS) {
    return SCR_SUCCESS;
  }

  /* didn't find the value in the db, so let's add it */

  /* escape parameter */
  char* qname = scr_mysql_quote_string(name);

  /* check that we got valid strings for each of our parameters */
  if (qname == NULL) {
    scr_err("Failed to escape and quote one or more arguments @ %s:%d",
            __FILE__, __LINE__
    );
    return SCR_FAILURE;
  }

  /* construct the query */
  char query[1024];
  int n = snprintf(query, sizeof(query),
    "INSERT IGNORE INTO `%s` (`id`,`name`) VALUES (NULL, %s) ;",
    table, qname
  );

  /* free the strings as they are now encoded into the query */
  scr_free(&qname);

  /* check that we were able to construct the query ok */
  if (n >= sizeof(query)) {
    scr_err("Insufficient buffer space (%lu bytes) to build query (%lu bytes) @ %s:%d",
            sizeof(query), n, __FILE__, __LINE__
    );
    return SCR_FAILURE;
  }

  /* execute the query */
  if (scr_db_debug >= 1) {
    scr_dbg(0, "%s", query);
  }
  if (mysql_real_query(&scr_mysql, query, (unsigned int) strlen(query))) {
    scr_err("Insert failed, query = (%s), error = (%s) @ %s:%d",
            query, mysql_error(&scr_mysql), __FILE__, __LINE__
    );
    /* don't return failure, since another process may have just beat us to the punch */
    /*return SCR_FAILURE;*/
  }

  /* alright, now we should be able to read the id */
  rc = scr_mysql_read_id(table, name, id);

#endif
  return rc;
}
예제 #7
0
파일: scr_log.c 프로젝트: LLNL/scr
/* lookups a type string and returns its id, 
 * inserts string into types table if not found,
 * caches lookups to avoid database reading more than once */
int scr_mysql_type_id(const char* type, int* id)
{
#ifdef HAVE_LIBMYSQLCLIENT
  /* check that we don't have a NULL string */
  if (type == NULL) {
    scr_err("Type string is NULL @ %s:%d",
            __FILE__, __LINE__
    );
    return SCR_FAILURE;
  }

  /* first check the hash in case we can avoid reading from the database */
  unsigned long tmp_id;
  if (scr_hash_util_get_unsigned_long(scr_db_types, type, &tmp_id) == SCR_SUCCESS) {
    /* found our id from the hash, convert to an int and return */
    *id = (int) tmp_id;
    return SCR_SUCCESS;
  }

  /* failed to find our id in the hash, lookup the id for our jobname */
  if (scr_mysql_read_write_id("types", type, &tmp_id) != SCR_SUCCESS) {
    scr_err("Failed to find type_id for %s @ %s:%d",
            type, __FILE__, __LINE__
    );
    return SCR_FAILURE;
  }

  /* got our id, now cache the lookup */
  scr_hash_util_set_unsigned_long(scr_db_types, type, tmp_id);

  /* cast the id down to an int */
  *id = (int) tmp_id;
#endif
  return SCR_SUCCESS;
}
예제 #8
0
파일: scr_summary.c 프로젝트: LLNL/scr
/* read in the summary file from dir */
static int scr_summary_read_v6(const scr_path* dir, scr_hash* summary_hash)
{
  /* check that we got a pointer to a hash */
  if (summary_hash == NULL) {
    return SCR_FAILURE;
  }

  /* assume that we'll fail */
  int rc = SCR_FAILURE;

  /* build the summary filename */
  scr_path* summary_path = scr_path_dup(dir);
  scr_path_append_str(summary_path, ".scr");
  scr_path_append_str(summary_path, "summary.scr");
  char* summary_file = scr_path_strdup(summary_path);

  /* check whether we can read the file before we actually try,
   * we take this step to avoid printing an error in scr_hash_read */
  if (scr_file_is_readable(summary_file) != SCR_SUCCESS) {
    goto cleanup;
  }

  /* read in the summary hash file */
  if (scr_hash_read(summary_file, summary_hash) != SCR_SUCCESS) {
    scr_err("Reading summary file %s @ %s:%d",
      summary_file, __FILE__, __LINE__
    );
    goto cleanup;
  }

  /* read the version from the summary hash */
  int version;
  if (scr_hash_util_get_int(summary_hash, SCR_SUMMARY_KEY_VERSION, &version) != SCR_SUCCESS) {
    scr_err("Failed to read version from summary file %s @ %s:%d",
      summary_file, __FILE__, __LINE__
    );
    goto cleanup;
  }

  /* check that the version number matches */
  if (version != SCR_SUMMARY_FILE_VERSION_6) {
    scr_err("Summary file %s is version %d instead of version %d @ %s:%d",
      summary_file, version, SCR_SUMMARY_FILE_VERSION_6, __FILE__, __LINE__
    );
    goto cleanup;
  }

  /* if we made it here, we successfully read the summary file as a hash */
  rc = SCR_SUCCESS;

cleanup:
  /* free the summary file string */
  scr_free(&summary_file);
  scr_path_delete(&summary_path);

  return rc;
}
예제 #9
0
파일: scr_env.c 프로젝트: LLNL/scr
/* allocate and return a string containing the node name */
char* scr_env_nodename()
{
  char* name = NULL;

  #ifndef SCR_BGQ
    /* we just use the string returned by gethostname */
    char hostname[256];
    if (gethostname(hostname, sizeof(hostname)) == 0) {
      name = strdup(hostname);
    } else {
      scr_err("Call to gethostname failed @ %s:%d",
        __FILE__, __LINE__
      );
    }
  #else
    /* here, we derive a string from the personality */
    Personality_t personality;
    unsigned int x, y, m, n, j, c;
    Kernel_GetPersonality(&personality, sizeof(personality));
    bg_decodeComputeCardCoreOnNodeBoardUCI(personality.Kernel_Config.UCI,&x,&y,&m,&n,&j,&c);

    /* construct the hostname */
    char hostname[256];
    int num = snprintf(
      hostname, sizeof(hostname),
      "R%X%X-M%d-N%02d-J%02d-A%dof%d-B%dof%d-C%dof%d-D%dof%d-E%dof%d",
      x, y, m, n, j,
      personality.Network_Config.Acoord, personality.Network_Config.Anodes,
      personality.Network_Config.Bcoord, personality.Network_Config.Bnodes,
      personality.Network_Config.Ccoord, personality.Network_Config.Cnodes,
      personality.Network_Config.Dcoord, personality.Network_Config.Dnodes,
      personality.Network_Config.Ecoord, personality.Network_Config.Enodes
    );

    /* check that we constructed the hostname correctly */
    if (num < 0) {
      /* error */
      scr_err("Error calling snprintf when building hostname rc=%d @ %s:%d",
        num, __FILE__, __LINE__
      );
    } else if (num >= sizeof(hostname)) {
      /* name was truncated */
      scr_err("Temporary buffer of %d bytes too small to construct hostname, needed %d bytes @ %s:%d",
        sizeof(hostname), num, __FILE__, __LINE__
      );
    } else {
      /* duplicate the name */
      name = strdup(hostname);
    }
  #endif

  return name;
}
예제 #10
0
int file_dump(char * file, float *buf, size_t size)
{

  ssize_t n = 0;
  int retries = 10;
  int fd;

  fd = open(file, O_WRONLY | O_CREAT, S_IREAD | S_IWRITE) ;
  if (fd < 0) {
    fprintf(stderr, "Error: %s", file);
    exit(1);
  }

  while (n < size)
    {
      ssize_t rc = write(fd, (char*) buf + n, size - n);
      //      fprintf(stderr, "data: %d\n", rc);
      if (rc > 0) {
	n += rc;
      } else if (rc == 0) {
	/* something bad happened, print an error and abort */
	scr_err("Error writing %s: write(%d, %x, %ld) returned 0 @ %s:%d",
		file, fd, (char*) buf + n, size - n, __FILE__, __LINE__
		);
	exit(1);
      } else { /* (rc < 0) */
	/* got an error, check whether it was serious */
	if (errno == EINTR || errno == EAGAIN) {
	  continue;
	}

	/* something worth printing an error about */
	retries--;
	if (retries) {
	  /* print an error and try again */
	  scr_err("Error writing %s: write(%d, %x, %ld) errno=%d %m @ %s:%d",
		  file, fd, (char*) buf + n, size - n, errno, __FILE__, __LINE__
		  );
	} else {
	  /* too many failed retries, give up */
	  scr_err("Giving up write to %s: write(%d, %x, %ld) errno=%d %m @ %s:%d",
		  file, fd, (char*) buf + n, size - n, errno, __FILE__, __LINE__
		  );
	  exit(1);
	}
      }
    }
  close(fd);
  return n;

}
예제 #11
0
파일: scr_io.c 프로젝트: cartazio/scr
/* recursively create directory and subdirectories */
int scr_mkdir(const char* dir, mode_t mode)
{
  int rc = SCR_SUCCESS;

  /* With dirname, either the original string may be modified or the function may return a
   * pointer to static storage which will be overwritten by the next call to dirname,
   * so we need to strdup both the argument and the return string. */

  /* extract leading path from dir = full path - basename */
  char* dircopy = strdup(dir);
  char* path    = strdup(dirname(dircopy));

  /* if we can read path or path=="." or path=="/", then there's nothing to do,
   * otherwise, try to create it */
  if (access(path, R_OK) < 0 &&
      strcmp(path,".") != 0  &&
      strcmp(path,"/") != 0)
  {
    rc = scr_mkdir(path, mode);
  }

  /* if we can write to path, try to create subdir within path */
  if (access(path, W_OK) == 0 && rc == SCR_SUCCESS) {
    int tmp_rc = mkdir(dir, mode);
    if (tmp_rc < 0) {
      if (errno == EEXIST) {
        /* don't complain about mkdir for a directory that already exists */
        scr_free(&dircopy);
        scr_free(&path);
        return SCR_SUCCESS;
      } else {
        scr_err("Creating directory: mkdir(%s, %x) path=%s errno=%d %s @ %s:%d",
                dir, mode, path, errno, strerror(errno), __FILE__, __LINE__
        );
        rc = SCR_FAILURE;
      }
    }
  } else {
    scr_err("Cannot write to directory: %s @ %s:%d",
            path, __FILE__, __LINE__
    );
    rc = SCR_FAILURE;
  }

  /* free our dup'ed string and return error code */
  scr_free(&dircopy);
  scr_free(&path);
  return rc;
}
예제 #12
0
int process_args(int argc, char **argv, struct arglist* args)
{
  int ckpt;

  /* define our options */
  static struct option long_options[] = {
    {"dir",       required_argument, NULL, 'd'},
    {"help",      no_argument,       NULL, 'h'},
    {0, 0, 0, 0}
  };

  /* set our options to default values */
  args->dir = NULL;

  /* loop through and process all options */
  int c;
  do {
    /* read in our next option */
    int option_index = 0;
    c = getopt_long(argc, argv, "d:h", long_options, &option_index);
    switch (c) {
      case 'd':
        /* directory containing nodes file */
        args->dir = optarg;
        break;
      case 'h':
        /* print help message and exit */
        print_usage();
        break;
      case '?':
        /* getopt_long printed an error message */
        break;
      default:
        if (c != -1) {
          /* missed an option */
          scr_err("%s: Option '%s' specified but not processed", PROG, argv[option_index]);
        }
    }
  } while (c != -1);

  /* check that we got a directory name */
  if (args->dir == NULL) {
    scr_err("%s: Must specify directory containing nodes file via '--dir <dir>'", PROG);
    return 0;
  }

  return 1;
}
예제 #13
0
파일: scr_env.c 프로젝트: LLNL/scr
/* environment specific init/finalize */
int scr_env_init(void)
{

#ifdef SCR_RESOURCE_MANAGER_PMIX
  /* init pmix */
  int retval = PMIx_Init(&scr_pmix_proc, NULL, 0);
  if (retval != PMIX_SUCCESS) {
    scr_err("PMIx_Init failed: rc=%d @ %s:%d",
      retval, __FILE__, __LINE__
    );
    return SCR_FAILURE;
  }
  scr_dbg(1, "PMIx_Init succeeded @ %s:%d", __FILE__, __LINE__);
#endif /* SCR_MACHINE_TYPE == SCR_PMIX */

#ifdef HAVE_LIBCPPR
  /* attempt to init cppr */
  int cppr_ret = cppr_status();
  if (cppr_ret != CPPR_SUCCESS) {
    scr_abort(-1, "libcppr cppr_status() failed: %d '%s' @ %s:%d",
              cppr_ret, cppr_err_to_str(cppr_ret), __FILE__, __LINE__
    );
  }
  scr_dbg(1, "#bold CPPR is present @ %s:%d", __FILE__, __LINE__);
#endif /* HAVE_LIBCPPR */

    return SCR_SUCCESS;
}
예제 #14
0
파일: scr_log.c 프로젝트: LLNL/scr
/* allocate a new string, having escaped all internal quotes
 * using mysql_real_escape_string, escaping is needed
 * in case values to be inserted have quotes,
 * caller is responsible for freeing string */
char* scr_mysql_quote_string(const char* value)
{
#ifdef HAVE_LIBMYSQLCLIENT
  if (value != NULL) {
    /* start with a leading single quote, escape internal quotes
     * by adding a leading backslash (could double length of input
     * string), then end with trailing single quote and
     * terminating NUL */
    int n = strlen(value);
    char* q = (char*) malloc(2*n+1+2);
    if (q != NULL) {
      q[0] = '\'';
      mysql_real_escape_string(&scr_mysql, &q[1], value, n);
      n = strlen(q);
      q[n] = '\'';
      q[n+1] = '\0';
      return q;
    } else {
      scr_err("Failed to allocate buffer space to encode string %s @ %s:%d",
              value, __FILE__, __LINE__
      );
      return NULL;
    }
  } else {
    return strdup("NULL");
  }
#else
  return NULL;
#endif
}
예제 #15
0
파일: scr_io.c 프로젝트: cartazio/scr
/* read line from file into buf with given size */
ssize_t scr_read_line(const char* file, int fd, char* buf, size_t size)
{
  /* read up to size-1 bytes from fd into buf until we find a newline or EOF */
  ssize_t n = 0;
  int found_end = 0;
  while (n < size-1 && !found_end) {
    /* read a character from the file */
    char c;
    ssize_t nread = scr_read(file, fd, &c, sizeof(c));

    if (nread > 0) {
      /* we read a character, copy it over to the buffer */
      buf[n] = c;
      n++;

      /* check whether we hit the end of the line */
      if (c == '\n') {
        found_end = 1;
      }
    } else if (nread == 0) {
      /* we hit the end of the file */
      found_end = 1;
    } else { /* nread < 0 */
      /* we hit an error */
      scr_err("Error reading from file %s @ %s:%d",
              file, __FILE__, __LINE__
      );
      return -1;
    }
  }

  /* tack on the NULL character */
  buf[n] = '\0';

  /* if we exit the while loop but didn't find the end of the line, the buffer was too small */
  if (!found_end) {
    scr_err("Buffer too small to read line from file %s @ %s:%d",
            file, __FILE__, __LINE__
    );
    return -1;
  }

  /* NOTE: we don't want to count the NULL which we added, but there is no need to adjust n here */
  return n;
}
예제 #16
0
파일: scr_io.c 프로젝트: cartazio/scr
/* seek file descriptor to specified position */
int scr_lseek(const char* file, int fd, off_t pos, int whence)
{
  off_t rc = lseek(fd, pos, whence);
  if (rc == (off_t)-1) {
    scr_err("Error seeking %s: errno=%d %s @ %s:%d",
      file, errno, strerror(errno), __FILE__, __LINE__
    );
    return SCR_FAILURE;
  }
  return SCR_SUCCESS;
}
예제 #17
0
파일: scr_param.c 프로젝트: cartazio/scr
/* read config files and store contents */
int scr_param_init()
{
  /* allocate storage and read in config files if we haven't already */
  if (scr_param_ref_count == 0) {
    /* allocate hash object to hold names we cannot read from the
     * environment */
    scr_no_user_hash = scr_hash_new();
    scr_hash_set(scr_no_user_hash, "SCR_CNTL_BASE", scr_hash_new());

    /* allocate hash object to store values from user config file,
     * if specified */
    char* user_file = user_config_path();
    if (user_file != NULL) {
      scr_user_hash = scr_hash_new();
      scr_config_read(user_file, scr_user_hash);
    }
    scr_free(&user_file);

    /* allocate hash object to store values from system config file */
    scr_system_hash = scr_hash_new();
    scr_config_read(scr_config_file, scr_system_hash);

    /* initialize our hash to cache lookups to getenv */
    scr_env_hash = scr_hash_new();

    /* warn user if he set any parameters in his environment or user
     * config file which aren't permitted */
    scr_hash_elem* elem;
    for (elem = scr_hash_elem_first(scr_no_user_hash);
         elem != NULL;
         elem = scr_hash_elem_next(elem))
    {
      /* get the parameter name */
      char* key = scr_hash_elem_key(elem);

      char* env_val = getenv(key);
      scr_hash* env_hash = scr_hash_get(scr_user_hash, key);

      /* check whether this is set in the environment */
      if (env_val != NULL || env_hash != NULL) {
        scr_err("%s cannot be set in the environment or user configuration file, ignoring setting",
          key
        );
      }
    }
  }

  /* increment our reference count */
  scr_param_ref_count++;

  return SCR_SUCCESS;
}
예제 #18
0
파일: scr_io.c 프로젝트: cartazio/scr
/* make a good attempt to write to file (retries, if necessary, return error if fail) */
ssize_t scr_write_attempt(const char* file, int fd, const void* buf, size_t size)
{
  ssize_t n = 0;
  int retries = 10;
  while (n < size)
  {
    ssize_t rc = write(fd, (char*) buf + n, size - n);
    if (rc > 0) {
      n += rc;
    } else if (rc == 0) {
      /* something bad happened, print an error and abort */
      scr_err("Error writing file %s write returned 0 @ %s:%d",
	      file, __FILE__, __LINE__
      );
      return -1;
    } else { /* (rc < 0) */
      /* got an error, check whether it was serious */
      if (errno == EINTR || errno == EAGAIN) {
        continue;
      }

      /* something worth printing an error about */
      retries--;
      if (retries) {
        /* print an error and try again */
        scr_err("Error writing file %s errno=%d %s @ %s:%d",
                file, errno, strerror(errno), __FILE__, __LINE__
        );
      } else {
        /* too many failed retries, give up */
        scr_err("Giving up write of file %s errno=%d %s @ %s:%d",
                file, errno, strerror(errno), __FILE__, __LINE__
        );
        return -1;
      }
    }
  }
  return n;
}
예제 #19
0
파일: scr_io.c 프로젝트: cartazio/scr
/* remove directory */
int scr_rmdir(const char* dir)
{
  /* delete directory */
  int rc = rmdir(dir);
  if (rc < 0) {
    /* whoops, something failed when we tried to delete our directory */
    scr_err("Error deleting directory: %s (rmdir returned %d %s) @ %s:%d",
      dir, rc, strerror(errno), __FILE__, __LINE__
    );
    return SCR_FAILURE;
  }
  return SCR_SUCCESS;
}
예제 #20
0
파일: scr_io.c 프로젝트: cartazio/scr
/* reliable read from file descriptor (retries, if necessary, until hard error) */
ssize_t scr_read(const char* file, int fd, void* buf, size_t size)
{
  ssize_t n = 0;
  int retries = 10;
  while (n < size)
  {
    int rc = read(fd, (char*) buf + n, size - n);
    if (rc  > 0) {
      n += rc;
    } else if (rc == 0) {
      /* EOF */
      return n;
    } else { /* (rc < 0) */
      /* got an error, check whether it was serious */
      if (errno == EINTR || errno == EAGAIN) {
        continue;
      }

      /* something worth printing an error about */
      retries--;
      if (retries) {
        /* print an error and try again */
        scr_err("Error reading %s: read(%d, %x, %ld) errno=%d %s @ %s:%d",
                file, fd, (char*) buf + n, size - n, errno, strerror(errno), __FILE__, __LINE__
        );
      } else {
        /* too many failed retries, give up */
        scr_err("Giving up read of %s: read(%d, %x, %ld) errno=%d %s @ %s:%d",
	        file, fd, (char*) buf + n, size - n, errno, strerror(errno), __FILE__, __LINE__
        );
        exit(1);
      }
    }
  }
  return n;
}
예제 #21
0
파일: scr_util.c 프로젝트: kento/librscr
/* unpack an unsigned 64 bit value to specified buffer in host order */
int scr_unpack_uint64_t(void* buf, size_t buf_size, size_t* buf_pos, uint64_t* val)
{
  /* check that we have a valid pointer to a buffer position value */
  if (buf == NULL || buf_pos == NULL || val == NULL) {
    scr_err("NULL pointer to buffer, buffer position, or value @ %s:%d",
            __FILE__, __LINE__
    );
    return SCR_FAILURE;
  }

  /* get current buffer position */
  size_t pos = *buf_pos;

  /* compute final buffer position */
  size_t pos_final = pos + sizeof(uint64_t);

  /* check that we won't overrun the buffer */
  if (pos_final > buf_size) {
    scr_err("Attempting to unpack too many bytes into buffer @ %s:%d",
            __FILE__, __LINE__
    );
    return SCR_FAILURE;
  }

  /* read value from buffer (stored in network order) */
  uint64_t val_network;
  memcpy(&val_network, buf + pos, sizeof(val_network));

  /* conver to host order */
  *val = scr_ntoh64(val_network);

  /* update position */
  *buf_pos = pos_final;

  return SCR_SUCCESS;
}
예제 #22
0
파일: scr_log.c 프로젝트: LLNL/scr
/* initialize the logging */
int scr_log_init()
{
  int rc = SCR_SUCCESS;

  /* read in parameters */
  char* value = NULL;

  scr_param_init();

  /* check whether SCR logging DB is enabled */
  if ((value = scr_param_get("SCR_DB_ENABLE")) != NULL) {
    scr_db_enable = atoi(value);
  }

  /* read in the debug level for database log messages */
  if ((value = scr_param_get("SCR_DB_DEBUG")) != NULL) {
    scr_db_debug = atoi(value);
  }

  /* SCR log DB connection parameters */
  if ((value = scr_param_get("SCR_DB_HOST")) != NULL) {
    scr_db_host = strdup(value);
  }
  if ((value = scr_param_get("SCR_DB_USER")) != NULL) {
    scr_db_user = strdup(value);
  }
  if ((value = scr_param_get("SCR_DB_PASS")) != NULL) {
    scr_db_pass = strdup(value);
  }
  if ((value = scr_param_get("SCR_DB_NAME")) != NULL) {
    scr_db_name = strdup(value);
  }

  scr_param_finalize();

  /* connect to the database, if enabled */
  if (scr_db_enable) {
    if (scr_mysql_connect() != SCR_SUCCESS) {
      scr_err("Failed to connect to SCR logging database, disabling database logging @ %s:%d",
              __FILE__, __LINE__
      );
      scr_db_enable = 0;
      rc = SCR_FAILURE;
    }
  }

  return rc; 
}
예제 #23
0
파일: scr_hash.c 프로젝트: kento/librscr
/* given an element, set its key and hash fields */
static scr_hash_elem* scr_hash_elem_init(scr_hash_elem* elem, const char* key, scr_hash* hash)
{
  if (elem != NULL) {
    if (key != NULL) {
      elem->key = strdup(key);
    } else {
      /* bad idea to allow key to be set to NULL */
      elem->key = NULL;
      scr_err("Setting hash element key to NULL @ %s:%d",
              __FILE__, __LINE__
      );
    }
    elem->hash = hash;
  }
  return elem;
}
예제 #24
0
/* for file name listed in meta, fetch that file from src_dir and store
 * a copy in dst_dir, record full path to copy in newfile, and
 * return whether operation succeeded */
static int scr_fetch_file(
  const char* dst_file,
  const char* src_dir,
  const scr_meta* meta)
{
  int rc = SCR_SUCCESS;

  /* build full path to source file */
  scr_path* path_src_file = scr_path_from_str(dst_file);
  scr_path_basename(path_src_file);
  scr_path_prepend_str(path_src_file, src_dir);
  char* src_file = scr_path_strdup(path_src_file);

  /* fetch the file */
  uLong crc;
  uLong* crc_p = NULL;
  if (scr_crc_on_flush) {
    crc_p = &crc;
  }
  rc = scr_file_copy(src_file, dst_file, scr_file_buf_size, crc_p);

  /* check that crc matches crc stored in meta */
  uLong meta_crc;
  if (scr_meta_get_crc32(meta, &meta_crc) == SCR_SUCCESS) {
    if (rc == SCR_SUCCESS && scr_crc_on_flush && crc != meta_crc) {
      rc = SCR_FAILURE;
      scr_err("CRC32 mismatch detected when fetching file from %s to %s @ %s:%d",
        src_file, dst_file, __FILE__, __LINE__
      );

      /* TODO: would be good to log this, but right now only rank 0
       * can write log entries */
      /*
      if (scr_log_enable) {
        time_t now = scr_log_seconds();
        scr_log_event("CRC32 MISMATCH", filename, NULL, &now, NULL);
      }
      */
    }
  }

  /* free path and string for source file */
  scr_free(&src_file);
  scr_path_delete(&path_src_file);

  return rc;
}
예제 #25
0
파일: scr_env.c 프로젝트: LLNL/scr
/* allocate and return a string containing the current username */
char* scr_env_username()
{
  char* name = NULL;

  /* read $USER environment variable for username */
  char* value;
  if ((value = getenv("USER")) != NULL) {
    name = strdup(value);
    if (name == NULL) {
      scr_err("Failed to allocate memory to record username (%s) @ %s:%d",
              value, __FILE__, __LINE__
      );
    }
  }

  return name;
}
예제 #26
0
파일: scr_io.c 프로젝트: cartazio/scr
/* open file with specified flags and mode, retry open a few times on failure */
int scr_open(const char* file, int flags, ...)
{
  /* extract the mode (see man 2 open) */
  int mode_set = 0;
  mode_t mode = 0;
  if (flags & O_CREAT) {
    va_list ap;
    va_start(ap, flags);
    mode = va_arg(ap, mode_t);
    va_end(ap);
    mode_set = 1;
  }

  int fd = -1;
  if (mode_set) { 
    fd = open(file, flags, mode);
  } else {
    fd = open(file, flags);
  }
  if (fd < 0) {
    scr_dbg(1, "Opening file: open(%s) errno=%d %s @ %s:%d",
            file, errno, strerror(errno), __FILE__, __LINE__
    );

    /* try again */
    int tries = SCR_OPEN_TRIES;
    while (tries && fd < 0) {
      usleep(SCR_OPEN_USLEEP);
      if (mode_set) { 
        fd = open(file, flags, mode);
      } else {
        fd = open(file, flags);
      }
      tries--;
    }

    /* if we still don't have a valid file, consider it an error */
    if (fd < 0) {
      scr_err("Opening file: open(%s) errno=%d %s @ %s:%d",
              file, errno, strerror(errno), __FILE__, __LINE__
      );
    }
  }
  return fd;
}
예제 #27
0
파일: scr_rebuild_xor.c 프로젝트: c-a-h/scr
static int scr_compute_crc(scr_filemap* map, int id, int rank, const char* file)
{
  /* compute crc for the file */
  uLong crc_file;
  if (scr_crc32(file, &crc_file) != SCR_SUCCESS) {
    scr_err("Failed to compute crc for file %s @ %s:%d",
      file, __FILE__, __LINE__
    );
    return SCR_FAILURE;
  }

  /* allocate a new meta data object */
  scr_meta* meta = scr_meta_new();
  if (meta == NULL) {
    scr_abort(-1, "Failed to allocate meta data object @ %s:%d",
      __FILE__, __LINE__
    );
  }

  /* read meta data from filemap */
  if (scr_filemap_get_meta(map, id, rank, file, meta) != SCR_SUCCESS) {
    return SCR_FAILURE;
  }

  int rc = SCR_SUCCESS;

  /* read crc value from meta data */
  uLong crc_meta;
  if (scr_meta_get_crc32(meta, &crc_meta) == SCR_SUCCESS) {
    /* check that the values are the same */
    if (crc_file != crc_meta) {
      rc = SCR_FAILURE;
    }
  } else {
    /* record crc in filemap */
    scr_meta_set_crc32(meta, crc_file);
    scr_filemap_set_meta(map, id, rank, file, meta);
  }

  /* free our meta data object */
  scr_meta_delete(&meta);

  return rc;
}
예제 #28
0
파일: scr_io.c 프로젝트: cartazio/scr
/* fsync and close file */
int scr_close(const char* file, int fd)
{
  /* fsync first */
  if (fsync(fd) < 0) {
    /* print warning that fsync failed */
    scr_dbg(2, "Failed to fsync file descriptor: %s errno=%d %s @ file %s:%d",
            file, errno, strerror(errno), __FILE__, __LINE__
    );
  }

  /* now close the file */
  if (close(fd) != 0) {
    /* hit an error, print message */
    scr_err("Closing file descriptor %d for file %s: errno=%d %s @ %s:%d",
            fd, file, errno, strerror(errno), __FILE__, __LINE__
    );
    return SCR_FAILURE;
  }

  return SCR_SUCCESS;
}
예제 #29
0
파일: scr_io.c 프로젝트: cartazio/scr
/* opens specified file and waits on a lock before returning the file descriptor */
int scr_open_with_lock(const char* file, int flags, mode_t mode)
{
  /* open the file */
  int fd = scr_open(file, flags, mode);
  if (fd < 0) {
    scr_err("Opening file for write: scr_open(%s) errno=%d %s @ %s:%d",
            file, errno, strerror(errno), __FILE__, __LINE__
    );
    return fd;
  }

  /* acquire an exclusive file lock */
  int ret = scr_file_lock_write(file, fd);
  if (ret != SCR_SUCCESS) {
    close(fd);
    return ret;
  }
     
  /* return the opened file descriptor */
  return fd;
}
예제 #30
0
파일: scr_summary.c 프로젝트: LLNL/scr
/* read in the summary file from dir */
static int scr_summary_read_v5(const scr_path* dir, scr_hash* summary_hash)
{
  /* check that we got a pointer to a hash */
  if (summary_hash == NULL) {
    return SCR_FAILURE;
  }

  /* assume that we'll fail */
  int rc = SCR_FAILURE;

  /* build the summary filename */
  scr_path* summary_path = scr_path_dup(dir);
  scr_path_append_str(summary_path, "summary.scr");
  char* summary_file = scr_path_strdup(summary_path);

  /* check whether we can read the file before we actually try,
   * we take this step to avoid printing an error in scr_hash_read */
  if (scr_file_is_readable(summary_file) != SCR_SUCCESS) {
    goto cleanup;
  }

  /* read in the summary hash file */
  if (scr_hash_read_path(summary_path, summary_hash) != SCR_SUCCESS) {
    scr_err("Reading summary file %s @ %s:%d",
      summary_file, __FILE__, __LINE__
    );
    goto cleanup;
  }

  /* if we made it here, we successfully read the summary file as a hash */
  rc = SCR_SUCCESS;

cleanup:
  /* free the summary path */
  scr_free(&summary_file);
  scr_path_delete(&summary_path);

  return rc;
}