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

libdm: introduce dm_get_status_mirror

Add missing function to parse mirror status.
This commit is contained in:
Zdenek Kabelac 2015-11-30 21:16:43 +01:00
parent 46c8d6bb8a
commit fa87979004
4 changed files with 152 additions and 15 deletions

View File

@ -1,5 +1,6 @@
Version 1.02.113 - Version 1.02.113 -
===================================== =====================================
Add dm_get_status_mirror() for parsing mirror status line.
Version 1.02.112 - 28th November 2015 Version 1.02.112 - 28th November 2015
===================================== =====================================

View File

@ -0,0 +1 @@
dm_get_status_mirror

View File

@ -127,6 +127,7 @@ enum {
* each ioctl command you want to execute. * each ioctl command you want to execute.
*/ */
struct dm_pool;
struct dm_task; struct dm_task;
struct dm_timestamp; struct dm_timestamp;
@ -281,17 +282,43 @@ void *dm_get_next_target(struct dm_task *dmt,
char **target_type, char **params); char **target_type, char **params);
/* /*
* Parse params from STATUS call for raid target * Following dm_get_status_* functions will allocate approriate status structure
* from passed mempool together with the necessary character arrays.
* Destroying the mempool will release all asociated allocation.
*/ */
struct dm_pool;
/* /* Parse params from STATUS call for mirror target */
* dm_get_status_raid will allocate the dm_status_raid structure and typedef enum {
* the necessary character arrays from the mempool provided to the DM_STATUS_MIRROR_ALIVE = 'A',/* No failures */
* function. If the mempool is from a dev_manager struct (dm->mem), DM_STATUS_MIRROR_FLUSH_FAILED = 'F',/* Mirror out-of-sync */
* then the caller does not need to free the memory - simply calling DM_STATUS_MIRROR_WRITE_FAILED = 'D',/* Mirror out-of-sync */
* dev_manager_destroy will do. DM_STATUS_MIRROR_SYNC_FAILED = 'S',/* Mirror out-of-sync */
*/ DM_STATUS_MIRROR_READ_FAILED = 'R',/* Mirror data unaffected */
DM_STATUS_MIRROR_UNCLASSIFIED = 'U' /* Bug */
} dm_status_mirror_health_t;
struct dm_status_mirror {
uint64_t total_regions;
uint64_t insync_regions;
uint32_t dev_count;
struct {
dm_status_mirror_health_t health;
uint32_t major;
uint32_t minor;
} *devs;
const char *log_type;
uint32_t log_count;
struct {
dm_status_mirror_health_t health;
uint32_t major;
uint32_t minor;
} *logs;
};
int dm_get_status_mirror(struct dm_pool *mem, const char *params,
struct dm_status_mirror **status);
/* Parse params from STATUS call for raid target */
struct dm_status_raid { struct dm_status_raid {
uint64_t reserved; uint64_t reserved;
uint64_t total_regions; uint64_t total_regions;
@ -306,6 +333,7 @@ struct dm_status_raid {
int dm_get_status_raid(struct dm_pool *mem, const char *params, int dm_get_status_raid(struct dm_pool *mem, const char *params,
struct dm_status_raid **status); struct dm_status_raid **status);
/* Parse params from STATUS call for cache target */
struct dm_status_cache { struct dm_status_cache {
uint64_t version; /* zero for now */ uint64_t version; /* zero for now */
@ -341,6 +369,8 @@ int dm_get_status_cache(struct dm_pool *mem, const char *params,
struct dm_status_cache **status); struct dm_status_cache **status);
/* /*
* Parse params from STATUS call for snapshot target
*
* Snapshot target's format: * Snapshot target's format:
* <= 1.7.0: <used_sectors>/<total_sectors> * <= 1.7.0: <used_sectors>/<total_sectors>
* >= 1.8.0: <used_sectors>/<total_sectors> <metadata_sectors> * >= 1.8.0: <used_sectors>/<total_sectors> <metadata_sectors>
@ -358,9 +388,7 @@ struct dm_status_snapshot {
int dm_get_status_snapshot(struct dm_pool *mem, const char *params, int dm_get_status_snapshot(struct dm_pool *mem, const char *params,
struct dm_status_snapshot **status); struct dm_status_snapshot **status);
/* /* Parse params from STATUS call for thin_pool target */
* Parse params from STATUS call for thin_pool target
*/
typedef enum { typedef enum {
DM_THIN_DISCARDS_IGNORE, DM_THIN_DISCARDS_IGNORE,
DM_THIN_DISCARDS_NO_PASSDOWN, DM_THIN_DISCARDS_NO_PASSDOWN,
@ -385,9 +413,7 @@ struct dm_status_thin_pool {
int dm_get_status_thin_pool(struct dm_pool *mem, const char *params, int dm_get_status_thin_pool(struct dm_pool *mem, const char *params,
struct dm_status_thin_pool **status); struct dm_status_thin_pool **status);
/* /* Parse params from STATUS call for thin target */
* Parse params from STATUS call for thin target
*/
struct dm_status_thin { struct dm_status_thin {
uint64_t mapped_sectors; uint64_t mapped_sectors;
uint64_t highest_mapped_sector; uint64_t highest_mapped_sector;

View File

@ -355,3 +355,112 @@ int dm_get_status_thin(struct dm_pool *mem, const char *params,
return 1; return 1;
} }
/*
* dm core parms: 0 409600 mirror
* Mirror core parms: 2 253:4 253:5 400/400
* New-style failure params: 1 AA
* New-style log params: 3 cluster 253:3 A
* or 3 disk 253:3 A
* or 1 core
*/
#define DM_MIRROR_MAX_IMAGES 8 /* limited by kernel DM_KCOPYD_MAX_REGIONS */
int dm_get_status_mirror(struct dm_pool *mem, const char *params,
struct dm_status_mirror **status)
{
struct dm_status_mirror *s;
const char *p, *pos = params;
unsigned num_devs, argc, i;
int used;
if (!(s = dm_pool_zalloc(mem, sizeof(*s)))) {
log_error("Failed to alloc mem pool to parse mirror status.");
return 0;
}
if (sscanf(pos, "%u %n", &num_devs, &used) != 1)
goto_out;
pos += used;
if (num_devs > DM_MIRROR_MAX_IMAGES) {
log_error(INTERNAL_ERROR "More then " DM_TO_STRING(DM_MIRROR_MAX_IMAGES)
" reported in mirror status.");
goto out;
}
if (!(s->devs = dm_pool_alloc(mem, num_devs * sizeof(*(s->devs))))) {
log_error("Allocation of devs failed.");
goto out;
}
for (i = 0; i < num_devs; ++i, pos += used)
if (sscanf(pos, "%u:%u %n",
&(s->devs[i].major), &(s->devs[i].minor), &used) != 2)
goto_out;
if (sscanf(pos, FMTu64 "/" FMTu64 "%n",
&s->insync_regions, &s->total_regions, &used) != 2)
goto_out;
pos += used;
if (sscanf(pos, "%u %n", &argc, &used) != 1)
goto_out;
pos += used;
for (i = 0; i < num_devs ; ++i)
s->devs[i].health = pos[i];
if (!(pos = _advance_to_next_word(pos, argc)))
goto_out;
if (sscanf(pos, "%u %n", &argc, &used) != 1)
goto_out;
pos += used;
if (argc == 1) {
/* core, cluster-core */
if (!(s->log_type = dm_pool_strdup(mem, pos))) {
log_error("Allocation of log type string failed.");
goto out;
}
} else {
if (!(p = _advance_to_next_word(pos, 1)))
goto_out;
/* disk, cluster-disk */
if (!(s->log_type = dm_pool_strndup(mem, pos, p - pos - 1))) {
log_error("Allocation of log type string failed.");
goto out;
}
pos = p;
if ((argc > 2) && !strcmp(s->log_type, "disk")) {
s->log_count = argc - 2;
if (!(s->logs = dm_pool_alloc(mem, s->log_count * sizeof(*(s->logs))))) {
log_error("Allocation of logs failed.");
goto out;
}
for (i = 0; i < s->log_count; ++i, pos += used)
if (sscanf(pos, "%u:%u %n",
&s->logs[i].major, &s->logs[i].minor, &used) != 2)
goto_out;
for (i = 0; i < s->log_count; ++i)
s->logs[i].health = pos[i];
}
}
s->dev_count = num_devs;
*status = s;
return 1;
out:
log_error("Failed to parse mirror status %s.", params);
dm_pool_free(mem, s);
*status = NULL;
return 0;
}