]> sourceware.org Git - lvm2.git/commitdiff
vdo_manip: parsing status of VDO device
authorZdenek Kabelac <zkabelac@redhat.com>
Mon, 2 Jul 2018 15:20:30 +0000 (17:20 +0200)
committerZdenek Kabelac <zkabelac@redhat.com>
Mon, 9 Jul 2018 13:28:35 +0000 (15:28 +0200)
lib/activate/activate.h
lib/activate/dev_manager.c
lib/metadata/metadata-exported.h
lib/metadata/vdo_manip.c

index 09cd68852e40b64e8560910c6ac98b3855219918..6d70f64fabe528160768eb0411a86bae523d959c 100644 (file)
@@ -37,6 +37,7 @@ typedef enum {
        SEG_STATUS_SNAPSHOT,
        SEG_STATUS_THIN,
        SEG_STATUS_THIN_POOL,
+       SEG_STATUS_VDO_POOL,
        SEG_STATUS_UNKNOWN
 } lv_seg_status_type_t;
 
@@ -50,6 +51,7 @@ struct lv_seg_status {
                struct dm_status_snapshot *snapshot;
                struct dm_status_thin *thin;
                struct dm_status_thin_pool *thin_pool;
+               struct lv_status_vdo vdo_pool;
        };
 };
 
index 07fc93e4fe4688a578baaa4da4cc1096a2178e26..25d5e697261f687ea18d5f5d423fff96bee1735a 100644 (file)
@@ -209,6 +209,10 @@ static int _get_segment_status_from_target_params(const char *target_name,
                if (!dm_get_status_snapshot(seg_status->mem, params, &seg_status->snapshot))
                        return_0;
                seg_status->type = SEG_STATUS_SNAPSHOT;
+       } else if (segtype_is_vdo_pool(segtype)) {
+               if (!parse_vdo_pool_status(seg_status->mem, seg->lv, params, &seg_status->vdo_pool))
+                       return_0;
+               seg_status->type = SEG_STATUS_VDO_POOL;
        } else
                /*
                 * TODO: Add support for other segment types too!
index b2211391475c51d0e7138c3b454a0d9964223698..b6ac4cb974ebab3a62f7a4b1d19d50dbbcb730c0 100644 (file)
@@ -1250,11 +1250,21 @@ int wipe_cache_pool(struct logical_volume *cache_pool_lv);
 
 
 /* ++  metadata/vdo_manip.c */
+struct lv_status_vdo {
+       struct dm_pool *mem;
+       struct dm_vdo_status *vdo;
+       uint64_t data_blocks_used;      /* grabbed from /sys/kvdo */
+       uint64_t logical_blocks_used;   /* grabbed from /sys/kvdo */
+       dm_percent_t usage;
+       dm_percent_t saving;
+};
 
 const char *get_vdo_compression_state_name(enum dm_vdo_compression_state state);
 const char *get_vdo_index_state_name(enum dm_vdo_index_state state);
 const char *get_vdo_operating_mode_name(enum dm_vdo_operating_mode mode);
 uint64_t get_vdo_pool_virtual_size(const struct lv_segment *vdo_pool_seg);
+int parse_vdo_pool_status(struct dm_pool *mem, const struct logical_volume *vdo_pool_lv,
+                         const char *params, struct lv_status_vdo *status);
 struct logical_volume *convert_vdo_pool_lv(struct logical_volume *data_lv,
                                           const struct dm_vdo_target_params *vtp,
                                           uint32_t *virtual_extents);
index 8aee3dc0093489b1d9f61856e0481993285144d7..5801a1b59134d9bed744838e9ba1832a85a208bd 100644 (file)
@@ -93,6 +93,89 @@ uint64_t get_vdo_pool_virtual_size(const struct lv_segment *vdo_pool_seg)
                                 vdo_pool_seg->vdo_pool_header_size);
 }
 
+static int _sysfs_get_kvdo_value(const char *dm_name, const char *vdo_param, uint64_t *value)
+{
+       char path[PATH_MAX];
+       char temp[64];
+       int fd, size, r = 0;
+
+       if (dm_snprintf(path, sizeof(path), "%skvdo/%s/%s",
+                       dm_sysfs_dir(), dm_name, vdo_param) < 0) {
+               log_error("Failed to build kmod path.");
+               goto bad;
+       }
+
+       if ((fd = open(path, O_RDONLY)) < 0) {
+               if (errno != ENOENT)
+                       log_sys_error("open", path);
+               else
+                       log_sys_debug("open", path);
+               goto bad;
+       }
+
+       if ((size = read(fd, temp, sizeof(temp) - 1)) < 0) {
+               log_sys_error("read", path);
+               goto bad;
+       }
+       temp[size] = 0;
+       errno = 0;
+       *value = strtoll(temp, NULL, 0);
+       if (errno) {
+               log_sys_error("strtool", path);
+               goto bad;
+       }
+
+       r = 1;
+bad:
+       if (fd >= 0 && close(fd))
+               log_sys_error("close", path);
+
+       return r;
+}
+
+int parse_vdo_pool_status(struct dm_pool *mem, const struct logical_volume *vdo_pool_lv,
+                         const char *params, struct lv_status_vdo *status)
+{
+       struct dm_vdo_status_parse_result result;
+       char *dm_name;
+
+       status->usage = DM_PERCENT_INVALID;
+       status->saving = DM_PERCENT_INVALID;
+
+       if (!(dm_name = dm_build_dm_name(mem, vdo_pool_lv->vg->name,
+                                        vdo_pool_lv->name, NULL))) {
+               log_error("Failed to build VDO DM name %s.",
+                         display_lvname(vdo_pool_lv));
+               return 0;
+       }
+
+       if (!dm_vdo_status_parse(mem, params, &result)) {
+               log_error("Cannot parse %s VDO pool status %s.",
+                         display_lvname(vdo_pool_lv), result.error);
+               return 0;
+       }
+
+       status->vdo = result.status;
+
+       if (result.status->operating_mode == DM_VDO_MODE_NORMAL) {
+               if (!_sysfs_get_kvdo_value(dm_name, "statistics/data_blocks_used",
+                                          &status->data_blocks_used))
+                       return_0;
+
+               if (!_sysfs_get_kvdo_value(dm_name, "statistics/logical_blocks_used",
+                                          &status->logical_blocks_used))
+                       return_0;
+
+               status->usage = dm_make_percent(result.status->used_blocks,
+                                               result.status->total_blocks);
+               status->saving = dm_make_percent(status->logical_blocks_used - status->data_blocks_used,
+                                                status->logical_blocks_used);
+       }
+
+       return 1;
+}
+
+
 /*
  * Formats data LV for a use as a VDO pool LV.
  *
This page took 0.047026 seconds and 5 git commands to generate.