提交 58fb5faf 编写于 作者: G gaohuatao 提交者: lifeng68

devmapper: add devmapper_mount_layer func

Signed-off-by: Ngaohuatao <gaohuatao@huawei.com>
上级 117e5af6
......@@ -31,6 +31,7 @@
#include "devices_constants.h"
#include "device_setup.h"
#include "libdevmapper.h"
#include "driver.h"
#define DM_LOG_FATAL 2
#define DM_LOG_DEBUG 7
......@@ -281,6 +282,23 @@ static char *get_dev_name(const char *name)
return util_string_append(name, DEVMAPPER_DECICE_DIRECTORY);
}
char *dev_name(struct device_set *devset, image_devmapper_device_info *info)
{
char *res_str = NULL;
char *dm_name = NULL;
dm_name = get_dm_name(devset, info->hash);
if (dm_name == NULL) {
goto out;
}
res_str = get_dev_name(dm_name);
out:
free(dm_name);
return res_str;
}
// thin-pool or isulad-thinpool
static char *get_pool_name(struct device_set *devset)
{
......@@ -2414,4 +2432,149 @@ free_out:
free_image_devmapper_device_info(base_info);
free_image_devmapper_device_info(info);
return ret;
}
// moptions->options_len > 0
static char *generate_mount_options(const struct driver_mount_opts *moptions, const char *dev_options)
{
char *res_str = NULL;
char *options = NULL;
bool add_nouuid = false;
options = util_strdup_s(dev_options);
if (moptions != NULL && moptions->options_len > 0) {
add_nouuid = !util_valid_str(options) || strings_contains_word("nouuid", options);
free(options);
options = util_string_join(",", (const char **)moptions->options, moptions->options_len);
if (add_nouuid) {
res_str = util_strdup_s("nouuid");
}
}
append_mount_options(&res_str, options);
free(options);
return res_str;
}
int mount_device(const char *hash, const char *path, const struct driver_mount_opts *mount_opts)
{
int ret = 0;
image_devmapper_device_info *info = NULL;
struct device_set *devset = NULL;
char *dev_fname = NULL;
char *options = NULL;
if (hash == NULL || path == NULL || mount_opts == NULL) {
ERROR("devmapper: failed to mount device");
return -1;
}
if (devmapper_conf_wrlock()) {
ERROR("lock devmapper conf failed");
return -1;
}
devset = devmapper_driver_devices_get();
if (devset == NULL) {
goto free_out;
}
info = lookup_device(devset, hash);
if (info == NULL) {
ERROR("devmapper: lookup device %s failed", info);
ret = -1;
goto free_out;
}
if (info->deleted) {
ret = -1;
ERROR("devmapper: Base device %s has been marked for deferred deletion", info->hash);
goto free_out;
}
dev_fname = dev_name(devset, info);
if (dev_fname) {
ERROR("devmapper: failed to get device full name");
goto free_out;
}
ret = activate_device_if_needed(devset, info, false);
if (ret != 0) {
ERROR("devmapper: Error activating devmapper device for %s", hash);
goto free_out;
}
options = generate_mount_options(mount_opts, devset->mount_options);
ret = util_mount(dev_fname, path, "ext4", options);
if (ret != 0) {
ERROR("devmapper: Error mounting %s on %s", dev_fname, path);
goto free_out;
}
free_out:
if (devmapper_conf_unlock()) {
ERROR("unlock devmapper conf failed");
ret = -1;
}
free_image_devmapper_device_info(info);
free(dev_fname);
free(options);
return ret;
}
// UnmountDevice unmounts the device and removes it from hash.
int unmount_device(const char *hash, const char *mount_path)
{
int ret = 0;
image_devmapper_device_info *info = NULL;
struct device_set *devset = NULL;
if (hash == NULL || mount_path == NULL) {
ERROR("devmapper: failed to unmount device");
return -1;
}
if (devmapper_conf_wrlock()) {
ERROR("lock devmapper conf failed");
return -1;
}
devset = devmapper_driver_devices_get();
if (devset == NULL) {
goto free_out;
}
info = lookup_device(devset, hash);
if (info == NULL) {
ERROR("devmapper: lookup device %s failed", info);
ret = -1;
goto free_out;
}
if (util_detect_mounted(mount_path)) {
ret = umount2(mount_path, MNT_DETACH);
if (ret < 0 && errno != EINVAL) {
WARN("Failed to umount directory %s:%s", mount_path, strerror(errno));
goto free_out;
}
}
ret = util_path_remove(mount_path);
if (ret != 0) {
DEBUG("devmapper: doing remove on a unmounted device %s failed", mount_path);
}
ret = deactivate_device(devset, info);
if (ret != 0) {
ERROR("devmapper: Error deactivating device");
}
free_out:
if (devmapper_conf_unlock()) {
ERROR("unlock devmapper conf failed");
ret = -1;
}
free_image_devmapper_device_info(info);
return ret;
}
\ No newline at end of file
......@@ -78,7 +78,8 @@ int devmapper_conf_unlock();
struct device_set *devmapper_driver_devices_get();
int add_device(const char *hash, const char *base_hash, const json_map_string_string *storage_opts);
int mount_device(const char *hash, const char *path, const struct driver_mount_opts *mount_opts);
int unmount_device(const char *hash, const char *mount_path);
#ifdef __cplusplus
}
......
......@@ -43,6 +43,7 @@ int do_create(const char *id, const char *parent, const struct driver_create_opt
return add_device(id, parent, create_opts->storage_opt);
}
// devmapper_create_rw creates a layer that is writable for use as a container file system
int devmapper_create_rw(const char *id, const char *parent, const struct graphdriver *driver,
const struct driver_create_opts *create_opts)
{
......@@ -64,10 +65,99 @@ int devmapper_rm_layer(const char *id, const struct graphdriver *driver)
return 0;
}
static int write_file(const char *fpath, const char *buf)
{
int fd = 0;
ssize_t nwrite;
if (fpath == NULL || buf == NULL) {
return 0;
}
fd = util_open(fpath, O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, 0600);
if (fd < 0) {
ERROR("Failed to open file: %s: %s", fpath, strerror(errno));
return -1;
}
nwrite = util_write_nointr(fd, buf, strlen(buf));
if (nwrite < 0) {
ERROR("Failed to write %s to %s: %s", buf, fpath, strerror(errno));
close(fd);
return -1;
}
close(fd);
return 0;
}
// devmapper_mount_layer mounts a device with given id into the root filesystem
char *devmapper_mount_layer(const char *id, const struct graphdriver *driver,
const struct driver_mount_opts *mount_opts)
{
return NULL;
char *mnt_point_dir = NULL;
char *mnt_parent_dir = NULL;
char *rootfs = NULL;
char *id_file = NULL;
int ret = 0;
if (id == NULL || driver == NULL || mount_opts == NULL) {
return NULL;
}
mnt_parent_dir = util_path_join(driver->home, "mnt");
if (mnt_parent_dir == NULL) {
ERROR("Failed to join devmapper mnt dir%s", id);
goto out;
}
mnt_point_dir = util_path_join(mnt_parent_dir, id);
if (mnt_point_dir == NULL) {
ERROR("Failed to join devampper mount point dir:%s", id);
goto out;
}
DEBUG("devmapper: start to mount container device");
ret = mount_device(id, mnt_point_dir, mount_opts);
if (ret != 0) {
goto out;
}
rootfs = util_path_join(mnt_point_dir, "rootfs");
if (rootfs == NULL) {
ERROR("Failed to join devmapper rootfs %s", mnt_point_dir);
goto out;
}
if (util_mkdir_p(rootfs, 0755) != 0 || !util_dir_exists(rootfs)) {
ERROR("Unable to create devmapper rootfs directory %s.", rootfs);
ret = -1;
if (unmount_device(id, mnt_point_dir) != 0) {
DEBUG("devmapper: unmount %s failed", mnt_point_dir);
}
goto out;
}
id_file = util_path_join(mnt_point_dir, "id");
if (!util_file_exists(id_file)) {
// Create an "id" file with the container/image id in it to help reconstruct this in case
// of later problems
ret = write_file(id_file, id);
if (ret != 0) {
if (unmount_device(id, mnt_point_dir) != 0) {
DEBUG("devmapper: unmount %s failed", mnt_point_dir);
}
}
}
out:
free(mnt_parent_dir);
free(mnt_point_dir);
free(id_file);
if (ret != 0) {
free(rootfs);
rootfs = NULL;
}
return rootfs;
}
int devmapper_umount_layer(const char *id, const struct graphdriver *driver)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册