Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

record: make all info in text format #1435

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions cmds/dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -972,9 +972,12 @@ static void dump_chrome_footer(struct uftrace_dump_ops *ops, struct uftrace_data
struct uftrace_chrome_dump *chrome = container_of(ops, typeof(*chrome), ops);

/* read recorded date and time */
snprintf(buf, sizeof(buf), "%s/info", opts->dirname);
if (stat(buf, &statbuf) < 0)
return;
snprintf(buf, sizeof(buf), "%s/info.txt", opts->dirname);
if (stat(buf, &statbuf) < 0) {
snprintf(buf, sizeof(buf), "%s/info", opts->dirname);
if (stat(buf, &statbuf) < 0)
return;
}

ctime_r(&statbuf.st_mtime, buf);
buf[strlen(buf) - 1] = '\0';
Expand Down
91 changes: 87 additions & 4 deletions cmds/info.c
Original file line number Diff line number Diff line change
Expand Up @@ -848,6 +848,87 @@ static int read_uftrace_version(void *arg)
return 0;
}

void write_header(int fd, struct uftrace_file_header *hdr)
{
dprintf(fd, "magic:%s\n", hdr->magic);
dprintf(fd, "version:%u\n", hdr->version);
dprintf(fd, "header_size:%u\n", hdr->header_size);
dprintf(fd, "endian:%u\n", hdr->endian);
dprintf(fd, "elf_class:%u\n", hdr->elf_class);
dprintf(fd, "feat_mask:%" PRIu64 "\n", hdr->feat_mask);
dprintf(fd, "info_mask:%" PRIu64 "\n", hdr->info_mask);
dprintf(fd, "max_stack:%u\n", hdr->max_stack);
}

static char *read_header_field(FILE *fp, struct uftrace_file_header *hdr, const char *field,
char *buf)
{
int len = strlen(field);

if (fgets(buf, PATH_MAX, fp) == NULL)
return NULL;
if (strncmp(buf, field, len))
return NULL;
return &buf[len];
}

int read_header(struct uftrace_file_header *hdr, FILE *fp, bool is_info_txt)
{
char buf[PATH_MAX];
char *data;
char *copied_magic;

if (!is_info_txt) {
if (fread(hdr, sizeof(*hdr), 1, fp) != 1)
return -1;
return 0;
}

data = read_header_field(fp, hdr, "magic:", buf);
if (!data)
return -1;
copied_magic = copy_info_str(data);
memcpy(hdr->magic, copied_magic, UFTRACE_MAGIC_LEN);
free(copied_magic);

data = read_header_field(fp, hdr, "version:", buf);
if (!data)
return -1;
sscanf(data, "%u", &hdr->version);

data = read_header_field(fp, hdr, "header_size:", buf);
if (!data)
return -1;
sscanf(data, "%hu", &hdr->header_size);

data = read_header_field(fp, hdr, "endian:", buf);
if (!data)
return -1;
sscanf(data, "%hhu", &hdr->endian);

data = read_header_field(fp, hdr, "elf_class:", buf);
if (!data)
return -1;
sscanf(data, "%hhu", &hdr->elf_class);

data = read_header_field(fp, hdr, "feat_mask:", buf);
if (!data)
return -1;
sscanf(data, "%" PRIu64, &hdr->feat_mask);

data = read_header_field(fp, hdr, "info_mask:", buf);
if (!data)
return -1;
sscanf(data, "%" PRIu64, &hdr->info_mask);

data = read_header_field(fp, hdr, "max_stack:", buf);
if (!data)
return -1;
sscanf(data, "%hu", &hdr->max_stack);

return 0;
}

