Commit 54f42f2b authored by Pavel Emelyanov's avatar Pavel Emelyanov

mount: Basic mount points dumping

Dumping is straightforward -- just copy all the mount_info
fields into the new image file. Dump everything but fstype,
this one will come in a separate patch.
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent e0cb53a1
...@@ -289,6 +289,17 @@ struct ipc_sem_entry { ...@@ -289,6 +289,17 @@ struct ipc_sem_entry {
u8 pad[6]; u8 pad[6];
} __packed; } __packed;
struct mnt_entry {
u32 mnt_id;
u32 root_dev;
u32 root_dentry_len;
u32 parent_mnt_id;
u32 mountpoint_path_len;
u32 flags;
u32 source_len;
u32 options_len;
} __packed;
#define VMA_AREA_NONE (0 << 0) #define VMA_AREA_NONE (0 << 0)
#define VMA_AREA_REGULAR (1 << 0) /* Dumpable area */ #define VMA_AREA_REGULAR (1 << 0) /* Dumpable area */
#define VMA_AREA_STACK (1 << 1) #define VMA_AREA_STACK (1 << 1)
......
...@@ -7,12 +7,15 @@ ...@@ -7,12 +7,15 @@
#include <errno.h> #include <errno.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <string.h> #include <string.h>
#include <stdlib.h>
#include "crtools.h"
#include "types.h" #include "types.h"
#include "util.h" #include "util.h"
#include "log.h" #include "log.h"
#include "mount.h" #include "mount.h"
#include "proc_parse.h" #include "proc_parse.h"
#include "image.h"
static struct mount_info *mntinfo; static struct mount_info *mntinfo;
...@@ -38,13 +41,111 @@ int collect_mount_info(void) ...@@ -38,13 +41,111 @@ int collect_mount_info(void)
return 0; return 0;
} }
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);
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;
}
int dump_mnt_ns(int ns_pid, struct cr_fdset *fdset) int dump_mnt_ns(int ns_pid, struct cr_fdset *fdset)
{ {
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; return -1;
xfree(pm);
pm = n;
} while (pm);
return 0;
} }
void show_mountpoints(int fd, struct cr_options *o) void show_mountpoints(int fd, struct cr_options *o)
{ {
struct mnt_entry me;
char buf[PATH_MAX];
pr_img_head(CR_FD_MOUNTPOINTS); pr_img_head(CR_FD_MOUNTPOINTS);
while (1) {
int ret;
ret = read_img_eof(fd, &me);
if (ret <= 0)
break;
pr_msg("%d:%d ", me.mnt_id, me.parent_mnt_id);
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);
}
pr_img_tail(CR_FD_MOUNTPOINTS); pr_img_tail(CR_FD_MOUNTPOINTS);
} }
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