Switch libdevmapper library to use libdm as it;s backend lib and do not

communicate with device-mapper directly. Our lvm stack now looks like this
lvm<->libdevmapper<->libdm<->dm where only libdm knows how our dm protocol
looks like.

No objections on tech-userlevel@.
This commit is contained in:
haad 2011-02-08 03:26:12 +00:00
parent 83425a0f36
commit 0527bde829
5 changed files with 264 additions and 365 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: libdm-nbsd-iface.c,v 1.10 2011/01/12 08:16:23 haad Exp $ */
/* $NetBSD: libdm-nbsd-iface.c,v 1.11 2011/02/08 03:26:12 haad Exp $ */
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
@ -28,6 +28,7 @@
#include <dirent.h>
#include <limits.h>
#include <dm.h>
#include <dev/dm/netbsd-dm.h>
#include <dm-ioctl.h>
@ -38,8 +39,8 @@
#endif
/*
* Ensure build compatibility.
* The hard-coded versions here are the highest present
* Ensure build compatibility.
* The hard-coded versions here are the highest present
* in the _cmd_data arrays.
*/
@ -104,9 +105,9 @@ static int _control_device_number(uint32_t *major, uint32_t *minor)
{
nbsd_get_dm_major(major, DM_CHAR_MAJOR);
*minor = 0;
return 1;
}
@ -185,7 +186,7 @@ int dm_is_dm_major(uint32_t major)
uint32_t dm_major;
nbsd_get_dm_major(&dm_major, DM_BLOCK_MAJOR);
if (major == dm_major)
return 1;
@ -201,7 +202,7 @@ static int _open_control(void)
if (_control_fd != -1)
return 1;
#ifdef RUMP_ACTION
#ifdef RUMP_ACTION
rump_init();
#endif
snprintf(control, sizeof(control), "%s/control", dm_dir());
@ -297,7 +298,7 @@ static int _check_version(char *version, size_t size)
}
/*
* Find out device-mapper's major version number the first time
* Find out device-mapper's major version number the first time
* this is called and whether or not we support it.
*/
int dm_check_version(void)
@ -422,14 +423,14 @@ int dm_format_dev(char *buf, int bufsize, uint32_t dev_major,
dev_t dev;
size_t val_len,i;
struct kinfo_drivers *kd;
mode = 0;
nbsd_get_dm_major(&dm_major, DM_BLOCK_MAJOR);
if (bufsize < 8)
return 0;
if (sysctlbyname("kern.drivers",NULL,&val_len,NULL,0) < 0) {
printf("sysctlbyname failed");
return 0;
@ -451,7 +452,7 @@ int dm_format_dev(char *buf, int bufsize, uint32_t dev_major,
break;
}
}
dev = MKDEV(major,dev_minor);
mode |= S_IFBLK;
@ -489,10 +490,10 @@ int dm_task_get_info(struct dm_task *dmt, struct dm_info *info)
info->target_count = dmt->dmi.v4->target_count;
info->open_count = dmt->dmi.v4->open_count;
info->event_nr = dmt->dmi.v4->event_nr;
nbsd_get_dm_major(&info->major, DM_BLOCK_MAJOR); /* get netbsd dm device major number */
info->minor = MINOR(dmt->dmi.v4->dev);
return 1;
}
@ -657,44 +658,39 @@ struct target *create_target(uint64_t start, uint64_t len, const char *type,
}
/* Parse given dm task structure to proplib dictionary. */
static int _flatten(struct dm_task *dmt, prop_dictionary_t dm_dict)
static int _flatten(struct dm_task *dmt, libdm_task_t task)
{
prop_array_t cmd_array;
prop_dictionary_t target_spec;
libdm_cmd_t cmd;
libdm_table_t table;
struct target *t;
size_t len;
char type[DM_MAX_TYPE_NAME];
uint32_t major, flags;
int count = 0;
const int (*version)[3];
flags = 0;
version = &_cmd_data_v4[dmt->type].version;
cmd_array = prop_array_create();
flags = 0;
cmd = libdm_cmd_create();
for (t = dmt->head; t; t = t->next) {
target_spec = prop_dictionary_create();
prop_dictionary_set_uint64(target_spec,DM_TABLE_START,t->start);
prop_dictionary_set_uint64(target_spec,DM_TABLE_LENGTH,t->length);
strlcpy(type,t->type,DM_MAX_TYPE_NAME);
prop_dictionary_set_cstring(target_spec,DM_TABLE_TYPE,type);
prop_dictionary_set_cstring(target_spec,DM_TABLE_PARAMS,t->params);
table = libdm_table_create();
prop_array_set(cmd_array,count,target_spec);
libdm_table_set_start(t->start, table);
libdm_table_set_length(t->length, table);
libdm_table_set_target(type, table);
libdm_table_set_params(t->params, table);
libdm_cmd_set_table(table, cmd);
libdm_table_destroy(table);
prop_object_release(target_spec);
count++;
}
if (count && (dmt->sector || dmt->message)) {
log_error("targets and message are incompatible");
return -1;
@ -739,29 +735,26 @@ static int _flatten(struct dm_task *dmt, prop_dictionary_t dm_dict)
if (dmt->geometry)
len += strlen(dmt->geometry) + 1;
nbsd_dmi_add_version((*version), dm_dict);
nbsd_get_dm_major(&major, DM_BLOCK_MAJOR);
/*
* Only devices with major which is equal to netbsd dm major
/*
* Only devices with major which is equal to netbsd dm major
* dm devices in NetBSD can't have more majors then one assigned to dm.
*/
if (dmt->major != major && dmt->major != -1)
return -1;
if (dmt->minor >= 0) {
flags |= DM_PERSISTENT_DEV_FLAG;
prop_dictionary_set_uint32(dm_dict, DM_IOCTL_MINOR, dmt->minor);
libdm_task_set_minor(dmt->minor, task);
}
/* Set values to dictionary. */
if (dmt->dev_name)
prop_dictionary_set_cstring(dm_dict, DM_IOCTL_NAME, dmt->dev_name);
libdm_task_set_name(dmt->dev_name, task);
if (dmt->uuid)
prop_dictionary_set_cstring(dm_dict, DM_IOCTL_UUID, dmt->uuid);
libdm_task_set_uuid(dmt->uuid, task);
if (dmt->type == DM_DEVICE_SUSPEND)
flags |= DM_SUSPEND_FLAG;
if (dmt->no_flush)
@ -777,18 +770,18 @@ static int _flatten(struct dm_task *dmt, prop_dictionary_t dm_dict)
"by kernel. It will use live table.");
flags |= DM_QUERY_INACTIVE_TABLE_FLAG;
}
prop_dictionary_set_uint32(dm_dict, DM_IOCTL_FLAGS, flags);
prop_dictionary_set_uint32(dm_dict, DM_IOCTL_EVENT, dmt->event_nr);
libdm_task_set_flags(task, flags);
// prop_dictionary_set_uint32(dm_dict, DM_IOCTL_EVENT, dmt->event_nr);
if (dmt->newname)
prop_array_set_cstring(cmd_array, 0, dmt->newname);
libdm_dev_set_newname(dmt->newname, cmd);
/* Add array for all COMMAND specific data. */
prop_dictionary_set(dm_dict, DM_IOCTL_CMD_DATA, cmd_array);
prop_object_release(cmd_array);
libdm_task_set_cmd(cmd, task);
libdm_cmd_destroy(cmd);
return 0;
}
@ -874,7 +867,7 @@ static int _create_and_load_v4(struct dm_task *dmt)
int r;
printf("create and load called \n");
/* Use new task struct to create the device */
if (!(task = dm_task_create(DM_DEVICE_CREATE))) {
log_error("Failed to create device-mapper task struct");
@ -958,7 +951,7 @@ static int _reload_with_suppression_v4(struct dm_task *dmt)
struct dm_task *task;
struct target *t1, *t2;
int r;
/* New task to get existing table information */
if (!(task = dm_task_create(DM_DEVICE_TABLE))) {
log_error("Failed to create device-mapper task struct");
@ -991,7 +984,7 @@ static int _reload_with_suppression_v4(struct dm_task *dmt)
while (t2 && t2->next)
t2 = t2->next;
dmt->existing_table_size = t2 ? t2->start + t2->length : 0;
if ((task->dmi.v4->flags & DM_READONLY_FLAG) ? 1 : 0 != dmt->read_only)
goto no_match;
@ -1009,7 +1002,7 @@ static int _reload_with_suppression_v4(struct dm_task *dmt)
t1 = t1->next;
t2 = t2->next;
}
if (!t1 && !t2) {
dmt->dmi.v4 = task->dmi.v4;
task->dmi.v4 = NULL;
@ -1037,54 +1030,22 @@ no_match:
static struct dm_ioctl *_do_dm_ioctl(struct dm_task *dmt, unsigned command)
{
struct dm_ioctl *dmi;
prop_dictionary_t dm_dict_in, dm_dict_out;
uint32_t flags;
libdm_task_t task;
dm_dict_in = NULL;
dm_dict_in = prop_dictionary_create(); /* Dictionary send to kernel */
dm_dict_out = prop_dictionary_create(); /* Dictionary received from kernel */
/* Set command name to dictionary */
prop_dictionary_set_cstring(dm_dict_in, DM_IOCTL_COMMAND,
_cmd_data_v4[dmt->type].name);
task = libdm_task_create(_cmd_data_v4[dmt->type].name);
/* Parse dmi from libdevmapper to dictionary */
if (_flatten(dmt, dm_dict_in) < 0)
if (_flatten(dmt, task) < 0)
goto bad;
prop_dictionary_get_uint32(dm_dict_in, DM_IOCTL_FLAGS, &flags);
if (dmt->type == DM_DEVICE_TABLE)
flags |= DM_STATUS_TABLE_FLAG;
libdm_task_set_status_flag(task);
if (dmt->no_open_count)
flags |= DM_SKIP_BDGET_FLAG;
libdm_task_set_exists_flag(task);
flags |= DM_EXISTS_FLAG;
/* Set flags to dictionary. */
prop_dictionary_set_uint32(dm_dict_in,DM_IOCTL_FLAGS,flags);
prop_dictionary_externalize_to_file(dm_dict_in,"/tmp/test_in");
log_very_verbose("Ioctl type %s --- flags %d",_cmd_data_v4[dmt->type].name,flags);
//printf("name %s, major %d minor %d\n uuid %s\n",
//dm_task_get_name(dmt), dmt->minor, dmt->major, dm_task_get_uuid(dmt));
log_very_verbose("Ioctl type %s --- flags %d",_cmd_data_v4[dmt->type].name, libdm_task_get_flags(task));
/* Send dictionary to kernel and wait for reply. */
#ifdef RUMP_ACTION
struct plistref prefp;
int err;
prop_dictionary_externalize_to_pref(dm_dict_in, &prefp);
if (rump_sys_ioctl(_control_fd, NETBSD_DM_IOCTL, &prefp) != 0) {
dm_dict_out = prop_dictionary_internalize(prefp.pref_plist);
#else
if (prop_dictionary_sendrecv_ioctl(dm_dict_in,_control_fd,
NETBSD_DM_IOCTL,&dm_dict_out) != 0) {
#endif
if (libdm_task_run(task) != 0) {
if (errno == ENOENT &&
((dmt->type == DM_DEVICE_INFO) ||
(dmt->type == DM_DEVICE_MKNODES) ||
@ -1095,37 +1056,27 @@ static struct dm_ioctl *_do_dm_ioctl(struct dm_task *dmt, unsigned command)
* for nonexisting device after info, deps, mknodes call.
* It returns dmi sent to kernel with DM_EXISTS_FLAG = 0;
*/
dmi = nbsd_dm_dict_to_dmi(dm_dict_in,_cmd_data_v4[dmt->type].cmd);
dmi->flags &= ~DM_EXISTS_FLAG;
dmi = nbsd_dm_dict_to_dmi(task, _cmd_data_v4[dmt->type].cmd);
prop_object_release(dm_dict_in);
prop_object_release(dm_dict_out);
libdm_task_del_exists_flag(task);
libdm_task_destroy(task);
goto out;
} else {
log_error("ioctl %s call failed with errno %d\n",
log_error("ioctl %s call failed with errno %d\n",
_cmd_data_v4[dmt->type].name, errno);
prop_object_release(dm_dict_in);
prop_object_release(dm_dict_out);
libdm_task_destroy(task);
goto bad;
}
}
#ifdef RUMP_ACTION
dm_dict_out = prop_dictionary_internalize(prefp.pref_plist);
#endif
prop_dictionary_externalize_to_file(dm_dict_out,"/tmp/test_out");
/* Parse kernel dictionary to dmi structure and return it to libdevmapper. */
dmi = nbsd_dm_dict_to_dmi(dm_dict_out,_cmd_data_v4[dmt->type].cmd);
dmi = nbsd_dm_dict_to_dmi(task, _cmd_data_v4[dmt->type].cmd);
prop_object_release(dm_dict_in);
prop_object_release(dm_dict_out);
out:
libdm_task_destroy(task);
out:
return dmi;
bad:
return NULL;
@ -1162,7 +1113,7 @@ int dm_task_run(struct dm_task *dmt)
if ((dmt->type == DM_DEVICE_RELOAD) && dmt->suppress_identical_reload)
return _reload_with_suppression_v4(dmt);
if (!_open_control())
return 0;
@ -1192,7 +1143,7 @@ int dm_task_run(struct dm_task *dmt)
set_dev_node_read_ahead(dmt->dev_name, dmt->read_ahead,
dmt->read_ahead_flags);
break;
case DM_DEVICE_MKNODES:
if (dmi->flags & DM_EXISTS_FLAG)
add_dev_node(dmi->name, MAJOR(dmi->dev),

View File

@ -1,4 +1,4 @@
/* $NetBSD: libdm_netbsd.c,v 1.6 2010/12/23 17:44:33 christos Exp $ */
/* $NetBSD: libdm_netbsd.c,v 1.7 2011/02/08 03:26:12 haad Exp $ */
/*
* Copyright (c) 1996, 1997, 1998, 1999, 2002 The NetBSD Foundation, Inc.
@ -42,6 +42,7 @@
#include <unistd.h>
#include <stdbool.h>
#include <dm.h>
#include <dev/dm/netbsd-dm.h>
#include <dm-ioctl.h>
@ -51,10 +52,10 @@
#define DMI_SIZE 16 * 1024
static int dm_list_versions(prop_dictionary_t, struct dm_ioctl *);
static int dm_list_devices(prop_dictionary_t, struct dm_ioctl *);
static int dm_dev_deps(prop_dictionary_t, struct dm_ioctl *);
static int dm_table_status(prop_dictionary_t, struct dm_ioctl *);
static int dm_list_versions(libdm_task_t, struct dm_ioctl *);
static int dm_list_devices(libdm_task_t, struct dm_ioctl *);
static int dm_dev_deps(libdm_task_t, struct dm_ioctl *);
static int dm_table_status(libdm_task_t, struct dm_ioctl *);
int
nbsd_get_dm_major(uint32_t *major, int type)
@ -78,8 +79,7 @@ nbsd_get_dm_major(uint32_t *major, int type)
}
for (i = 0, val_len /= sizeof(*kd); i < val_len; i++) {
if (strncmp(kd[i].d_name,DM_NAME,strlen(kd[i].d_name)) == 0){
if (strncmp(kd[i].d_name,DM_NAME,strlen(kd[i].d_name)) == 0) {
if (type == DM_CHAR_MAJOR)
/* Set major to dm-driver char major number. */
@ -87,7 +87,6 @@ nbsd_get_dm_major(uint32_t *major, int type)
else
if (type == DM_BLOCK_MAJOR)
*major = kd[i].d_bmajor;
free(kd);
return 1;
@ -95,113 +94,89 @@ nbsd_get_dm_major(uint32_t *major, int type)
}
free(kd);
return 0;
}
int
nbsd_dmi_add_version(const int *version, prop_dictionary_t dm_dict)
{
prop_array_t ver;
size_t i;
if ((ver = prop_array_create()) == NULL)
return -1;
for (i=0;i<3;i++)
prop_array_set_uint32(ver,i,version[i]);
if ((prop_dictionary_set(dm_dict,"version",ver)) == false)
return -1;
prop_object_release(ver);
return 0;
}
struct dm_ioctl*
nbsd_dm_dict_to_dmi(prop_dictionary_t dm_dict,const int cmd)
nbsd_dm_dict_to_dmi(libdm_task_t task, const int cmd)
{
struct dm_ioctl *dmi;
prop_array_t ver;
size_t i;
int r;
char *name, *uuid;
uint32_t major,minor;
name = NULL;
uuid = NULL;
minor = 0;
nbsd_get_dm_major(&major, DM_BLOCK_MAJOR);
if (!(dmi = dm_malloc(DMI_SIZE)))
return NULL;
memset(dmi,0,DMI_SIZE);
prop_dictionary_get_int32(dm_dict, DM_IOCTL_OPEN, &dmi->open_count);
prop_dictionary_get_uint32(dm_dict, DM_IOCTL_EVENT, &dmi->event_nr);
prop_dictionary_get_uint32(dm_dict, DM_IOCTL_FLAGS, &dmi->flags);
prop_dictionary_get_uint32(dm_dict, DM_IOCTL_TARGET_COUNT,
&dmi->target_count);
memset(dmi, 0, DMI_SIZE);
if (prop_dictionary_get_uint32(dm_dict, DM_IOCTL_MINOR, &minor))
dmi->open_count = libdm_task_get_open_num(task);
dmi->event_nr = libdm_task_get_event_num(task);
dmi->flags = libdm_task_get_flags(task);
dmi->target_count = libdm_task_get_target_num(task);
minor = libdm_task_get_minor(task);
if (minor != 0)
dmi->dev = MKDEV(major, minor);
else
dmi->dev = 0;
name = libdm_task_get_name(task);
uuid = libdm_task_get_uuid(task);
/* Copy name and uuid to dm_ioctl. */
if (prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_NAME,
(const char **)&name)){
if (name != NULL)
strlcpy(dmi->name, name, DM_NAME_LEN);
} else
else
dmi->name[0] = '\0';
if (prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_UUID,
(const char **)&uuid)){
if (uuid != NULL)
strlcpy(dmi->uuid, uuid, DM_UUID_LEN);
} else
else
dmi->uuid[0] = '\0';
/* dmi parsing values, size of dmi block and offset to data. */
dmi->data_size = DMI_SIZE;
dmi->data_start = sizeof(struct dm_ioctl);
/* Get kernel version from dm_dict. */
ver = prop_dictionary_get(dm_dict,DM_IOCTL_VERSION);
for(i=0; i<3; i++)
prop_array_get_uint32(ver,i,&dmi->version[i]);
libdm_task_get_cmd_version(task, dmi->version, 3);
switch (cmd){
case DM_LIST_VERSIONS:
r = dm_list_versions(dm_dict,dmi);
r = dm_list_versions(task, dmi);
if (r >= 0)
dmi->target_count = r;
break;
case DM_LIST_DEVICES:
r = dm_list_devices(dm_dict,dmi);
r = dm_list_devices(task, dmi);
if (r >= 0)
dmi->target_count = r;
break;
break;
case DM_TABLE_STATUS:
r = dm_table_status(dm_dict,dmi);
r = dm_table_status(task, dmi);
if (r >= 0)
dmi->target_count = r;
break;
break;
case DM_TABLE_DEPS:
r = dm_dev_deps(dm_dict,dmi);
r = dm_dev_deps(task, dmi);
if (r >= 0)
dmi->target_count = r;
break;
}
break;
}
return dmi;
}
@ -212,21 +187,22 @@ nbsd_dm_dict_to_dmi(prop_dictionary_t dm_dict,const int cmd)
*/
static int
dm_list_versions(prop_dictionary_t dm_dict, struct dm_ioctl *dmi)
dm_list_versions(libdm_task_t task, struct dm_ioctl *dmi)
{
struct dm_target_versions *dmtv,*odmtv;
prop_array_t targets,ver;
prop_dictionary_t target_dict;
prop_object_iterator_t iter;
libdm_cmd_t cmd;
libdm_iter_t iter;
libdm_target_t target;
uint32_t ver[3];
char *name;
size_t j,i,slen,rec_size;
odmtv = NULL;
name = NULL;
j = 0;
dmtv = (struct dm_target_versions *)((uint8_t *)dmi + dmi->data_start);
/* printf("dmi: vers: %d.%d.%d data_size: %d data_start: %d name: %s t_count: %d\n",
@ -237,61 +213,55 @@ dm_list_versions(prop_dictionary_t dm_dict, struct dm_ioctl *dmi)
printf("dmtv: size: %p --- %p\n",dmtv,(struct dm_target_versions *)(dmi+312));*/
/* get prop_array of target_version dictionaries */
if ((targets = prop_dictionary_get(dm_dict,DM_IOCTL_CMD_DATA))){
if ((cmd = libdm_task_get_cmd(task)) == NULL)
return -ENOENT;
iter = prop_array_iterator(targets);
if (!iter)
err(EXIT_FAILURE,"dm_list_versions %s",__func__);
iter = libdm_cmd_iter_create(cmd);
while((target_dict = prop_object_iterator_next(iter)) != NULL){
j++;
prop_dictionary_get_cstring_nocopy(target_dict,
DM_TARGETS_NAME,(const char **)&name);
slen = strlen(name) + 1;
rec_size = sizeof(struct dm_target_versions) + slen + 1;
while((target = libdm_cmd_get_target(iter)) != NULL){
j++;
if (rec_size > dmi->data_size)
return -ENOMEM;
ver = prop_dictionary_get(target_dict,DM_TARGETS_VERSION);
for (i=0; i<3; i++)
prop_array_get_uint32(ver,i,&dmtv->version[i]);
name = libdm_target_get_name(target);
dmtv->next = rec_size;
slen = strlen(name) + 1;
rec_size = sizeof(struct dm_target_versions) + slen + 1;
strlcpy(dmtv->name,name,slen);
if (rec_size > dmi->data_size)
return -ENOMEM;
odmtv = dmtv;
dmtv =(struct dm_target_versions *)((uint8_t *)dmtv + rec_size);
}
libdm_target_get_version(target, dmtv->version, sizeof(ver));
if (odmtv != NULL)
odmtv->next = 0;
}
dmtv->next = rec_size;
strlcpy(dmtv->name,name,slen);
odmtv = dmtv;
dmtv =(struct dm_target_versions *)((uint8_t *)dmtv + rec_size);
libdm_target_destroy(target);
}
if (odmtv != NULL)
odmtv->next = 0;
libdm_iter_destroy(iter);
prop_object_iterator_release(iter);
return j;
}
/*
* List all available dm devices in system.
*/
* List all available dm devices in system.
*/
static int
dm_list_devices(prop_dictionary_t dm_dict, struct dm_ioctl *dmi)
dm_list_devices(libdm_task_t task, struct dm_ioctl *dmi)
{
struct dm_name_list *dml,*odml;
prop_array_t targets;
prop_dictionary_t target_dict;
prop_object_iterator_t iter;
libdm_cmd_t cmd;
libdm_iter_t iter;
libdm_dev_t dev;
uint32_t minor;
uint32_t major;
char *name;
size_t j,slen,rec_size;
@ -300,170 +270,150 @@ dm_list_devices(prop_dictionary_t dm_dict, struct dm_ioctl *dmi)
minor = 0;
j = 0;
nbsd_get_dm_major(&major,DM_BLOCK_MAJOR);
nbsd_get_dm_major(&major, DM_BLOCK_MAJOR);
dml = (struct dm_name_list *)((uint8_t *)dmi + dmi->data_start);
if ((targets = prop_dictionary_get(dm_dict,DM_IOCTL_CMD_DATA))){
if ((cmd = libdm_task_get_cmd(task)) == NULL)
return -ENOENT;
iter = prop_array_iterator(targets);
if (!iter)
err(EXIT_FAILURE,"dm_list_devices %s",__func__);
iter = libdm_cmd_iter_create(cmd);
while((target_dict = prop_object_iterator_next(iter)) != NULL){
while((dev = libdm_cmd_get_dev(iter)) != NULL){
prop_dictionary_get_cstring_nocopy(target_dict,
DM_DEV_NAME,(const char **)&name);
name = libdm_dev_get_name(dev);
minor = libdm_dev_get_minor(dev);
dml->dev = MKDEV(major, minor);
prop_dictionary_get_uint32(target_dict,DM_DEV_DEV,&minor);
slen = strlen(name) + 1;
rec_size = sizeof(struct dm_name_list) + slen + 1;
dml->dev = MKDEV(major,minor);
slen = strlen(name) + 1;
rec_size = sizeof(struct dm_name_list) + slen + 1;
if (rec_size > dmi->data_size)
return -ENOMEM;
if (rec_size > dmi->data_size)
return -ENOMEM;
dml->next = rec_size;
strlcpy(dml->name,name,slen);
odml = dml;
dml =(struct dm_name_list *)((uint8_t *)dml + rec_size);
dml->next = rec_size;
strlcpy(dml->name, name, slen);
odml = dml;
dml =(struct dm_name_list *)((uint8_t *)dml + rec_size);
j++;
j++;
}
if (odml != NULL)
odml->next = 0;
libdm_dev_destroy(dev);
}
prop_object_iterator_release(iter);
if (odml != NULL)
odml->next = 0;
libdm_iter_destroy(iter);
return j;
}
/*
* Print status of each table, target arguments, start sector,
* Print status of each table, target arguments, start sector,
* size and target name.
*/
static int
dm_table_status(prop_dictionary_t dm_dict,struct dm_ioctl *dmi)
dm_table_status(libdm_task_t task, struct dm_ioctl *dmi)
{
struct dm_target_spec *dmts, *odmts;
prop_array_t targets;
prop_dictionary_t target_dict;
prop_object_iterator_t iter;
libdm_cmd_t cmd;
libdm_table_t table;
libdm_iter_t iter;
uint32_t flags;
char *type,*params,*params_start;
char *type, *params, *params_start;
size_t j, plen, rec_size, next;
bool prm;
size_t j,plen,rec_size,next;
j = 0;
next = 0;
j = next = rec_size = 0;
params = NULL;
odmts = NULL;
rec_size = 0;
plen = -1;
prm = false;
dmts = (struct dm_target_spec *)((uint8_t *)dmi + dmi->data_start);
if ((targets = prop_dictionary_get(dm_dict,DM_IOCTL_CMD_DATA))){
iter = prop_array_iterator(targets);
if (!iter)
err(EXIT_FAILURE,"dm_table_status %s",__func__);
dmts = (struct dm_target_spec *)((uint8_t *)dmi + dmi->data_start);
while((target_dict = prop_object_iterator_next(iter)) != NULL){
if ((cmd = libdm_task_get_cmd(task)) == NULL)
return ENOENT;
prop_dictionary_get_cstring_nocopy(target_dict,
DM_TABLE_TYPE,(const char **)&type);
iter = libdm_cmd_iter_create(cmd);
prm = prop_dictionary_get_cstring_nocopy(target_dict,
DM_TABLE_PARAMS,(const char **)&params);
while ((table = libdm_cmd_get_table(iter)) != NULL) {
dmts->sector_start = libdm_table_get_start(table);
dmts->length = libdm_table_get_length(table);
dmts->status = libdm_table_get_status(table);
prop_dictionary_get_uint64(target_dict,DM_TABLE_START,&dmts->sector_start);
prop_dictionary_get_uint64(target_dict,DM_TABLE_LENGTH,&dmts->length);
prop_dictionary_get_int32(target_dict,DM_TABLE_STAT,&dmts->status);
type = libdm_table_get_target(table);
params = libdm_table_get_params(table);
if (prm)
plen = strlen(params) + 1;
if (params != NULL)
plen = strlen(params) + 1;
rec_size = sizeof(struct dm_target_spec) + plen;
rec_size = sizeof(struct dm_target_spec) + plen;
/*
* In linux when copying table status from kernel next is
* number of bytes from the start of the first dm_target_spec
* structure. I don't know why but, it has to be done this way.
*/
next += rec_size;
if (rec_size > dmi->data_size)
return -ENOMEM;
/*
* In linux when copying table status from kernel next is
* number of bytes from the start of the first dm_target_spec
* structure. I don't know why but, it has to be done this way.
*/
next += rec_size;
dmts->next = next;
strlcpy(dmts->target_type, type, DM_MAX_TYPE_NAME);
if (rec_size > dmi->data_size)
return -ENOMEM;
params_start = (char *)dmts + sizeof(struct dm_target_spec);
dmts->next = next;
strlcpy(dmts->target_type, type, DM_MAX_TYPE_NAME);
params_start = (char *)dmts + sizeof(struct dm_target_spec);
if (prm)
strlcpy(params_start, params, plen);
else
params_start = "\0";
if (params != NULL)
strlcpy(params_start, params, plen);
else
params_start = "\0";
odmts = dmts;
dmts = (struct dm_target_spec *)((uint8_t *)dmts + rec_size);
odmts = dmts;
dmts = (struct dm_target_spec *)((uint8_t *)dmts + rec_size);
j++;
j++;
}
libdm_table_destroy(table);
}
if (odmts != NULL)
odmts->next = 0;
}
prop_object_iterator_release(iter);
if (odmts != NULL)
odmts->next = 0;
libdm_iter_destroy(iter);
return j;
}
/*
* Print dm device dependiences, get minor/major number for
* devices. From kernel I will receive major:minor number of
* block device used with target. I have to translate it to
* raw device numbers and use them, because all other parts of lvm2
* uses raw devices internaly.
* Print dm device dependiences, get minor/major number for
* devices. From kernel I will receive major:minor number of
* block device used with target. I have to translate it to
* raw device numbers and use them, because all other parts of lvm2
* uses raw devices internally.
*/
static int
dm_dev_deps(prop_dictionary_t dm_dict, struct dm_ioctl *dmi)
dm_dev_deps(libdm_task_t task, struct dm_ioctl *dmi)
{
struct dm_target_deps *dmtd;
struct kinfo_drivers *kd;
prop_array_t targets;
prop_object_iterator_t iter;
libdm_cmd_t cmd;
libdm_iter_t iter;
dev_t dev_deps;
uint32_t major;
size_t val_len, i, j;
uint64_t dev_tmp;
dev_tmp = 0;
dev_deps = 0;
j = 0;
i = 0;
if (sysctlbyname("kern.drivers",NULL,&val_len,NULL,0) < 0) {
printf("sysctlbyname failed");
return 0;
}
if ((kd = malloc (val_len)) == NULL){
if ((kd = malloc(val_len)) == NULL){
printf("malloc kd info error\n");
return 0;
}
@ -472,35 +422,31 @@ dm_dev_deps(prop_dictionary_t dm_dict, struct dm_ioctl *dmi)
printf("sysctlbyname failed kd");
return 0;
}
dmtd = (struct dm_target_deps *)((uint8_t *)dmi + dmi->data_start);
if ((targets = prop_dictionary_get(dm_dict, DM_IOCTL_CMD_DATA))){
if ((cmd = libdm_task_get_cmd(task)) == NULL)
return -ENOENT;
iter = prop_array_iterator(targets);
if (!iter)
err(EXIT_FAILURE,"dm_target_deps %s", __func__);
iter = libdm_cmd_iter_create(cmd);
while((prop_object_iterator_next(iter)) != NULL){
prop_array_get_uint64(targets, j, &dev_tmp);
for (i = 0, val_len /= sizeof(*kd); i < val_len; i++){
if (kd[i].d_bmajor == MAJOR(dev_tmp)) {
major = kd[i].d_cmajor;
break;
}
while((dev_deps = libdm_cmd_get_deps(iter)) != 0) {
for (i = 0, val_len /= sizeof(*kd); i < val_len; i++){
if (kd[i].d_bmajor == MAJOR(dev_deps)) {
major = kd[i].d_cmajor;
break;
}
dmtd->dev[j] = MKDEV(major,MINOR(dev_tmp));
j++;
}
}
dmtd->dev[j] = MKDEV(major, MINOR(dev_deps));
j++;
}
dmtd->count = j;
prop_object_iterator_release(iter);
libdm_iter_destroy(iter);
free(kd);
return j;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: libdm-netbsd.h,v 1.1 2009/12/05 11:38:40 haad Exp $
/* $NetBSD: libdm-netbsd.h,v 1.2 2011/02/08 03:26:13 haad Exp $
/*
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@ -33,6 +33,7 @@
#define __LIB_DM_H__
#include <prop/proplib.h>
#include <libdm.h>
# define MAJOR(x) major((x))
# define MINOR(x) minor((x))
@ -48,11 +49,9 @@
/* libdm_netbsd.c */
int nbsd_get_dm_major(uint32_t *, int); /* Get dm device major numbers */
int nbsd_dmi_add_cmd(const char *, prop_dictionary_t);
int nbsd_dmi_add_version(const int [3], prop_dictionary_t);
int nbsd_dm_add_uint(const char *, uint64_t, prop_dictionary_t);
int nbsd_dm_add_str(const char *, char *, prop_dictionary_t );
int nbsd_dmi_add_cmd(const char *, libdm_task_t);
int nbsd_dmi_add_version(const int [3], libdm_task_t);
struct dm_ioctl* nbsd_dm_dict_to_dmi(prop_dictionary_t, const int);
struct dm_ioctl* nbsd_dm_dict_to_dmi(libdm_task_t, const int);
#endif /* __NETBSD_DM_H__ */

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.5 2010/12/23 17:46:55 christos Exp $
# $NetBSD: Makefile,v 1.6 2011/02/08 03:26:13 haad Exp $
USE_FORT?= no
NOLINT= #defined
@ -13,6 +13,8 @@ MAN= dmsetup.8
BINDIR= /sbin
#CFLAGS+= -g -O0
CPPFLAGS+= -I${LIBDM_DISTDIR}/ -I${LIBDM_DISTDIR}/misc \
-I. -I${LIBDM_DISTDIR}/ioctl -I${LVM2_DISTDIR}/include
@ -22,8 +24,9 @@ LIBDM_OBJDIR!= cd ${LIBDM_SRCDIR} && ${PRINTOBJDIR}
LDADD+= -L${LIBDM_OBJDIR} -ldevmapper
DPADD+= ${LIBDM_OBJDIR}/libdevmapper.a
LDADD+= -lprop
LDADD+= -ldm -lprop
LDSTATIC= -static
.PATH: ${LVM2_DISTDIR}/tools
.include <bsd.prog.mk>

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.7 2009/12/01 23:12:51 haad Exp $
# $NetBSD: Makefile,v 1.8 2011/02/08 03:26:13 haad Exp $
USE_FORT?= no
NOLINT= #defined
@ -99,7 +99,7 @@ LIBDM_OBJDIR!= cd ${LIBDM_SRCDIR} && ${PRINTOBJDIR}
LDADD+= -L${LIBDM_OBJDIR} -ldevmapper
DPADD+= ${LIBDM_OBJDIR}/libdevmapper.a
LDADD+= -lprop -ledit -ltermcap
LDADD+= -ldm -lprop -ledit -ltermcap
LDSTATIC= -static