struct uftrace_info_handler {
enum uftrace_info_bits bit;
int (*handler)(void *arg);
Expand Down Expand Up @@ -981,10 +1062,12 @@ void process_uftrace_info(struct uftrace_data *handle, struct uftrace_opts *opts
if (info_mask == 0)
return;

snprintf(buf, sizeof(buf), "%s/info", opts->dirname);

if (stat(buf, &statbuf) < 0)
return;
snprintf(buf, sizeof(buf), "%s/info.txt", opts->dirname);
if (stat(buf, &statbuf) < 0) {
snprintf(buf, sizeof(buf), "%s/info", opts->dirname);
if (stat(buf, &statbuf) < 0)
return;
}

process(data, "# system information\n");
process(data, "# ==================\n");
Expand Down
27 changes: 11 additions & 16 deletions cmds/record.c
Original file line number Diff line number Diff line change
Expand Up @@ -418,11 +418,12 @@ int fill_file_header(struct uftrace_opts *opts, int status, struct rusage *rusag
char *filename = NULL;
struct uftrace_file_header hdr;
char elf_ident[EI_NIDENT];
char buf[PATH_MAX];

xasprintf(&filename, "%s/info", opts->dirname);
xasprintf(&filename, "%s/info.txt", opts->dirname);
pr_dbg3("fill header (metadata) info in %s\n", filename);

fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0644);
fd = open(filename, O_RDWR | O_CREAT | O_TRUNC, 0644);
if (fd < 0)
pr_err("cannot open info file");

Expand All @@ -444,19 +445,16 @@ int fill_file_header(struct uftrace_opts *opts, int status, struct rusage *rusag
hdr.unused1 = 0;
hdr.unused2 = 0;

if (write(fd, &hdr, sizeof(hdr)) != (int)sizeof(hdr))
pr_err("writing header info failed");

fill_uftrace_info(&hdr.info_mask, fd, opts, status, rusage, elapsed_time);

try_write:
ret = pwrite(fd, &hdr, sizeof(hdr), 0);
if (ret != (int)sizeof(hdr)) {
static int retry = 0;

if (ret > 0 && retry++ < 3)
goto try_write;
memset(buf, 0, PATH_MAX);
lseek(fd, 0, SEEK_SET);
if (read(fd, buf, PATH_MAX) < 0)
goto close_efd;

lseek(fd, 0, SEEK_SET);
write_header(fd, &hdr);
if (write(fd, buf, strlen(buf)) < 0) {
pr_dbg("writing header info failed.\n");
goto close_efd;
}
Expand Down Expand Up @@ -1352,14 +1350,12 @@ static void send_dbg_files(int sock, const char *dirname)
static void send_info_file(int sock, const char *dirname)
{
int fd;
char *filename = NULL;
struct uftrace_file_header hdr;
struct stat stbuf;
void *info;
int len;

xasprintf(&filename, "%s/info", dirname);
fd = open(filename, O_RDONLY);
fd = open_correct_info_file(dirname, O_RDONLY);
if (fd < 0)
pr_err("open info failed");

Expand All @@ -1379,7 +1375,6 @@ static void send_info_file(int sock, const char *dirname)

close(fd);
free(info);
free(filename);
}

static void send_kernel_metadata(int sock, const char *dirname)
Expand Down
2 changes: 1 addition & 1 deletion cmds/recv.c
Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,7 @@ static void recv_trace_info(int sock, int len)
if (read_all(sock, info, len) < 0)
pr_err("recv info failed");

write_client_file(client, "info", 2, &hdr, sizeof(hdr), info, len);
write_client_file(client, "info.txt", 2, &hdr, sizeof(hdr), info, len);

free(info);
}
Expand Down
3 changes: 3 additions & 0 deletions uftrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,7 @@ int command_tui(int argc, char *argv[], struct uftrace_opts *opts);

extern volatile bool uftrace_done;

int open_correct_info_file(const char *dirname, int flags, ...);
int open_data_file(struct uftrace_opts *opts, struct uftrace_data *handle);
int open_info_file(struct uftrace_opts *opts, struct uftrace_data *handle);
void __close_data_file(struct uftrace_opts *opts, struct uftrace_data *handle, bool unload_modules);
Expand Down Expand Up @@ -542,6 +543,8 @@ struct rusage;

int fill_file_header(struct uftrace_opts *opts, int status, struct rusage *rusage,
char *elapsed_time);
void write_header(int fd, struct uftrace_file_header *hdr);
int read_header(struct uftrace_file_header *hdr, FILE *fp, bool is_info_txt);
void fill_uftrace_info(uint64_t *info_mask, int fd, struct uftrace_opts *opts, int status,
struct rusage *rusage, char *elapsed_time);
int read_uftrace_info(uint64_t info_mask, struct uftrace_data *handle);
Expand Down
67 changes: 59 additions & 8 deletions utils/data-file.c
Original file line number Diff line number Diff line change
Expand Up @@ -347,21 +347,56 @@ bool data_is_lp64(struct uftrace_data *handle)
return handle->hdr.elf_class == ELFCLASS64;
}

int open_correct_info_file(const char *dirname, int flags, ...)
{
char buf[PATH_MAX];
struct stat statbuf;

snprintf(buf, sizeof(buf), "%s/info.txt", dirname);
if (stat(buf, &statbuf) < 0) {
snprintf(buf, sizeof(buf), "%s/info", dirname);
if (stat(buf, &statbuf) < 0)
return -1;
}

if (flags & O_CREAT) {
va_list ap;
mode_t mode;

va_start(ap, flags);
mode = va_arg(ap, mode_t);
va_end(ap);

return open(buf, flags, mode);
}
return open(buf, flags);
}

int open_info_file(struct uftrace_opts *opts, struct uftrace_data *handle)
{
FILE *fp;
char buf[PATH_MAX];
char info_txt[PATH_MAX];
char info_bin[PATH_MAX];
bool is_info_txt = true;
int saved_errno = 0;
struct stat stbuf;

memset(handle, 0, sizeof(*handle));

snprintf(buf, sizeof(buf), "%s/info", opts->dirname);
snprintf(info_txt, sizeof(info_txt), "%s/info.txt", opts->dirname);

fp = fopen(buf, "rb");
fp = fopen(info_txt, "r");
if (fp != NULL)
goto ok;

snprintf(info_bin, sizeof(info_bin), "%s/info", opts->dirname);

fp = fopen(info_bin, "rb");
if (fp != NULL) {
is_info_txt = false;
goto ok;
}

saved_errno = errno;
/* provide a better error code for empty/invalid directories */
if (stat(opts->dirname, &stbuf) == 0)
Expand All @@ -370,28 +405,44 @@ int open_info_file(struct uftrace_opts *opts, struct uftrace_data *handle)
/* if default dirname is failed */
if (!strcmp(opts->dirname, UFTRACE_DIR_NAME)) {
/* try again inside the current directory */
fp = fopen("./info.txt", "r");
if (fp != NULL) {
opts->dirname = "./";
goto ok;
}

fp = fopen("./info", "rb");
if (fp != NULL) {
opts->dirname = "./";
is_info_txt = false;
goto ok;
}

/* retry with old default dirname */
snprintf(buf, sizeof(buf), "%s/info", UFTRACE_DIR_OLD_NAME);
fp = fopen(buf, "rb");
snprintf(info_txt, sizeof(info_txt), "%s/info.txt", UFTRACE_DIR_OLD_NAME);
fp = fopen(info_txt, "r");
if (fp != NULL) {
opts->dirname = UFTRACE_DIR_OLD_NAME;
goto ok;
}

snprintf(info_bin, sizeof(info_bin), "%s/info", UFTRACE_DIR_OLD_NAME);
fp = fopen(info_bin, "rb");
if (fp != NULL) {
opts->dirname = UFTRACE_DIR_OLD_NAME;
is_info_txt = false;
goto ok;
}

saved_errno = errno;

/* restore original file name for error reporting */
snprintf(buf, sizeof(buf), "%s/info", opts->dirname);
snprintf(info_txt, sizeof(info_txt), "%s/info.txt", opts->dirname);
snprintf(info_bin, sizeof(info_bin), "%s/info", opts->dirname);
}

/* data file loading is failed */
pr_dbg("cannot open %s file\n", buf);
pr_dbg("cannot open %s or %s file\n", info_txt, info_bin);

return -saved_errno;
ok:
Expand All @@ -406,7 +457,7 @@ int open_info_file(struct uftrace_opts *opts, struct uftrace_data *handle)
handle->last_perf_idx = -1;
INIT_LIST_HEAD(&handle->events);

if (fread(&handle->hdr, sizeof(handle->hdr), 1, fp) != 1)
if (read_header(&handle->hdr, fp, is_info_txt) < 0)
pr_err("cannot read header data");

if (memcmp(handle->hdr.magic, UFTRACE_MAGIC_STR, UFTRACE_MAGIC_LEN))
Expand Down