driver.c 8.0 KB
Newer Older
O
overweight 已提交
1 2
/******************************************************************************
 * Copyright (c) Huawei Technologies Co., Ltd. 2017-2019. All rights reserved.
3 4 5 6
 * iSulad licensed under the Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *     http://license.coscl.org.cn/MulanPSL2
O
overweight 已提交
7 8 9
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
 * PURPOSE.
10
 * See the Mulan PSL v2 for more details.
O
overweight 已提交
11 12 13 14
 * Author: tanyifeng
 * Create: 2017-11-22
 * Description: provide image functions
 ******************************************************************************/
L
LiFeng 已提交
15

O
overweight 已提交
16 17 18 19 20 21 22 23
#include "driver.h"

#include <stdlib.h>
#include <string.h>
#include <sys/mount.h>
#include <linux/limits.h>

#include "driver_overlay2.h"
W
WangFengTu 已提交
24
#include "driver_devmapper.h"
H
haozi007 已提交
25
#include "utils_array.h"
O
overweight 已提交
26
#include "utils.h"
L
LiuHao 已提交
27
#include "libisulad.h"
H
haozi007 已提交
28
#include "isula_libutils/log.h"
29
#include "util_archive.h"
O
overweight 已提交
30

L
LiFeng 已提交
31 32 33
static struct graphdriver *g_graphdriver = NULL;

/* overlay2 */
O
overweight 已提交
34
#define DRIVER_OVERLAY2_NAME "overlay2"
L
LiFeng 已提交
35 36
#define DRIVER_OVERLAY_NAME "overlay"

O
overweight 已提交
37 38
static const struct graphdriver_ops g_overlay2_ops = {
    .init = overlay2_init,
39
    .create_rw = overlay2_create_rw,
L
LiFeng 已提交
40
    .create_ro = overlay2_create_ro,
41 42 43 44 45
    .rm_layer = overlay2_rm_layer,
    .mount_layer = overlay2_mount_layer,
    .umount_layer = overlay2_umount_layer,
    .exists = overlay2_layer_exists,
    .apply_diff = overlay2_apply_diff,
L
LiFeng 已提交
46 47
    .get_layer_metadata = overlay2_get_layer_metadata,
    .get_driver_status = overlay2_get_driver_status,
L
LiFeng 已提交
48
    .clean_up = overlay2_clean_up,
49
    .try_repair_lowers = overlay2_repair_lowers,
O
overweight 已提交
50 51
};

W
WangFengTu 已提交
52 53 54 55 56 57 58
/* devicemapper */
#define DRIVER_DEVMAPPER_NAME "devicemapper"

static const struct graphdriver_ops g_devmapper_ops = {
    .init = devmapper_init,
};

O
overweight 已提交
59
static struct graphdriver g_drivers[] = {
L
LiFeng 已提交
60 61
    {.name = DRIVER_OVERLAY2_NAME,  .ops = &g_overlay2_ops},
    {.name = DRIVER_OVERLAY_NAME,   .ops = &g_overlay2_ops},
W
WangFengTu 已提交
62
    {.name = DRIVER_DEVMAPPER_NAME, .ops = &g_devmapper_ops}
O
overweight 已提交
63 64 65 66
};

static const size_t g_numdrivers = sizeof(g_drivers) / sizeof(struct graphdriver);

H
haozi007 已提交
67
int graphdriver_init(const struct storage_module_init_options *opts)
O
overweight 已提交
68
{
69
    int ret = 0;
O
overweight 已提交
70
    size_t i = 0;
71
    char driver_home[PATH_MAX] = { 0 };
O
overweight 已提交
72

L
LiFeng 已提交
73
    if (opts == NULL || opts->storage_root == NULL || opts->driver_name == NULL) {
74 75
        ret = -1;
        goto out;
76 77
    }

L
LiFeng 已提交
78
    int nret = snprintf(driver_home, PATH_MAX, "%s/%s", opts->storage_root, opts->driver_name);
79 80
    if (nret < 0 || (size_t)nret >= PATH_MAX) {
        ERROR("Sprintf graph driver path failed");
81 82
        ret = -1;
        goto out;
O
overweight 已提交
83 84 85
    }

    for (i = 0; i < g_numdrivers; i++) {
L
LiFeng 已提交
86 87
        if (strcmp(opts->driver_name, g_drivers[i].name) == 0) {
            if (g_drivers[i].ops->init(&g_drivers[i], driver_home, (const char **)opts->driver_opts, opts->driver_opts_len) != 0) {
88
                ret = -1;
L
LiFeng 已提交
89
                goto out;
90
            }
L
LiFeng 已提交
91 92 93 94
            g_graphdriver = &g_drivers[i];
            break;
        }
    }
95

96
    if (i == g_numdrivers) {
L
LiFeng 已提交
97
        ERROR("unsupported driver %s", opts->driver_name);
98 99 100
        ret = -1;
        goto out;
    }
101

102 103 104
out:
    return ret;
}
105

