Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 4613 → Rev 4616

/branches/snapshot/uspace/app/chkpnt/checkpoint.c
1,4 → 1,241
#include <stdlib.h>
#include <sysinfo.h>
#include <stdio.h>
#include <errno.h>
#include <sys/stat.h>
#include <vfs/vfs.h>
#include <unistd.h>
#include <fcntl.h>
#include <ipc/ipc.h>
#include <sys/types.h>
#include <malloc.h>
 
#include <udebug.h>
 
#define THBUF_SIZE 64
#define FILE_CHUNK_SIZE 250
 
int spawn_task(char* task, char *argv[]);
int write_to_disk(void *buffer, size_t n, char *filename);
int init_disk();
int connect_kbox(int task_id, int *kbox_phone_id);
int store_kstack(int kbox_phone_id, thash_t tid);
int store_thread_struct(int kbox_phone_id, thash_t tid);
int checkpoint(unsigned int kbox_phone_id_arg);
int write_uspace_mem_to_disk(unsigned *buffer, size_t n, uintptr_t start_addr, char *filename);
int store_uspace_memory_areas_to_disk(int kbox_phone_id);
 
 
int main(int argc, char **argv)
{
char *task = "/app/tetris";
char *argv_spawn[2];
argv_spawn[0] = task;
argv_spawn[1] = NULL;
 
int task_id = spawn_task(task, argv_spawn);
 
checkpoint(task_id);
 
return (0);
}
 
int checkpoint(unsigned int task_id)
{
/* Create the directories. */
init_disk();
 
int kbox_phone_id;
connect_kbox(task_id, &kbox_phone_id);
 
int dbg_ret;
dbg_ret = udebug_begin(kbox_phone_id);
 
uintptr_t thread_hash_buf[THBUF_SIZE];
size_t copied, needed;
udebug_thread_read(kbox_phone_id, thread_hash_buf, sizeof(thread_hash_buf), &copied, &needed);
 
printf("Press a key to store kstack contents...\n");
getchar();
store_kstack(kbox_phone_id, thread_hash_buf[0]);
 
printf("Press a key to store thread structure...\n");
getchar();
store_thread_struct(kbox_phone_id, thread_hash_buf[0]);
 
printf("Press a key to read and write uspace memory contents...\n");
getchar();
store_uspace_memory_areas_to_disk(kbox_phone_id);
 
printf("Press key to FINISH checkpointing...\n");
getchar();
 
int rc_end = udebug_end(kbox_phone_id);
printf("rc end: %i\n", rc_end);
 
}
 
int spawn_task(char* task, char *argv[])
{
int task_id = task_spawn(task, argv);
if (task_id <= 0)
printf("error spawning\n");
 
printf("spawned task %s with id: %i\n", task, task_id);
 
return (task_id);
}
 
int init_disk()
{
int rc;
if ((rc = mkdir("/mydir", 0)) != 0)
printf("mkdir() failed.\n");
 
return (rc);
}
 
int connect_kbox(int task_id, int *kbox_phone_id)
{
*kbox_phone_id = ipc_connect_kbox(task_id);
if (*kbox_phone_id == ENOTSUP)
printf("not suppported\n");
 
if (*kbox_phone_id < 0) {
printf("Error connecting\n");
printf("ipc_connect_task(%lld) -> %d ", task_id, *kbox_phone_id);
return (-1);
}
 
return (0);
}
 
int store_kstack(int kbox_phone_id, thash_t tid)
{
size_t copied, needed;
unsigned tmp[1];
udebug_thread_copy_kstack(kbox_phone_id, tid, tmp, sizeof(tmp), &copied, &needed);
 
void *kstack_buffer = malloc(needed);
udebug_thread_copy_kstack(kbox_phone_id, tid, kstack_buffer, needed, &copied, &needed);
 
write_to_disk(kstack_buffer, needed, "/mydir/kstack");
 
printf("size of kstack: %p\n", needed);
 
free(kstack_buffer);
 
return (0);
}
 
int store_thread_struct(int kbox_phone_id, thash_t tid)
{
size_t ts_copied, ts_needed, ts_needed_old;
 
udebug_thread_get_thread_struct(kbox_phone_id, tid, NULL, 0, &ts_copied, &ts_needed);
ts_needed_old = ts_needed;
void *thread_struct_buffer = malloc(ts_needed);
udebug_thread_get_thread_struct(kbox_phone_id, tid, thread_struct_buffer, ts_needed, &ts_copied, &ts_needed);
 
write_to_disk(thread_struct_buffer, ts_copied, "/mydir/ts");
 
free(thread_struct_buffer);
 
return (0);
}
 
int store_uspace_memory_areas_to_disk(int kbox_phone_id)
{
size_t mem_copied, mem_needed;
 
unsigned *mem_areas_buf = (unsigned *)malloc(sizeof(unsigned *) * THBUF_SIZE);
udebug_task_memory_areas_read(kbox_phone_id, mem_areas_buf, THBUF_SIZE*sizeof(unsigned), &mem_copied, &mem_needed);
int areas = mem_copied / sizeof(unsigned);
 
int i;
for (i=0; i<areas; i+=2)
{
size_t size = mem_areas_buf[i+1] - mem_areas_buf[i];
unsigned *mem_read_out = malloc(size);
udebug_mem_read(kbox_phone_id, mem_read_out, mem_areas_buf[i], size);
 
char file_name_buf[25];
snprintf(file_name_buf, 25, "/mydir/%i.mem", i);
 
printf("Writing area at %p to disk, size: %p.\n", mem_areas_buf[i], size);
write_uspace_mem_to_disk(mem_read_out, size, mem_areas_buf[i], file_name_buf);
 
free(mem_read_out);
}
 
return (0);
}
 
