Add initial support for striping target, hardcode maximal number of stripes

to 2 for now. strategy routine must be written, for now only parsing and
support routines are available. This is work in progress code and should be
taken very carefully.
This commit is contained in:
haad 2009-03-01 23:15:56 +00:00
parent dcc33b5c39
commit f048f56f71
2 changed files with 117 additions and 13 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: dm.h,v 1.9 2009/02/19 23:07:32 haad Exp $ */
/* $NetBSD: dm.h,v 1.10 2009/03/01 23:15:56 haad Exp $ */
/*
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@ -163,6 +163,14 @@ typedef struct target_linear_config {
uint64_t offset;
} dm_target_linear_config_t;
/* for stripe : */
typedef struct target_stripe_config {
#define MAX_STRIPES 2
struct target_linear_config stripe_devs[MAX_STRIPES];
uint8_t stripe_num;
uint64_t stripe_chunksize;
size_t params_len;
} dm_target_stripe_config_t;
/* for mirror : */
typedef struct target_mirror_config {

View File

@ -1,4 +1,4 @@
/*$NetBSD: dm_target_stripe.c,v 1.2 2009/01/02 22:33:51 haad Exp $*/
/*$NetBSD: dm_target_stripe.c,v 1.3 2009/03/01 23:15:56 haad Exp $*/
/*
* Copyright (c) 2009 The NetBSD Foundation, Inc.
@ -36,6 +36,8 @@
#include <sys/param.h>
#include <sys/buf.h>
#include <sys/kmem.h>
#include <sys/vnode.h>
#include "dm.h"
@ -61,9 +63,11 @@ dm_target_stripe_modcmd(modcmd_t cmd, void *arg)
switch (cmd) {
case MODULE_CMD_INIT:
if ((dmt = dm_target_lookup("stripe")) != NULL)
if ((dmt = dm_target_lookup("stripe")) != NULL) {
dm_target_unbusy(dmt);
return EEXIST;
}
dmt = dm_target_alloc("stripe");
dmt->version[0] = 1;
@ -97,34 +101,94 @@ dm_target_stripe_modcmd(modcmd_t cmd, void *arg)
#endif
/* Init function called from dm_table_load_ioctl. */
/*
* Init function called from dm_table_load_ioctl.
* Example line sent to dm from lvm tools when using striped target.
* start length striped #stripes chunk_size device1 offset1 ... deviceN offsetN
* 0 65536 striped 2 512 /dev/hda 0 /dev/hdb 0
*/
int
dm_target_stripe_init(dm_dev_t *dmv, void **target_config, char *argv)
dm_target_stripe_init(dm_dev_t *dmv, void **target_config, char *params)
{
dm_target_stripe_config_t *tsc;
size_t len;
char **ap, *argv[10];
if(params == NULL)
return EINVAL;
len = strlen(params) + 1;
/*
* Parse a string, containing tokens delimited by white space,
* into an argument vector
*/
for (ap = argv; ap < &argv[9] &&
(*ap = strsep(&params, " \t")) != NULL;) {
if (**ap != '\0')
ap++;
}
printf("Stripe target init function called!!\n");
*target_config = NULL;
printf("Stripe target chunk size %s number of stripes %s\n", argv[1], argv[0]);
printf("Stripe target device name %s -- offset %s\n", argv[2], argv[3]);
printf("Stripe target device name %s -- offset %s\n", argv[4], argv[5]);
if (atoi(argv[0]) > MAX_STRIPES)
return ENOTSUP;
if ((tsc = kmem_alloc(sizeof(dm_target_stripe_config_t), KM_NOSLEEP))
== NULL)
return ENOMEM;
/* Insert dmp to global pdev list */
if ((tsc->stripe_devs[0].pdev = dm_pdev_insert(argv[2])) == NULL)
return ENOENT;
/* Insert dmp to global pdev list */
if ((tsc->stripe_devs[1].pdev = dm_pdev_insert(argv[4])) == NULL)
return ENOENT;
tsc->stripe_devs[0].offset = atoi(argv[3]);
tsc->stripe_devs[1].offset = atoi(argv[5]);
/* Save length of param string */
tsc->params_len = len;
tsc->stripe_chunksize = atoi(argv[1]);
tsc->stripe_num = (uint8_t)atoi(argv[0]);
*target_config = tsc;
dmv->dev_type = DM_STRIPE_DEV;
return ENOSYS;
return 0;
}
/* Status routine called to get params string. */
char *
dm_target_stripe_status(void *target_config)
{
return NULL;
dm_target_stripe_config_t *tsc;
char *params;
tsc = target_config;
if ((params = kmem_alloc(tsc->params_len, KM_NOSLEEP)) == NULL)
return NULL;
snprintf(params, tsc->params_len, "%d %lld %s %lld %s %lld", tsc->stripe_num, tsc->stripe_chunksize,
tsc->stripe_devs[0].pdev->name, tsc->stripe_devs[0].offset,
tsc->stripe_devs[1].pdev->name, tsc->stripe_devs[1].offset);
return params;
}
/* Strategy routine called from dm_strategy. */
int
dm_target_stripe_strategy(dm_table_entry_t *table_en, struct buf *bp)
{
printf("Stripe target read function called!!\n");
bp->b_error = EIO;
bp->b_resid = 0;
@ -137,11 +201,23 @@ dm_target_stripe_strategy(dm_table_entry_t *table_en, struct buf *bp)
int
dm_target_stripe_destroy(dm_table_entry_t *table_en)
{
table_en->target_config = NULL;
dm_target_stripe_config_t *tsc;
tsc = table_en->target_config;
if (tsc == NULL)
return 0;
dm_pdev_decr(tsc->stripe_devs[0].pdev);
dm_pdev_decr(tsc->stripe_devs[1].pdev);
/* Unbusy target so we can unload it */
dm_target_unbusy(table_en->target);
kmem_free(tsc, sizeof(dm_target_stripe_config_t));
table_en->target_config = NULL;
return 0;
}
@ -149,6 +225,26 @@ dm_target_stripe_destroy(dm_table_entry_t *table_en)
int
dm_target_stripe_deps(dm_table_entry_t *table_en, prop_array_t prop_array)
{
dm_target_stripe_config_t *tsc;
struct vattr va;
int error;
if (table_en->target_config == NULL)
return ENOENT;
tsc = table_en->target_config;
if ((error = VOP_GETATTR(tsc->stripe_devs[0].pdev->pdev_vnode, &va, curlwp->l_cred)) != 0)
return error;
prop_array_add_uint64(prop_array, (uint64_t)va.va_rdev);
if ((error = VOP_GETATTR(tsc->stripe_devs[1].pdev->pdev_vnode, &va, curlwp->l_cred)) != 0)
return error;
prop_array_add_uint64(prop_array, (uint64_t)va.va_rdev);
return 0;
}