diff --git a/cr-restore.c b/cr-restore.c index 03a2ee1f1..81267cb26 100644 --- a/cr-restore.c +++ b/cr-restore.c @@ -605,6 +605,10 @@ static int restore_task_with_children(void *_arg) exit(-1); } + ret = log_init_by_pid(); + if (ret < 0) + exit(1); + list_for_each_entry(me, &tasks, list) if (me->pid == pid) break; diff --git a/crtools.c b/crtools.c index b4c0a2ce3..d38b0706a 100644 --- a/crtools.c +++ b/crtools.c @@ -395,6 +395,7 @@ int main(int argc, char *argv[]) { "help", no_argument, 0, 'h' }, { SK_EST_PARAM, no_argument, 0, 42 }, { "close", required_argument, 0, 43 }, + { "log-pid", no_argument, 0, 44}, { }, }; @@ -434,6 +435,7 @@ int main(int argc, char *argv[]) } break; case 'o': + opts.output = strdup(optarg); if (log_init(optarg)) return -1; log_inited = 1; @@ -470,6 +472,9 @@ int main(int argc, char *argv[]) close(fd); break; } + case 44: + opts.log_file_per_pid = 1; + break; case 'h': default: goto usage; @@ -553,7 +558,9 @@ usage: pr_msg(" --%s checkpoint/restore established TCP connections\n", SK_EST_PARAM); pr_msg("\n* Logging:\n"); - pr_msg(" -o|--log-file log file name (relative path is relative to --images-dir)\n"); + pr_msg(" -o|--log-file [NAME] log file name (relative path is relative to --images-dir)\n"); + pr_msg(" --log-pid if the -o option is in effect, each restored processes is\n"); + pr_msg(" written to the [NAME].pid file\n"); pr_msg(" -v [num] set logging level\n"); pr_msg(" 0 - silent (only error messages)\n"); pr_msg(" 1 - informative (default)\n"); diff --git a/include/crtools.h b/include/crtools.h index ece5cf5c3..9fce868e0 100644 --- a/include/crtools.h +++ b/include/crtools.h @@ -74,6 +74,8 @@ struct cr_options { bool ext_unix_sk; bool tcp_established_ok; unsigned int namespaces_flags; + bool log_file_per_pid; + char *output; }; extern struct cr_options opts; diff --git a/include/log.h b/include/log.h index feaedb472..e4bb73a08 100644 --- a/include/log.h +++ b/include/log.h @@ -3,6 +3,7 @@ extern int log_init(const char *output); extern void log_fini(void); +extern int log_init_by_pid(void); extern int log_get_fd(void); diff --git a/log.c b/log.c index 4e242235f..cd1ed5362 100644 --- a/log.c +++ b/log.c @@ -23,6 +23,9 @@ static unsigned int current_loglevel = DEFAULT_LOGLEVEL; static int current_logfd = DEFAULT_LOGFD; +static char buffer[PAGE_SIZE]; +static char buf_off = 0; + int log_get_fd(void) { return current_logfd; @@ -67,6 +70,23 @@ err: return -1; } +int log_init_by_pid(void) +{ + char path[PATH_MAX]; + + if (!opts.log_file_per_pid) { + buf_off = snprintf(buffer, PAGE_SIZE, "%6d: ", getpid()); + return 0; + } + + if (!opts.output) + return 0; + + snprintf(path, PATH_MAX, "%s.%d", opts.output, getpid()); + + return log_init(path); +} + void log_fini(void) { if (current_logfd > 2) @@ -86,7 +106,7 @@ void log_set_loglevel(unsigned int level) void print_on_level(unsigned int loglevel, const char *format, ...) { va_list params; - int fd; + int fd, size, ret, off; if (unlikely(loglevel == LOG_MSG)) { fd = STDOUT_FILENO; @@ -97,6 +117,16 @@ void print_on_level(unsigned int loglevel, const char *format, ...) } va_start(params, format); - vdprintf(fd, format, params); + size = vsnprintf(buffer + buf_off, PAGE_SIZE - buf_off, format, params); va_end(params); + + size += buf_off; + + off = 0; + while (off < size) { + ret = write(fd, buffer + off, size - off); + if (ret <= 0) + break; + off += ret; + } } diff --git a/test/zdtm.sh b/test/zdtm.sh index 5e56976f1..0a5556651 100644 --- a/test/zdtm.sh +++ b/test/zdtm.sh @@ -113,7 +113,7 @@ run_test() done echo Restore $pid - setsid $CRTOOLS restore -D $ddump -o restore.log -v 4 -d -t $pid $args || return 2 + setsid $CRTOOLS restore --log-pid -D $ddump -o restore.log -v 4 -d -t $pid $args || return 2 save_fds $pid $ddump/restore.fd diff_fds $ddump/dump.fd $ddump/restore.fd || return 2