Пример #1
0
char *libxl__domid_to_name(libxl__gc *gc, uint32_t domid)
{
    char *s = libxl_domid_to_name(libxl__gc_owner(gc), domid);
    if ( s )
        libxl__ptr_add(gc, s);
    return s;
}
Пример #2
0
char *libxl__cpupoolid_to_name(libxl__gc *gc, uint32_t poolid)
{
    char *s = libxl_cpupoolid_to_name(libxl__gc_owner(gc), poolid);
    if ( s )
        libxl__ptr_add(gc, s);
    return s;
}
Пример #3
0
void *libxl__calloc(libxl__gc *gc, size_t nmemb, size_t size)
{
    void *ptr = calloc(nmemb, size);
    if (!ptr) libxl__alloc_failed(CTX, __func__, nmemb, size);

    libxl__ptr_add(gc, ptr);
    return ptr;
}
Пример #4
0
void *libxl__zalloc(libxl__gc *gc, int bytes)
{
    void *ptr = calloc(bytes, 1);
    if (!ptr) libxl__alloc_failed(CTX, __func__, bytes, 1);

    libxl__ptr_add(gc, ptr);
    return ptr;
}
Пример #5
0
void *libxl__malloc(libxl__gc *gc, size_t size)
{
    void *ptr = malloc(size);
    if (!ptr) libxl__alloc_failed(CTX, __func__, size, 1);

    libxl__ptr_add(gc, ptr);
    return ptr;
}
char *libxl__strdup(libxl__gc *gc, const char *c)
{
    char *s = strdup(c);

    if (s)
        libxl__ptr_add(gc, s);

    return s;
}
Пример #7
0
char *libxl__strndup(libxl__gc *gc, const char *c, size_t n)
{
    char *s = strndup(c, n);

    if (!s) libxl__alloc_failed(CTX, __func__, n, 1);

    libxl__ptr_add(gc, s);

    return s;
}
Пример #8
0
char *libxl__strdup(libxl__gc *gc, const char *c)
{
    char *s = strdup(c);

    if (!s) libxl__alloc_failed(CTX, __func__, strlen(c), 1);

    libxl__ptr_add(gc, s);

    return s;
}
void *libxl__calloc(libxl__gc *gc, size_t nmemb, size_t size)
{
    void *ptr = calloc(nmemb, size);
    if (!ptr) {
        libxl__error_set(libxl__gc_owner(gc), ENOMEM);
        return NULL;
    }

    libxl__ptr_add(gc, ptr);
    return ptr;
}
void *libxl__zalloc(libxl__gc *gc, int bytes)
{
    void *ptr = calloc(bytes, 1);
    if (!ptr) {
        libxl__error_set(libxl__gc_owner(gc), ENOMEM);
        return NULL;
    }

    libxl__ptr_add(gc, ptr);
    return ptr;
}
Пример #11
0
void *libxl__realloc(libxl__gc *gc, void *ptr, size_t new_size)
{
    void *new_ptr = realloc(ptr, new_size);
    int i = 0;

    if (new_ptr == NULL && new_size != 0)
        libxl__alloc_failed(CTX, __func__, new_size, 1);

    if (ptr == NULL) {
        libxl__ptr_add(gc, new_ptr);
    } else if (new_ptr != ptr && libxl__gc_is_real(gc)) {
        for (i = 0; i < gc->alloc_maxsize; i++) {
            if (gc->alloc_ptrs[i] == ptr) {
                gc->alloc_ptrs[i] = new_ptr;
                break;
            }
        }
    }

    return new_ptr;
}
Пример #12
0
void libxl__bootloader_run(libxl__egc *egc, libxl__bootloader_state *bl)
{
    STATE_AO_GC(bl->ao);
    const libxl_domain_build_info *info = bl->info;
    uint32_t domid = bl->domid;
    char *logfile_tmp = NULL;
    int rc, r;

    libxl__bootloader_init(bl);

    if (info->type != LIBXL_DOMAIN_TYPE_PV) {
        LOG(DEBUG, "not a PV domain, skipping bootloader");
        rc = 0;
        goto out_ok;
    }

    if (!info->u.pv.bootloader) {
        LOG(DEBUG, "no bootloader configured, using user supplied kernel");
        bl->kernel->path = bl->info->u.pv.kernel;
        bl->ramdisk->path = bl->info->u.pv.ramdisk;
        bl->cmdline = bl->info->u.pv.cmdline;
        rc = 0;
        goto out_ok;
    }

    if (!bl->disk) {
        LOG(ERROR, "cannot run bootloader with no boot disk");
        rc = ERROR_FAIL;
        goto out;
    }

    bootloader_setpaths(gc, bl);

    const char *logfile_leaf = GCSPRINTF("bootloader.%"PRIu32, domid);
    rc = libxl_create_logfile(CTX, logfile_leaf, &logfile_tmp);
    if (rc) goto out;

    /* Transfer ownership of log filename to bl and the gc */
    bl->logfile = logfile_tmp;
    libxl__ptr_add(gc, logfile_tmp);
    logfile_tmp = NULL;

    bl->display.log = fopen(bl->logfile, "a");
    if (!bl->display.log) {
        LOGE(ERROR, "failed to create bootloader logfile %s", bl->logfile);
        rc = ERROR_FAIL;
        goto out;
    }

    for (;;) {
        r = mkdir(bl->outputdir, 0600);
        if (!r) break;
        if (errno == EINTR) continue;
        if (errno == EEXIST) break;
        LOGE(ERROR, "failed to create bootloader dir %s", bl->outputdir);
        rc = ERROR_FAIL;
        goto out;
    }

    for (;;) {
        r = open(bl->outputpath, O_WRONLY|O_CREAT|O_TRUNC, 0600);
        if (r>=0) {
            close(r);
            break;
        }
        if (errno == EINTR) continue;
        LOGE(ERROR, "failed to precreate bootloader output %s", bl->outputpath);
        rc = ERROR_FAIL;
        goto out;
    }


    /* This sets the state of the dls struct from Undefined to Idle */
    libxl__device_disk_local_init(&bl->dls);
    bl->dls.ao = ao;
    bl->dls.in_disk = bl->disk;
    bl->dls.blkdev_start = info->blkdev_start;
    bl->dls.callback = bootloader_disk_attached_cb;
    libxl__device_disk_local_initiate_attach(egc, &bl->dls);
    return;

out:
    assert(rc);
out_ok:
    free(logfile_tmp);
    bootloader_callback(egc, bl, rc);
}
/*
 * filedescriptors:
 *   fifo_fd        - bootstring output from the bootloader
 *   xenconsoled_fd - input/output from/to xenconsole
 *   bootloader_fd  - input/output from/to pty that controls the bootloader
 * The filedescriptors are NDELAY, so it's ok to try to read
 * bigger chunks than may be available, to keep e.g. curses
 * screen redraws in the bootloader efficient. xenconsoled_fd is the side that
 * gets xenconsole input, which will be keystrokes, so a small number
 * is sufficient. bootloader_fd is pygrub output, which will be curses screen
 * updates, so a larger number (1024) is appropriate there.
 *
 * For writeable descriptors, only include them in the set for select
 * if there is actual data to write, otherwise this would loop too fast,
 * eating up CPU time.
 */
