示例#1
0
static void
vfs_load_file_to_memory (const char *file, void **data, size_t *size)
{
    assert(data != NULL);
    assert(size != NULL);

    errval_t err;
    vfs_handle_t vh;

    err = vfs_open(file, &vh);
    if (err_is_fail(err)) {
        USER_PANIC_ERR(err, "Error opening %s", file);
    }

    struct vfs_fileinfo info;
    err = vfs_stat(vh, &info);
    assert_err(err, "vfs_stat");

    *data = malloc(info.size);
    assert(*data != NULL);

    err = vfs_read(vh, *data, info.size, size);
    assert_err(err, "vfs_read");
    assert(*size == info.size);

    vfs_close(vh);
}
示例#2
0
文件: pal_io.cpp 项目: AArnott/corefx
// To reduce the number of string copies, this function calling pattern works as follows:
// 1) The managed code calls GetDirentSize() to get the platform-specific
//    size of the dirent struct.
// 2) The managed code creates a byte[] buffer of the size of the native dirent
//    and passes a pointer to this buffer to this function.
// 3) This function passes input byte[] buffer to the OS to fill with dirent
//    data which makes the 1st strcpy.
// 4) The ConvertDirent function will fill DirectoryEntry outputEntry with
//    pointers from byte[] buffer.
// 5) The managed code uses DirectoryEntry outputEntry to find start of d_name
//    and the value of d_namelen, if avalable, to copy the name from
//    byte[] buffer into a managed string that the caller can use; this makes
//    the 2nd and final strcpy.
extern "C" int32_t SystemNative_ReadDirR(DIR* dir, void* buffer, int32_t bufferSize, DirectoryEntry* outputEntry)
{
    assert(buffer != nullptr);
    assert(dir != nullptr);
    assert(outputEntry != nullptr);

    if (bufferSize < static_cast<int32_t>(sizeof(dirent)))
    {
        assert(false && "Buffer size too small; use GetDirentSize to get required buffer size");
        return ERANGE;
    }

    dirent* result = nullptr;
    dirent* entry = static_cast<dirent*>(buffer);
#if HAVE_READDIR_R
    int error = readdir_r(dir, entry, &result);

    // positive error number returned -> failure
    if (error != 0)
    {
        assert(error > 0);
        *outputEntry = {}; // managed out param must be initialized
        return error;
    }

    // 0 returned with null result -> end-of-stream
    if (result == nullptr)
    {
        *outputEntry = {}; // managed out param must be initialized
        return -1;         // shim convention for end-of-stream
    }

    // 0 returned with non-null result (guaranteed to be set to entry arg) -> success
    assert(result == entry);
#else
    errno = 0;
    result = readdir(dir);

    // 0 returned with null result -> end-of-stream
    if (result == nullptr)
    {
        *outputEntry = {}; // managed out param must be initialized

        //  kernel set errno -> failure
        if (errno != 0)
        {
            assert_err(errno == EBADF, "Invalid directory stream descriptor dir", errno);
            return errno;
        }
        return -1;
    }

    assert(result->d_reclen <= bufferSize);
    memcpy_s(entry, sizeof(dirent), result, static_cast<size_t>(result->d_reclen));
#endif
    ConvertDirent(*entry, outputEntry);
    return 0;
}
示例#3
0
int main(int argc, char* argv[])
{

    size_t size_wanted = 1<<20;
    size_t runs = 100;
    struct reset_opt *reset = NULL;
    struct measure_opt *measure = NULL;
    bool dump = false;

    assert(argc>0);
    if (argc == 1) {
        usage(argv[0]);
        return 0;
    }

    bool args_ok = true;

    for (int arg = 1; arg < argc; arg++) {
        if (strcmp(argv[arg], "help") == 0
            || strcmp(argv[arg], "--help") == 0
            || strcmp(argv[arg], "-h") == 0)
        {
            usage(argv[0]);
            return 0;
        }
        if (strncmp(argv[arg], "size=", 5) == 0) {
            size_wanted = atol(argv[arg]+5);
        }
        if (strncmp(argv[arg], "logsize=", 8) == 0) {
            size_t logsize = atol(argv[arg]+8);
            if (logsize > 31) {
                printf("ERROR: logsize too big\n");
                args_ok = false;
            }
            else {
                size_wanted = 1 << logsize;
            }
        }
        else if (strncmp(argv[arg], "count=", 6) == 0) {
            size_wanted = atol(argv[arg]+6)*sizeof(struct cte);
        }
        else if (strncmp(argv[arg], "logcount=", 9) == 0) {
            size_t logcount = atol(argv[arg]+9);
            if (logcount > (31-OBJBITS_CTE)) {
                printf("ERROR: logcount too big\n");
                args_ok = false;
            }
            else {
                size_wanted = (1 << logcount)*sizeof(struct cte);
            }
        }
        else if (strncmp(argv[arg], "runs=", 5) == 0) {
            runs = atol(argv[arg]+5);
        }
        else if (strncmp(argv[arg], "reset=", 6) == 0) {
            char *name = argv[arg]+6;
            int i;
            for (i = 0; reset_opts[i].name; i++) {
                if (strcmp(reset_opts[i].name, name) == 0) {
                    reset = &reset_opts[i];
                    break;
                }
            }
            if (!reset_opts[i].name) {
                args_ok = false;
                printf("ERROR: unkown reset \"%s\"\n", name);
            }
        }
        else if (strncmp(argv[arg], "measure=", 8) == 0) {
            char *name = argv[arg]+8;
            if (strcmp(name, "dump") == 0) {
                measure = NULL;
                dump = true;
            }
            else {
                int i;
                for (i = 0; measure_opts[i].name; i++) {
                    if (strcmp(measure_opts[i].name, name) == 0) {
                        measure = &measure_opts[i];
                        break;
                    }
                }

                if (measure_opts[i].name) {
                    dump = false;
                }
                else {
                    args_ok = false;
                    printf("ERROR: unkown measure \"%s\"\n", name);
                }
            }
        }
        else {
            args_ok = false;
            printf("ERROR: unkown argument %s\n", argv[arg]);
        }
    }
    if (!args_ok) {
        usage(argv[0]);
        return 1;
    }

    assert(size_wanted > 0);
    assert(runs > 0);
    assert(reset);
    assert(measure || dump);

    errval_t err;
    struct capref frame;
    size_t size;
    err = frame_alloc(&frame, size_wanted, &size);
    assert_err(err, "alloc");
    assert(size >= size_wanted);
    printf("got %lu bytes\n", size);

    struct memobj *m;
    struct vregion *v;
    void *addr;

    err = vspace_map_one_frame(&addr, size, frame, &m, &v);
    assert_err(err, "map");

    if (dump) {
        reset_and_dump(addr, size_wanted, runs, reset->fn, reset->name);
    }
    else {
        bench_init();

        char *bench_name = malloc(strlen(reset->name)+strlen(measure->name)+2);
        strcpy(bench_name, reset->name);
        strcat(bench_name, ":");
        strcat(bench_name, measure->name);
        test(addr, size_wanted, runs, reset->fn, measure->fn, bench_name);

        free(bench_name);
    }

    printf("client done\n");

    vregion_destroy(v);
    cap_destroy(frame);

    return 0;
}
示例#4
0
// To reduce the number of string copies, the caller of this function is responsible to ensure the memory
// referenced by outputEntry remains valid until it is read.
// If the platform supports readdir_r, the caller provides a buffer into which the data is read.
// If the platform uses readdir, the caller must ensure no calls are made to readdir/closedir since those will invalidate
// the current dirent. We assume the platform supports concurrent readdir calls to different DIRs.
int32_t SystemNative_ReadDirR(DIR* dir, uint8_t* buffer, int32_t bufferSize, DirectoryEntry* outputEntry)
{
    assert(dir != NULL);
    assert(outputEntry != NULL);

#if HAVE_READDIR_R
    assert(buffer != NULL);

    // align to dirent
    struct dirent* entry = (struct dirent*)((size_t)(buffer + dirent_alignment - 1) & ~(dirent_alignment - 1));

    // check there is dirent size available at entry
    if ((buffer + bufferSize) < ((uint8_t*)entry + sizeof(struct dirent)))
    {
        assert(false && "Buffer size too small; use GetReadDirRBufferSize to get required buffer size");
        return ERANGE;
    }

    struct dirent* result = NULL;
#ifdef _AIX
    // AIX returns 0 on success, but bizarrely, it returns 9 for both error and
    // end-of-directory. result is NULL for both cases. The API returns the
    // same thing for EOD/error, so disambiguation between the two is nearly
    // impossible without clobbering errno for yourself and seeing if the API
    // changed it. See:
    // https://www.ibm.com/support/knowledgecenter/ssw_aix_71/com.ibm.aix.basetrf2/readdir_r.htm

    errno = 0; // create a success condition for the API to clobber
    int error = readdir_r(dir, entry, &result);

    if (error == 9)
    {
        memset(outputEntry, 0, sizeof(*outputEntry)); // managed out param must be initialized
        return errno == 0 ? -1 : errno;
    }
#else
    int error = readdir_r(dir, entry, &result);

    // positive error number returned -> failure
    if (error != 0)
    {
        assert(error > 0);
        memset(outputEntry, 0, sizeof(*outputEntry)); // managed out param must be initialized
        return error;
    }

    // 0 returned with null result -> end-of-stream
    if (result == NULL)
    {
        memset(outputEntry, 0, sizeof(*outputEntry)); // managed out param must be initialized
        return -1;         // shim convention for end-of-stream
    }
#endif

    // 0 returned with non-null result (guaranteed to be set to entry arg) -> success
    assert(result == entry);
#else
    (void)buffer;     // unused
    (void)bufferSize; // unused
    errno = 0;
    struct dirent* entry = readdir(dir);

    // 0 returned with null result -> end-of-stream
    if (entry == NULL)
    {
        memset(outputEntry, 0, sizeof(*outputEntry)); // managed out param must be initialized

        //  kernel set errno -> failure
        if (errno != 0)
        {
            assert_err(errno == EBADF, "Invalid directory stream descriptor dir", errno);
            return errno;
        }
        return -1;
    }
#endif
    ConvertDirent(entry, outputEntry);
    return 0;
}
示例#5
0
int main (int argc, char *argv[])
{
    errval_t err;
    char *cardName = NULL;

    const char *imagefile = IMAGEFILE;

    vfs_init();
    
    err = timer_init();
    if (err_is_fail(err)) {
        USER_PANIC_ERR(err, "error initialising timer client library\n");
    }

    if (argc < 3) {
        printf("Usage: %s <Network card Name> <vfs mount URI> [disk image path]\n",
               argv[0]);
        printf("<Network card Name> value is ignored in this version\n");
        return 1;
    }

    if(argc > 3) {
        imagefile = argv[3];
    }

    cardName = argv[1];
    printf("vmkitmon: start\n");
    printf("Ignoring the cardname [%s], and using the default one from vfs_mount\n",
            cardName);
    vfs_mkdir(VFS_MOUNTPOINT);
    err = vfs_mount(VFS_MOUNTPOINT, argv[2]);
    if (err_is_fail(err)) {
        printf("vmkitmon: error mounting %s: %s\n", argv[2], err_getstring(err));
        return 1;
    }

    /* Initialization */
    err = realmode_init();
    assert_err(err, "realmode_init");
    // fetch all relevant multiboot data
    //load_multiboot_files();

    // aquire the standard input
#if 1
    err = terminal_want_stdin(TERMINAL_SOURCE_SERIAL);
    assert_err(err, "terminal_want_stdin");
#endif

    // load files
    // FIXME: use a dynamic way to specify those arguments
    printf("Loading file [%s]\n", GRUB_IMG_PATH);
    vfs_load_file_to_memory(GRUB_IMG_PATH, &grub_image, &grub_image_size);
    printf("Loading file [%s]\n", imagefile);
    vfs_load_file_to_memory(imagefile, &hdd0_image, &hdd0_image_size);
    printf("Done with file loading\n");

    /* Guest execution */
    // perform some sanity checks
    if (grub_image == NULL) {
        printf("vmkitmon: no grub image available, abort\n");
        return 1;
    }

    guest = guest_create ();
    assert(guest != NULL);
    err = guest_make_runnable(guest, true);
    assert_err(err, "guest_make_runnable");

    printf("vmkitmon: end\n");

    messages_handler_loop();
}