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>
23 * Write a packet of data to a file.
25 int pack_write(struct file
*f
, char *buf
,
26 int len
, int last_pkt
, int flag
)
28 static char *pack
= NULL
;
30 int ret
, to_copy
, wrtn
= 0;
33 if (!(pack
=(char*)kmalloc(PACKET_SIZE
, GFP_KERNEL
)))
38 to_copy
= (len
>(PACKET_SIZE
-pos
))?(PACKET_SIZE
-pos
):(len
);
41 copy_from_user(&(pack
[pos
]), buf
+wrtn
, to_copy
);
43 ckpt_strncpy(&(pack
[pos
]), buf
+wrtn
, to_copy
);
49 // If we've reached the last data.
50 if ( (pos
==PACKET_SIZE
) || (last_pkt
) ) {
51 mm_segment_t fs
= get_fs();
54 ret
= f
->f_op
->write(f
, pack
, pos
, &(f
->f_pos
));
67 if ( (last_pkt
) && (pack
!=NULL
) ) {
69 mm_segment_t fs
= get_fs();
72 wrtn
= f
->f_op
->write(f
, pack
, pos
, &f
->f_pos
);
85 void dump_header_struct(struct file
*file
, struct task_struct
*p
, int in_sys_call
)
89 ckpt_strncpy(hdr
.signature
, "CKPT", 4);
90 hdr
.major_version
= CKPT_MAJOR
;
91 hdr
.minor_version
= CKPT_MINOR
;
92 hdr
.num_segments
= p
->mm
->map_count
;
103 hdr
.fsgid
= p
->fsgid
;
104 hdr
.ngroups
= p
->group_info
->ngroups
;
105 hdr
.in_sys_call
= in_sys_call
;
106 ckpt_strncpy(hdr
.comm
, p
->comm
, 16);
109 pack_write(file
, (void*)&hdr
, sizeof(struct header
), 0, FROM_KERNEL
);
112 void dump_memory_struct(struct file
*file
, struct task_struct
*p
)
114 struct mm_struct
*mm
= p
->mm
;
118 printk("Saving vm structure\n");
121 mem
.start_code
= mm
->start_code
;
122 mem
.end_code
= mm
->end_code
;
123 mem
.start_data
= mm
->start_data
;
124 mem
.end_data
= mm
->end_data
;
125 mem
.start_brk
= mm
->start_brk
;
127 mem
.start_stack
= mm
->start_stack
;
128 mem
.arg_start
= mm
->arg_start
;
129 mem
.arg_end
= mm
->arg_end
;
130 mem
.env_start
= mm
->env_start
;
131 mem
.env_end
= mm
->env_end
;
134 pack_write(file
, (void*)&mem
, sizeof(struct memory
), 0, FROM_KERNEL
);
137 static inline int should_dump(unsigned long flags
)
139 if (!(flags
& VM_WRITE
) || (flags
& VM_MAYSHARE
))
145 void dump_segments(struct file
*file
, struct mm_struct
*mm
, int memleft
)
148 struct vm_area_struct
*vm
= mm
->mmap
;
154 printk("Saving segments\n");
155 if (!(buffer
= kmalloc(PAGE_SIZE
, GFP_KERNEL
)))
158 for (; vm
; vm
= vm
->vm_next
) {
159 seg
.vm_start
= vm
->vm_start
;
160 seg
.vm_end
= vm
->vm_end
;
161 seg
.prot
= vm
->vm_page_prot
.pgprot
;
162 seg
.flags
= vm
->vm_flags
;
164 seg
.pgoff
= vm
->vm_pgoff
;
167 if (!should_dump(seg
.flags
)) {
171 pth
.mnt
= vm
->vm_file
->f_vfsmnt
;
172 pth
.dentry
= vm
->vm_file
->f_dentry
;
173 line
= d_path(&pth
, buffer
, PAGE_SIZE
);
174 buffer
[PAGE_SIZE
-1] = 0;
176 ckpt_strncpy(seg
.filename
, line
, CKPT_MAX_FILENAME
);
180 pack_write(file
, (void*)&seg
, sizeof(struct segments
), 0, FROM_KERNEL
);
182 if (memleft
< sizeof(struct segments
))
183 memleft
= PAGE_SIZE
+ memleft
;
184 memleft
-= sizeof(struct segments
);
188 * Dump the padding so the header is a mutiple of a page size,
189 * that's what the memleft is used for.
193 padbuf
= (char*)kmalloc(memleft
, GFP_KERNEL
);
194 pack_write(file
, padbuf
, memleft
, 0, FROM_KERNEL
);
201 static char *prot_str
[] = {"PROT_READ", "PROT_WRITE", "PROT_EXEC"};
202 static void print_prot(uint32_t prot
)
209 printk("%s ", prot_str
[i
]);
214 static void print_flags(uint32_t flags
)
216 flags
= get_mmap_flags(flags
);
218 if (flags
& MAP_SHARED
)
219 printk("MAP_SHARED ");
221 printk("MAP_PRIVATE ");
223 if (flags
& MAP_FIXED
)
224 printk("MAP_FIXED ");
225 if (flags
& MAP_ANONYMOUS
)
226 printk("MAP_ANONYMOUS ");
229 if (flags
& MAP_GROWSDOWN
)
230 printk("MAP_GROWSDOWN ");
231 if (flags
& MAP_DENYWRITE
)
232 printk("MAP_DENYWRITE ");
233 if (flags
& MAP_EXECUTABLE
)
234 printk("MAP_EXECUTABLE ");
235 if (flags
& MAP_LOCKED
)
236 printk("MAP_LOCKED ");
237 if (flags
& MAP_POPULATE
)
238 printk("MAP_POPULATE ");
239 if (flags
& MAP_NONBLOCK
)
240 printk("MAP_NONBLOCK ");
244 * Dump vm area to file.
246 static void dump_vm_area(struct file
*f
, struct task_struct
*p
,
247 struct vm_area_struct
*vm
)
250 unsigned long addr
= vm
->vm_start
;
254 printk(":::Saving the vm_area for the %d time(s)", ++i
);
255 printk(":::%d page(s)\n", (int)(vm
->vm_end
- vm
->vm_start
+ PAGE_SIZE
- 1) >> 12);
257 /* we may write to the pgtable */
258 down_write(&p
->mm
->mmap_sem
);
260 while (addr
< vm
->vm_end
) {
261 data
= get_kernel_address(p
, vm
, addr
);
264 if ((unsigned long)data
& ~PAGE_MASK
)
265 printk("Warning: address %p not aligned!\n", data
);
267 if (pack_write(f
, (void*)data
, PAGE_SIZE
, 0, FROM_KERNEL
) != PAGE_SIZE
)
268 printk("Warning: not all dumped\n");
275 up_write(&p
->mm
->mmap_sem
);
276 printk("::::::%d pages saved:::\n", j
);
281 void dump_vm_areas(struct file
*file
, struct task_struct
*p
)
283 struct vm_area_struct
*vm
= p
->mm
->mmap
;
286 printk("Saving vm areas, we have %d vm areas\n", p
->mm
->map_count
);
288 for (; vm
; vm
= vm
->vm_next
) {
290 printk("0x%08x - 0x%08x ", (u32
)vm
->vm_start
, (u32
)vm
->vm_end
);
291 print_prot( vm
->vm_page_prot
.pgprot
);
292 print_flags(vm
->vm_flags
);
295 if (should_dump(vm
->vm_flags
) && vm
->vm_file
)
296 dump_vm_area(file
, p
, vm
);
300 void dump_registers(struct file
*file
, struct task_struct
*p
, struct pt_regs
*regs
, int in_sys_call
)
303 printk("Saving registers\n");
306 /* avoid inifinte loop! */
308 } else if (in_sys_call
) {
309 /* If we are in a system call, we must restart it */
314 pack_write(file
, (void *)regs
, sizeof(*regs
), 0, FROM_KERNEL
);
318 int get_file_cnt(struct task_struct
*p
, struct files_struct
*files
)
327 if (fds
>= files
->fdt
->max_fds
)
329 set
= files
->fdt
->open_fds
->fds_bits
[j
++];
332 if (ckpt_icheck_task(p
, fds
)) {
345 int dump_open_files(struct file
*file
, struct task_struct
*p
, struct files_struct
*files
, int *size
)
347 struct open_files_hdr open_files_hdr
;
348 struct open_files open_files
;
349 struct ckpt_fdcache_struct
*fdcache
;
350 char buffer
[PAGE_SIZE
];
353 int fdcache_size
= 0;
354 int file_cnt
= get_file_cnt(p
, files
);
359 printk("Saving file table\n");
360 printk("max_fds = %d\n", files
->fdt
->max_fds
);
361 printk("%d named opened files\n", file_cnt
);
364 open_files_hdr
.number_open_files
= file_cnt
;
365 pack_write(file
, (void*)&open_files_hdr
, sizeof(struct open_files_hdr
), 0, FROM_KERNEL
);
367 if (! (fdcache
= kmalloc(sizeof(struct ckpt_fdcache_struct
) * file_cnt
, GFP_KERNEL
)))
370 /* Now we dump them */
373 if (fds
>= files
->fdt
->max_fds
)
375 set
= files
->fdt
->open_fds
->fds_bits
[j
++];
378 struct file
*fdes
= fcheck_files(files
, fds
);
379 struct dentry
*dent
= fdes
? fdes
->f_dentry
: NULL
;
380 struct inode
*inode
= dent
? dent
->d_inode
: NULL
;
388 // check whether this inode has appeared before
389 for (i
= 0; i
< fdcache_size
; i
++) {
390 if (inode
== fdcache
[i
].inode
) {
393 printk("fd %d is a dup of fd %d\n", (int)fds
, fdcache
[i
].fd
);
394 open_files
.type
= CKPT_DUP
;
395 open_files
.u
.dup
.dupfd
= fdcache
[i
].fd
;
396 open_files
.entry_size
= sizeof(struct open_files
);
397 pack_write(file
, (void*)&open_files
, sizeof(struct open_files
), 0, FROM_KERNEL
);
398 struct_size
+= open_files
.entry_size
;
403 // if not a dup, push to the cache
404 fdcache
[fdcache_size
].fd
= fds
;
405 fdcache
[fdcache_size
].inode
= inode
;
409 printk("fd %d has no entry\n", fds
);
410 } else if (S_ISSOCK(inode
->i_mode
)) {
411 printk("fd %d is socket - unsupported\n", fds
);
413 } else if (IS_FD_NAMED(fdes
)) { /* *** REGULAR FILE *** */
415 pth
.mnt
= mntget(fdes
->f_vfsmnt
);
416 pth
.dentry
= dget(dent
);
417 line
= d_path(&pth
, buffer
, PAGE_SIZE
);
418 buffer
[PAGE_SIZE
-1] = 0;
422 open_files
.type
= CKPT_FILE
;
424 open_files
.u
.file
.file
= (unsigned long)fdes
;
425 open_files
.u
.file
.flags
= fdes
->f_flags
;
426 open_files
.u
.file
.mode
= fdes
->f_mode
;
427 open_files
.u
.file
.file_pos
= fdes
->f_pos
;
428 open_files
.entry_size
= buffer
+ PAGE_SIZE
- line
+
429 sizeof(struct open_files
);
430 pack_write(file
, (void*)&open_files
, sizeof(struct open_files
), 0, FROM_KERNEL
);
433 printk("fd %02d: %04d: %08ld: %s \n", fds
, open_files
.entry_size
,
434 open_files
.u
.file
.file_pos
, line
);
436 pack_write(file
, (void*)line
, open_files
.entry_size
- sizeof(struct open_files
), 0, FROM_KERNEL
);
438 struct_size
+= open_files
.entry_size
;
441 printk("Unknown file type, cannot handle\n");
455 void dump_cwd(struct file
*file
, struct task_struct
*p
, int *res
)
458 char buffer
[PAGE_SIZE
];
462 pth
.dentry
= dget(p
->fs
->pwd
.dentry
);
463 pth
.mnt
= mntget(p
->fs
->pwd
.mnt
);
464 line
= d_path(&pth
, buffer
, PAGE_SIZE
);
465 buffer
[PAGE_SIZE
-1] = 0;
466 size
= buffer
+ PAGE_SIZE
- line
;
471 printk("saving cwd: %s\n", line
);
472 pack_write(file
, (void *)&size
, sizeof(size
), 0, FROM_KERNEL
);
473 pack_write(file
, (void *)line
, size
, 0, FROM_KERNEL
);
475 *res
= size
+ sizeof(size
);
478 void dump_signal(struct file
*file
, struct task_struct
*p
, int *size
)
481 struct signal_struct sig
;
482 unsigned long * signal
= (unsigned long *)&p
->pending
.signal
;
485 printk("Saving signal handlers\n");
487 spin_lock_irq(&p
->sighand
->siglock
);
490 /* ignore SIGSTOP/SIGCONT */
491 if ((_NSIG_WORDS
== 2 && signal
[0]) & ~(0x60000L
|| signal
[1]))
492 printk("pending signals not saved: %08lx %08lx\n",
493 signal
[0], signal
[1]);
495 blocked
= p
->blocked
;
498 spin_unlock_irq(&p
->sighand
->siglock
);
500 pack_write(file
, (void*)&blocked
, sizeof(blocked
), 0, FROM_KERNEL
);
501 pack_write(file
, (void*)&sig
, sizeof(sig
), 0, FROM_KERNEL
);
502 *size
= sizeof(blocked
) + sizeof(sig
);
505 void write_end(struct file
*file
)
507 pack_write(file
, NULL
, 0, 1, FROM_KERNEL
); /* last packet */