/******* --About nosparse.cpp-- Preventing fragmentation of ".vmem" file of VMware Server 1.0.x on Linux(32 or 64bit) Generating .vmem file as a normal file, not as a sparse file. This code is based on the "hook_tcp.cpp" by Yoggy(http://www.t-dori.net/?hook_tcp.so) Special thanx to Yoggy and Team t-dori! --How to use-- Compile: ***!! you need to compile this code on the 32 bit Linux box !!*** g++ -Wall -fPIC -shared -o nosparse.so nosparse.cpp -ldl Run: example_shell> LD_PRELOAD=/root/vmware/nosparse.so /usr/lib/vmware/bin/vmware-vmx -x -C /vmware/Linux/Linux.vmx -@ \"\" & Suppose "nosparse.so" is on /root/vmware and your guest .vmx file is /vmware/Linux/Linux.vmx Your guest OS needs at least more than 200MB memory allocated. Generating .vmem file takes some time. Please be patient. Author: Kanatoko http://www.jumperz.net/ *******/ #include #include #include #if defined(RTLD_NEXT) #define REAL_LIBC RTLD_NEXT #else #define REAL_LIBC ((void *) -1L) #endif using namespace std; static int flag1 = 0; // pointer to the original function static int (*original_pwrite64) (int file_descriptor, const void *buf, size_t nbyte, off64_t offset) = NULL; // for logging #define LOG(...) do { \ syslog(LOG_INFO, __VA_ARGS__); \ } while(0) #define SADDR_B(target,shift) (((target) >> (shift)) & 0x000000ff) static void __attribute__ ((constructor)) _constructor() { // for syslog openlog(NULL, LOG_CONS | LOG_NDELAY | LOG_PID, LOG_USER); //get address of the original function original_pwrite64 = (int(*)(int,const void*,size_t, off64_t)) dlsym(REAL_LIBC, "pwrite64"); } static void __attribute__ ((destructor)) _destructor() { closelog(); } ssize_t pwrite64(int fd, const void *buf, size_t nbyte, off64_t offset) { int rv; if( flag1 == 0 && offset > ( 1024 * 1024 * 200 ) //works only if offset is larger than 200MB && nbyte == 1 ) { flag1 = 1; LOG( "pwrite64 is hooked. ARGS: nbyte=%d, offset=%d\n", nbyte, (int)offset ); LOG( "creating .vmem file...\n" ); int bufsize = 1024 * 1024; char buffer[ bufsize ]; off64_t remain = offset + 1; while( remain > 0 ) { if( remain > bufsize ) { rv = write( fd, buffer, bufsize ); } else { rv = write( fd, buffer, remain ); } if( rv == -1 ) { LOG( "write failed.\n" ); return -1; } remain -= rv; } return 1; } else { rv = (*original_pwrite64)(fd, buf, nbyte, offset ); return rv; } }