176 lines
6.6 KiB
Diff
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
|
|
|