Commit a501b480 authored by Pavel Emelyanov's avatar Pavel Emelyanov

show: Remove deprecated code

The 'show' action has been deprecated since 1.6, let's finally drop it.

The print_data() routine is kept for yet another (to be deprecated too)
feature called 'criu exec'.
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
Acked-by: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
parent a4239104
......@@ -12,7 +12,6 @@ obj-y += cr-errno.o
obj-y += cr-exec.o
obj-y += cr-restore.o
obj-y += cr-service.o
obj-y += cr-show.o
obj-y += crtools.o
obj-y += eventfd.o
obj-y += eventpoll.o
......
......@@ -6,6 +6,7 @@
#include "parasite-syscall.h"
#include "vma.h"
#include "log.h"
#include "util.h"
struct syscall_exec_desc {
char *name;
......
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <limits.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <ctype.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "asm/types.h"
#include "list.h"
#include "imgset.h"
#include "namespaces.h"
#include "compiler.h"
#include "cr_options.h"
#include "util.h"
#include "sockets.h"
#include "image.h"
#include "uts_ns.h"
#include "ipc_ns.h"
#include "pstree.h"
#include "cr-show.h"
#include "crtools.h"
#include "protobuf.h"
#include "images/pstree.pb-c.h"
#include "images/pipe-data.pb-c.h"
#include "images/siginfo.pb-c.h"
#define DEF_PAGES_PER_LINE 6
static LIST_HEAD(pstree_list);
static void pipe_data_handler(struct cr_img *img, void *obj)
{
PipeDataEntry *e = obj;
print_image_data(img, e->bytes, opts.show_pages_content);
}
static int nice_width_for(unsigned long addr)
{
int ret = 3;
while (addr) {
addr >>= 4;
ret++;
}
return ret;
}
static inline void pr_xdigi(unsigned char *data, size_t len, int pos)
{
if (pos < len)
pr_msg("%02x ", data[pos]);
else
pr_msg(" ");
}
static inline void pr_xsym(unsigned char *data, size_t len, int pos)
{
char sym;
if (pos < len)
sym = data[pos];
else
sym = ' ';
pr_msg("%c", isprint(sym) ? sym : '.');
}
void print_data(unsigned long addr, unsigned char *data, size_t size)
{
int i, j, addr_len;
unsigned zero_line = 0;
addr_len = nice_width_for(addr + size);
for (i = 0; i < size; i += 16) {
if (*(u64 *)(data + i) == 0 && *(u64 *)(data + i + 8) == 0) {
if (zero_line == 0)
zero_line = 1;
else {
if (zero_line == 1) {
pr_msg("*\n");
zero_line = 2;
}
continue;
}
} else
zero_line = 0;
pr_msg("%#0*lx: ", addr_len, addr + i);
for (j = 0; j < 8; j++)
pr_xdigi(data, size, i + j);
pr_msg(" ");
for (j = 8; j < 16; j++)
pr_xdigi(data, size, i + j);
pr_msg(" |");
for (j = 0; j < 8; j++)
pr_xsym(data, size, i + j);
pr_msg(" ");
for (j = 8; j < 16; j++)
pr_xsym(data, size, i + j);
pr_msg("|\n");
}
}
void print_image_data(struct cr_img *img, unsigned int length, int show)
{
void *data;
int ret;
if (!show) {
lseek(img_raw_fd(img), length, SEEK_CUR);
return;
}
pr_msg("\n");
data = xmalloc(length);
if (!data)
return;
ret = read_img_buf(img, (unsigned char *)data, length);
if (ret < 0) {
xfree(data);
return;
}
print_data(0, (unsigned char *)data, length);
xfree(data);
}
static void show_pagemaps(struct cr_img *img, void *obj)
{
pb_show_plain_pretty(img, PB_PAGEMAP, "nr_pages:%u");
}
void show_siginfo(struct cr_img *img)
{
int ret;
pr_img_head(CR_FD_SIGNAL);
while (1) {
SiginfoEntry *sie;
siginfo_t *info;
ret = pb_read_one_eof(img, &sie, PB_SIGINFO);
if (ret <= 0)
break;
info = (siginfo_t *) sie->siginfo.data;
pr_msg("signal: si_signo=%d si_code=%x\n",
info->si_signo, info->si_code);
siginfo_entry__free_unpacked(sie, NULL);
}
pr_img_tail(CR_FD_SIGNAL);
}
static int pstree_item_from_pb(PstreeEntry *e, struct pstree_item *item)
{
int i;
item->pid.virt = e->pid;
item->nr_threads = e->n_threads;
item->threads = xzalloc(sizeof(struct pid) * e->n_threads);
if (!item->threads)
return -1;
for (i = 0; i < item->nr_threads; i++)
item->threads[i].virt = e->threads[i];
return 0;
}
static void pstree_handler(struct cr_img *img, void *obj)
{
PstreeEntry *e = obj;
struct pstree_item *item = NULL;
item = xzalloc(sizeof(struct pstree_item));
if (!item)
return;
if (pstree_item_from_pb(e, item)) {
xfree(item);
return;
}
list_add_tail(&item->sibling, &pstree_list);
}
static void show_collect_pstree(struct cr_img *img, int collect)
{
pb_show_plain_payload_pretty(img, PB_PSTREE,
collect ? pstree_handler : NULL, "*:%d");
}
static inline char *task_state_str(int state)
{
switch (state) {
case TASK_ALIVE:
return "running/sleeping";
case TASK_DEAD:
return "zombie";
default:
return "UNKNOWN";
}
}
static void show_core_regs(UserX86RegsEntry *regs)
{
#define pr_regs4(s, n1, n2, n3, n4) \
pr_msg("\t%8s: 0x%-16"PRIx64" " \
"%8s: 0x%-16"PRIx64" " \
"%8s: 0x%-16"PRIx64" " \
"%8s: 0x%-16"PRIx64"\n", \
#n1, s->n1, \
#n2, s->n2, \
#n3, s->n3, \
#n4, s->n4)
#define pr_regs3(s, n1, n2, n3) \
pr_msg("\t%8s: 0x%-16"PRIx64" " \
"%8s: 0x%-16"PRIx64" " \
"%8s: 0x%-16"PRIx64"\n", \
#n1, s->n1, \
#n2, s->n2, \
#n3, s->n3)
pr_msg("\t---[ GP registers set ]---\n");
pr_regs4(regs, cs, ip, ds, es);
pr_regs4(regs, ss, sp, fs, gs);
pr_regs4(regs, di, si, dx, cx);
pr_regs4(regs, ax, r8, r9, r10);
pr_regs4(regs, r11, r12, r13, r14);
pr_regs3(regs, r15, bp, bx);
pr_regs4(regs, orig_ax, flags, fs_base, gs_base);
pr_msg("\n");
}
void show_thread_info(ThreadInfoX86 *thread_info)
{
if (!thread_info)
return;
pr_msg("\t---[ Thread info ]---\n");
pr_msg("\tclear_tid_addr: 0x%"PRIx64"\n", thread_info->clear_tid_addr);
pr_msg("\n");
show_core_regs(thread_info->gpregs);
}
static struct {
u32 magic;
u32 mask;
char *hint;
} magic_hints[] = {
{ .magic = 0x45311224, .mask = 0xffffffff, .hint = "ip route dump", },
{ .magic = 0x47361222, .mask = 0xffffffff, .hint = "ip ifaddr dump", },
{ .magic = 0x00008b1f, .mask = 0x0000ffff, .hint = "gzip file", },
{ },
};
static void try_hint_magic(u32 magic)
{
int i;
for (i = 0; magic_hints[i].hint != 0; i++)
if ((magic & magic_hints[i].mask) == magic_hints[i].magic)
pr_msg("This can be %s\n", magic_hints[i].hint);
}
#define SHOW_PLAIN(name) { name##_MAGIC, PB_##name, false, NULL, NULL, }
/* nothing special behind this -S, just to avoid heavy patching */
#define SHOW_PLAINS(name) { name##S_MAGIC, PB_##name, false, NULL, NULL, }
#define SHOW_VERT(name) { name##_MAGIC, PB_##name, true, NULL, NULL, }
static struct show_image_info show_infos[] = {
SHOW_VERT(INVENTORY),
SHOW_VERT(CORE),
SHOW_VERT(IDS),
SHOW_VERT(CREDS),
SHOW_VERT(UTSNS),
SHOW_VERT(IPC_VAR),
SHOW_VERT(FS),
SHOW_VERT(GHOST_FILE),
SHOW_VERT(MM),
SHOW_VERT(CGROUP),
SHOW_PLAINS(REG_FILE),
SHOW_PLAINS(NS_FILE),
SHOW_PLAIN(EVENTFD_FILE),
SHOW_PLAIN(EVENTPOLL_FILE),
SHOW_PLAIN(EVENTPOLL_TFD),
SHOW_PLAIN(SIGNALFD),
SHOW_PLAIN(TIMERFD),
SHOW_PLAIN(INOTIFY_FILE),
SHOW_PLAIN(INOTIFY_WD),
SHOW_PLAIN(FANOTIFY_FILE),
SHOW_PLAIN(FANOTIFY_MARK),
SHOW_PLAINS(VMA),
SHOW_PLAINS(PIPE),
SHOW_PLAIN(FIFO),
SHOW_PLAIN(SIGACT),
SHOW_PLAIN(NETLINK_SK),
SHOW_PLAIN(REMAP_FPATH),
SHOW_PLAINS(MNT),
SHOW_PLAINS(TTY_FILE),
SHOW_PLAIN(TTY_INFO),
SHOW_PLAIN(RLIMIT),
SHOW_PLAIN(TUNFILE),
SHOW_PLAINS(EXT_FILE),
SHOW_PLAIN(IRMAP_CACHE),
SHOW_PLAIN(CPUINFO),
SHOW_PLAIN(USERNS),
SHOW_PLAIN(NETNS),
{ FILE_LOCKS_MAGIC, PB_FILE_LOCK, false, NULL, "3:%u", },
{ TCP_STREAM_MAGIC, PB_TCP_STREAM, true, show_tcp_stream, "1:%u 2:%u 3:%u 4:%u 12:%u", },
{ STATS_MAGIC, PB_STATS, true, NULL, "1.1:%u 1.2:%u 1.3:%u 1.4:%u 1.5:%Lu 1.6:%Lu 1.7:%Lu 1.8:%u", },
{ FDINFO_MAGIC, PB_FDINFO, false, NULL, "flags:%#o fd:%d", },
{ UNIXSK_MAGIC, PB_UNIX_SK, false, NULL, "1:%#x 2:%#x 3:%d 4:%d 5:%d 6:%d 7:%d 8:%#x 11:S", },
{ INETSK_MAGIC, PB_INET_SK, false, NULL, "1:%#x 2:%#x 3:%d 4:%d 5:%d 6:%d 7:%d 8:%d 9:%2x 11:A 12:A", },
{ PACKETSK_MAGIC, PB_PACKET_SOCK, false, NULL, "5:%d", },
{ ITIMERS_MAGIC, PB_ITIMER, false, NULL, "*:%Lu", },
{ POSIX_TIMERS_MAGIC, PB_POSIX_TIMER, false, NULL, "*:%d 5:%Lu 7:%Lu 8:%lu 9:%Lu 10:%Lu", },
{ NETDEV_MAGIC, PB_NETDEV, false, NULL, "2:%d", },
{ PAGEMAP_MAGIC, PB_PAGEMAP_HEAD, true, show_pagemaps, NULL, },
{ PIPES_DATA_MAGIC, PB_PIPE_DATA, false, pipe_data_handler, NULL, },
{ FIFO_DATA_MAGIC, PB_PIPE_DATA, false, pipe_data_handler, NULL, },
{ SK_QUEUES_MAGIC, PB_SK_QUEUES, false, sk_queue_data_handler, NULL, },
{ IPCNS_SHM_MAGIC, PB_IPC_SHM, false, ipc_shm_handler, NULL, },
{ IPCNS_SEM_MAGIC, PB_IPC_SEM, false, ipc_sem_handler, NULL, },
{ IPCNS_MSG_MAGIC, PB_IPCNS_MSG_ENT, false, ipc_msg_handler, NULL, },
{ }
};
static int cr_parse_file(void)
{
u32 magic;
int ret = -1, fd;
struct cr_img *img = NULL;
fd = open(opts.show_dump_file, O_RDONLY);
if (fd < 0) {
pr_perror("Can't open %s", opts.show_dump_file);
goto out;
}
img = img_from_fd(fd);
if (!img)
goto out;
if (read_img(img, &magic) < 0)
goto out;
ret = cr_parse_fd(img, magic);
out:
if (img)
close_image(img);
else
close_safe(&fd);
return ret;
}
int cr_parse_fd(struct cr_img *img, u32 magic)
{
int ret = 0, i;
if (magic == IMG_COMMON_MAGIC || magic == IMG_SERVICE_MAGIC) {
if (read_img(img, &magic) < 0)
goto out;
}
if (magic == PSTREE_MAGIC) {
show_collect_pstree(img, 0);
goto out;
}
if (magic == SIGNAL_MAGIC || magic == PSIGNAL_MAGIC) {
show_siginfo(img);
goto out;
}
for (i = 0; show_infos[i].magic; i++) {
struct show_image_info *si;
si = &show_infos[i];
if (si->magic != magic)
continue;
do_pb_show_plain(img, si->pb_type, si->single,
si->payload, si->fmt);
goto out;
}
ret = -1;
pr_err("Unknown magic %#x in %s\n",
magic, opts.show_dump_file);
try_hint_magic(magic);
out:
return ret;
}
static int cr_show_pstree_item(struct pstree_item *item)
{
int ret = -1, i;
struct cr_img *img;
struct cr_imgset *cr_imgset = NULL;
TaskKobjIdsEntry *ids;
cr_imgset = cr_task_imgset_open(item->pid.virt, O_SHOW);
if (!cr_imgset)
goto out;
pr_msg("Task %d:\n", item->pid.virt);
pr_msg("----------------------------------------\n");
cr_parse_fd(img_from_set(cr_imgset, CR_FD_CORE), CORE_MAGIC);
if (item->nr_threads > 1) {
for (i = 0; i < item->nr_threads; i++) {
if (item->threads[i].virt == item->pid.virt)
continue;
img = open_image(CR_FD_CORE, O_SHOW, item->threads[i].virt);
if (!img)
goto outc;
pr_msg("Thread %d.%d:\n", item->pid.virt, item->threads[i].virt);
pr_msg("----------------------------------------\n");
cr_parse_fd(img, CORE_MAGIC);
close_image(img);
}
}
pr_msg("Resources for %d:\n", item->pid.virt);
pr_msg("----------------------------------------\n");
for (i = _CR_FD_TASK_FROM + 1; i < _CR_FD_TASK_TO; i++)
if ((i != CR_FD_CORE) && (i != CR_FD_IDS)) {
pr_msg("* ");
pr_msg(imgset_template[i].fmt, item->pid.virt);
pr_msg(":\n");
cr_parse_fd(img_from_set(cr_imgset, i), imgset_template[i].magic);
}
img = open_image(CR_FD_RLIMIT, O_SHOW, item->pid.virt);
if (img) {
pr_msg("* ");
pr_msg(imgset_template[CR_FD_RLIMIT].fmt, item->pid.virt);
pr_msg(":\n");
cr_parse_fd(img, RLIMIT_MAGIC);
close_image(img);
}
if (pb_read_one(img_from_set(cr_imgset, CR_FD_IDS), &ids, PB_IDS) > 0) {
img = open_image(CR_FD_FDINFO, O_SHOW, ids->files_id);
if (img) {
pr_msg("* ");
pr_msg(imgset_template[CR_FD_FDINFO].fmt, ids->files_id);
pr_msg(":\n");
cr_parse_fd(img, FDINFO_MAGIC);
close_image(img);
}
task_kobj_ids_entry__free_unpacked(ids, NULL);
}
pr_msg("---[ end of task %d ]---\n", item->pid.virt);
ret = 0;
outc:
close_cr_imgset(&cr_imgset);
out:
return ret;
}
static int cr_show_pid(int pid)
{
int ret;
struct cr_img *img;
struct pstree_item item;
img = open_image(CR_FD_PSTREE, O_SHOW);
if (!img)
return -1;
while (1) {
PstreeEntry *pe;
ret = pb_read_one_eof(img, &pe, PB_PSTREE);
if (ret <= 0) {
close_image(img);
return ret;
}
if (pe->pid == pid) {
pstree_item_from_pb(pe, &item);
pstree_entry__free_unpacked(pe, NULL);
break;
}
pstree_entry__free_unpacked(pe, NULL);
}
close_image(img);
return cr_show_pstree_item(&item);
}
static int cr_show_all(void)
{
struct pstree_item *item = NULL, *tmp;
int ret = -1, pid;
struct cr_img *img;
img = open_image(CR_FD_PSTREE, O_SHOW);
if (!img)
goto out;
show_collect_pstree(img, 1);
close_image(img);
pid = list_first_entry(&pstree_list, struct pstree_item, sibling)->pid.virt;
ret = try_show_namespaces(pid);
if (ret)
goto out;
list_for_each_entry(item, &pstree_list, sibling)
if (cr_show_pstree_item(item))
break;
out:
list_for_each_entry_safe(item, tmp, &pstree_list, sibling) {
list_del(&item->sibling);
xfree(item->threads);
xfree(item);
}
return ret;
}
int cr_show(int pid)
{
if (isatty(STDOUT_FILENO)) {
pr_msg("The \"show\" action is deprecated by the CRIT utility.\n");
pr_msg("To view an image use the \"crit decode -i $name --pretty\" command.\n");
return -1;
}
if (opts.show_dump_file)
return cr_parse_file();
if (pid)
return cr_show_pid(pid);
return cr_show_all();
}
......@@ -661,8 +661,11 @@ int main(int argc, char *argv[], char *envp[])
return ret != 0;
}
if (!strcmp(argv[optind], "show"))
return cr_show(pid) != 0;
if (!strcmp(argv[optind], "show")) {
pr_msg("The \"show\" action is deprecated by the CRIT utility.\n");
pr_msg("To view an image use the \"crit decode -i $name --pretty\" command.\n");
return -1;
}
if (!strcmp(argv[optind], "check"))
return cr_check() != 0;
......
#include <stdlib.h>
#include "image-desc.h"
#include "cr-show.h"
#include "magic.h"
#include "image.h"
......
#ifndef __CR_SHOW_H__
#define __CR_SHOW_H__
#include <stdbool.h>
#include "asm/types.h"
struct cr_img;
struct show_image_info {
u32 magic;
int pb_type;
bool single;
void (*payload)(struct cr_img *, void *);
char *fmt;
};
extern void show_siginfo(struct cr_img *);
extern void sk_queue_data_handler(struct cr_img *, void *obj);
extern void ipc_shm_handler(struct cr_img *, void *obj);
extern void ipc_msg_handler(struct cr_img *, void *obj);
extern void ipc_sem_handler(struct cr_img *, void *obj);
extern int cr_parse_fd(struct cr_img *, u32 magic);
extern void show_tcp_stream(struct cr_img *, void *obj);
#endif /* __CR_SHOW_H__ */
......@@ -21,7 +21,6 @@ extern int prepare_inventory(InventoryEntry *he);
extern int cr_dump_tasks(pid_t pid);
extern int cr_pre_dump_tasks(pid_t pid);
extern int cr_restore_tasks(void);
extern int cr_show(int pid);
extern int convert_to_elf(char *elf_path, int fd_core);
extern int cr_check(void);
extern int cr_exec(int pid, char **opts);
......
......@@ -75,7 +75,6 @@ extern int dump_mnt_namespaces(void);
extern int dump_namespaces(struct pstree_item *item, unsigned int ns_flags);
extern int prepare_namespace_before_tasks(void);
extern int prepare_namespace(struct pstree_item *item, unsigned long clone_flags);
extern int try_show_namespaces(int pid);
extern int switch_ns(int pid, struct ns_desc *nd, int *rst);
extern int restore_ns(int rst, struct ns_desc *nd);
......
......@@ -27,20 +27,6 @@ extern int pb_write_one(struct cr_img *, void *obj, int type);
#include <google/protobuf-c/protobuf-c.h>
extern void do_pb_show_plain(struct cr_img *, int type, int single_entry,
void (*payload_hadler)(struct cr_img *, void *obj),
const char *pretty_fmt);
/* Don't have objects at hands to also do typechecking here */
#define pb_show_plain_payload_pretty(__fd, __type, payload_hadler, pretty) \
do_pb_show_plain(__fd, __type, 0, payload_hadler, pretty)
#define pb_show_plain_payload(__fd, __proto_message_name, payload_hadler) \
pb_show_plain_payload_pretty(__fd, __proto_message_name, payload_hadler, NULL)
#define pb_show_plain_pretty(__fd, __proto_message_name, __pretty) \
pb_show_plain_payload_pretty(__fd, __proto_message_name, NULL, __pretty)
struct collect_image_info {
int fd_type;
int pb_type;
......
......@@ -281,4 +281,6 @@ char *xstrcat(char *str, const char *fmt, ...)
char *xsprintf(const char *fmt, ...)
__attribute__ ((__format__ (__printf__, 1, 2)));
void print_data(unsigned long addr, unsigned char *data, size_t size);
#endif /* __CR_UTIL_H__ */
......@@ -62,7 +62,6 @@ static void pr_ipc_sem_array(unsigned int loglevel, int nr, u16 *values)
}
#define pr_info_ipc_sem_array(nr, values) pr_ipc_sem_array(LOG_INFO, nr, values)
#define pr_msg_ipc_sem_array(nr, values) pr_ipc_sem_array(LOG_MSG, nr, values)
static void pr_info_ipc_sem_entry(const IpcSemEntry *sem)
{
......@@ -473,48 +472,6 @@ err:
return ret < 0 ? -1 : 0;
}
void ipc_sem_handler(struct cr_img *img, void *obj)
{
IpcSemEntry *e = obj;
u16 *values;
int size;
pr_msg("\n");
size = round_up(sizeof(u16) * e->nsems, sizeof(u64));
values = xmalloc(size);
if (values == NULL)
return;
if (read_img_buf(img, values, size) <= 0) {
xfree(values);
return;
}
pr_msg_ipc_sem_array(e->nsems, values);
xfree(values);
}
static void ipc_msg_data_handler(struct cr_img *img, void *obj)
{
IpcMsg *e = obj;
print_image_data(img, round_up(e->msize, sizeof(u64)), opts.show_pages_content);
}
void ipc_msg_handler(struct cr_img *img, void *obj)
{
IpcMsgEntry *e = obj;
int msg_nr = 0;
pr_msg("\n");
while (msg_nr++ < e->qnum)
pb_show_plain_payload(img, PB_IPCNS_MSG, ipc_msg_data_handler);
}
void ipc_shm_handler(struct cr_img *img, void *obj)
{
IpcShmEntry *e = obj;
print_image_data(img, round_up(e->size, sizeof(u32)), opts.show_pages_content);
}
static int prepare_ipc_sem_values(struct cr_img *img, const IpcSemEntry *sem)
{
int ret, size;
......
......@@ -10,7 +10,6 @@
#include <signal.h>
#include <sched.h>
#include "cr-show.h"
#include "util.h"
#include "imgset.h"
#include "uts_ns.h"
......@@ -1338,66 +1337,5 @@ err_unds:
return -1;
}
int try_show_namespaces(int ns_pid)
{
struct cr_imgset *imgset;
int i, ret;
struct cr_img *img;
TaskKobjIdsEntry *ids;
pr_msg("Namespaces for %d:\n", ns_pid);
img = open_image(CR_FD_IDS, O_RSTR, ns_pid);
if (!img)
return -1;
ret = pb_read_one(img, &ids, PB_IDS);
close_image(img);
if (ret < 0)
return -1;
imgset = cr_imgset_open(ids->net_ns_id, NETNS, O_SHOW);
if (imgset) {
pr_msg("-------------------NETNS---------------------\n");
for (i = _CR_FD_NETNS_FROM + 1; i < _CR_FD_NETNS_TO; i++) {
img = img_from_set(imgset, i);
if (!img)
continue;
cr_parse_fd(img, imgset_template[i].magic);
}
close_cr_imgset(&imgset);
}
imgset = cr_imgset_open(ids->ipc_ns_id, IPCNS, O_SHOW);
if (imgset) {
pr_msg("-------------------IPCNS---------------------\n");
for (i = _CR_FD_IPCNS_FROM + 1; i < _CR_FD_IPCNS_TO; i++) {
img = img_from_set(imgset, i);
if (!img)
continue;
cr_parse_fd(img, imgset_template[i].magic);
}
close_cr_imgset(&imgset);
}
img = open_image(CR_FD_UTSNS, O_SHOW, ids->uts_ns_id);
if (img) {
pr_msg("-------------------UTSNS---------------------\n");
cr_parse_fd(img, imgset_template[CR_FD_UTSNS].magic);
close_image(img);
}
img = open_image(CR_FD_MNTS, O_SHOW, ids->mnt_ns_id);
if (img) {
pr_msg("-------------------MNTNS---------------------\n");
cr_parse_fd(img, imgset_template[CR_FD_MNTS].magic);
close_image(img);
}
pr_msg("---[ end of %d namespaces ]---\n", ns_pid);
return 0;
}
struct ns_desc pid_ns_desc = NS_DESC_ENTRY(CLONE_NEWPID, "pid");
struct ns_desc user_ns_desc = NS_DESC_ENTRY(CLONE_NEWUSER, "user");
......@@ -27,471 +27,6 @@
*/
#define PB_PKOBJ_LOCAL_SIZE 1024
#define INET_ADDR_LEN 40
typedef struct {
void *data;
int number;
int depth;
int count;
char fmt[32];
} pb_pr_field_t;
typedef struct {
void *arg;
int single_entry;
const char *pretty_fmt;
pb_pr_field_t cur;
} pb_pr_ctl_t;
typedef int (*pb_pr_show_t)(pb_pr_field_t *field);
/*
* This one describes how fields should be shown
* @fsize is the size of the field entry
* @show is the callback to print the entry
*/
struct pb_shower {
size_t fsize;
pb_pr_show_t show;
};
static int pb_msg_int32x(pb_pr_field_t *field)
{
pr_msg("%#x", *(int *)field->data);
return 0;
}
static int pb_msg_int64x(pb_pr_field_t *field)
{
pr_msg("%#016lx", *(long *)field->data);
return 0;
}
static int pb_msg_int64x_r(pb_pr_field_t *field)
{
long val = *(long *)field->data;
if (val)
pr_msg("%#016lx", val);
else
pr_msg("0");
return 0;
}
static int pb_msg_string(pb_pr_field_t *field)
{
pr_msg("\"%s\"", *(char **)field->data);
return 0;
}
static int pb_msg_unk(pb_pr_field_t *field)
{
pr_msg("unknown object %p", field->data);
return 0;
}
static inline void print_tabs(pb_pr_ctl_t *ctl)
{
int counter = ctl->cur.depth;
if (!ctl->single_entry)
return;
while (counter--)
pr_msg("\t");
}
static void print_nested_message_braces(pb_pr_ctl_t *ctl, int right_brace)
{
print_tabs(ctl);
pr_msg("%s%s", (right_brace) ? "}" : "{", (ctl->single_entry) ? "\n" : " ");
}
static void pb_show_msg(const void *msg, pb_pr_ctl_t *ctl);
static int show_nested_message(pb_pr_field_t *field)
{
pb_pr_ctl_t *ctl = container_of(field, pb_pr_ctl_t, cur);
void *arg = ctl->arg;
print_nested_message_braces(ctl, 0);
field->depth++;
pb_show_msg(field->data, ctl);
field->depth--;
print_nested_message_braces(ctl, 1);
ctl->arg = arg;
return 0;
}
static int show_enum(pb_pr_field_t *field)
{
pb_pr_ctl_t *ctl = container_of(field, pb_pr_ctl_t, cur);
ProtobufCEnumDescriptor *d = ctl->arg;
const char *val_name = NULL;
int val, i;
val = *(int *)field->data;
for (i = 0; i < d->n_values; i++)
if (d->values[i].value == val) {
val_name = d->values[i].name;
break;
}
if (val_name != NULL)
pr_msg("%s", val_name);
else
pr_msg("%d", val);
return 0;
}
static int show_bool(pb_pr_field_t *field)
{
protobuf_c_boolean val = *(protobuf_c_boolean *)field->data;
if (val)
pr_msg("True");
else
pr_msg("False");
return 0;
}
static int show_bytes(pb_pr_field_t *field)
{
ProtobufCBinaryData *bytes = (ProtobufCBinaryData *)field->data;
int i = 0;
while (i < bytes->len)
pr_msg("%02x ", bytes->data[i++]);
return 0;
}
static int pb_show_pretty(pb_pr_field_t *field)
{
switch (field->fmt[0]) {
case '%':
pr_msg(field->fmt, *(long *)field->data);
break;
case 'S':
{
ProtobufCBinaryData *name = (ProtobufCBinaryData *)field->data;
int i;
for (i = 0; i < name->len; i++) {
char c = (char)name->data[i];
if (isprint(c))
pr_msg("%c", c);
else if (c != 0)
pr_msg(".");
}
break;
}
case 'A':
{
char addr[INET_ADDR_LEN] = "<unknown>";
int family = (field->count == 1) ? AF_INET : AF_INET6;
if (inet_ntop(family, (void *)field->data, addr,
INET_ADDR_LEN) == NULL)
pr_msg("failed to translate");
else
pr_msg("%s", addr);
}
return 1;
}
return 0;
}
static void pb_copy_fmt(const char *fmt, char *to)
{
while (*fmt != ' ' && *fmt != '\0') {
*to = *fmt;
to++;
fmt++;
}
*to = '\0';
}
static const char *pb_next_pretty(const char *pfmt)
{
pfmt = strchr(pfmt, ' ');
if (pfmt) {
while (*pfmt == ' ')
pfmt++;
if (*pfmt == '\0')
pfmt = NULL;
}
return pfmt;
}
static int pb_find_fmt(char *what, pb_pr_ctl_t *ctl)
{
int len;
const char *pretty = ctl->pretty_fmt;
len = strlen(what);
while (1) {
if (!strncmp(pretty, what, len)) {
pb_copy_fmt(pretty + len, ctl->cur.fmt);
return 1;
}
pretty = pb_next_pretty(pretty + len);
if (!pretty)
return 0;
}
}
static int pb_field_show_pretty(const ProtobufCFieldDescriptor *fd, pb_pr_ctl_t *ctl)
{
char cookie[32];
if (!ctl->pretty_fmt)
return 0;
sprintf(cookie, "%s:", fd->name);
if (pb_find_fmt(cookie, ctl))
return 1;
if (!ctl->cur.depth)
sprintf(cookie, "%d:", ctl->cur.number);
else
sprintf(cookie, "%d.%d:", ctl->cur.depth, ctl->cur.number);
if (pb_find_fmt(cookie, ctl))
return 1;
sprintf(cookie, "*:");
if (pb_find_fmt(cookie, ctl))
return 1;
return 0;
}
static void pb_prepare_shower(const ProtobufCFieldDescriptor *fd,
pb_pr_ctl_t *ctl, struct pb_shower *sh)
{
sh->fsize = 0;
sh->show = pb_msg_unk;
switch (fd->type) {
case PROTOBUF_C_TYPE_INT32:
case PROTOBUF_C_TYPE_SINT32:
case PROTOBUF_C_TYPE_UINT32:
case PROTOBUF_C_TYPE_SFIXED32:
sh->fsize = 4;
sh->show = pb_msg_int32x;
break;
case PROTOBUF_C_TYPE_INT64:
case PROTOBUF_C_TYPE_SINT64:
case PROTOBUF_C_TYPE_SFIXED64:
case PROTOBUF_C_TYPE_FIXED32:
case PROTOBUF_C_TYPE_UINT64:
case PROTOBUF_C_TYPE_FIXED64:
sh->fsize = 8;
sh->show = (fd->label == PROTOBUF_C_LABEL_REPEATED ?
pb_msg_int64x_r : pb_msg_int64x);
break;
case PROTOBUF_C_TYPE_STRING:
sh->fsize = sizeof (void *);
sh->show = pb_msg_string;
break;
case PROTOBUF_C_TYPE_MESSAGE:
sh->fsize = sizeof (void *);
sh->show = show_nested_message;
ctl->arg = (void *)fd->descriptor;
break;
case PROTOBUF_C_TYPE_ENUM:
sh->fsize = 4;
sh->show = show_enum;
ctl->arg = (void *)fd->descriptor;
break;
case PROTOBUF_C_TYPE_BOOL:
sh->fsize = sizeof (protobuf_c_boolean);
sh->show = show_bool;
break;
case PROTOBUF_C_TYPE_BYTES:
sh->fsize = sizeof (ProtobufCBinaryData);
sh->show = show_bytes;
break;
case PROTOBUF_C_TYPE_FLOAT:
sh->fsize = 4;
break;
case PROTOBUF_C_TYPE_DOUBLE:
sh->fsize = 8;
break;
default:
BUG();
}
if (pb_field_show_pretty(fd, ctl))
sh->show = pb_show_pretty;
}
static void pb_show_repeated(const ProtobufCFieldDescriptor *fd,
pb_pr_ctl_t *ctl, struct pb_shower *sh)
{
pb_pr_field_t *field = &ctl->cur;
unsigned long i, nr_fields = field->count;
if (nr_fields == 0) {
pr_msg("<empty>");
return;
}
if (fd->type == PROTOBUF_C_TYPE_MESSAGE) {
void *p = field->data;
for (i = 0; i < nr_fields; i++) {
field->data = (void *)(*(long *)p);
sh->show(field);
p += sh->fsize;
}
return;
}
for (i = 0; i < nr_fields; i++) {
if (i)
pr_msg(":");
if (sh->show(field))
break;
field->data += sh->fsize;
}
}
static void pb_show_field(const ProtobufCFieldDescriptor *fd, pb_pr_ctl_t *ctl)
{
struct pb_shower sh;
print_tabs(ctl);
pr_msg("%s: ", fd->name);
pb_prepare_shower(fd, ctl, &sh);
pb_show_repeated(fd, ctl, &sh);
if (ctl->single_entry)
pr_msg("\n");
else
pr_msg(" ");
}
static int pb_optional_field_present(const ProtobufCFieldDescriptor *field,
const void *msg)
{
if ((field->type == PROTOBUF_C_TYPE_MESSAGE) ||
(field->type == PROTOBUF_C_TYPE_STRING)) {
const void *opt_flag = * (const void * const *)(msg + field->offset);
if ((opt_flag == NULL) || (opt_flag == field->default_value))
return 0;
} else {
const protobuf_c_boolean *has = msg + field->quantifier_offset;
if (!*has)
return 0;
}
return 1;
}
static bool should_show_field(const char *name)
{
char *s, *e;
int len;
if (!opts.show_fmt)
return true;
len = strlen(name);
s = opts.show_fmt;
while (1) {
e = strchrnul(s, ',');
if (e - s == len) {
if (!strncmp(name, s, len))
return true;
}
if (*e == '\0')
return false;
s = e + 1;
}
}
static void pb_show_msg(const void *msg, pb_pr_ctl_t *ctl)
{
int i;
const ProtobufCMessageDescriptor *md = ctl->arg;
BUG_ON(md == NULL);
for (i = 0; i < md->n_fields; i++) {
const ProtobufCFieldDescriptor fd = md->fields[i];
unsigned long *data;
size_t nr_fields;
nr_fields = 1;
data = (unsigned long *)(msg + fd.offset);
if (fd.label == PROTOBUF_C_LABEL_OPTIONAL) {
if (!pb_optional_field_present(&fd, msg))
continue;
}
if (!should_show_field(fd.name))
continue;
if (fd.label == PROTOBUF_C_LABEL_REPEATED) {
nr_fields = *(size_t *)(msg + fd.quantifier_offset);
data = (unsigned long *)*data;
}
ctl->cur.data = data;
ctl->cur.number = i + 1;
ctl->cur.count = nr_fields;
pb_show_field(&fd, ctl);
}
}
static inline void pb_no_payload(struct cr_img *i, void *obj) { }
void do_pb_show_plain(struct cr_img *img, int type, int single_entry,
void (*payload_hadler)(struct cr_img *, void *obj),
const char *pretty_fmt)
{
pb_pr_ctl_t ctl = {NULL, single_entry, pretty_fmt};
void (*handle_payload)(struct cr_img *, void *obj);
if (!cr_pb_descs[type].pb_desc) {
pr_err("Wrong object requested %d\n", type);
return;
}
handle_payload = (payload_hadler) ? : pb_no_payload;
while (1) {
void *obj;
if (pb_read_one_eof(img, &obj, type) <= 0)
break;
ctl.arg = (void *)cr_pb_descs[type].pb_desc;
pb_show_msg(obj, &ctl);
handle_payload(img, obj);
cr_pb_descs[type].free(obj, NULL);
if (single_entry)
break;
pr_msg("\n");
}
}
static char *image_name(struct cr_img *img)
{
int fd = img->_x.fd;
......
......@@ -179,12 +179,6 @@ err_brk:
return ret;
}
void sk_queue_data_handler(struct cr_img *img, void *obj)
{
SkPacketEntry *e = obj;
print_image_data(img, e->length, opts.show_pages_content);
}
int restore_sk_queue(int fd, unsigned int peer_id)
{
struct sk_packet *pkt, *tmp;
......
......@@ -21,7 +21,6 @@
#include "namespaces.h"
#include "xmalloc.h"
#include "config.h"
#include "cr-show.h"
#include "kerndat.h"
#include "rst-malloc.h"
......@@ -758,14 +757,3 @@ out:
return ret;
}
void show_tcp_stream(struct cr_img *img, void *obj)
{
TcpStreamEntry *e = obj;
if (opts.show_pages_content) {
pr_msg("In-queue:");
print_image_data(img, e->inq_len, 1);
pr_msg("Out-queue:");
print_image_data(img, e->outq_len, 1);
}
}
......@@ -11,7 +11,6 @@
#include "cr_options.h"
#include "imgset.h"
#include "protobuf.h"
#include "cr-show.h"
#include "string.h"
#include "files.h"
#include "files-reg.h"
......
......@@ -32,6 +32,7 @@
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <sched.h>
#include <ctype.h>
#include "compiler.h"
#include "asm/types.h"
......@@ -42,6 +43,7 @@
#include "vma.h"
#include "mem.h"
#include "namespaces.h"
#include "log.h"
#include "cr_options.h"
#include "servicefd.h"
......@@ -1000,3 +1002,75 @@ void tcp_nodelay(int sk, bool on)
int val = on ? 1 : 0;
setsockopt(sk, SOL_TCP, TCP_NODELAY, &val, sizeof(val));
}
static inline void pr_xsym(unsigned char *data, size_t len, int pos)
{
char sym;
if (pos < len)
sym = data[pos];
else
sym = ' ';
pr_msg("%c", isprint(sym) ? sym : '.');
}
static inline void pr_xdigi(unsigned char *data, size_t len, int pos)
{
if (pos < len)
pr_msg("%02x ", data[pos]);
else
pr_msg(" ");
}
static int nice_width_for(unsigned long addr)
{
int ret = 3;
while (addr) {
addr >>= 4;
ret++;
}
return ret;
}
void print_data(unsigned long addr, unsigned char *data, size_t size)
{
int i, j, addr_len;
unsigned zero_line = 0;
addr_len = nice_width_for(addr + size);
for (i = 0; i < size; i += 16) {
if (*(u64 *)(data + i) == 0 && *(u64 *)(data + i + 8) == 0) {
if (zero_line == 0)
zero_line = 1;
else {
if (zero_line == 1) {
pr_msg("*\n");
zero_line = 2;
}
continue;
}
} else
zero_line = 0;
pr_msg("%#0*lx: ", addr_len, addr + i);
for (j = 0; j < 8; j++)
pr_xdigi(data, size, i + j);
pr_msg(" ");
for (j = 8; j < 16; j++)
pr_xdigi(data, size, i + j);
pr_msg(" |");
for (j = 0; j < 8; j++)
pr_xsym(data, size, i + j);
pr_msg(" ");
for (j = 8; j < 16; j++)
pr_xsym(data, size, i + j);
pr_msg("|\n");
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment