Commit 31f69e71 authored by Yaroslav Halchenko's avatar Yaroslav Halchenko

New upstream version 1.0.14

parent bda84814
Metadata-Version: 1.1
Metadata-Version: 1.2
Name: reprozip
Version: 1.0.10
Version: 1.0.14
Summary: Linux tool enabling reproducible experiments (packer)
Home-page: http://vida-nyu.github.io/reprozip/
Author: Remi Rampin
Author-email: remirampin@gmail.com
Home-page: https://www.reprozip.org/
Author: Remi Rampin, Fernando Chirigati, Dennis Shasha, Juliana Freire
Author-email: reprozip-users@vgc.poly.edu
Maintainer: Remi Rampin
Maintainer-email: remirampin@gmail.com
License: BSD-3-Clause
Project-URL: Homepage, https://github.com/ViDA-NYU/reprozip
Project-URL: Documentation, https://docs.reprozip.org/
Project-URL: Examples, https://examples.reprozip.org/
Project-URL: Say Thanks, https://saythanks.io/to/remram44
Project-URL: Source, https://github.com/ViDA-NYU/reprozip
Project-URL: Tracker, https://github.com/ViDA-NYU/reprozip/issues
Description: ReproZip
========
......@@ -25,7 +33,7 @@ Description: ReproZip
ReproZip is currently being developed at `NYU <http://engineering.nyu.edu/>`_. The team includes:
* `Fernando Chirigati <https://vgc.poly.edu/~fchirigati/>`_
* `Fernando Chirigati <http://fchirigati.com/>`_
* `Juliana Freire <https://vgc.poly.edu/~juliana/>`_
* `Remi Rampin <https://remirampin.com/>`_
* `Dennis Shasha <http://cs.nyu.edu/shasha/>`_
......@@ -38,9 +46,6 @@ Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: BSD License
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.3
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: C
Classifier: Topic :: Scientific/Engineering
......
......@@ -17,7 +17,7 @@ For more detailed information, please refer to our `website <https://www.reprozi
ReproZip is currently being developed at `NYU <http://engineering.nyu.edu/>`_. The team includes:
* `Fernando Chirigati <https://vgc.poly.edu/~fchirigati/>`_
* `Fernando Chirigati <http://fchirigati.com/>`_
* `Juliana Freire <https://vgc.poly.edu/~juliana/>`_
* `Remi Rampin <https://remirampin.com/>`_
* `Dennis Shasha <http://cs.nyu.edu/shasha/>`_
......
......@@ -22,7 +22,7 @@ static sqlite3_uint64 gettime(void)
/* LCOV_EXCL_START : clock_gettime() is unlikely to fail */
log_critical(0, "getting time failed (clock_gettime): %s",
strerror(errno));
exit(1);
exit(125);
/* LCOV_EXCL_END */
}
timestamp = now.tv_sec;
......
#include <assert.h>
#include <errno.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "log.h"
extern int trace_verbosity;
static FILE *logfile = NULL;
int log_open_file(const char *filename)
{
assert(logfile == NULL);
logfile = fopen(filename, "ab");
if(logfile == NULL)
{
log_critical(0, "couldn't open log file: %s", strerror(errno));
return -1;
}
return 0;
}
void log_close_file(void)
{
if(logfile != NULL)
{
fclose(logfile);
logfile = NULL;
}
}
void log_real_(pid_t tid, const char *tag, int lvl, const char *format, ...)
{
va_list args;
char datestr[13]; /* HH:MM:SS.mmm */
static char *buffer = NULL;
static size_t bufsize = 4096;
int length;
if(buffer == NULL)
buffer = malloc(bufsize);
{
struct timeval tv;
gettimeofday(&tv, NULL);
strftime(datestr, 13, "%H:%M:%S", localtime(&tv.tv_sec));
sprintf(datestr+8, ".%03u", (unsigned int)(tv.tv_usec / 1000));
}
va_start(args, format);
length = vsnprintf(buffer, bufsize, format, args);
va_end(args);
if(length >= bufsize)
{
while(length >= bufsize)
bufsize *= 2;
free(buffer);
buffer = malloc(bufsize);
va_start(args, format);
length = vsnprintf(buffer, bufsize, format, args);
va_end(args);
}
if(trace_verbosity >= lvl)
{
fprintf(stderr, "[REPROZIP] %s %s: ", datestr, tag);
if(tid > 0)
fprintf(stderr, "[%d] ", tid);
fwrite(buffer, length, 1, stderr);
}
if(logfile && lvl <= 2)
{
fprintf(logfile, "[REPROZIP] %s %s: ", datestr, tag);
if(tid > 0)
fprintf(logfile, "[%d] ", tid);
fwrite(buffer, length, 1, logfile);
fflush(logfile);
}
}
......@@ -8,40 +8,27 @@
#include <sys/types.h>
int log_open_file(const char *filename);
void log_close_file(void);
extern int logging_level;
void log_real_(pid_t tid, const char *tag, int lvl, const char *format, ...);
int log_setup(void);
void log_real_(pid_t tid, int lvl, const char *format, ...);
#ifdef __GNUC__
#define log_critical(i, s, ...) log_critical_(i, s "\n", ## __VA_ARGS__)
#define log_error(i, s, ...) log_critical_(i, s "\n", ## __VA_ARGS__)
#define log_warn(i, s, ...) log_warn_(i, s "\n", ## __VA_ARGS__)
#define log_info(i, s, ...) log_info_(i, s "\n", ## __VA_ARGS__)
#define log_debug(i, s, ...) log_debug_(i, s "\n", ## __VA_ARGS__)
#define log_critical_(i, s, ...) log_real_(i, "CRITICAL", 0, s, ## __VA_ARGS__)
#define log_error_(i, s, ...) log_real_(i, "ERROR", 0, s, ## __VA_ARGS__)
#define log_warn_(i, s, ...) log_real_(i, "WARNING", 1, s, ## __VA_ARGS__)
#define log_info_(i, s, ...) log_real_(i, "INFO", 2, s, ## __VA_ARGS__)
#define log_debug_(i, s, ...) log_real_(i, "DEBUG", 3, s, ## __VA_ARGS__)
#define log_critical(i, s, ...) log_real_(i, 50, s, ## __VA_ARGS__)
#define log_error(i, s, ...) log_real_(i, 40, s, ## __VA_ARGS__)
#define log_warn(i, s, ...) log_real_(i, 30, s, ## __VA_ARGS__)
#define log_info(i, s, ...) log_real_(i, 20, s, ## __VA_ARGS__)
#define log_debug(i, s, ...) log_real_(i, 10, s, ## __VA_ARGS__)
#else
#define log_critical(i, s, ...) log_critical_(i, s "\n", __VA_ARGS__)
#define log_error(i, s, ...) log_critical_(i, s "\n", __VA_ARGS__)
#define log_warn(i, s, ...) log_warn_(i, s "\n", __VA_ARGS__)
#define log_info(i, s, ...) log_info_(i, s "\n", __VA_ARGS__)
#define log_debug(i, s, ...) log_debug_(i, s "\n", __VA_ARGS__)
#define log_critical_(i, s, ...) log_real_(i, "CRITICAL", 0, s, __VA_ARGS__)
#define log_error_(i, s, ...) log_real_(i, "ERROR", 0, s, __VA_ARGS__)
#define log_warn_(i, s, ...) log_real_(i, "WARNING", 1, s, __VA_ARGS__)
#define log_info_(i, s, ...) log_real_(i, "INFO", 2, s, __VA_ARGS__)
#define log_debug_(i, s, ...) log_real_(i, "DEBUG", 3, s, __VA_ARGS__)
#define log_critical(i, s, ...) log_real_(i, 50, s, __VA_ARGS__)
#define log_error(i, s, ...) log_real_(i, 40, s, __VA_ARGS__)
#define log_warn(i, s, ...) log_real_(i, 30, s, __VA_ARGS__)
#define log_info(i, s, ...) log_real_(i, 20, s, __VA_ARGS__)
#define log_debug(i, s, ...) log_real_(i, 10, s, __VA_ARGS__)
#endif
#endif
#include <assert.h>
#include <errno.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <Python.h>
#include "log.h"
static PyObject *py_logger = NULL;
static PyObject *py_logger_log = NULL;
int logging_level = 0;
int log_setup()
{
if(py_logger == NULL)
{
// Import Python's logging module
PyObject *logging = PyImport_ImportModuleEx("logging",
NULL, NULL, NULL);
if(logging == NULL)
return -1;
// Get the logger
{
PyObject *func = PyObject_GetAttrString(logging, "getLogger");
py_logger = PyObject_CallFunction(func, "(s)", "reprozip");
Py_DECREF(logging);
Py_DECREF(func);
if(py_logger == NULL)
return -1;
}
// Get the log function
py_logger_log = PyObject_GetAttrString(py_logger, "log");
if(py_logger_log == NULL)
{
Py_DECREF(py_logger);
py_logger = NULL;
return -1;
}
}
// Get the effective logging level
{
PyObject *meth = PyObject_GetAttrString(py_logger,
"getEffectiveLevel");
PyObject *level = PyObject_CallFunctionObjArgs(meth, NULL);
Py_DECREF(meth);
if(level == NULL)
return -1;
logging_level = PyLong_AsLong(level);
if(PyErr_Occurred())
{
Py_DECREF(level);
return -1;
}
Py_DECREF(level);
}
return 0;
}
void log_real_(pid_t tid, int lvl, const char *format, ...)
{
va_list args;
char datestr[13]; /* HH:MM:SS.mmm */
static char *buffer = NULL;
static size_t bufsize = 4096;
size_t length;
/* Fast filter: don't call Python if level is not enough */
if(lvl < logging_level)
return;
if(buffer == NULL)
buffer = malloc(bufsize);
{
struct timeval tv;
gettimeofday(&tv, NULL);
strftime(datestr, 13, "%H:%M:%S", localtime(&tv.tv_sec));
sprintf(datestr+8, ".%03u", (unsigned int)(tv.tv_usec / 1000));
}
va_start(args, format);
length = (size_t)vsnprintf(buffer, bufsize, format, args);
va_end(args);
if(length + 1 >= bufsize)
{
while(length + 1 >= bufsize)
bufsize *= 2;
free(buffer);
buffer = malloc(bufsize);
va_start(args, format);
length = vsnprintf(buffer, bufsize, format, args);
va_end(args);
}
if(tid > 0)
PyObject_CallFunction(py_logger_log, "(l, s, l, s)",
lvl, "[%d] %s", tid, buffer);
else
PyObject_CallFunction(py_logger_log, "(l, s, s)",
lvl, "%s", buffer);
}
#include <Python.h>
#include "database.h"
#include "log.h"
#include "tracer.h"
......@@ -62,25 +63,23 @@ static PyObject *pytracer_execute(PyObject *self, PyObject *args)
PyObject *ret = NULL;
int exit_status;
/* Reads arguments */
char *binary = NULL, *databasepath = NULL;
char **argv = NULL;
size_t argv_len;
int verbosity;
PyObject *py_binary, *py_argv, *py_databasepath;
if(!PyArg_ParseTuple(args, "OO!Oi",
&py_binary,
&PyList_Type, &py_argv,
&py_databasepath,
&verbosity))
return NULL;
if(verbosity < 0)
if(log_setup() != 0)
{
PyErr_SetString(Err_Base, "verbosity should be >= 0");
PyErr_SetString(Err_Base, "Error occurred");
return NULL;
}
trace_verbosity = verbosity;
/* Reads arguments */
if(!PyArg_ParseTuple(args, "OO!O",
&py_binary,
&PyList_Type, &py_argv,
&py_databasepath))
return NULL;
binary = get_string(py_binary);
if(binary == NULL)
......@@ -147,7 +146,7 @@ done:
static PyMethodDef methods[] = {
{"execute", pytracer_execute, METH_VARARGS,
"execute(binary, argv, databasepath, verbosity)\n"
"execute(binary, argv, databasepath)\n"
"\n"
"Runs the specified binary with the argument list argv under trace and "
"writes\nthe captured events to SQLite3 database databasepath."},
......
This diff is collapsed.
......@@ -94,10 +94,6 @@ static void get_x86_64_reg(register_type *reg, uint64_t value)
}
int trace_verbosity = 0;
#define verbosity trace_verbosity
void free_execve_info(struct ExecveInfo *execi)
{
free_strarray(execi->argv);
......@@ -131,7 +127,7 @@ struct Process *trace_get_empty_process(void)
}
/* Count unknown processes */
if(verbosity >= 3)
if(logging_level <= 10)
{
size_t unknown = 0;
for(i = 0; i < processes_size; ++i)
......@@ -142,9 +138,8 @@ struct Process *trace_get_empty_process(void)
}
/* Allocate more! */
if(verbosity >= 3)
log_debug(0, "process table full (%d), reallocating",
(int)processes_size);
log_debug(0, "process table full (%d), reallocating",
(int)processes_size);
{
struct Process *pool;
size_t prev_size = processes_size;
......@@ -168,8 +163,7 @@ struct ThreadGroup *trace_new_threadgroup(pid_t tgid, char *wd)
threadgroup->tgid = tgid;
threadgroup->wd = wd;
threadgroup->refs = 1;
if(verbosity >= 3)
log_debug(tgid, "threadgroup (= process) created");
log_debug(tgid, "threadgroup (= process) created");
return threadgroup;
}
......@@ -179,22 +173,20 @@ void trace_free_process(struct Process *process)
if(process->threadgroup != NULL)
{
process->threadgroup->refs--;
if(verbosity >= 3)
log_debug(process->tid,
"process died, threadgroup tgid=%d refs=%d",
process->threadgroup->tgid, process->threadgroup->refs);
log_debug(process->tid,
"process died, threadgroup tgid=%d refs=%d",
process->threadgroup->tgid, process->threadgroup->refs);
if(process->threadgroup->refs == 0)
{
if(verbosity >= 3)
log_debug(process->threadgroup->tgid,
"deallocating threadgroup");
log_debug(process->threadgroup->tgid,
"deallocating threadgroup");
if(process->threadgroup->wd != NULL)
free(process->threadgroup->wd);
free(process->threadgroup);
}
process->threadgroup = NULL;
}
else if(verbosity >= 3)
else
log_debug(process->tid, "threadgroup==NULL");
if(process->execve_info != NULL)
{
......@@ -216,6 +208,8 @@ void trace_count_processes(unsigned int *p_nproc, unsigned int *p_unknown)
case PROCSTAT_UNKNOWN:
/* Exists but no corresponding syscall has returned yet */
++unknown;
++nproc;
break;
case PROCSTAT_ALLOCATED:
/* Not yet attached but it will show up eventually */
case PROCSTAT_ATTACHED:
......@@ -265,15 +259,24 @@ int trace_add_files_from_proc(unsigned int process, pid_t tid,
unsigned long int offset;
unsigned int dev_major, dev_minor;
unsigned long int inode;
char pathname[4096];
sscanf(line,
"%lx-%lx %4s %lx %x:%x %lu %s",
int path_offset;
int ret = sscanf(line,
"%lx-%lx %4s %lx %x:%x %lu %n",
&addr_start, &addr_end,
perms,
&offset,
&dev_major, &dev_minor,
&inode,
pathname);
&path_offset);
char *pathname = line + path_offset;
if(ret != 7)
{
log_error(tid, "Invalid format in /proc/%d/maps (%d):\n %s", tid,
ret, line);
free(line);
fclose(fp);
return -1;
}
#ifdef DEBUG_PROC_PARSER
log_info(tid,
......@@ -295,8 +298,8 @@ int trace_add_files_from_proc(unsigned int process, pid_t tid,
#endif
if(inode > 0)
{
if(strncmp(pathname, binary, 4096) != 0
&& strncmp(previous_path, pathname, 4096) != 0)
if(strcmp(pathname, binary) != 0
&& strncmp(pathname, previous_path, 4096) != 0)
{
#ifdef DEBUG_PROC_PARSER
log_info(tid, " adding to database");
......@@ -364,10 +367,9 @@ static int trace(pid_t first_proc, int *first_exit_code)
trace_free_process(process);
}
trace_count_processes(&nprocs, &unknown);
if(verbosity >= 2)
log_info(tid, "process exited (%s %d), %d processes remain",
(exitcode & 0x0100)?"signal":"code", exitcode & 0xFF,
(unsigned int)nprocs);
log_info(tid, "process exited (%s %d), %d processes remain",
(exitcode & 0x0100)?"signal":"code", exitcode & 0xFF,
(unsigned int)nprocs);
if(nprocs <= 0)
break;
if(unknown >= nprocs)
......@@ -387,8 +389,7 @@ static int trace(pid_t first_proc, int *first_exit_code)
process = trace_find_process(tid);
if(process == NULL)
{
if(verbosity >= 3)
log_debug(tid, "process appeared");
log_debug(tid, "process appeared");
process = trace_get_empty_process();
process->status = PROCSTAT_UNKNOWN;
process->flags = 0;
......@@ -404,11 +405,10 @@ static int trace(pid_t first_proc, int *first_exit_code)
{
process->status = PROCSTAT_ATTACHED;
if(verbosity >= 3)
log_debug(tid, "process attached");
log_debug(tid, "process attached");
trace_set_options(tid);
ptrace(PTRACE_SYSCALL, tid, NULL, NULL);
if(verbosity >= 2)
if(logging_level <= 20)
{
unsigned int nproc, unknown;
trace_count_processes(&nproc, &unknown);
......@@ -549,8 +549,7 @@ static int trace(pid_t first_proc, int *first_exit_code)
else
{
siginfo_t si;
if(verbosity >= 2)
log_info(tid, "caught signal %d", signum);
log_info(tid, "caught signal %d", signum);
if(ptrace(PTRACE_GETSIGINFO, tid, 0, (long)&si) >= 0)
ptrace(PTRACE_SYSCALL, tid, NULL, signum);
else
......@@ -616,13 +615,12 @@ static void sigint_handler(int signo)
(void)signo;
if(now - last_int < 2)
{
if(verbosity >= 1)
log_error(0, "cleaning up on SIGINT");
log_error(0, "cleaning up on SIGINT");
cleanup();
restore_signals();
exit(1);
exit(128 + 2);
}
else if(verbosity >= 1)
else
log_error(0, "Got SIGINT, press twice to abort...");
last_int = now;
}
......@@ -661,7 +659,7 @@ int fork_and_trace(const char *binary, int argc, char **argv,
child = fork();
if(child != 0 && verbosity >= 2)
if(child != 0)
log_info(0, "child created, pid=%d", child);
if(child == 0)
......@@ -676,9 +674,9 @@ int fork_and_trace(const char *binary, int argc, char **argv,
0,
"couldn't use ptrace: %s\n"
"This could be caused by a security policy or isolation "
"mechanism (such as\n Docker), see http://bit.ly/2bZd8Fa",
"mechanism (such as Docker), see http://bit.ly/2bZd8Fa",
strerror(errno));
exit(1);
exit(125);
}
/* Stop this once so tracer can set options */
kill(getpid(), SIGSTOP);
......@@ -686,32 +684,12 @@ int fork_and_trace(const char *binary, int argc, char **argv,
execvp(binary, args);
log_critical(0, "couldn't execute the target command (execvp "
"returned): %s", strerror(errno));
exit(1);
}
/* Open log file */
{
char logfilename[4096];
const char *home = getenv("HOME");
if(!home || !home[0])
{
log_critical(0, "couldn't open log file: $HOME not set");
restore_signals();
return 1;
}
strcpy(logfilename, home);
strcat(logfilename, "/.reprozip/log");
if(log_open_file(logfilename) != 0)
{
restore_signals();
return 1;
}
exit(127);
}
if(db_init(database_path) != 0)
{
kill(child, SIGKILL);
log_close_file();
restore_signals();
return 1;
}
......@@ -726,8 +704,7 @@ int fork_and_trace(const char *binary, int argc, char **argv,
process->threadgroup = trace_new_threadgroup(child, get_wd());
process->in_syscall = 0;
if(verbosity >= 2)
log_info(0, "process %d created by initial fork()", child);
log_info(0, "process %d created by initial fork()", child);
if( (db_add_first_process(&process->identifier,
process->threadgroup->wd) != 0)
|| (db_add_file_open(process->identifier, process->threadgroup->wd,
......@@ -736,7 +713,6 @@ int fork_and_trace(const char *binary, int argc, char **argv,
/* LCOV_EXCL_START : Database insertion shouldn't fail */
db_close(1);
cleanup();
log_close_file();
restore_signals();
return 1;
/* LCOV_EXCL_END */
......@@ -747,19 +723,16 @@ int fork_and_trace(const char *binary, int argc, char **argv,
{
cleanup();
db_close(1);
log_close_file();
restore_signals();
return 1;
}
if(db_close(0) != 0)
{
log_close_file();
restore_signals();
return 1;
}
log_close_file();
restore_signals();
return 0;
}
......@@ -8,9 +8,6 @@ int fork_and_trace(const char *binary, int argc, char **argv,
const char *database_path, int *exit_status);
extern int trace_verbosity;
/* This is NOT a union because sign-extension rules depend on actual register
* sizes. */
typedef struct S_register_type {
......
......@@ -13,9 +13,6 @@
#include "log.h"
extern int trace_verbosity;
unsigned int flags2mode(int flags)
{
unsigned int mode = 0;
......@@ -146,13 +143,10 @@ int path_is_dir(const char *pathname)
struct stat buf;
if(lstat(pathname, &buf) != 0)
{
if(trace_verbosity >= 1)
{
/* LCOV_EXCL_START : shouldn't happen because a tracer process just
* accessed it */
log_error(0, "error stat()ing %s: %s", pathname, strerror(errno));
/* LCOV_EXCL_END */
}
/* LCOV_EXCL_START : shouldn't happen because a tracer process just
* accessed it */
log_error(0, "error stat()ing %s: %s", pathname, strerror(errno));
/* LCOV_EXCL_END */
return 0;
}
return S_ISDIR(buf.st_mode)?1:0;
......
Metadata-Version: 1.1
Metadata-Version: 1.2
Name: reprozip
Version: 1.0.10
Version: 1.0.14
Summary: Linux tool enabling reproducible experiments (packer)
Home-page: http://vida-nyu.github.io/reprozip/
Author: Remi Rampin
Author-email: remirampin@gmail.com
Home-page: https://www.reprozip.org/
Author: Remi Rampin, Fernando Chirigati, Dennis Shasha, Juliana Freire
Author-email: reprozip-users@vgc.poly.edu
Maintainer: Remi Rampin
Maintainer-email: remirampin@gmail.com
License: BSD-3-Clause
Project-URL: Homepage, https://github.com/ViDA-NYU/reprozip
Project-URL: Documentation, https://docs.reprozip.org/
Project-URL: Examples, https://examples.reprozip.org/
Project-URL: Say Thanks, https://saythanks.io/to/remram44
Project-URL: Source, https://github.com/ViDA-NYU/reprozip
Project-URL: Tracker, https://github.com/ViDA-NYU/reprozip/issues
Description: ReproZip
========
......@@ -25,7 +33,7 @@ Description: ReproZip
ReproZip is currently being developed at `NYU <http://engineering.nyu.edu/>`_. The team includes:
* `Fernando Chirigati <https://vgc.poly.edu/~fchirigati/>`_
* `Fernando Chirigati <http://fchirigati.com/>`_
* `Juliana Freire <https://vgc.poly.edu/~juliana/>`_
* `Remi Rampin <https://remirampin.com/>`_
* `Dennis Shasha <http://cs.nyu.edu/shasha/>`_
......@@ -38,9 +46,6 @@ Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: BSD License
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.3
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: C
Classifier: Topic :: Scientific/Engineering
......
......@@ -5,10 +5,10 @@ setup.py
native/config.h
native/database.c
native/database.h
native/log.c
native/log.h
native/ptrace_utils.c
native/ptrace_utils.h
native/pylog.c
native/pytracer.c
native/syscalls.c
native/syscalls.h
......
......@@ -2,4 +2,4 @@
# This file is part of ReproZip which is released under the Revised BSD License
# See file LICENSE for full license details.
__version__ = '1.0.10'
__version__ = '1.0.14'
......@@ -36,8 +36,11 @@ import usagestats
import yaml
from .utils import iteritems, itervalues, unicode_, stderr, UniqueNames, \
escape, CommonEqualityMixin, optional_return_type, hsize, join_root, \
copyfile
escape, CommonEqualityMixin, optional_return_type, isodatetime, hsize, \
join_root, copyfile
logger = logging.getLogger(__name__.split('.', 1)[0])
FILE_READ = 0x01
......@@ -343,18 +346,18 @@ def load_iofiles(config, runs):
if name in files:
if files[name].path != path:
old_name, name = name, uniquenames(name)
logging.warning("File name appears multiple times: %s\n"
"Using name %s instead",
old_name, name)
logger.warning("File name appears multiple times: %s\n"
"Using name %s instead",
old_name, name)