X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=osdep.c;h=56e6963f1572589d1dbfc3bda8915ae6368ffd5a;hb=4a81ab81e4d947a3a0c8408c743ad94e7c1b8a30;hp=8c2f0a9ec41b346033dfbbd77781cfe509d92aea;hpb=87ecb68bdf8a3e40ef885ddbb7ca1797dca40ebf;p=qemu.git diff --git a/osdep.c b/osdep.c index 8c2f0a9ec..56e6963f1 100644 --- a/osdep.c +++ b/osdep.c @@ -28,261 +28,141 @@ #include #include #include -#ifdef HOST_SOLARIS + +/* Needed early for CONFIG_BSD etc. */ +#include "config-host.h" + +#if defined(CONFIG_MADVISE) || defined(CONFIG_POSIX_MADVISE) +#include +#endif + +#ifdef CONFIG_SOLARIS #include #include +/* See MySQL bug #7156 (http://bugs.mysql.com/bug.php?id=7156) for + discussion about Solaris header problems */ +extern int madvise(caddr_t, size_t, int); #endif #include "qemu-common.h" -#include "sysemu.h" +#include "trace.h" +#include "qemu_socket.h" -#ifdef _WIN32 -#include -#elif defined(_BSD) -#include +int qemu_madvise(void *addr, size_t len, int advice) +{ + if (advice == QEMU_MADV_INVALID) { + errno = EINVAL; + return -1; + } +#if defined(CONFIG_MADVISE) + return madvise(addr, len, advice); +#elif defined(CONFIG_POSIX_MADVISE) + return posix_madvise(addr, len, advice); #else -#include + errno = EINVAL; + return -1; #endif - -void *get_mmap_addr(unsigned long size) -{ - return NULL; -} - -void qemu_free(void *ptr) -{ - free(ptr); -} - -void *qemu_malloc(size_t size) -{ - return malloc(size); } -#if defined(_WIN32) - -void *qemu_vmalloc(size_t size) -{ - /* FIXME: this is not exactly optimal solution since VirtualAlloc - has 64Kb granularity, but at least it guarantees us that the - memory is page aligned. */ - return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE); -} -void qemu_vfree(void *ptr) +/* + * Opens a file with FD_CLOEXEC set + */ +int qemu_open(const char *name, int flags, ...) { - VirtualFree(ptr, 0, MEM_RELEASE); -} - -#else + int ret; + int mode = 0; -#if defined(USE_KQEMU) + if (flags & O_CREAT) { + va_list ap; -#include -#include -#include - -void *kqemu_vmalloc(size_t size) -{ - static int phys_ram_fd = -1; - static int phys_ram_size = 0; - const char *tmpdir; - char phys_ram_file[1024]; - void *ptr; -#ifdef HOST_SOLARIS - struct statvfs stfs; -#else - struct statfs stfs; -#endif + va_start(ap, flags); + mode = va_arg(ap, int); + va_end(ap); + } - if (phys_ram_fd < 0) { - tmpdir = getenv("QEMU_TMPDIR"); - if (!tmpdir) -#ifdef HOST_SOLARIS - tmpdir = "/tmp"; - if (statvfs(tmpdir, &stfs) == 0) { +#ifdef O_CLOEXEC + ret = open(name, flags | O_CLOEXEC, mode); #else - tmpdir = "/dev/shm"; - if (statfs(tmpdir, &stfs) == 0) { + ret = open(name, flags, mode); + if (ret >= 0) { + qemu_set_cloexec(ret); + } #endif - int64_t free_space; - int ram_mb; - extern int ram_size; - free_space = (int64_t)stfs.f_bavail * stfs.f_bsize; - if ((ram_size + 8192 * 1024) >= free_space) { - ram_mb = (ram_size / (1024 * 1024)); - fprintf(stderr, - "You do not have enough space in '%s' for the %d MB of QEMU virtual RAM.\n", - tmpdir, ram_mb); - if (strcmp(tmpdir, "/dev/shm") == 0) { - fprintf(stderr, "To have more space available provided you have enough RAM and swap, do as root:\n" - "umount /dev/shm\n" - "mount -t tmpfs -o size=%dm none /dev/shm\n", - ram_mb + 16); - } else { - fprintf(stderr, - "Use the '-m' option of QEMU to diminish the amount of virtual RAM or use the\n" - "QEMU_TMPDIR environment variable to set another directory where the QEMU\n" - "temporary RAM file will be opened.\n"); - } - fprintf(stderr, "Or disable the accelerator module with -no-kqemu\n"); - exit(1); - } - } - snprintf(phys_ram_file, sizeof(phys_ram_file), "%s/qemuXXXXXX", - tmpdir); - phys_ram_fd = mkstemp(phys_ram_file); - if (phys_ram_fd < 0) { - fprintf(stderr, - "warning: could not create temporary file in '%s'.\n" - "Use QEMU_TMPDIR to select a directory in a tmpfs filesystem.\n" - "Using '/tmp' as fallback.\n", - tmpdir); - snprintf(phys_ram_file, sizeof(phys_ram_file), "%s/qemuXXXXXX", - "/tmp"); - phys_ram_fd = mkstemp(phys_ram_file); - if (phys_ram_fd < 0) { - fprintf(stderr, "Could not create temporary memory file '%s'\n", - phys_ram_file); - exit(1); - } - } - unlink(phys_ram_file); - } - size = (size + 4095) & ~4095; - ftruncate(phys_ram_fd, phys_ram_size + size); - ptr = mmap(NULL, - size, - PROT_WRITE | PROT_READ, MAP_SHARED, - phys_ram_fd, phys_ram_size); - if (ptr == MAP_FAILED) { - fprintf(stderr, "Could not map physical memory\n"); - exit(1); - } - phys_ram_size += size; - return ptr; + return ret; } -void kqemu_vfree(void *ptr) +/* + * A variant of write(2) which handles partial write. + * + * Return the number of bytes transferred. + * Set errno if fewer than `count' bytes are written. + * + * This function don't work with non-blocking fd's. + * Any of the possibilities with non-bloking fd's is bad: + * - return a short write (then name is wrong) + * - busy wait adding (errno == EAGAIN) to the loop + */ +ssize_t qemu_write_full(int fd, const void *buf, size_t count) { - /* may be useful some day, but currently we do not need to free */ -} + ssize_t ret = 0; + ssize_t total = 0; + + while (count) { + ret = write(fd, buf, count); + if (ret < 0) { + if (errno == EINTR) + continue; + break; + } -#endif + count -= ret; + buf += ret; + total += ret; + } -/* alloc shared memory pages */ -void *qemu_vmalloc(size_t size) -{ -#if defined(USE_KQEMU) - if (kqemu_allowed) - return kqemu_vmalloc(size); -#endif -#ifdef _BSD - return valloc(size); -#else - return memalign(4096, size); -#endif + return total; } -void qemu_vfree(void *ptr) +/* + * Opens a socket with FD_CLOEXEC set + */ +int qemu_socket(int domain, int type, int protocol) { -#if defined(USE_KQEMU) - if (kqemu_allowed) - kqemu_vfree(ptr); -#endif - free(ptr); -} + int ret; +#ifdef SOCK_CLOEXEC + ret = socket(domain, type | SOCK_CLOEXEC, protocol); + if (ret != -1 || errno != EINVAL) { + return ret; + } #endif + ret = socket(domain, type, protocol); + if (ret >= 0) { + qemu_set_cloexec(ret); + } -void *qemu_mallocz(size_t size) -{ - void *ptr; - ptr = qemu_malloc(size); - if (!ptr) - return NULL; - memset(ptr, 0, size); - return ptr; -} - -char *qemu_strdup(const char *str) -{ - char *ptr; - ptr = qemu_malloc(strlen(str) + 1); - if (!ptr) - return NULL; - strcpy(ptr, str); - return ptr; + return ret; } -int qemu_create_pidfile(const char *filename) +/* + * Accept a connection and set FD_CLOEXEC + */ +int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen) { - char buffer[128]; - int len; -#ifndef _WIN32 - int fd; - - fd = open(filename, O_RDWR | O_CREAT, 0600); - if (fd == -1) - return -1; - - if (lockf(fd, F_TLOCK, 0) == -1) - return -1; - - len = snprintf(buffer, sizeof(buffer), "%ld\n", (long)getpid()); - if (write(fd, buffer, len) != len) - return -1; -#else - HANDLE file; - DWORD flags; - OVERLAPPED overlap; - BOOL ret; - - /* Open for writing with no sharing. */ - file = CreateFile(filename, GENERIC_WRITE, 0, NULL, - OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - - if (file == INVALID_HANDLE_VALUE) - return -1; + int ret; - flags = LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY; - overlap.hEvent = 0; - /* Lock 1 byte. */ - ret = LockFileEx(file, flags, 0, 0, 1, &overlap); - if (ret == 0) - return -1; - - /* Write PID to file. */ - len = snprintf(buffer, sizeof(buffer), "%ld\n", (long)getpid()); - ret = WriteFileEx(file, (LPCVOID)buffer, (DWORD)len, - &overlap, NULL); - if (ret == 0) - return -1; +#ifdef CONFIG_ACCEPT4 + ret = accept4(s, addr, addrlen, SOCK_CLOEXEC); + if (ret != -1 || errno != ENOSYS) { + return ret; + } #endif - return 0; -} - -#ifdef _WIN32 - -/* Offset between 1/1/1601 and 1/1/1970 in 100 nanosec units */ -#define _W32_FT_OFFSET (116444736000000000ULL) - -int qemu_gettimeofday(qemu_timeval *tp) -{ - union { - unsigned long long ns100; /*time since 1 Jan 1601 in 100ns units */ - FILETIME ft; - } _now; - - if(tp) - { - GetSystemTimeAsFileTime (&_now.ft); - tp->tv_usec=(long)((_now.ns100 / 10ULL) % 1000000ULL ); - tp->tv_sec= (long)((_now.ns100 - _W32_FT_OFFSET) / 10000000ULL); + ret = accept(s, addr, addrlen); + if (ret >= 0) { + qemu_set_cloexec(ret); } - /* Always return 0 as per Open Group Base Specifications Issue 6. - Do not set errno on error. */ - return 0; + + return ret; } -#endif /* _WIN32 */