2 #include <linux/kernel.h>
3 #include <linux/module.h>
5 #include <linux/cdev.h>
6 #include <linux/binfmts.h>
8 #include <asm/uaccess.h>
9 #include <linux/file.h>
10 #include <linux/sys.h>
16 #include <linux/mount.h>
17 #include <linux/swapops.h>
18 #include <linux/sched.h>
21 struct header
* restore_header_struct(struct file
*file
)
23 static struct header hdr
;
27 ret
= file
->f_op
->read(file
, (char*)&hdr
, sizeof(hdr
), &file
->f_pos
);
29 if ((ret
!= sizeof(hdr
)) || ckpt_strncmp(hdr
.signature
, "CKPT", 4) ||
30 hdr
.major_version
!= CKPT_MAJOR
||
31 hdr
.minor_version
!= CKPT_MINOR
) {
32 printk("Invalid checkpoint file\n");
37 if (((hdr
.uid
!= current
->euid
&& hdr
.uid
!= current
->uid
)
38 && (current
->uid
&& current
->euid
)))
43 if (current
->uid
== 0 || current
->euid
== 0) {
44 current
->uid
= hdr
.uid
;
45 current
->euid
= hdr
.euid
;
46 current
->suid
= hdr
.suid
;
47 current
->fsuid
= hdr
.fsuid
;
48 current
->gid
= hdr
.gid
;
49 current
->egid
= hdr
.egid
;
50 current
->sgid
= hdr
.sgid
;
51 current
->fsgid
= hdr
.fsgid
;
52 current
->group_info
->ngroups
= hdr
.ngroups
;
58 struct pt_regs
* restore_registers(struct file
*file
)
60 static struct pt_regs regs
;
63 printk("Restoring registers\n");
66 file
->f_op
->read(file
, (void*)®s
, sizeof(regs
), &file
->f_pos
);
67 memcpy(task_pt_regs(current
), ®s
, sizeof(regs
));
68 printk("REGISTERS:::TEST::: CS:%08x, SS:%08x, EIP:%p\n", regs
.cs
, regs
.ss
, (void*)regs
.ip
);
72 void restore_memory_struct(struct file
*file
, struct header
*hdr
)
77 printk("Reading header: %d segments\n",hdr
->num_segments
);
79 ckpt_strncpy(current
->comm
, hdr
->comm
, 16);
82 current
->state
= TASK_INTERRUPTIBLE
;
86 printk("Restoring vm structure\n");
88 file
->f_op
->read(file
, (void*)&mem
, sizeof(struct memory
), &file
->f_pos
);
90 current
->mm
->start_code
= mem
.start_code
;
91 current
->mm
->end_code
= mem
.end_code
;
92 current
->mm
->start_data
= mem
.start_data
;
93 current
->mm
->end_data
= mem
.end_data
;
94 current
->mm
->start_brk
= mem
.start_brk
;
95 current
->mm
->brk
= mem
.brk
;
96 current
->mm
->start_stack
= mem
.start_stack
;
97 current
->mm
->arg_start
= mem
.arg_start
;
98 current
->mm
->arg_end
= mem
.arg_end
;
99 current
->mm
->env_start
= mem
.env_start
;
100 current
->mm
->env_end
= mem
.env_end
;
103 unsigned long restore_vm_areas(struct file
*file
, int count
, int from
)
108 unsigned long mmap_prot
, mmap_flags
, ret
= 0;
110 mm_segment_t fs
= get_fs();
113 printk("Restoring vm areas\n");
115 /* Map all the segments */
116 for (i
= 0; i
< count
; i
++) {
117 printk("Restoring vm areas for the %d time(s)\n", i
+ 1);
122 file
->f_op
->read(file
, (void*)&seg
, sizeof(struct segments
), &file
->f_pos
);
123 size
= seg
.vm_end
- seg
.vm_start
;
126 mmap_prot
= seg
.flags
& 7;
127 mmap_flags
= get_mmap_flags(seg
.flags
);
130 mmap_flags
&= ~VM_EXECUTABLE
;
134 int growsdown
= mmap_flags
& MAP_GROWSDOWN
;
136 mmap_flags
&= ~ MAP_DENYWRITE
;
138 mmap_flags
&= ~MAP_GROWSDOWN
;
140 ret
= do_mmap(file
, seg
.vm_start
, size
, mmap_prot
,
141 mmap_flags
| MAP_FIXED
, from
);
143 mmap_flags
|= MAP_GROWSDOWN
;
150 mmap_flags
&= ~ MAP_DENYWRITE
;
151 mfile
= open_private_file(0, seg
.filename
, O_RDONLY
,
152 mmap_prot
& PROT_WRITE
?3:1);
153 ret
= do_mmap(mfile
, seg
.vm_start
, size
, mmap_prot
,
154 mmap_flags
| MAP_FIXED
, seg
.pgoff
);
157 int growsdown
= mmap_flags
& MAP_GROWSDOWN
;
159 mmap_flags
&= ~ MAP_DENYWRITE
;
161 mmap_flags
&= ~MAP_GROWSDOWN
;
163 ret
= do_mmap(file
, seg
.vm_start
, size
, mmap_prot
,
164 mmap_flags
| MAP_FIXED
, from
);
166 mmap_flags
|= MAP_GROWSDOWN
;
172 if (ret
!= seg
.vm_start
) {
173 printk("Restart: Mapping error at map #%d.",i
+ 1);
174 printk("Sent %lX and got %X (%ld)\n",
175 seg
.vm_start
, (__u32
)ret
, (signed long)ret
);
179 printk("file mapped successfuly at: %p\n", (void *)ret
);
187 int restore_open_files(struct file
*file
)
189 struct open_files_hdr open_files_hdr
;
190 struct open_files open_files
;
195 printk("Restoring file table\n");
197 if (file
->f_op
->read(file
, (void*)&open_files_hdr
, sizeof(struct open_files_hdr
), &file
->f_pos
)
198 != sizeof(struct open_files_hdr
)) {
202 for (i
= 0; i
< open_files_hdr
.number_open_files
; i
++) {
206 if (file
->f_op
->read(file
, (void*)&open_files
, sizeof(struct open_files
), &file
->f_pos
)
207 != sizeof(struct open_files
)) {
211 fdes
= current
->files
->fdt
->fd
[open_files
.fd
];
212 inode
= fdes
->f_dentry
->d_inode
;
214 switch (open_files
.type
) {
217 /* We don't need to do anything, since
218 someone (restart) has already dupped/opened the
219 file. We just skip this entry.
222 file
->f_pos
+= open_files
.entry_size
- sizeof(struct open_files
);
224 /*! \todo Handle the case of restarting a pipe file. Refer to do_checkpoint()
230 !S_ISFIFO(inode->i_mode) ) {
231 printk("WARNING: restart: fd %d was not previously open or is not a pipe!!!\n",open_files.fd);
233 send_sig(SIGKILL, current, 0);
237 // Now read the information left in the pipe
238 if (open_files.entry_size>0) {
239 f->f_op->read(f, (void*)PIPE_BASE(*inode), open_files.entry_size, &f->f_pos);
240 PIPE_LEN(*inode)+=open_files.entry_size;
245 printk("Socket not supported\n");
254 void restore_signal(struct file
*file
)
257 struct sighand_struct sighand
;
261 printk("Restoring signal handlers\n");
263 file
->f_op
->read(file
, (void*)&blocked
, sizeof(sigset_t
), &file
->f_pos
);
264 file
->f_op
->read(file
, (void*)&sighand
, sizeof(sighand
), &file
->f_pos
);
266 spin_lock_irq(¤t
->sighand
->siglock
);
268 current
->blocked
= blocked
;
269 for (i
= 0; i
< _NSIG
; i
++)
270 current
->sighand
->action
[i
] = sighand
.action
[i
];
272 spin_unlock_irq(¤t
->sighand
->siglock
);
276 void restore_cwd(struct file
*file
)
281 file
->f_op
->read(file
, (void*)&size
, sizeof(int), &file
->f_pos
);