]> git.proxmox.com Git - ceph.git/blame - ceph/src/pmdk/src/libpmempool/rm.c
import ceph 16.2.7
[ceph.git] / ceph / src / pmdk / src / libpmempool / rm.c
CommitLineData
a4b75251
TL
1// SPDX-License-Identifier: BSD-3-Clause
2/* Copyright 2016-2018, Intel Corporation */
3
4/*
5 * rm.c -- implementation of pmempool_rm() function
6 */
7#include <errno.h>
8#include <fcntl.h>
9
10#include "libpmempool.h"
11#include "out.h"
12#include "os.h"
13#include "util.h"
14#include "set.h"
15#include "file.h"
16
17#define PMEMPOOL_RM_ALL_FLAGS (\
18 PMEMPOOL_RM_FORCE |\
19 PMEMPOOL_RM_POOLSET_LOCAL |\
20 PMEMPOOL_RM_POOLSET_REMOTE)
21
22#define ERR_F(f, ...) do {\
23 if (CHECK_FLAG((f), FORCE))\
24 LOG(2, "!(ignored) " __VA_ARGS__);\
25 else\
26 ERR(__VA_ARGS__);\
27} while (0)
28
29#define CHECK_FLAG(f, i) ((f) & PMEMPOOL_RM_##i)
30
31struct cb_args {
32 unsigned flags;
33 int error;
34};
35
36/*
37 * rm_local -- (internal) remove single local file
38 */
39static int
40rm_local(const char *path, unsigned flags, int is_part_file)
41{
42 int ret = util_unlink_flock(path);
43 if (!ret) {
44 LOG(3, "%s: removed", path);
45 return 0;
46 }
47
48 int oerrno = errno;
49 os_stat_t buff;
50 ret = os_stat(path, &buff);
51 if (!ret) {
52 if (S_ISDIR(buff.st_mode)) {
53 errno = EISDIR;
54 if (is_part_file)
55 ERR("%s: removing file failed", path);
56 else
57 ERR("removing file failed");
58 return -1;
59 }
60 }
61
62 errno = oerrno;
63
64 if (is_part_file)
65 ERR_F(flags, "%s: removing file failed", path);
66 else
67 ERR_F(flags, "removing file failed");
68
69 if (CHECK_FLAG(flags, FORCE))
70 return 0;
71
72 return -1;
73}
74
75/*
76 * rm_remote -- (internal) remove remote replica
77 */
78static int
79rm_remote(const char *node, const char *path, unsigned flags)
80{
81 if (!Rpmem_remove) {
82 ERR_F(flags, "cannot remove remote replica"
83 " -- missing librpmem");
84 return -1;
85 }
86
87 int rpmem_flags = 0;
88 if (CHECK_FLAG(flags, FORCE))
89 rpmem_flags |= RPMEM_REMOVE_FORCE;
90
91 if (CHECK_FLAG(flags, POOLSET_REMOTE))
92 rpmem_flags |= RPMEM_REMOVE_POOL_SET;
93
94 int ret = Rpmem_remove(node, path, rpmem_flags);
95 if (ret) {
96 ERR_F(flags, "%s/%s removing failed", node, path);
97 if (CHECK_FLAG(flags, FORCE))
98 ret = 0;
99 } else {
100 LOG(3, "%s/%s: removed", node, path);
101 }
102
103 return ret;
104}
105
106/*
107 * rm_cb -- (internal) foreach part callback
108 */
109static int
110rm_cb(struct part_file *pf, void *arg)
111{
112 struct cb_args *args = (struct cb_args *)arg;
113 int ret;
114 if (pf->is_remote) {
115 ret = rm_remote(pf->remote->node_addr, pf->remote->pool_desc,
116 args->flags);
117 } else {
118 ret = rm_local(pf->part->path, args->flags, 1);
119 }
120
121 if (ret)
122 args->error = ret;
123
124 return 0;
125}
126
127/*
128 * pmempool_rmU -- remove pool files or poolsets
129 */
130#ifndef _WIN32
131static inline
132#endif
133int
134pmempool_rmU(const char *path, unsigned flags)
135{
136 LOG(3, "path %s flags %x", path, flags);
137 int ret;
138
139 if (flags & ~PMEMPOOL_RM_ALL_FLAGS) {
140 ERR("invalid flags specified");
141 errno = EINVAL;
142 return -1;
143 }
144
145 int is_poolset = util_is_poolset_file(path);
146 if (is_poolset < 0) {
147 os_stat_t buff;
148 ret = os_stat(path, &buff);
149 if (!ret) {
150 if (S_ISDIR(buff.st_mode)) {
151 errno = EISDIR;
152 ERR("removing file failed");
153 return -1;
154 }
155 }
156 ERR_F(flags, "removing file failed");
157 if (CHECK_FLAG(flags, FORCE))
158 return 0;
159
160 return -1;
161 }
162
163 if (!is_poolset) {
164 LOG(2, "%s: not a poolset file", path);
165 return rm_local(path, flags, 0);
166 }
167
168 LOG(2, "%s: poolset file", path);
169
170 /* fill up pool_set structure */
171 struct pool_set *set = NULL;
172 int fd = os_open(path, O_RDONLY);
173 if (fd == -1 || util_poolset_parse(&set, path, fd)) {
174 ERR_F(flags, "parsing poolset file failed");
175 if (fd != -1)
176 os_close(fd);
177 if (CHECK_FLAG(flags, FORCE))
178 return 0;
179 return -1;
180 }
181 os_close(fd);
182
183 if (set->remote) {
184 /* ignore error - it will be handled in rm_remote() */
185 (void) util_remote_load();
186 }
187
188 util_poolset_free(set);
189
190 struct cb_args args;
191 args.flags = flags;
192 args.error = 0;
193 ret = util_poolset_foreach_part(path, rm_cb, &args);
194 if (ret == -1) {
195 ERR_F(flags, "parsing poolset file failed");
196 if (CHECK_FLAG(flags, FORCE))
197 return 0;
198
199 return ret;
200 }
201
202 ASSERTeq(ret, 0);
203
204 if (args.error)
205 return args.error;
206
207 if (CHECK_FLAG(flags, POOLSET_LOCAL)) {
208 ret = rm_local(path, flags, 0);
209 if (ret) {
210 ERR_F(flags, "removing pool set file failed");
211 } else {
212 LOG(3, "%s: removed", path);
213 }
214
215 if (CHECK_FLAG(flags, FORCE))
216 return 0;
217
218 return ret;
219 }
220
221 return 0;
222}
223
224#ifndef _WIN32
225/*
226 * pmempool_rm -- remove pool files or poolsets
227 */
228int
229pmempool_rm(const char *path, unsigned flags)
230{
231 return pmempool_rmU(path, flags);
232}
233#else
234/*
235 * pmempool_rmW -- remove pool files or poolsets in widechar
236 */
237int
238pmempool_rmW(const wchar_t *path, unsigned flags)
239{
240 char *upath = util_toUTF8(path);
241 if (upath == NULL) {
242 ERR("Invalid poolest/pool file path.");
243 return -1;
244 }
245
246 int ret = pmempool_rmU(upath, flags);
247
248 util_free_UTF8(upath);
249 return ret;
250}
251#endif