提交 6222ee93 编写于 作者: G gaohuatao 提交者: lifeng68

devmapper: get driver status and apply diff

Signed-off-by: Ngaohuatao <gaohuatao@huawei.com>
上级 991683de
......@@ -23,6 +23,7 @@
#include <dirent.h>
#include <sys/sysmacros.h>
#include <sys/mount.h>
#include <sys/vfs.h>
#include "log.h"
#include "libisulad.h"
......@@ -2702,5 +2703,144 @@ free_out:
free_image_devmapper_device_info(info);
free(dm_name);
return ret;
}
void free_devmapper_status(struct status *st)
{
if (st == NULL) {
return;
}
free(st->pool_name);
st->pool_name = NULL;
free(st->data_file);
st->data_file = NULL;
free(st->data_loopback);
st->data_loopback = NULL;
free(st->metadata_file);
st->metadata_file = NULL;
free(st->metadata_loopback);
st->metadata_loopback = NULL;
free(st->base_device_fs);
st->base_device_fs = NULL;
free(st);
}
static bool is_real_file(const char *f)
{
struct stat st;
int nret;
if (f == NULL) {
return false;
}
nret = stat(f, &st);
if (nret < 0) {
return false;
}
return S_ISREG(st.st_mode);
}
static int get_underlying_available_space(const char *loop_file, uint64_t *available)
{
struct statfs buf;
int ret;
if (loop_file == NULL) {
return -1;
}
ret = statfs(loop_file, &buf);
if (ret < 0) {
WARN("devmapper: can not stat loopfile filesystem %s", loop_file);
return ret;
}
*available = buf.f_bfree * buf.f_bsize;
return 0;
}
struct status *device_set_status()
{
int ret = 0;
struct status *st = NULL;
struct device_set *devset = NULL;
uint64_t total_size_in_sectors, transaction_id, data_used;
uint64_t data_total, metadata_used, metadata_total;
uint64_t min_free_data;
st = util_common_calloc_s(sizeof(struct status));
if (st == NULL) {
ERROR("devmapper: out of memory");
return NULL;
}
if (devmapper_conf_rdlock()) {
ERROR("lock devmapper conf failed");
free_devmapper_status(st);
st = NULL;
return NULL;
}
devset = devmapper_driver_devices_get();
if (devset == NULL) {
free_devmapper_status(st);
st = NULL;
goto free_out;
}
st->pool_name = get_pool_name(devset);
st->data_file = util_strdup_s(devset->data_device);
st->data_loopback = util_strdup_s(devset->data_loop_file);
st->metadata_file = util_strdup_s(devset->metadata_device);
st->metadata_loopback = util_strdup_s(devset->metadata_loop_file);
st->udev_sync_supported = udev_sync_supported();
st->deferred_remove_enabled = devset->deferred_remove;
st->deferred_delete_enabled = devset->deferred_delete;
st->deferred_deleted_device_count = devset->nr_deleted_devices;
st->base_device_size = get_base_device_size(devset);
st->base_device_fs = util_strdup_s(devset->base_device_filesystem);
ret = pool_status(devset, &total_size_in_sectors, &transaction_id, &data_used, &data_total, &metadata_used,
&metadata_total);
if (ret == 0) {
uint64_t block_size_in_sectors = total_size_in_sectors / data_total;
st->data.used = data_used * block_size_in_sectors * 512;
st->data.total = data_total * block_size_in_sectors * 512;
st->data.available = st->data.total - st->data.used;
st->metadata.used = metadata_used * 4096;
st->metadata.total = metadata_total * 4096;
st->metadata.available = st->metadata.total - st->metadata.used;
st->sector_size = block_size_in_sectors * 512;
if (is_real_file(devset->data_loop_file)) {
uint64_t actual_space;
ret = get_underlying_available_space(devset->data_loop_file, &actual_space);
if (ret == 0 && actual_space < st->metadata.available) {
st->data.available = actual_space;
}
}
if (is_real_file(devset->metadata_loop_file)) {
uint64_t actual_space;
ret = get_underlying_available_space(devset->data_loop_file, &actual_space);
if (ret == 0 && actual_space < st->metadata.available) {
st->metadata.available = actual_space;
}
}
min_free_data = (data_total * (uint64_t)devset->min_free_space_percent) / 100;
st->min_free_space = min_free_data * block_size_in_sectors * 512;
}
free_out:
if (devmapper_conf_unlock()) {
ERROR("unlock devmapper conf failed");
}
return st;
}
\ No newline at end of file
......@@ -76,6 +76,33 @@ struct devmapper_conf {
struct device_set *devset;
};
struct disk_usage {
// Used bytes on the disk.
uint64_t used;
// Total bytes on the disk.
uint64_t total;
// Available bytes on the disk.
uint64_t available;
};
struct status {
char *pool_name;
char *data_file;
char *data_loopback;
char *metadata_file;
char *metadata_loopback;
struct disk_usage metadata;
struct disk_usage data;
uint64_t base_device_size;
char *base_device_fs;
uint64_t sector_size;
bool udev_sync_supported;
bool deferred_remove_enabled;
bool deferred_delete_enabled;
unsigned int deferred_deleted_device_count;
uint64_t min_free_space;
};
int device_init(struct graphdriver *driver, const char *drvier_home, const char **options, size_t len);
int devmapper_conf_rdlock();
......@@ -91,6 +118,9 @@ bool has_device(const char *hash);
int delete_device(const char *hash, bool sync_delete);
int export_device_metadata(struct device_metadata *dev_metadata, const char *hash);
struct status *device_set_status();
void free_devmapper_status(struct status *st);
#ifdef __cplusplus
}
......
......@@ -32,6 +32,7 @@
#include "device_setup.h"
#include "deviceset.h"
#include "json_common.h"
#include "util_archive.h"
int devmapper_init(struct graphdriver *driver, const char *drvier_home, const char **options, size_t len)
{
......@@ -238,6 +239,20 @@ out:
return ret;
}
static void free_driver_mount_opts(struct driver_mount_opts *opts)
{
if (opts == NULL) {
return;
}
free(opts->mount_label);
opts->mount_label = NULL;
util_free_array_by_len(opts->options, opts->options_len);
opts->options = NULL;
free(opts);
}
bool devmapper_layer_exists(const char *id, const struct graphdriver *driver)
{
return has_device(id);
......@@ -246,7 +261,45 @@ bool devmapper_layer_exists(const char *id, const struct graphdriver *driver)
int devmapper_apply_diff(const char *id, const struct graphdriver *driver, const struct io_read_wrapper *content,
int64_t *layer_size)
{
return 0;
struct driver_mount_opts *mount_opts = NULL;
char *layer_fs = NULL;
int ret = 0;
struct archive_options options = { 0 };
if (id == NULL || driver == NULL || content == NULL) {
ERROR("invalid argument");
return -1;
}
mount_opts = util_common_calloc_s(sizeof(struct driver_mount_opts));
if (mount_opts == NULL) {
ERROR("devmapper: out of memory");
return -1;
}
layer_fs = devmapper_mount_layer(id, driver, mount_opts);
if (layer_fs == NULL) {
ERROR("devmapper: failed to mount layer %s", id);
ret = -1;
goto out;
}
options.whiteout_format = OVERLAY_WHITEOUT_FORMATE;
ret = archive_unpack(content, layer_fs, &options);
if (ret != 0) {
ERROR("devmapper: failed to unpack to :%s", layer_fs);
}
if (devmapper_umount_layer(id, driver)) {
ERROR("devmapper: failed to umount layer %s", id);
ret = -1;
}
out:
free_driver_mount_opts(mount_opts);
free(layer_fs);
return ret;
}
int devmapper_get_layer_metadata(const char *id, const struct graphdriver *driver, json_map_string_string *map_info)
......@@ -341,5 +394,22 @@ out:
int devmapper_get_driver_status(const struct graphdriver *driver, struct graphdriver_status *status)
{
return 0;
int ret = 0;
struct status *st = NULL;
if (driver == NULL || status == NULL) {
return -1;
}
st = device_set_status();
if (st == NULL) {
ERROR("Failed to get device set status");
return -1;
}
status->driver_name = util_strdup_s(driver->name);
// TODO
free_devmapper_status(st);
return ret;
}
......@@ -54,6 +54,7 @@ int devmapper_get_layer_metadata(const char *id, const struct graphdriver *drive
int devmapper_get_driver_status(const struct graphdriver *driver, struct graphdriver_status *status);
#ifdef __cplusplus
}
#endif
......
......@@ -525,6 +525,11 @@ cleanup:
return ret;
}
bool udev_sync_supported()
{
return dm_udev_get_sync_support() != 0;
}
bool udev_set_sync_support(bool enable)
{
int enable_sync = 1;
......
......@@ -104,6 +104,8 @@ int dev_remove_device(const char *name);
int dev_get_device_list(char ***list, size_t *length);
bool udev_sync_supported();
bool udev_set_sync_support(bool enable);
int dev_create_device(const char *pool_dev_name, int device_id);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册