Пример #1
0
static int deactivate_device(char *path)
{
    exa_rdev_handle_t *dev_req;
    int ret;

    dev_req = exa_rdev_handle_alloc(path);
    if (dev_req == NULL)
    {
	fprintf(stderr, "exa_rdev_request_init() failed, disk path = %s\n",
		path);
	return -1;
    }

    ret = exa_rdev_deactivate(dev_req, NULL);
    if (ret != 0)
	fprintf(stderr, "Failed to deactivate device %s: error %d\n",
		path, ret);

    exa_rdev_handle_free(dev_req);

    fprintf(stderr, "Deactivated device %s\n", path);

    return ret;
}
Пример #2
0
static int do_io(const char *disk_path, bool async, bool write, uint64_t offset,
                  uint64_t size_in_bytes)
{
    int exa_rdev_fd;
    int disk_fd;
    exa_rdev_handle_t *dev_req;
    uint64_t disk_size;
    int ret;

    /* Get disk size */
    disk_fd = os_disk_open_raw(disk_path, OS_DISK_READ);
    if (disk_fd < 0)
    {
	fprintf(stderr, "Can not open disk %s\n", disk_path);
	return -1;
    }

    ret = os_disk_get_size(disk_fd, &disk_size);
    if (ret < 0)
    {
	fprintf(stderr, "Can not get the size of disk %s\n", disk_path);
	return -1;
    }

    fprintf(stderr, "Disk %s has a size of %"PRIu64" bytes\n",
	    disk_path, disk_size);

    /* Initialise exa_rdev */
    exa_rdev_fd = exa_rdev_init();
    if (exa_rdev_fd <= 0)
    {
	fprintf(stderr, "exa_rdev_init() failed\n");
	return -1;
    }

    dev_req = exa_rdev_handle_alloc(disk_path);
    if (dev_req == NULL)
    {
	fprintf(stderr, "exa_rdev_request_init() failed, disk_path = %s\n",
		disk_path);
	close(exa_rdev_fd);
	return -1;
    }

    /* Carry on requests to exa_rdev */
    if (async)
    {
	fprintf(stderr, "Asynchronous mode\n");
	if (write)
	    async_op(RDEV_OP_WRITE, offset, size_in_bytes, dev_req);
	else
	    async_op(RDEV_OP_READ, offset, size_in_bytes, dev_req);
    }
    else
    {
	fprintf(stderr, "Synchronous mode\n");
	if (write)
	    sync_op(RDEV_OP_WRITE, offset, size_in_bytes, dev_req);
	else
	    sync_op(RDEV_OP_READ, offset, size_in_bytes, dev_req);
    }

    fprintf(stderr, "Finished %s %"PRIu64 " bytes on disk %s at offset %"PRIu64 "\n",
	    (write == true) ? "writing" : "reading",
	    size_in_bytes,
	    disk_path,
	    offset);

    close(exa_rdev_fd);

    return 0;
}
Пример #3
0
/* A new device is handled by the server, do the init operations in order to make the device usable */
int export_device(const exa_uuid_t *uuid, char *device_path)
{
    device_t *dev;
    int i, err;

    /* If device was already exported, do nothing */
    if (find_device_from_uuid(uuid) != NULL)
        return EXA_SUCCESS;

    dev = os_malloc(sizeof(struct device));
    if (dev == NULL)
    {
        err = -NBD_ERR_MALLOC_FAILED;
        goto error;
    }

    dev->handle = NULL;
    err = -CMD_EXP_ERR_OPEN_DEVICE;

    dev->handle = exa_rdev_handle_alloc(device_path);
    if (dev->handle == NULL)
        goto error;

    err = get_nb_sectors(device_path, &dev->size_in_sectors);
    if (err != EXA_SUCCESS)
        goto error;

    uuid_copy(&dev->uuid, uuid);
    strlcpy(dev->path, device_path, sizeof(dev->path));

    for (i = 0; i < NBMAX_DISKS_PER_NODE; i++)
        if (nbd_server.devices[i] == NULL)
            break;

    if (i >= NBMAX_DISKS_PER_NODE)
    {
        exalog_error("maximum number of exportable devices exceeded");
        err = -NBD_ERR_NB_RDEVS_CREATED;
    }

    dev->dev_index = i;
    dev->exit_thread = false;

    nbd_init_list(&nbd_server.list_root, &dev->disk_queue);

    /* resource needed to lock/unlock a zone */
    os_sem_init (&dev->lock_sem_disk, 0);

    /* launch disk thread (TD) */
    if (!exathread_create_named(&nbd_server.td_pid[dev->dev_index],
                                NBD_THREAD_STACK_SIZE + MIN_THREAD_STACK_SIZE,
                                exa_td_main, dev, "TD_thread"))
    {
        os_sem_destroy(&dev->lock_sem_disk);
        err = -NBD_ERR_THREAD_CREATION;
        goto error;
    }

    nbd_server.devices[dev->dev_index] = dev;

    return EXA_SUCCESS;

error:
    if (dev != NULL)
    {
        if (dev->handle != NULL)
            exa_rdev_handle_free(dev->handle);
        os_free(dev);
    }
    return err;
}