2013-11-05 12:33:03 +04:00
|
|
|
#ifndef __CR_VMA_H__
|
|
|
|
#define __CR_VMA_H__
|
|
|
|
|
2015-03-29 22:17:08 +03:00
|
|
|
#include "asm/types.h"
|
|
|
|
#include "image.h"
|
2013-11-06 15:33:40 +04:00
|
|
|
#include "list.h"
|
2015-03-29 22:17:08 +03:00
|
|
|
|
2013-11-06 15:44:32 +04:00
|
|
|
#include "protobuf/vma.pb-c.h"
|
2013-11-06 15:33:40 +04:00
|
|
|
|
2013-11-05 12:33:03 +04:00
|
|
|
struct vm_area_list {
|
|
|
|
struct list_head h;
|
|
|
|
unsigned nr;
|
2014-12-19 16:01:54 +03:00
|
|
|
unsigned int nr_aios;
|
2013-11-05 12:33:03 +04:00
|
|
|
unsigned long priv_size; /* nr of pages in private VMAs */
|
|
|
|
unsigned long longest; /* nr of pages in longest VMA */
|
|
|
|
};
|
|
|
|
|
|
|
|
#define VM_AREA_LIST(name) struct vm_area_list name = { .h = LIST_HEAD_INIT(name.h), .nr = 0, }
|
|
|
|
|
2014-02-03 15:12:22 +04:00
|
|
|
static inline void vm_area_list_init(struct vm_area_list *vml)
|
|
|
|
{
|
|
|
|
INIT_LIST_HEAD(&vml->h);
|
|
|
|
vml->nr = 0;
|
|
|
|
vml->priv_size = 0;
|
|
|
|
vml->longest = 0;
|
|
|
|
}
|
|
|
|
|
2014-02-07 13:51:29 +04:00
|
|
|
struct file_desc;
|
|
|
|
|
2013-11-05 12:33:03 +04:00
|
|
|
struct vma_area {
|
|
|
|
struct list_head list;
|
2014-02-04 00:08:16 +04:00
|
|
|
VmaEntry *e;
|
2013-11-05 12:33:03 +04:00
|
|
|
|
|
|
|
union {
|
2014-09-23 20:31:16 +04:00
|
|
|
struct /* for dump */ {
|
|
|
|
union {
|
2014-09-23 20:31:46 +04:00
|
|
|
/*
|
|
|
|
* These two cannot be assigned at once.
|
|
|
|
* The file_fd is an fd for a regular file and
|
|
|
|
* the socket_id is the inode number of the
|
|
|
|
* mapped (PF_PACKET) socket.
|
2014-12-19 16:01:54 +03:00
|
|
|
*
|
|
|
|
* The aio_nr_req is only for aio rings.
|
2014-09-23 20:31:46 +04:00
|
|
|
*/
|
2014-09-23 20:31:16 +04:00
|
|
|
int vm_file_fd;
|
|
|
|
int vm_socket_id;
|
2014-12-19 16:01:54 +03:00
|
|
|
unsigned int aio_nr_req;
|
2014-09-23 20:31:16 +04:00
|
|
|
};
|
2013-11-22 18:19:08 +04:00
|
|
|
|
2014-09-23 20:31:16 +04:00
|
|
|
char *aufs_rpath; /* path from aufs root */
|
|
|
|
char *aufs_fpath; /* full path from global root */
|
2014-01-31 20:31:06 +04:00
|
|
|
|
2014-09-23 20:31:46 +04:00
|
|
|
/*
|
|
|
|
* When several subsequent vmas have the same
|
|
|
|
* dev:ino pair all 'tail' ones set this to true
|
|
|
|
* and the vmst points to the head's stat buf.
|
|
|
|
*/
|
2014-09-23 20:31:16 +04:00
|
|
|
bool file_borrowed;
|
|
|
|
struct stat *vmst;
|
2014-09-23 20:32:00 +04:00
|
|
|
int mnt_id;
|
2014-09-23 20:31:16 +04:00
|
|
|
};
|
2014-02-03 00:18:32 +04:00
|
|
|
|
2014-09-23 20:31:16 +04:00
|
|
|
struct /* for restore */ {
|
|
|
|
struct file_desc *vmfd;
|
|
|
|
unsigned long *page_bitmap; /* existent pages */
|
|
|
|
unsigned long *ppage_bitmap; /* parent's existent pages */
|
|
|
|
unsigned long premmaped_addr; /* restore only */
|
|
|
|
};
|
|
|
|
};
|
2013-11-05 12:33:03 +04:00
|
|
|
};
|
|
|
|
|
2014-01-31 20:57:11 +04:00
|
|
|
extern struct vma_area *alloc_vma_area(void);
|
2013-11-15 14:04:48 +04:00
|
|
|
extern int collect_mappings(pid_t pid, struct vm_area_list *vma_area_list);
|
|
|
|
extern void free_mappings(struct vm_area_list *vma_area_list);
|
2013-11-05 12:33:03 +04:00
|
|
|
|
2014-02-04 00:08:16 +04:00
|
|
|
#define vma_area_is(vma_area, s) vma_entry_is((vma_area)->e, s)
|
|
|
|
#define vma_area_len(vma_area) vma_entry_len((vma_area)->e)
|
2013-11-05 12:33:03 +04:00
|
|
|
#define vma_entry_is(vma, s) (((vma)->status & (s)) == (s))
|
|
|
|
#define vma_entry_len(vma) ((vma)->end - (vma)->start)
|
|
|
|
|
2013-11-22 18:19:08 +04:00
|
|
|
/*
|
|
|
|
* vma_premmaped_start() can be used only in restorer.
|
|
|
|
* In other cases vma_area->premmaped_addr must be used.
|
|
|
|
* This hack is required, because vma_area isn't tranfered in restorer and
|
|
|
|
* shmid is used to determing which vma-s are cowed.
|
|
|
|
*/
|
|
|
|
#define vma_premmaped_start(vma) ((vma)->shmid)
|
|
|
|
|
2013-11-05 12:33:03 +04:00
|
|
|
static inline int in_vma_area(struct vma_area *vma, unsigned long addr)
|
|
|
|
{
|
2014-02-04 00:08:16 +04:00
|
|
|
return addr >= (unsigned long)vma->e->start &&
|
|
|
|
addr < (unsigned long)vma->e->end;
|
2013-11-05 12:33:03 +04:00
|
|
|
}
|
|
|
|
|
2015-07-31 10:36:26 -04:00
|
|
|
static inline bool vma_entry_is_private(VmaEntry *entry,
|
|
|
|
unsigned long task_size)
|
2015-03-29 22:17:08 +03:00
|
|
|
{
|
|
|
|
return vma_entry_is(entry, VMA_AREA_REGULAR) &&
|
|
|
|
(vma_entry_is(entry, VMA_ANON_PRIVATE) ||
|
|
|
|
vma_entry_is(entry, VMA_FILE_PRIVATE)) &&
|
2015-07-31 10:36:26 -04:00
|
|
|
(entry->end <= task_size);
|
2015-03-29 22:17:08 +03:00
|
|
|
}
|
|
|
|
|
2015-07-31 10:36:26 -04:00
|
|
|
static inline bool vma_area_is_private(struct vma_area *vma,
|
|
|
|
unsigned long task_size)
|
2015-03-29 22:17:08 +03:00
|
|
|
{
|
2015-07-31 10:36:26 -04:00
|
|
|
return vma_entry_is_private(vma->e, task_size);
|
2015-03-29 22:17:08 +03:00
|
|
|
}
|
|
|
|
|
2013-11-15 14:04:45 +04:00
|
|
|
#endif /* __CR_VMA_H__ */
|