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
* get_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
);
71 void restore_memory_struct(struct file
*file
, struct header
*hdr
)
76 printk("Reading header: %d segments\n",hdr
->num_segments
);
78 ckpt_strncpy(current
->comm
, hdr
->comm
, 16);
81 current
->state
= TASK_INTERRUPTIBLE
;
85 printk("Restoring vm structure\n");
87 file
->f_op
->read(file
, (void*)&mem
, sizeof(struct memory
), &file
->f_pos
);
89 current
->mm
->start_code
= mem
.start_code
;
90 current
->mm
->end_code
= mem
.end_code
;
91 current
->mm
->start_data
= mem
.start_data
;
92 current
->mm
->end_data
= mem
.end_data
;
93 current
->mm
->start_brk
= mem
.start_brk
;
94 current
->mm
->brk
= mem
.brk
;
95 current
->mm
->start_stack
= mem
.start_stack
;
96 current
->mm
->arg_start
= mem
.arg_start
;
97 current
->mm
->arg_end
= mem
.arg_end
;
98 current
->mm
->env_start
= mem
.env_start
;
99 current
->mm
->env_end
= mem
.env_end
;
102 unsigned long restore_vm_areas(struct file
*file
, int count
, int from
)
107 unsigned long mmap_prot
, mmap_flags
, ret
= 0;
109 mm_segment_t fs
= get_fs();
112 printk("Restoring vm areas\n");
114 /* Map all the segments */
115 for (i
= 0; i
< count
; i
++) {
116 printk("Restoring vm areas for the %d time(s)\n", i
+ 1);
121 file
->f_op
->read(file
, (void*)&seg
, sizeof(struct segments
), &file
->f_pos
);
122 size
= seg
.vm_end
- seg
.vm_start
;
125 mmap_prot
= seg
.flags
& 7;
126 mmap_flags
= get_mmap_flags(seg
.flags
);
129 mmap_flags
&= ~VM_EXECUTABLE
;
133 int growsdown
= mmap_flags
& MAP_GROWSDOWN
;
135 mmap_flags
&= ~ MAP_DENYWRITE
;
137 mmap_flags
&= ~MAP_GROWSDOWN
;
139 ret
= do_mmap(file
, seg
.vm_start
, size
, mmap_prot
,
140 mmap_flags
| MAP_FIXED
, from
);
142 mmap_flags
|= MAP_GROWSDOWN
;
149 print_prot(mmap_prot
); print_flags(seg
.flags
);
150 mmap_flags
&= ~ MAP_DENYWRITE
;
151 mmap_flags
|= VM_EXECUTABLE
;
152 mfile
= open_private_file(0, seg
.filename
, O_RDONLY
,
153 mmap_prot
& PROT_WRITE
?3:1);
155 printk("open file %s error\n", seg
.filename
);
158 printk("size: %ld == pgoff: %ld\n", size
, seg
.pgoff
);
159 ret
= do_mmap(mfile
, seg
.vm_start
, size
,
160 mmap_prot
, mmap_flags
| MAP_FIXED
,
161 seg
.pgoff
* PAGE_SIZE
);
164 int growsdown
= mmap_flags
& MAP_GROWSDOWN
;
166 mmap_flags
&= ~ MAP_DENYWRITE
;
168 mmap_flags
&= ~MAP_GROWSDOWN
;
170 ret
= do_mmap(file
, seg
.vm_start
, size
, mmap_prot
,
171 mmap_flags
| MAP_FIXED
, from
);
173 mmap_flags
|= MAP_GROWSDOWN
;
179 if (ret
!= seg
.vm_start
) {
180 printk("Restart: Mapping error at map #%d.",i
+ 1);
181 printk("Sent %lX and got %X (%ld)\n",
182 seg
.vm_start
, (__u32
)ret
, (signed long)ret
);
186 printk("file mapped successfuly at: %p\n", (void *)ret
);
194 int restore_open_files(struct file
*file
)
196 struct open_files_hdr open_files_hdr
;
197 struct open_files open_files
;
202 printk("Restoring file table\n");
204 if (file
->f_op
->read(file
, (void*)&open_files_hdr
, sizeof(struct open_files_hdr
), &file
->f_pos
)
205 != sizeof(struct open_files_hdr
)) {
209 for (i
= 0; i
< open_files_hdr
.number_open_files
; i
++) {
213 if (file
->f_op
->read(file
, (void*)&open_files
, sizeof(struct open_files
), &file
->f_pos
)
214 != sizeof(struct open_files
)) {
218 fdes
= current
->files
->fdt
->fd
[open_files
.fd
];
219 inode
= fdes
->f_dentry
->d_inode
;
221 switch (open_files
.type
) {
224 /* We don't need to do anything, since
225 someone (restart) has already dupped/opened the
226 file. We just skip this entry.
229 file
->f_pos
+= open_files
.entry_size
- sizeof(struct open_files
);
231 /*! \todo Handle the case of restarting a pipe file. Refer to do_checkpoint()
237 !S_ISFIFO(inode->i_mode) ) {
238 printk("WARNING: restart: fd %d was not previously open or is not a pipe!!!\n",open_files.fd);
240 send_sig(SIGKILL, current, 0);
244 // Now read the information left in the pipe
245 if (open_files.entry_size>0) {
246 f->f_op->read(f, (void*)PIPE_BASE(*inode), open_files.entry_size, &f->f_pos);
247 PIPE_LEN(*inode)+=open_files.entry_size;
252 printk("Socket not supported\n");
261 void restore_signal(struct file
*file
)
264 struct sighand_struct sighand
;
268 printk("Restoring signal handlers\n");
270 file
->f_op
->read(file
, (void*)&blocked
, sizeof(sigset_t
), &file
->f_pos
);
271 file
->f_op
->read(file
, (void*)&sighand
, sizeof(sighand
), &file
->f_pos
);
273 spin_lock_irq(¤t
->sighand
->siglock
);
275 current
->blocked
= blocked
;
276 for (i
= 0; i
< _NSIG
; i
++)
277 current
->sighand
->action
[i
] = sighand
.action
[i
];
279 spin_unlock_irq(¤t
->sighand
->siglock
);
283 void restore_cwd(struct file
*file
)
288 file
->f_op
->read(file
, (void*)&size
, sizeof(int), &file
->f_pos
);