1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00

Add features to get table/status & wait for next event.

This commit is contained in:
Patrick Caulfield 2002-05-03 11:55:58 +00:00
parent 05dba2d9c0
commit f6524657fa
3 changed files with 149 additions and 8 deletions

View File

@ -35,9 +35,20 @@ static char *dm_cmd_list[] = {
"info", "info",
"deps", "deps",
"rename", "rename",
"version" "version",
"status",
"table",
"waitevent"
}; };
static void *_align(void *ptr, unsigned int a)
{
register unsigned long align = --a;
return (void *) (((unsigned long) ptr + align) & ~align);
}
void dm_task_destroy(struct dm_task *dmt) void dm_task_destroy(struct dm_task *dmt)
{ {
struct target *t, *n; struct target *t, *n;
@ -74,6 +85,49 @@ int dm_task_get_driver_version(struct dm_task *dmt, char *version, size_t size)
return 1; return 1;
} }
void *dm_get_next_target(struct dm_task *dmt, void *next, unsigned long long *start,
unsigned long long *length,
char **target_type,
char **params)
{
struct target *t;
if (!next)
next = dmt->head;
t = next;
if (t) {
*start = t->start;
*length = t->length;
*target_type = t->type;
*params = t->params;
return t->next;
}
return NULL;
}
/* Unmarshall the target info returned from a status call */
static int unmarshal_status(struct dm_task *dmt, struct dm_ioctl *dmi)
{
char *outbuf = (char *)dmi + sizeof(struct dm_ioctl);
char *outptr = outbuf;
int i;
for (i=0; i < dmi->target_count; i++) {
struct dm_target_spec *spec = (struct dm_target_spec *)outptr;
if (!dm_task_add_target(dmt, spec->sector_start, spec->length,
spec->target_type, outptr+sizeof(*spec)))
return 0;
outptr += sizeof(struct dm_target_spec);
outptr += strlen(outptr) + 1;
_align(outptr, ALIGNMENT);
}
return 1;
}
int dm_task_get_info(struct dm_task *dmt, struct dm_info *info) int dm_task_get_info(struct dm_task *dmt, struct dm_info *info)
{ {
if (!dmt->dmi) if (!dmt->dmi)
@ -154,13 +208,6 @@ struct target *create_target(uint64_t start,
return NULL; return NULL;
} }
static void *_align(void *ptr, unsigned int a)
{
register unsigned long align = --a;
return (void *) (((unsigned long) ptr + align) & ~align);
}
static void *_add_target(struct target *t, void *out, void *end) static void *_add_target(struct target *t, void *out, void *end)
{ {
void *out_sp = out; void *out_sp = out;
@ -334,6 +381,19 @@ int dm_task_run(struct dm_task *dmt)
command = DM_VERSION; command = DM_VERSION;
break; break;
case DM_DEVICE_STATUS:
command = DM_GET_STATUS;
break;
case DM_DEVICE_TABLE:
dmi->flags |= DM_STATUS_TABLE_FLAG;
command = DM_GET_STATUS;
break;
case DM_DEVICE_WAITEVENT:
command = DM_WAIT_EVENT;
break;
default: default:
log_error("Internal error: unknown device-mapper task %d", log_error("Internal error: unknown device-mapper task %d",
dmt->type); dmt->type);
@ -360,6 +420,12 @@ int dm_task_run(struct dm_task *dmt)
case DM_DEVICE_RENAME: case DM_DEVICE_RENAME:
rename_dev_node(dmt->dev_name, dmt->newname); rename_dev_node(dmt->dev_name, dmt->newname);
break; break;
case DM_DEVICE_STATUS:
case DM_DEVICE_TABLE:
if (!unmarshal_status(dmt, dmi))
goto bad;
break;
} }
dmt->dmi = dmi; dmt->dmi = dmi;

View File

@ -44,6 +44,10 @@ enum {
DM_DEVICE_RENAME, DM_DEVICE_RENAME,
DM_DEVICE_VERSION, DM_DEVICE_VERSION,
DM_DEVICE_STATUS,
DM_DEVICE_TABLE,
DM_DEVICE_WAITEVENT
}; };
struct dm_task; struct dm_task;
@ -91,6 +95,13 @@ int dm_task_add_target(struct dm_task *dmt,
uint64_t start, uint64_t start,
uint64_t size, const char *ttype, const char *params); uint64_t size, const char *ttype, const char *params);
/* Use this to retrive target information returned from a STATUS call */
void *dm_get_next_target(struct dm_task *dmt,
void *next, unsigned long long *start,
unsigned long long *length,
char **target_type,
char **params);
/* /*
* Call this to actually run the ioctl. * Call this to actually run the ioctl.
*/ */

View File

@ -227,6 +227,67 @@ static int _resume(int argc, char **argv)
return _simple(DM_DEVICE_RESUME, argv[1]); return _simple(DM_DEVICE_RESUME, argv[1]);
} }
static int _wait(int argc, char **argv)
{
struct dm_task *dmt;
if (!(dmt = dm_task_create(DM_DEVICE_WAITEVENT)))
return 0;
if (!dm_task_set_name(dmt, argv[1]))
goto out;
if (!dm_task_run(dmt))
goto out;
dm_task_destroy(dmt);
out:
return 1;
}
static int _status(int argc, char **argv)
{
int r = 0;
struct dm_task *dmt;
void *next = NULL;
unsigned long long start, length;
char *target_type = NULL;
char *params;
int cmd;
if (strcmp(argv[0], "status") == 0)
cmd = DM_DEVICE_STATUS;
else
cmd = DM_DEVICE_TABLE;
if (!(dmt = dm_task_create(cmd)))
return 0;
if (!dm_task_set_name(dmt, argv[1]))
goto out;
if (!dm_task_run(dmt))
goto out;
/* Fetch targets and print 'em */
do {
next = dm_get_next_target(dmt, next, &start, &length,
&target_type, &params);
if (target_type) {
printf("%lld %lld %s %s\n",
start, length, target_type, params);
}
} while (next);
r = 1;
out:
dm_task_destroy(dmt);
return r;
}
static int _info(int argc, char **argv) static int _info(int argc, char **argv)
{ {
int r = 0; int r = 0;
@ -345,6 +406,9 @@ static struct command _commands[] = {
{"info", "<dev_name>", 1, 1, _info}, {"info", "<dev_name>", 1, 1, _info},
{"deps", "<dev_name>", 1, 1, _deps}, {"deps", "<dev_name>", 1, 1, _deps},
{"rename", "<dev_name> <new_name>", 2, 2, _rename}, {"rename", "<dev_name> <new_name>", 2, 2, _rename},
{"status", "<dev_name>", 1, 1, _status},
{"table", "<dev_name>", 1, 1, _status},
{"wait", "<dev_name>", 1, 1, _wait},
{"version", "", 0, 0, _version}, {"version", "", 0, 0, _version},
{NULL, NULL, 0, 0, NULL} {NULL, NULL, 0, 0, NULL}
}; };