mirror of
git://sourceware.org/git/lvm2.git
synced 2025-09-27 05:44:18 +03:00
Compare commits
1 Commits
v2_03_22
...
dev-agk-fs
Author | SHA1 | Date | |
---|---|---|---|
|
60e50072e5 |
@@ -283,4 +283,26 @@ FIELD(PVSEGS, pvseg, NUM, "SSize", len, 0, uint32, pvseg_size, "Number of extent
|
||||
/*
|
||||
* End of PVSEGS type fields
|
||||
*/
|
||||
|
||||
/*
|
||||
* MOUNTINFO type fields
|
||||
*/
|
||||
FIELD(MOUNTINFO, mountinfo, STR, "Mounted on", mountpoint, 0, string, mount_point, "Mount point of filesystem on device.", 0)
|
||||
/*
|
||||
* End of MOUNTINFO type fields
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* FSINFO type fields
|
||||
*/
|
||||
FIELD(FSINFO, fsinfo, SIZ, "FSUsed", fs_used, 0, size64, fs_used, "Space used in mounted filesystem on device.", 0)
|
||||
FIELD(FSINFO, fsinfo, SIZ, "FSSize", fs_size, 0, size64, fs_size, "Size of mounted filesystem on device.", 0)
|
||||
FIELD(FSINFO, fsinfo, SIZ, "FSFree", fs_free, 0, size64, fs_free, "Free space in mounted filesystem on device.", 0)
|
||||
FIELD(FSINFO, fsinfo, SIZ, "FSAvail", fs_avail, 0, size64, fs_avail, "Available space in mounted filesystem on device.", 0)
|
||||
/*
|
||||
* End of FSINFO type fields
|
||||
*/
|
||||
|
||||
|
||||
/* *INDENT-ON* */
|
||||
|
@@ -520,6 +520,16 @@ GET_PVSEG_NUM_PROPERTY_FN(pvseg_start, pvseg->pe)
|
||||
GET_PVSEG_NUM_PROPERTY_FN(pvseg_size, (SECTOR_SIZE * pvseg->len))
|
||||
#define _pvseg_size_set prop_not_implemented_set
|
||||
|
||||
#define _mount_point_get prop_not_implemented_get
|
||||
#define _mount_point_set prop_not_implemented_set
|
||||
#define _fs_used_get prop_not_implemented_get
|
||||
#define _fs_used_set prop_not_implemented_set
|
||||
#define _fs_size_get prop_not_implemented_get
|
||||
#define _fs_size_set prop_not_implemented_set
|
||||
#define _fs_free_get prop_not_implemented_get
|
||||
#define _fs_free_set prop_not_implemented_set
|
||||
#define _fs_avail_get prop_not_implemented_get
|
||||
#define _fs_avail_set prop_not_implemented_set
|
||||
|
||||
struct lvm_property_type _properties[] = {
|
||||
#include "columns.h"
|
||||
|
@@ -36,6 +36,8 @@ struct lvm_report_object {
|
||||
struct lv_segment *seg;
|
||||
struct pv_segment *pvseg;
|
||||
struct label *label;
|
||||
struct lvm_mountinfo *mountinfo;
|
||||
struct lvm_fsinfo *fsinfo;
|
||||
};
|
||||
|
||||
static uint32_t log_seqnum = 1;
|
||||
@@ -3791,6 +3793,13 @@ static struct volume_group _unknown_vg = {
|
||||
.tags = DM_LIST_HEAD_INIT(_unknown_vg.tags),
|
||||
};
|
||||
|
||||
static struct lvm_mountinfo _unknown_mountinfo = {
|
||||
.mountpoint = ""
|
||||
};
|
||||
|
||||
static struct lvm_fsinfo _unknown_fsinfo = {
|
||||
};
|
||||
|
||||
static void *_obj_get_vg(void *obj)
|
||||
{
|
||||
struct volume_group *vg = ((struct lvm_report_object *)obj)->vg;
|
||||
@@ -3828,6 +3837,16 @@ static void *_obj_get_pvseg(void *obj)
|
||||
return ((struct lvm_report_object *)obj)->pvseg;
|
||||
}
|
||||
|
||||
static void *_obj_get_mountinfo(void *obj)
|
||||
{
|
||||
return ((struct lvm_report_object *)obj)->mountinfo;
|
||||
}
|
||||
|
||||
static void *_obj_get_fsinfo(void *obj)
|
||||
{
|
||||
return ((struct lvm_report_object *)obj)->fsinfo;
|
||||
}
|
||||
|
||||
static void *_obj_get_devtypes(void *obj)
|
||||
{
|
||||
return obj;
|
||||
@@ -3853,6 +3872,8 @@ static const struct dm_report_object_type _report_types[] = {
|
||||
{ LABEL, "Physical Volume Label", "pv_", _obj_get_label },
|
||||
{ SEGS, "Logical Volume Segment", "seg_", _obj_get_seg },
|
||||
{ PVSEGS, "Physical Volume Segment", "pvseg_", _obj_get_pvseg },
|
||||
{ MOUNTINFO, "Mount Point", "mount_", _obj_get_mountinfo },
|
||||
{ FSINFO, "Filesystem", "fs_", _obj_get_fsinfo },
|
||||
{ 0, "", "", NULL },
|
||||
};
|
||||
|
||||
@@ -3885,6 +3906,8 @@ typedef struct volume_group type_vg;
|
||||
typedef struct lv_segment type_seg;
|
||||
typedef struct pv_segment type_pvseg;
|
||||
typedef struct label type_label;
|
||||
typedef struct lvm_mountinfo type_mountinfo;
|
||||
typedef struct lvm_fsinfo type_fsinfo;
|
||||
|
||||
typedef dev_known_type_t type_devtype;
|
||||
|
||||
@@ -4012,7 +4035,8 @@ int report_object(void *handle, int selection_only, const struct volume_group *v
|
||||
const struct logical_volume *lv, const struct physical_volume *pv,
|
||||
const struct lv_segment *seg, const struct pv_segment *pvseg,
|
||||
const struct lv_with_info_and_seg_status *lvdm,
|
||||
const struct label *label)
|
||||
const struct label *label,
|
||||
const struct lvm_mountinfo *mountinfo, const struct lvm_fsinfo *fsinfo)
|
||||
{
|
||||
struct selection_handle *sh = selection_only ? (struct selection_handle *) handle : NULL;
|
||||
struct device dummy_device = { .dev = 0 };
|
||||
@@ -4023,7 +4047,9 @@ int report_object(void *handle, int selection_only, const struct volume_group *v
|
||||
.pv = (struct physical_volume *) pv,
|
||||
.seg = (struct lv_segment *) seg,
|
||||
.pvseg = (struct pv_segment *) pvseg,
|
||||
.label = (struct label *) (label ? : (pv ? pv_label(pv) : NULL))
|
||||
.label = (struct label *) (label ? : (pv ? pv_label(pv) : NULL)),
|
||||
.mountinfo = (struct lvm_mountinfo *) mountinfo ? : &_unknown_mountinfo,
|
||||
.fsinfo = (struct lvm_fsinfo *) fsinfo ? : &_unknown_fsinfo,
|
||||
};
|
||||
|
||||
/* FIXME workaround for pv_label going through cache; remove once struct
|
||||
|
@@ -32,9 +32,22 @@ typedef enum {
|
||||
SEGS = 256,
|
||||
PVSEGS = 512,
|
||||
LABEL = 1024,
|
||||
DEVTYPES = 2048
|
||||
DEVTYPES = 2048,
|
||||
MOUNTINFO = 4096,
|
||||
FSINFO = 8192
|
||||
} report_type_t;
|
||||
|
||||
struct lvm_mountinfo {
|
||||
const char *mountpoint;
|
||||
};
|
||||
|
||||
struct lvm_fsinfo {
|
||||
uint64_t fs_used;
|
||||
uint64_t fs_size;
|
||||
uint64_t fs_free;
|
||||
uint64_t fs_avail;
|
||||
};
|
||||
|
||||
/*
|
||||
* The "struct selection_handle" is used only for selection
|
||||
* of items that should be processed further (not for display!).
|
||||
@@ -104,7 +117,8 @@ int report_object(void *handle, int selection_only, const struct volume_group *v
|
||||
const struct logical_volume *lv, const struct physical_volume *pv,
|
||||
const struct lv_segment *seg, const struct pv_segment *pvseg,
|
||||
const struct lv_with_info_and_seg_status *lvdm,
|
||||
const struct label *label);
|
||||
const struct label *label,
|
||||
const struct lvm_mountinfo *mountinfo, const struct lvm_fsinfo *fsinfo);
|
||||
int report_devtypes(void *handle);
|
||||
int report_cmdlog(void *handle, const char *type, const char *context,
|
||||
const char *object_type_name, const char *object_name,
|
||||
|
139
tools/reporter.c
139
tools/reporter.c
@@ -17,6 +17,8 @@
|
||||
|
||||
#include "report.h"
|
||||
|
||||
#include <sys/vfs.h>
|
||||
|
||||
typedef enum {
|
||||
REPORT_IDX_NULL = -1,
|
||||
REPORT_IDX_SINGLE,
|
||||
@@ -79,7 +81,7 @@ static int _vgs_single(struct cmd_context *cmd __attribute__((unused)),
|
||||
struct selection_handle *sh = handle->selection_handle;
|
||||
|
||||
if (!report_object(sh ? : handle->custom_handle, sh != NULL,
|
||||
vg, NULL, NULL, NULL, NULL, NULL, NULL))
|
||||
vg, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL))
|
||||
return_ECMD_FAILED;
|
||||
|
||||
check_current_backup(vg);
|
||||
@@ -177,7 +179,7 @@ static int _do_lvs_with_info_and_status_single(struct cmd_context *cmd,
|
||||
}
|
||||
|
||||
if (!report_object(sh ? : handle->custom_handle, sh != NULL,
|
||||
lv->vg, lv, NULL, NULL, NULL, &status, NULL))
|
||||
lv->vg, lv, NULL, NULL, NULL, &status, NULL, NULL, NULL))
|
||||
goto out;
|
||||
|
||||
r = ECMD_PROCESSED;
|
||||
@@ -239,7 +241,7 @@ static int _do_segs_with_info_and_status_single(struct cmd_context *cmd,
|
||||
}
|
||||
|
||||
if (!report_object(sh ? : handle->custom_handle, sh != NULL,
|
||||
seg->lv->vg, seg->lv, NULL, seg, NULL, &status, NULL))
|
||||
seg->lv->vg, seg->lv, NULL, seg, NULL, &status, NULL, NULL, NULL))
|
||||
goto_out;
|
||||
|
||||
r = ECMD_PROCESSED;
|
||||
@@ -367,7 +369,7 @@ static int _do_pvsegs_sub_single(struct cmd_context *cmd,
|
||||
if (!report_object(sh ? : handle->custom_handle, sh != NULL,
|
||||
vg, seg ? seg->lv : &_free_logical_volume,
|
||||
pvseg->pv, seg ? : &_free_lv_segment, pvseg,
|
||||
&status, pv_label(pvseg->pv))) {
|
||||
&status, pv_label(pvseg->pv), NULL, NULL)) {
|
||||
ret = ECMD_FAILED;
|
||||
goto_out;
|
||||
}
|
||||
@@ -443,17 +445,101 @@ static int _pvsegs_with_lv_info_and_status_single(struct cmd_context *cmd,
|
||||
return process_each_segment_in_pv(cmd, vg, pv, handle, _pvsegs_with_lv_info_and_status_sub_single);
|
||||
}
|
||||
|
||||
struct mountinfo_s { // FIXME
|
||||
unsigned maj; //FIXME
|
||||
unsigned min; //FIXME
|
||||
const char *mountpoint;
|
||||
};
|
||||
|
||||
static int _get_mountpoint(char *buffer, unsigned major, unsigned minor,
|
||||
char *target, void *cb_data)
|
||||
{
|
||||
struct mountinfo_s *data = cb_data;
|
||||
|
||||
if ((major == data->maj) && (minor == data->min))
|
||||
data->mountpoint = dm_strdup(target); // FIXME error/pool
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _populate_mount_info(struct physical_volume *pv, struct lvm_mountinfo *mountinfo)
|
||||
{
|
||||
struct mountinfo_s data = {
|
||||
.maj = MAJOR(pv->dev->dev),
|
||||
.min = MINOR(pv->dev->dev),
|
||||
};
|
||||
|
||||
if (!dm_mountinfo_read(_get_mountpoint, &data))
|
||||
return 0;
|
||||
|
||||
if (data.mountpoint)
|
||||
mountinfo->mountpoint = data.mountpoint;
|
||||
else
|
||||
mountinfo->mountpoint = "";
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _populate_fs_info(const char *mountpoint, struct lvm_fsinfo *fsinfo)
|
||||
{
|
||||
struct statfs buf;
|
||||
|
||||
if (statfs(mountpoint, &buf)) {
|
||||
log_sys_error("statfs", mountpoint);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fsinfo->fs_size = (buf.f_blocks * buf.f_bsize) >> SECTOR_SHIFT;
|
||||
fsinfo->fs_free = (buf.f_bfree * buf.f_bsize) >> SECTOR_SHIFT;
|
||||
fsinfo->fs_avail = (buf.f_bavail * buf.f_bsize) >> SECTOR_SHIFT;
|
||||
fsinfo->fs_used = ((buf.f_blocks - buf.f_bfree) * buf.f_bsize) >> SECTOR_SHIFT;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _do_pvs_with_mount_and_fs_info_single(struct cmd_context *cmd, struct volume_group *vg,
|
||||
struct physical_volume *pv,
|
||||
struct processing_handle *handle,
|
||||
int do_mount_info, int do_fs_info)
|
||||
{
|
||||
struct selection_handle *sh = handle->selection_handle;
|
||||
struct lvm_mountinfo mountinfo;
|
||||
struct lvm_fsinfo fsinfo;
|
||||
|
||||
if (do_mount_info)
|
||||
if (!_populate_mount_info(pv, &mountinfo))
|
||||
return_0;
|
||||
|
||||
if (do_fs_info && *mountinfo.mountpoint)
|
||||
if (!_populate_fs_info(mountinfo.mountpoint, &fsinfo))
|
||||
return_0;
|
||||
|
||||
if (!report_object(sh ? : handle->custom_handle, sh != NULL,
|
||||
vg, NULL, pv, NULL, NULL, NULL, NULL, do_mount_info ? &mountinfo : NULL, do_fs_info && *mountinfo.mountpoint ? &fsinfo : NULL))
|
||||
return_ECMD_FAILED;
|
||||
|
||||
return ECMD_PROCESSED;
|
||||
}
|
||||
|
||||
static int _pvs_single(struct cmd_context *cmd, struct volume_group *vg,
|
||||
struct physical_volume *pv,
|
||||
struct processing_handle *handle)
|
||||
{
|
||||
struct selection_handle *sh = handle->selection_handle;
|
||||
return _do_pvs_with_mount_and_fs_info_single(cmd, vg, pv, handle, 0, 0);
|
||||
}
|
||||
|
||||
if (!report_object(sh ? : handle->custom_handle, sh != NULL,
|
||||
vg, NULL, pv, NULL, NULL, NULL, NULL))
|
||||
return_ECMD_FAILED;
|
||||
static int _pvs_with_mount_info_single(struct cmd_context *cmd, struct volume_group *vg,
|
||||
struct physical_volume *pv,
|
||||
struct processing_handle *handle)
|
||||
{
|
||||
return _do_pvs_with_mount_and_fs_info_single(cmd, vg, pv, handle, 1, 0);
|
||||
}
|
||||
|
||||
return ECMD_PROCESSED;
|
||||
static int _pvs_with_fs_info_single(struct cmd_context *cmd, struct volume_group *vg,
|
||||
struct physical_volume *pv,
|
||||
struct processing_handle *handle)
|
||||
{
|
||||
return _do_pvs_with_mount_and_fs_info_single(cmd, vg, pv, handle, 1, 1);
|
||||
}
|
||||
|
||||
static int _label_single(struct cmd_context *cmd, struct label *label,
|
||||
@@ -462,7 +548,7 @@ static int _label_single(struct cmd_context *cmd, struct label *label,
|
||||
struct selection_handle *sh = handle->selection_handle;
|
||||
|
||||
if (!report_object(sh ? : handle->custom_handle, sh != NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, label))
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, label, NULL, NULL))
|
||||
return_ECMD_FAILED;
|
||||
|
||||
return ECMD_PROCESSED;
|
||||
@@ -487,6 +573,8 @@ static int _get_final_report_type(struct report_args *args,
|
||||
report_type_t report_type,
|
||||
int *lv_info_needed,
|
||||
int *lv_segment_status_needed,
|
||||
int *mountinfo_needed,
|
||||
int *fsinfo_needed,
|
||||
report_type_t *final_report_type)
|
||||
{
|
||||
/* Do we need to acquire LV device info in addition? */
|
||||
@@ -498,8 +586,16 @@ static int _get_final_report_type(struct report_args *args,
|
||||
/* Ensure options selected are compatible */
|
||||
if (report_type & SEGS)
|
||||
report_type |= LVS;
|
||||
|
||||
if (report_type & PVSEGS)
|
||||
report_type |= PVS;
|
||||
|
||||
if (report_type & FSINFO)
|
||||
report_type |= MOUNTINFO;
|
||||
|
||||
if (report_type & MOUNTINFO)
|
||||
report_type |= PVS; // FIXME Temporarily drive fs and mount from pvs
|
||||
|
||||
if ((report_type & (LVS | LVSINFO | LVSSTATUS | LVSINFOSTATUS)) &&
|
||||
(report_type & (PVS | LABEL)) && !(single_args->args_are_pvs || (args->full_report_vg && single_args->report_type == PVSEGS))) {
|
||||
log_error("Can't report LV and PV fields at the same time in %sreport type \"%s\"%s%s.",
|
||||
@@ -509,6 +605,12 @@ static int _get_final_report_type(struct report_args *args,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Do we need to acquire mount point information? */
|
||||
*mountinfo_needed = (report_type & MOUNTINFO) ? 1 : 0;
|
||||
|
||||
/* Do we need to acquire mounted filesystem information? */
|
||||
*fsinfo_needed = (report_type & FSINFO) ? 1 : 0;
|
||||
|
||||
/* Change report type if fields specified makes this necessary */
|
||||
if (report_type & FULL)
|
||||
report_type = FULL;
|
||||
@@ -603,7 +705,7 @@ static int _report_all_in_lv(struct cmd_context *cmd, struct processing_handle *
|
||||
|
||||
static int _report_all_in_pv(struct cmd_context *cmd, struct processing_handle *handle,
|
||||
struct physical_volume *pv, report_type_t type,
|
||||
int do_lv_info, int do_lv_seg_status)
|
||||
int do_lv_info, int do_lv_seg_status, int do_mount_info, int do_fs_info)
|
||||
{
|
||||
int r = 0;
|
||||
|
||||
@@ -635,7 +737,7 @@ int report_for_selection(struct cmd_context *cmd,
|
||||
struct selection_handle *sh = parent_handle->selection_handle;
|
||||
struct report_args args = {0};
|
||||
struct single_report_args *single_args = &args.single_args[REPORT_IDX_SINGLE];
|
||||
int do_lv_info, do_lv_seg_status;
|
||||
int do_lv_info, do_lv_seg_status, do_mount_info, do_fs_info;
|
||||
struct processing_handle *handle;
|
||||
int r = 0;
|
||||
|
||||
@@ -645,6 +747,7 @@ int report_for_selection(struct cmd_context *cmd,
|
||||
if (!_get_final_report_type(&args, single_args,
|
||||
single_args->report_type,
|
||||
&do_lv_info, &do_lv_seg_status,
|
||||
&do_mount_info, &do_fs_info,
|
||||
&sh->report_type))
|
||||
return_0;
|
||||
|
||||
@@ -688,7 +791,7 @@ int report_for_selection(struct cmd_context *cmd,
|
||||
r = _report_all_in_vg(cmd, handle, vg, sh->report_type, do_lv_info, do_lv_seg_status);
|
||||
break;
|
||||
case PVS:
|
||||
r = _report_all_in_pv(cmd, handle, pv, sh->report_type, do_lv_info, do_lv_seg_status);
|
||||
r = _report_all_in_pv(cmd, handle, pv, sh->report_type, do_lv_info, do_lv_seg_status, do_mount_info, do_fs_info);
|
||||
break;
|
||||
default:
|
||||
log_error(INTERNAL_ERROR "report_for_selection: incorrect report type");
|
||||
@@ -1079,6 +1182,7 @@ static int _do_report(struct cmd_context *cmd, struct processing_handle *handle,
|
||||
int lock_global = 0;
|
||||
int lv_info_needed;
|
||||
int lv_segment_status_needed;
|
||||
int do_mount_info, do_fs_info;
|
||||
int report_in_group = 0;
|
||||
int r = ECMD_FAILED;
|
||||
|
||||
@@ -1091,7 +1195,9 @@ static int _do_report(struct cmd_context *cmd, struct processing_handle *handle,
|
||||
handle->custom_handle = report_handle;
|
||||
|
||||
if (!_get_final_report_type(args, single_args, report_type, &lv_info_needed,
|
||||
&lv_segment_status_needed, &report_type))
|
||||
&lv_segment_status_needed,
|
||||
&do_mount_info, &do_fs_info,
|
||||
&report_type))
|
||||
goto_out;
|
||||
|
||||
if (!(args->log_only && (single_args->report_type != CMDLOG))) {
|
||||
@@ -1151,7 +1257,10 @@ static int _do_report(struct cmd_context *cmd, struct processing_handle *handle,
|
||||
if (single_args->args_are_pvs)
|
||||
r = process_each_pv(cmd, args->argc, args->argv, NULL,
|
||||
arg_is_set(cmd, all_ARG), 0,
|
||||
handle, &_pvs_single);
|
||||
handle,
|
||||
do_fs_info ? &_pvs_with_fs_info_single :
|
||||
do_mount_info ? &_pvs_with_mount_info_single :
|
||||
&_pvs_single);
|
||||
else
|
||||
r = process_each_vg(cmd, args->argc, args->argv, NULL, NULL,
|
||||
0, 0, handle, &_pvs_in_vg);
|
||||
|
Reference in New Issue
Block a user