static char * bootloader_interact(libxl__gc *gc, int xenconsoled_fd, int bootloader_fd, int fifo_fd)
{
    int ret;

    size_t nr_out = 0, size_out = 0;
    char *output = NULL;

    /* input from xenconsole. read on xenconsoled_fd write to bootloader_fd */
    int xenconsoled_prod = 0, xenconsoled_cons = 0;
    char xenconsoled_buf[XENCONSOLED_BUF_SIZE];
    /* output from bootloader. read on bootloader_fd write to xenconsoled_fd */
    int bootloader_prod = 0, bootloader_cons = 0;
    char bootloader_buf[BOOTLOADER_BUF_SIZE];

    while(1) {
        fd_set wsel, rsel;
        int nfds;

        if (xenconsoled_prod == xenconsoled_cons)
            xenconsoled_prod = xenconsoled_cons = 0;
        if (bootloader_prod == bootloader_cons)
            bootloader_prod = bootloader_cons = 0;

        FD_ZERO(&rsel);
        FD_SET(fifo_fd, &rsel);
        nfds = fifo_fd + 1;
        if (xenconsoled_prod == 0 || (xenconsoled_prod < BOOTLOADER_BUF_SIZE && xenconsoled_cons == 0)) {
            FD_SET(xenconsoled_fd, &rsel);
            nfds = xenconsoled_fd + 1 > nfds ? xenconsoled_fd + 1 : nfds;
        }
        if (bootloader_prod == 0 || (bootloader_prod < BOOTLOADER_BUF_SIZE && bootloader_cons == 0)) {
            FD_SET(bootloader_fd, &rsel);
            nfds = bootloader_fd + 1 > nfds ? bootloader_fd + 1 : nfds;
        }

        FD_ZERO(&wsel);
        if (bootloader_prod != bootloader_cons) {
            FD_SET(xenconsoled_fd, &wsel);
            nfds = xenconsoled_fd + 1 > nfds ? xenconsoled_fd + 1 : nfds;
        }
        if (xenconsoled_prod != xenconsoled_cons) {
            FD_SET(bootloader_fd, &wsel);
            nfds = bootloader_fd + 1 > nfds ? bootloader_fd + 1 : nfds;
        }

        ret = select(nfds, &rsel, &wsel, NULL, NULL);
        if (ret < 0)
            goto out_err;

        /* Input from xenconsole, read xenconsoled_fd, write bootloader_fd */
        if (FD_ISSET(xenconsoled_fd, &rsel)) {
            ret = read(xenconsoled_fd, &xenconsoled_buf[xenconsoled_prod], XENCONSOLED_BUF_SIZE - xenconsoled_prod);
            if (ret < 0 && errno != EIO && errno != EAGAIN)
                goto out_err;
            if (ret > 0)
                xenconsoled_prod += ret;
        }
        if (FD_ISSET(bootloader_fd, &wsel)) {
            ret = write(bootloader_fd, &xenconsoled_buf[xenconsoled_cons], xenconsoled_prod - xenconsoled_cons);
            if (ret < 0 && errno != EIO && errno != EAGAIN)
                goto out_err;
            if (ret > 0)
                xenconsoled_cons += ret;
        }

        /* Input from bootloader, read bootloader_fd, write xenconsoled_fd */
        if (FD_ISSET(bootloader_fd, &rsel)) {
            ret = read(bootloader_fd, &bootloader_buf[bootloader_prod], BOOTLOADER_BUF_SIZE - bootloader_prod);
            if (ret < 0 && errno != EIO && errno != EAGAIN)
                goto out_err;
            if (ret > 0)
                bootloader_prod += ret;
        }
        if (FD_ISSET(xenconsoled_fd, &wsel)) {
            ret = write(xenconsoled_fd, &bootloader_buf[bootloader_cons], bootloader_prod - bootloader_cons);
            if (ret < 0 && errno != EIO && errno != EAGAIN)
                goto out_err;
            if (ret > 0)
                bootloader_cons += ret;
        }

        if (FD_ISSET(fifo_fd, &rsel)) {
            if (size_out - nr_out < 256) {
                char *temp;
                size_t new_size = size_out == 0 ? 32 : size_out * 2;

                temp = realloc(output, new_size);
                if (temp == NULL)
                    goto out_err;
                output = temp;
                memset(output + size_out, 0, new_size - size_out);
                size_out = new_size;
            }

            ret = read(fifo_fd, output + nr_out, size_out - nr_out);
            if (ret > 0)
                  nr_out += ret;
            if (ret == 0)
                break;
        }
    }

    libxl__ptr_add(gc, output);
    return output;

out_err:
    free(output);
    return NULL;
}
Пример #14
0
char *libxl__domid_to_name(libxl__gc *gc, uint32_t domid)
{
    char *s = libxl_domid_to_name(CTX, domid);
    libxl__ptr_add(gc, s);
    return s;
}
Пример #15
0
char *libxl__cpupoolid_to_name(libxl__gc *gc, uint32_t poolid)
{
    char *s = libxl_cpupoolid_to_name(CTX, poolid);
    libxl__ptr_add(gc, s);
    return s;
}