2012-05-04 13:38:00 +04:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <sys/mman.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <dirent.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <string.h>
|
2012-06-27 20:57:31 +04:00
|
|
|
#include <stdlib.h>
|
2012-05-04 13:38:00 +04:00
|
|
|
|
2012-06-27 20:57:31 +04:00
|
|
|
#include "crtools.h"
|
2012-05-04 13:38:00 +04:00
|
|
|
#include "types.h"
|
|
|
|
#include "util.h"
|
2012-05-04 13:38:00 +04:00
|
|
|
#include "log.h"
|
2012-05-04 13:38:00 +04:00
|
|
|
#include "mount.h"
|
|
|
|
#include "proc_parse.h"
|
2012-06-27 20:57:31 +04:00
|
|
|
#include "image.h"
|
2012-05-04 13:38:00 +04:00
|
|
|
|
2012-06-27 20:57:30 +04:00
|
|
|
static struct mount_info *mntinfo;
|
2012-05-04 13:38:00 +04:00
|
|
|
|
|
|
|
int open_mount(unsigned int s_dev)
|
2012-05-04 13:38:00 +04:00
|
|
|
{
|
2012-06-27 20:57:30 +04:00
|
|
|
struct mount_info *i;
|
2012-05-04 13:38:00 +04:00
|
|
|
|
2012-05-13 00:07:11 +04:00
|
|
|
for (i = mntinfo; i != NULL; i = i->next)
|
|
|
|
if (s_dev == i->s_dev)
|
|
|
|
return open(i->mountpoint, O_RDONLY);
|
2012-05-04 13:38:00 +04:00
|
|
|
|
|
|
|
return -ENOENT;
|
|
|
|
}
|
2012-05-04 13:38:00 +04:00
|
|
|
|
|
|
|
int collect_mount_info(void)
|
|
|
|
{
|
2012-05-13 00:07:11 +04:00
|
|
|
mntinfo = parse_mountinfo(getpid());
|
|
|
|
if (!mntinfo) {
|
2012-05-04 13:38:00 +04:00
|
|
|
pr_err("Parsing mountinfo %d failed\n", getpid());
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2012-05-12 03:30:10 +04:00
|
|
|
|
2012-06-27 20:57:32 +04:00
|
|
|
static char *fstypes[] = {
|
|
|
|
"unsupported",
|
|
|
|
"proc",
|
|
|
|
"sysfs",
|
|
|
|
};
|
|
|
|
|
|
|
|
static u32 encode_fstype(char *fst)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This fn is required for two things.
|
|
|
|
* 1st -- to check supported filesystems (as just mounting
|
|
|
|
* anything is wrong, almost every fs has its own features)
|
|
|
|
* 2nd -- save some space in the image (since we scan all
|
|
|
|
* names anyway)
|
|
|
|
*/
|
|
|
|
|
|
|
|
for (i = 0; i < ARRAY_SIZE(fstypes); i++)
|
|
|
|
if (!strcmp(fstypes[i], fst))
|
|
|
|
return i;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static char *decode_fstype(u32 fst)
|
|
|
|
{
|
|
|
|
static char uns[12];
|
|
|
|
|
|
|
|
if (fst >= ARRAY_SIZE(fstypes)) {
|
|
|
|
sprintf(uns, "x%d", fst);
|
|
|
|
return uns;
|
|
|
|
}
|
|
|
|
|
|
|
|
return fstypes[fst];
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int is_root(char *p)
|
|
|
|
{
|
|
|
|
return p[0] == '/' && p[1] == '\0';
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int is_root_mount(struct mount_info *mi)
|
|
|
|
{
|
|
|
|
return is_root(mi->mountpoint);
|
|
|
|
}
|
|
|
|
|
2012-06-27 20:57:31 +04:00
|
|
|
static int dump_one_mountpoint(struct mount_info *pm, int fd)
|
|
|
|
{
|
|
|
|
struct mnt_entry me;
|
|
|
|
|
|
|
|
pr_info("\t%d: %x:%s @ %s\n", pm->mnt_id, pm->s_dev,
|
|
|
|
pm->root, pm->mountpoint);
|
|
|
|
|
|
|
|
me.mnt_id = pm->mnt_id;
|
|
|
|
me.root_dev = pm->s_dev;
|
|
|
|
me.root_dentry_len = strlen(pm->root);
|
|
|
|
me.parent_mnt_id = pm->parent_mnt_id;
|
|
|
|
me.mountpoint_path_len = strlen(pm->mountpoint);
|
2012-06-27 20:57:32 +04:00
|
|
|
me.fstype = encode_fstype(pm->fstype);
|
|
|
|
if (!me.fstype && !is_root_mount(pm)) {
|
|
|
|
pr_err("FS %s unsupported\n", pm->fstype);
|
|
|
|
return -1;
|
|
|
|
}
|
2012-06-27 20:57:31 +04:00
|
|
|
|
|
|
|
me.flags = pm->flags;
|
|
|
|
me.source_len = strlen(pm->source);
|
|
|
|
me.options_len = strlen(pm->options);
|
|
|
|
|
|
|
|
if (write_img(fd, &me))
|
|
|
|
return -1;
|
|
|
|
if (write_img_buf(fd, pm->root, me.root_dentry_len))
|
|
|
|
return -1;
|
|
|
|
if (write_img_buf(fd, pm->mountpoint, me.mountpoint_path_len))
|
|
|
|
return -1;
|
|
|
|
if (write_img_buf(fd, pm->source, me.source_len))
|
|
|
|
return -1;
|
|
|
|
if (write_img_buf(fd, pm->options, me.options_len))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-05-12 03:30:10 +04:00
|
|
|
int dump_mnt_ns(int ns_pid, struct cr_fdset *fdset)
|
|
|
|
{
|
2012-06-27 20:57:31 +04:00
|
|
|
struct mount_info *pm;
|
|
|
|
int img_fd;
|
|
|
|
|
|
|
|
pm = parse_mountinfo(ns_pid);
|
|
|
|
if (!pm) {
|
|
|
|
pr_err("Can't parse %d's mountinfo\n", ns_pid);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
pr_info("Dumping mountpoints\n");
|
|
|
|
|
|
|
|
img_fd = fdset_fd(fdset, CR_FD_MOUNTPOINTS);
|
|
|
|
do {
|
|
|
|
struct mount_info *n = pm->next;
|
|
|
|
|
|
|
|
if (dump_one_mountpoint(pm, img_fd))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
xfree(pm);
|
|
|
|
pm = n;
|
|
|
|
} while (pm);
|
|
|
|
|
|
|
|
return 0;
|
2012-05-12 03:30:10 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void show_mountpoints(int fd, struct cr_options *o)
|
|
|
|
{
|
2012-06-27 20:57:31 +04:00
|
|
|
struct mnt_entry me;
|
|
|
|
char buf[PATH_MAX];
|
|
|
|
|
2012-05-12 03:30:10 +04:00
|
|
|
pr_img_head(CR_FD_MOUNTPOINTS);
|
2012-06-27 20:57:31 +04:00
|
|
|
|
|
|
|
while (1) {
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = read_img_eof(fd, &me);
|
|
|
|
if (ret <= 0)
|
|
|
|
break;
|
|
|
|
|
2012-06-27 20:57:32 +04:00
|
|
|
pr_msg("%d:%d [%s] ", me.mnt_id, me.parent_mnt_id,
|
|
|
|
decode_fstype(me.fstype));
|
2012-06-27 20:57:31 +04:00
|
|
|
|
|
|
|
ret = read_img_buf(fd, buf, me.root_dentry_len);
|
|
|
|
if (ret < 0)
|
|
|
|
break;
|
|
|
|
|
|
|
|
buf[me.root_dentry_len] = '\0';
|
|
|
|
pr_msg("%d:%d %s ", kdev_major(me.root_dev),
|
|
|
|
kdev_minor(me.root_dev), buf);
|
|
|
|
|
|
|
|
ret = read_img_buf(fd, buf, me.mountpoint_path_len);
|
|
|
|
if (ret < 0)
|
|
|
|
break;
|
|
|
|
|
|
|
|
buf[me.mountpoint_path_len] = '\0';
|
|
|
|
pr_msg("@ %s ", buf);
|
|
|
|
|
|
|
|
pr_msg("flags %08x ", me.flags);
|
|
|
|
|
|
|
|
ret = read_img_buf(fd, buf, me.source_len);
|
|
|
|
if (ret < 0)
|
|
|
|
break;
|
|
|
|
|
|
|
|
buf[me.source_len] = '\0';
|
|
|
|
pr_msg("dev %s ", buf);
|
|
|
|
|
|
|
|
ret = read_img_buf(fd, buf, me.options_len);
|
|
|
|
if (ret < 0)
|
|
|
|
break;
|
|
|
|
|
|
|
|
buf[me.options_len] = '\0';
|
|
|
|
pr_msg("options %s\n", buf);
|
|
|
|
}
|
|
|
|
|
2012-05-12 03:30:10 +04:00
|
|
|
pr_img_tail(CR_FD_MOUNTPOINTS);
|
|
|
|
}
|