L
LiFeng 已提交
106
int graphdriver_create_rw(const char *id, const char *parent, struct driver_create_opts *create_opts)
L
LiFeng 已提交
107 108 109 110
{
    if (g_graphdriver == NULL) {
        ERROR("Driver not inited yet");
        return -1;
O
overweight 已提交
111 112
    }

L
LiFeng 已提交
113 114 115 116 117 118
    if (id == NULL || parent == NULL || create_opts == NULL) {
        ERROR("Invalid input arguments for driver create");
        return -1;
    }

    return g_graphdriver->ops->create_rw(id, parent, g_graphdriver, create_opts);;
O
overweight 已提交
119 120
}

L
LiFeng 已提交
121
int graphdriver_create_ro(const char *id, const char *parent, const struct driver_create_opts *create_opts)
O
overweight 已提交
122
{
L
LiFeng 已提交
123 124 125
    if (g_graphdriver == NULL) {
        ERROR("Driver not inited yet");
        return -1;
O
overweight 已提交
126 127
    }

L
LiFeng 已提交
128 129 130
    if (id == NULL || parent == NULL || create_opts == NULL) {
        ERROR("Invalid input arguments for driver create");
        return -1;
O
overweight 已提交
131 132
    }

L
LiFeng 已提交
133
    return g_graphdriver->ops->create_ro(id, parent, g_graphdriver, create_opts);;
O
overweight 已提交
134 135
}

L
LiFeng 已提交
136
int graphdriver_rm_layer(const char *id)
O
overweight 已提交
137
{
L
LiFeng 已提交
138 139 140
    if (g_graphdriver == NULL) {
        ERROR("Driver not inited yet");
        return -1;
O
overweight 已提交
141 142
    }

L
LiFeng 已提交
143 144 145
    if (id == NULL) {
        ERROR("Invalid input arguments for driver remove layer");
        return -1;
O
overweight 已提交
146 147
    }

L
LiFeng 已提交
148 149
    return g_graphdriver->ops->rm_layer(id, g_graphdriver);
}
O
overweight 已提交
150

L
LiFeng 已提交
151 152 153 154
char *graphdriver_mount_layer(const char *id, const struct driver_mount_opts *mount_opts)
{
    if (g_graphdriver == NULL) {
        ERROR("Driver not inited yet");
O
overweight 已提交
155 156
        return NULL;
    }
L
LiFeng 已提交
157 158 159 160 161 162 163

    if (id == NULL || mount_opts == NULL) {
        ERROR("Invalid input arguments for driver mount layer");
        return NULL;
    }

    return g_graphdriver->ops->mount_layer(id, g_graphdriver, mount_opts);
O
overweight 已提交
164 165
}

L
LiFeng 已提交
166
int graphdriver_umount_layer(const char *id)
167
{
L
LiFeng 已提交
168 169 170
    if (g_graphdriver == NULL) {
        ERROR("Driver not inited yet");
        return -1;
171 172
    }

L
LiFeng 已提交
173 174 175
    if (id == NULL) {
        ERROR("Invalid input arguments for driver umount layer");
        return -1;
176 177
    }

L
LiFeng 已提交
178 179
    return g_graphdriver->ops->umount_layer(id, g_graphdriver);
}
180