int write_uspace_mem_to_disk(unsigned *buffer, size_t n, uintptr_t start_addr, char *filename)
{
size_t chunk_size = FILE_CHUNK_SIZE*sizeof(unsigned);
unsigned written = 0;
int fd0 = open(filename, O_CREAT);
int cnt;
uintptr_t tmp[1];
tmp[0] = start_addr;
 
cnt = write(fd0, tmp, sizeof(tmp));
 
while (written < n)
{
if (n - written < chunk_size)
chunk_size = n - written;
cnt = write(fd0, buffer, chunk_size);
if (cnt < 0)
{
printf("Writing to uspace memory failed! Written %p bytes. Code: %i\n", written, cnt);
break;
}
buffer += (cnt / sizeof(unsigned));
written += cnt;
}
 
printf("Written %p bytes. End address: %p\n", written, (unsigned*)((unsigned)start_addr + written));
close(fd0);
 
return (0);
}
 
int write_to_disk(void *buffer, size_t n, char *filename)
{
size_t chunk_size = FILE_CHUNK_SIZE * sizeof(unsigned);
printf("Writing to disk, size: %p, filename: %s.\n", n, filename);
int fd0 = open(filename, O_CREAT);
size_t written = 0;
 
size_t tmp[1];
tmp[0] = n;
write(fd0, tmp, sizeof(tmp));
 
while (written < n)
{
if (n - written < chunk_size)
{
chunk_size = n - written;
}
int cnt = write(fd0, buffer, chunk_size);
if (cnt < 0)
{
printf("Write failed! Code: %i\n", cnt);
break;
}
buffer += cnt;
written += cnt;
}
 
printf("Written %p bytes.\n", written);
close(fd0);
 
return (0);
}
 
/branches/snapshot/uspace/lib/libc/include/udebug.h
52,6 → 52,13
sysarg_t *val0, sysarg_t *val1);
int udebug_stop(int phoneid, thash_t tid);
 
int udebug_thread_copy_kstack(int phoneid, thash_t tid, void *buffer, size_t buf_size, size_t *copied, size_t *needed);
int udebug_thread_get_thread_struct(int phoneid, thash_t tid, void *buffer, size_t n, size_t *copied, size_t *needed);
int udebug_task_memory_areas_read(int phoneid, void *buffer, size_t n, size_t *copied, size_t *needed);
int udebug_thread_restore_thread_struct(int phoneid, thash_t tid, void *buffer);
int udebug_mem_write(int phoneid, void* buffer, void* start, size_t n);
int udebug_restore_kstack(int phoneid, thash_t tid, void *buffer, size_t size);
 
#endif
 
/** @}
/branches/snapshot/uspace/lib/libc/generic/udebug.c
99,5 → 99,59
tid);
}
 
int udebug_thread_copy_kstack(int phoneid, thash_t tid, void *buffer, size_t buf_size, size_t *copied, size_t *needed)
{
size_t arg_copied, arg_needed;
 
int rc = async_req_4_3(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_THREAD_COPY_KSTACK, (sysarg_t)buffer, buf_size, tid, NULL, &arg_copied, &arg_needed);
 
*copied = arg_copied;
*needed = arg_needed;
 
return (rc);
}
 
int udebug_thread_get_thread_struct(int phoneid, thash_t tid, void *buffer, size_t n, size_t *copied, size_t *needed)
{
ipcarg_t a_copied, a_needed;
 
int rc = async_req_4_3(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_THREAD_GET_THREAD_STRUCT, (sysarg_t)buffer, tid, n, NULL, &a_copied, &a_needed);
 
*copied = (size_t)a_copied;
*needed = (size_t)a_needed;
 
return (rc);
}
 
int udebug_task_memory_areas_read(int phoneid, void *buffer, size_t n, size_t *copied, size_t *needed)
{
ipcarg_t a_copied, a_needed;
int rc;
 
rc = async_req_3_3(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_TASK_MEM_AREAS_READ,
(sysarg_t)buffer, n, NULL, &a_copied, &a_needed);
 
*copied = (size_t)a_copied;
*needed = (size_t)a_needed;
 
return (rc);
}
 
int udebug_thread_restore_thread_struct(int phoneid, thash_t tid, void *buffer)
{
int rc = async_req_3_0(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_THREAD_RESTORE_THREAD_STRUCT, (sysarg_t)buffer, tid);
return (rc);
}
 
int udebug_mem_write(int phoneid, void *buffer, void *start, size_t n)
{
return async_req_4_0(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_MEM_WRITE, (sysarg_t)buffer, n, (sysarg_t)start);
}
 
int udebug_restore_kstack(int phoneid, thash_t tid, void *buffer, size_t size)
{
return async_req_4_0(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_RESTORE_KSTACK, (sysarg_t)buffer, size, tid);
}
 
/** @}
*/