/* * check_status_create -- create single status, push it to proper queue * * MSG_SEPARATOR character in fmt is treated as message separator. If creating * question but check arguments do not allow to make any changes (asking any * question is pointless) it takes part of message before MSG_SEPARATOR * character and use it to create error message. Character just before separator * must be a MSG_PLACE_OF_SEPARATION character. Return non 0 value if error * status would be created. */ int check_status_create(PMEMpoolcheck *ppc, enum pmempool_check_msg_type type, uint32_t question, const char *fmt, ...) { if (CHECK_IS_NOT(ppc, VERBOSE) && type == PMEMPOOL_CHECK_MSG_TYPE_INFO) return 0; struct check_status *st = status_alloc(); if (CHECK_IS(ppc, FORMAT_STR)) { va_list ap; va_start(ap, fmt); int p = vsnprintf(st->msg, MAX_MSG_STR_SIZE, fmt, ap); va_end(ap); /* append possible strerror at the end of the message */ if (type != PMEMPOOL_CHECK_MSG_TYPE_QUESTION && errno && p > 0) { char buff[UTIL_MAX_ERR_MSG]; util_strerror(errno, buff, UTIL_MAX_ERR_MSG); snprintf(st->msg + p, MAX_MSG_STR_SIZE - (size_t)p, ": %s", buff); } st->status.type = type; } return status_push(ppc, st, question); }
/* * rpmem_ssh_strerror -- read error using stderr channel */ const char * rpmem_ssh_strerror(struct rpmem_ssh *rps) { ssize_t ret = read(rps->cmd->fd_err, error_str, ERR_BUFF_SIZE); if (ret < 0) return "reading error string failed"; if (ret == 0) { if (errno) { char buff[UTIL_MAX_ERR_MSG]; util_strerror(errno, buff, UTIL_MAX_ERR_MSG); snprintf(error_str, ERR_BUFF_SIZE, "%s", buff); } else { snprintf(error_str, ERR_BUFF_SIZE, "unknown error"); } return error_str; } /* get rid of new line and carriage return chars */ char *cr = strchr(error_str, '\r'); if (cr) *cr = '\0'; char *nl = strchr(error_str, '\n'); if (nl) *nl = '\0'; return error_str; }
static void loaderror(const char *fmt, ...) { int err = errno; va_list ap; va_start(ap, fmt); vprintf(fmt, ap); va_end(ap); printf(": %s\n", util_strerror(err)); }
/* * out_common -- common output code, all output goes through here */ static void out_common(const char *file, int line, const char *func, int level, const char *suffix, const char *fmt, va_list ap) { int oerrno = errno; char buf[MAXPRINT]; unsigned cc = 0; int ret; const char *sep = ""; char errstr[UTIL_MAX_ERR_MSG] = ""; if (file) { char *f = strrchr(file, DIR_SEPARATOR); if (f) file = f + 1; ret = out_snprintf(&buf[cc], MAXPRINT - cc, "<%s>: <%d> [%s:%d %s] ", Log_prefix, level, file, line, func); if (ret < 0) { Print("out_snprintf failed"); goto end; } cc += (unsigned)ret; if (cc < Log_alignment) { memset(buf + cc, ' ', Log_alignment - cc); cc = Log_alignment; } } if (fmt) { if (*fmt == '!') { fmt++; sep = ": "; util_strerror(errno, errstr, UTIL_MAX_ERR_MSG); } ret = Vsnprintf(&buf[cc], MAXPRINT - cc, fmt, ap); if (ret < 0) { Print("Vsnprintf failed"); goto end; } cc += (unsigned)ret; } out_snprintf(&buf[cc], MAXPRINT - cc, "%s%s%s", sep, errstr, suffix); Print(buf); end: errno = oerrno; }
/* * rpmem_ssh_strerror -- read error using stderr channel */ const char * rpmem_ssh_strerror(struct rpmem_ssh *rps, int oerrno) { size_t len = 0; ssize_t ret; while ((ret = read(rps->cmd->fd_err, error_str + len, ERR_BUFF_LEN - len))) { if (ret < 0) return "reading error string failed"; len += (size_t)ret; } error_str[len] = '\0'; if (len == 0) { if (oerrno) { char buff[UTIL_MAX_ERR_MSG]; util_strerror(oerrno, buff, UTIL_MAX_ERR_MSG); snprintf(error_str, ERR_BUFF_LEN, "%s", buff); } else { snprintf(error_str, ERR_BUFF_LEN, "unknown error"); } } else { /* get rid of new line and carriage return chars */ char *cr = strchr(error_str, '\r'); if (cr) *cr = '\0'; char *nl = strchr(error_str, '\n'); if (nl) *nl = '\0'; } return error_str; }
/* * out_error -- common error output code, all error messages go through here */ static void out_error(const char *file, int line, const char *func, const char *suffix, const char *fmt, va_list ap) { int oerrno = errno; unsigned cc = 0; int ret; const char *sep = ""; char errstr[UTIL_MAX_ERR_MSG] = ""; char *errormsg = (char *)out_get_errormsg(); if (fmt) { if (*fmt == '!') { fmt++; sep = ": "; util_strerror(errno, errstr, UTIL_MAX_ERR_MSG); } ret = Vsnprintf(&errormsg[cc], MAXPRINT, fmt, ap); if (ret < 0) { strcpy(errormsg, "Vsnprintf failed"); goto end; } cc += (unsigned)ret; out_snprintf(&errormsg[cc], MAXPRINT - cc, "%s%s", sep, errstr); } #ifdef DEBUG if (Log_level >= 1) { char buf[MAXPRINT]; cc = 0; if (file) { char *f = strrchr(file, DIR_SEPARATOR); if (f) file = f + 1; ret = out_snprintf(&buf[cc], MAXPRINT, "<%s>: <1> [%s:%d %s] ", Log_prefix, file, line, func); if (ret < 0) { Print("out_snprintf failed"); goto end; } cc += (unsigned)ret; if (cc < Log_alignment) { memset(buf + cc, ' ', Log_alignment - cc); cc = Log_alignment; } } out_snprintf(&buf[cc], MAXPRINT - cc, "%s%s", errormsg, suffix); Print(buf); } #endif end: errno = oerrno; }
/* * out_init -- initialize the log * * This is called from the library initialization code. */ void out_init(const char *log_prefix, const char *log_level_var, const char *log_file_var, int major_version, int minor_version) { static int once; /* only need to initialize the out module once */ if (once) return; once++; Log_prefix = log_prefix; #ifdef DEBUG char *log_level; char *log_file; if ((log_level = getenv(log_level_var)) != NULL) { Log_level = atoi(log_level); if (Log_level < 0) { Log_level = 0; } } if ((log_file = getenv(log_file_var)) != NULL && log_file[0] != '\0') { size_t cc = strlen(log_file); /* reserve more than enough space for a PID + '\0' */ char *log_file_pid = alloca(cc + 30); if (cc > 0 && log_file[cc - 1] == '-') { snprintf(log_file_pid, cc + 30, "%s%d", log_file, getpid()); log_file = log_file_pid; } if ((Out_fp = fopen(log_file, "w")) == NULL) { char buff[UTIL_MAX_ERR_MSG]; util_strerror(errno, buff, UTIL_MAX_ERR_MSG); fprintf(stderr, "Error (%s): %s=%s: %s\n", log_prefix, log_file_var, log_file, buff); abort(); } } #endif /* DEBUG */ char *log_alignment = getenv("NVML_LOG_ALIGN"); if (log_alignment) { int align = atoi(log_alignment); if (align > 0) Log_alignment = (unsigned)align; } if (Out_fp == NULL) Out_fp = stderr; else setlinebuf(Out_fp); #ifdef DEBUG LOG(1, "pid %d: program: %s", getpid(), getexecname()); #endif LOG(1, "%s version %d.%d", log_prefix, major_version, minor_version); LOG(1, "src version %s", nvml_src_version); #ifdef USE_VG_PMEMCHECK /* * Attribute "used" to prevent compiler from optimizing out the variable * when LOG expands to no code (!DEBUG) */ static __attribute__((used)) const char *pmemcheck_msg = "compiled with support for Valgrind pmemcheck"; LOG(1, "%s", pmemcheck_msg); #endif /* USE_VG_PMEMCHECK */ #ifdef USE_VG_HELGRIND static __attribute__((used)) const char *helgrind_msg = "compiled with support for Valgrind helgrind"; LOG(1, "%s", helgrind_msg); #endif /* USE_VG_HELGRIND */ #ifdef USE_VG_MEMCHECK static __attribute__((used)) const char *memcheck_msg = "compiled with support for Valgrind memcheck"; LOG(1, "%s", memcheck_msg); #endif /* USE_VG_MEMCHECK */ #ifdef USE_VG_DRD static __attribute__((used)) const char *drd_msg = "compiled with support for Valgrind drd"; LOG(1, "%s", drd_msg); #endif /* USE_VG_DRD */ Last_errormsg_key_alloc(); }