iSulad/0060-1761-fix-leftover-devicemapper-mnt-dir.patch
zhangxiaoyu c2bb1cf604 update from upstream
Signed-off-by: zhangxiaoyu <zhangxiaoyu58@huawei.com>
2022-12-16 14:54:18 +08:00

176 lines
6.6 KiB
Diff

From 9b41a8d28d3ffbe33eb84d8e254b603012b22b34 Mon Sep 17 00:00:00 2001
From: DriedYellowPeach <wangrunze13@huawei.com>
Date: Sun, 11 Dec 2022 11:12:55 +0000
Subject: [PATCH 60/65] !1761 fix leftover devicemapper mnt dir * fix leftover
devicemapper mnt dir
---
.../graphdriver/devmapper/deviceset.c | 37 +++++++++++++
.../graphdriver/devmapper/deviceset.h | 2 +
.../graphdriver/devmapper/driver_devmapper.c | 55 ++++++++++++-------
.../oci/storage/layer_store/layer_store.c | 11 +++-
4 files changed, 84 insertions(+), 21 deletions(-)
diff --git a/src/daemon/modules/image/oci/storage/layer_store/graphdriver/devmapper/deviceset.c b/src/daemon/modules/image/oci/storage/layer_store/graphdriver/devmapper/deviceset.c
index 4dadc336..b157510a 100644
--- a/src/daemon/modules/image/oci/storage/layer_store/graphdriver/devmapper/deviceset.c
+++ b/src/daemon/modules/image/oci/storage/layer_store/graphdriver/devmapper/deviceset.c
@@ -486,6 +486,43 @@ out:
return exist;
}
+// return true if find the metadata
+// or the argument is wrong
+// or can't decide
+bool has_metadata(const char *hash, struct device_set *devset)
+{
+ char metadata_file[PATH_MAX] = { 0 };
+ char *metadata_path = NULL;
+ bool ret = true;
+ int nret = 0;
+
+ if (hash == NULL) {
+ return true;
+ }
+
+ metadata_path = metadata_dir(devset);
+ if (metadata_path == NULL) {
+ ERROR("Failed to get meta data directory");
+ goto out;
+ }
+
+ nret = snprintf(metadata_file, sizeof(metadata_file), "%s/%s", metadata_path, util_valid_str(hash) ? hash : "base");
+ if (nret < 0 || (size_t)nret >= sizeof(metadata_file)) {
+ ERROR("Failed to snprintf metadata file path with hash:%s, path is too long", hash);
+ goto out;
+ }
+
+ if (!util_file_exists(metadata_file)) {
+ WARN("No such file:%s, need not to load", metadata_file);
+ ret = false;
+ goto out;
+ }
+
+out:
+ free(metadata_path);
+ return ret;
+}
+
static image_devmapper_device_info *load_metadata(const struct device_set *devset, const char *hash)
{
image_devmapper_device_info *info = NULL;
diff --git a/src/daemon/modules/image/oci/storage/layer_store/graphdriver/devmapper/deviceset.h b/src/daemon/modules/image/oci/storage/layer_store/graphdriver/devmapper/deviceset.h
index c11eece6..ec985e40 100644
--- a/src/daemon/modules/image/oci/storage/layer_store/graphdriver/devmapper/deviceset.h
+++ b/src/daemon/modules/image/oci/storage/layer_store/graphdriver/devmapper/deviceset.h
@@ -83,6 +83,8 @@ int delete_device(const char *hash, bool sync_delete, struct device_set *devset)
int export_device_metadata(struct device_metadata *dev_metadata, const char *hash, struct device_set *devset);
+bool has_metadata(const char *hash, struct device_set *devset);
+
struct status *device_set_status(struct device_set *devset);
void free_devmapper_status(struct status *st);
diff --git a/src/daemon/modules/image/oci/storage/layer_store/graphdriver/devmapper/driver_devmapper.c b/src/daemon/modules/image/oci/storage/layer_store/graphdriver/devmapper/driver_devmapper.c
index dd231bd6..c83d3e54 100644
--- a/src/daemon/modules/image/oci/storage/layer_store/graphdriver/devmapper/driver_devmapper.c
+++ b/src/daemon/modules/image/oci/storage/layer_store/graphdriver/devmapper/driver_devmapper.c
@@ -144,28 +144,11 @@ int devmapper_create_ro(const char *id, const char *parent, const struct graphdr
return do_create(id, parent, driver, create_opts);
}
-// Remove removes a device with a given id, unmounts the filesystem.
-int devmapper_rm_layer(const char *id, const struct graphdriver *driver)
+static int devmapper_try_rm_layer_mnt(const char *id, const struct graphdriver *driver)
{
+ int ret = 0;
char *mnt_parent_dir = NULL;
char *mnt_point_dir = NULL;
- int ret = 0;
-
- if (!util_valid_str(id) || driver == NULL) {
- ERROR("invalid argument");
- return -1;
- }
-
- if (!has_device(id, driver->devset)) {
- DEBUG("Device with id:%s is not exist", id);
- goto out;
- }
-
- if (delete_device(id, false, driver->devset) != 0) {
- ERROR("failed to remove device %s", id);
- ret = -1;
- goto out;
- }
mnt_parent_dir = util_path_join(driver->home, "mnt");
if (mnt_parent_dir == NULL) {
@@ -193,6 +176,40 @@ out:
return ret;
}
+// Remove removes a device with a given id, unmounts the filesystem.
+int devmapper_rm_layer(const char *id, const struct graphdriver *driver)
+{
+ if (!util_valid_str(id) || driver == NULL) {
+ ERROR("invalid argument");
+ return -1;
+ }
+
+ if (!has_device(id, driver->devset)) {
+ DEBUG("Device with id:%s is not exist", id);
+ if (!has_metadata(id, driver->devset)) {
+ // this means metadata is lost
+ // if we can rm mnt, then the layer is removed
+ EVENT("try clean lost metadata and its mnt: %s", id);
+ return devmapper_try_rm_layer_mnt(id, driver);
+ }
+ // if has_metadata and not rm successfully, return -1
+ // so next start up of isulad will retry delete the layer.
+ return -1;
+ }
+
+ if (delete_device(id, false, driver->devset) != 0) {
+ ERROR("failed to remove device %s", id);
+ return -1;
+ }
+
+ if (devmapper_try_rm_layer_mnt(id, driver) != 0) {
+ ERROR("failed to remove mnt dir of Device: %s", id);
+ return -1;
+ }
+
+ 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)
diff --git a/src/daemon/modules/image/oci/storage/layer_store/layer_store.c b/src/daemon/modules/image/oci/storage/layer_store/layer_store.c
index b9ab0d65..60aaff22 100644
--- a/src/daemon/modules/image/oci/storage/layer_store/layer_store.c
+++ b/src/daemon/modules/image/oci/storage/layer_store/layer_store.c
@@ -1813,8 +1813,15 @@ static bool load_layer_json_cb(const char *path_name, const struct dirent *sub_d
remove_invalid_dir:
(void)graphdriver_umount_layer(sub_dir->d_name);
- (void)graphdriver_rm_layer(sub_dir->d_name);
- (void)util_recursive_rmdir(tmpdir, 0);
+ // layer not removed successfully, we can't remove layer.json
+ if (graphdriver_rm_layer(sub_dir->d_name) != 0) {
+ ERROR("failed to rm layer: %s when handing invalid rootfs", sub_dir->d_name);
+ goto free_out;
+ }
+ ERROR("tmpdir is %s", tmpdir);
+ if (util_recursive_rmdir(tmpdir, 0) != 0) {
+ ERROR("failed to rm rootfs dir: %s when handing invalid rootfs", tmpdir);
+ }
free_out:
free(rpath);
--
2.25.1