L
LiFeng 已提交
181 182 183 184 185
bool graphdriver_layer_exists(const char *id)
{
    if (g_graphdriver == NULL) {
        ERROR("Driver not inited yet");
        return -1;
186 187
    }

L
LiFeng 已提交
188 189 190
    if (id == NULL) {
        ERROR("Invalid input arguments for driver exists layer");
        return -1;
191
    }
L
LiFeng 已提交
192 193

    return g_graphdriver->ops->exists(id, g_graphdriver);
194 195
}

L
LiFeng 已提交
196
int graphdriver_apply_diff(const char *id, const struct io_read_wrapper *content, int64_t *layer_size)
O
overweight 已提交
197
{
L
LiFeng 已提交
198 199 200 201
    if (g_graphdriver == NULL) {
        ERROR("Driver not inited yet");
        return -1;
    }
O
overweight 已提交
202

L
LiFeng 已提交
203 204
    if (id == NULL || content == NULL || layer_size == NULL) {
        ERROR("Invalid input arguments for driver umount layer");
O
overweight 已提交
205 206 207
        return -1;
    }

L
LiFeng 已提交
208 209 210 211 212 213 214
    return g_graphdriver->ops->apply_diff(id, g_graphdriver, content, layer_size);
}

int graphdriver_get_layer_metadata(const char *id, json_map_string_string *map_info)
{
    if (g_graphdriver == NULL) {
        ERROR("Driver not inited yet");
O
overweight 已提交
215 216
        return -1;
    }
L
LiFeng 已提交
217 218 219 220

    if (id == NULL || map_info == NULL) {
        ERROR("Invalid input arguments for driver umount layer");
        return -1;
O
overweight 已提交
221
    }
L
LiFeng 已提交
222 223

    return g_graphdriver->ops->get_layer_metadata(id, g_graphdriver, map_info);
O
overweight 已提交
224 225
}

L
LiFeng 已提交
226
struct graphdriver_status *graphdriver_get_status(void)
O
overweight 已提交
227
{
L
LiFeng 已提交
228 229 230 231 232 233
    int ret = -1;
    struct graphdriver_status *status = NULL;

    if (g_graphdriver == NULL) {
        ERROR("Driver not inited yet");
        return NULL;
O
overweight 已提交
234
    }
L
LiFeng 已提交
235 236 237 238 239

    status = util_common_calloc_s(sizeof(struct graphdriver_status));
    if (status == NULL) {
        ERROR("Out of memory");
        goto free_out;
O
overweight 已提交
240
    }
L
LiFeng 已提交
241 242 243 244 245

    ret = g_graphdriver->ops->get_driver_status(g_graphdriver, status);
    if (ret != 0) {
        ERROR("Failed to get driver status");
        goto free_out;
O
overweight 已提交
246
    }
L
LiFeng 已提交
247 248 249 250 251

free_out:
    if (ret != 0) {
        free_graphdriver_status(status);
        return NULL;
O
overweight 已提交
252
    }
L
LiFeng 已提交
253
    return status;
O
overweight 已提交
254 255 256 257 258 259 260
}

void free_graphdriver_status(struct graphdriver_status *status)
{
    if (status == NULL) {
        return;
    }
261 262
    free(status->driver_name);
    status->driver_name = NULL;
O
overweight 已提交
263
    free(status->backing_fs);
264
    status->backing_fs = NULL;
W
WangFengTu 已提交
265
    free(status->status);
266
    status->status = NULL;
O
overweight 已提交
267 268 269
    free(status);
}

H
haozi007 已提交
270 271 272 273 274 275 276 277 278 279 280 281
void free_graphdriver_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);

    free(opts);
}

L
LiFeng 已提交
282 283 284 285 286 287 288 289 290
int graphdriver_cleanup(void)
{
    if (g_graphdriver == NULL) {
        ERROR("Driver not inited yet");
        return -1;
    }

    return g_graphdriver->ops->clean_up(g_graphdriver);
}
291 292 293 294 295 296 297 298 299 300 301 302 303 304 305

int graphdriver_try_repair_lowers(const char *id, const char *parent)
{
    if (g_graphdriver == NULL) {
        ERROR("Driver not inited yet");
        return -1;
    }

    if (id == NULL || parent == NULL) {
        ERROR("Invalid input arguments for driver repair lower");
        return -1;
    }

    return g_graphdriver->ops->try_repair_lowers(id, parent, g_graphdriver);
}