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:
parent
05dba2d9c0
commit
f6524657fa
@ -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;
|
||||||
|
@ -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.
|
||||||
*/
|
*/
|
||||||
|
@ -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, ¶ms);
|
||||||
|
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}
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user