~ubuntu-branches/ubuntu/karmic/vzctl/karmic

« back to all changes in this revision

Viewing changes to src/lib/destroy.c

  • Committer: Bazaar Package Importer
  • Author(s): Ola Lundqvist
  • Date: 2007-04-10 18:08:16 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20070410180816-0uuzj9fnna7gmzxv
Tags: 3.0.16-4
Etch has been released which means that this version can be uploaded
to unstable.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 *  Copyright (C) 2000-2006 SWsoft. All rights reserved.
 
2
 *  Copyright (C) 2000-2007 SWsoft. All rights reserved.
3
3
 *
4
4
 *  This program is free software; you can redistribute it and/or modify
5
5
 *  it under the terms of the GNU General Public License as published by
37
37
#include "lock.h"
38
38
#include "modules.h"
39
39
#include "create.h"
 
40
#include "env.h"
40
41
 
41
42
#define BACKUP          0
42
43
#define DESTR           1
43
44
 
 
45
const char destroy_dir_magic[]="vzctl-rm-me.";
 
46
 
44
47
static int destroydir(char *dir);
45
48
 
46
49
int del_dir(char *dir)
59
62
 
60
63
int vps_destroy_dir(envid_t veid, char *dir)
61
64
{
62
 
        int ret;
 
65
        int ret;
63
66
 
64
67
        if (!quota_ctl(veid, QUOTA_STAT)) {
65
68
                if ((ret = quota_off(veid, 0)))
69
72
        quota_ctl(veid, QUOTA_DROP);    
70
73
        if ((ret = destroydir(dir)))
71
74
                return ret;
72
 
        return 0;
 
75
        return 0;
73
76
}
74
77
 
75
78
static char *get_destroy_root(char *dir)
109
112
 
110
113
char *maketmpdir(const char *dir)
111
114
{
112
 
        char buf[STR_SIZE];
113
 
        char *tmp;
114
 
        char *tmp_dir;
 
115
        char buf[STR_SIZE];
 
116
        char *tmp;
 
117
        char *tmp_dir;
115
118
        int len;
116
119
 
117
 
        snprintf(buf, sizeof(buf), "%s/XXXXXXX", dir);
 
120
        snprintf(buf, sizeof(buf), "%s/%sXXXXXXX", dir, destroy_dir_magic);
118
121
        if ((tmp = mkdtemp(buf)) == NULL) {
119
 
                logger(0, errno, "Error in mkdtemp(%s)", buf);
 
122
                logger(-1, errno, "Error in mkdtemp(%s)", buf);
120
123
                return NULL;
121
124
        }
122
125
        len = strlen(dir);
123
 
        tmp_dir = (char *)malloc(strlen(tmp) - len);
 
126
        tmp_dir = (char *)malloc(strlen(tmp) - len);
124
127
        if (tmp_dir == NULL)
125
128
                return NULL;
126
 
        strcpy(tmp_dir, tmp + len + 1);
 
129
        strcpy(tmp_dir, tmp + len + 1);
127
130
 
128
 
        return tmp_dir;
 
131
        return tmp_dir;
129
132
}
130
133
 
 
134
/* Removes all the directories under 'root'
 
135
 * those names start with 'destroy_dir_magic'
 
136
 */
131
137
static void _destroydir(char *root)
132
138
{
133
139
        char buf[STR_SIZE];
141
147
                        return;
142
148
                del = 0;
143
149
                while ((ep = readdir(dp))) {
144
 
                        if (!strcmp(ep->d_name, ".") ||
145
 
                                !strcmp(ep->d_name, ".."))
 
150
                        if (strncmp(ep->d_name, destroy_dir_magic,
 
151
                                        sizeof(destroy_dir_magic) - 1))
146
152
                        {
147
153
                                continue;
148
154
                        }
149
155
                        snprintf(buf, sizeof(buf), "%s/%s", root, ep->d_name);
150
156
                        if (stat(buf, &st)) 
151
157
                                continue;
152
 
                        if (!S_ISDIR(st.st_mode))
 
158
                        if (!S_ISDIR(st.st_mode))
153
159
                                continue;
154
160
                        snprintf(buf, sizeof(buf), "rm -rf %s/%s",
155
161
                                root, ep->d_name);
175
181
 
176
182
        if (stat(dir, &st)) {
177
183
                if (errno != ENOENT) {
178
 
                        logger(0, errno, "Unable to stat %s", dir);
 
184
                        logger(-1, errno, "Unable to stat %s", dir);
179
185
                        return -1;
180
186
                }
181
187
                return 0;
182
188
        }
183
189
        if (!S_ISDIR(st.st_mode)) {
184
 
                logger(0, 0, "Warning: VPS private area is not a directory");
 
190
                logger(-1, 0, "Warning: VE private area is not a directory");
185
191
                if (unlink(dir)) {
186
 
                        logger(0, errno, "Unable to unlink %s", dir);
 
192
                        logger(-1, errno, "Unable to unlink %s", dir);
187
193
                        return -1;
188
194
                }
189
195
                return 0;
190
196
        }
191
197
        root = get_destroy_root(dir);
192
198
        if (root == NULL) {
193
 
                logger(0, 0, "Unable to get root for %s", dir);
 
199
                logger(-1, 0, "Unable to get root for %s", dir);
194
200
                return -1;
195
201
        }
196
 
        snprintf(tmp, sizeof(buf), "%s/tmp", root);
 
202
        snprintf(tmp, sizeof(tmp), "%s/tmp", root);
197
203
        free(root);
198
204
        if (!stat_file(tmp)) {
199
205
                if (mkdir(tmp, 0755)) {
200
 
                        logger(0, errno, "Can't create tmp dir %s", tmp);
 
206
                        logger(-1, errno, "Can't create tmp dir %s", tmp);
201
207
                        return VZ_FS_DEL_PRVT;
202
208
                }
203
209
        }
204
210
        /* First move to del */
205
211
        if ((tmp_nm = maketmpdir(tmp)) == NULL) {
206
 
                logger(0, 0, "Unable to generate temporary name in %s", tmp);
 
212
                logger(-1, 0, "Unable to generate temporary name in %s", tmp);
207
213
                return VZ_FS_DEL_PRVT;
208
214
        }
209
 
        snprintf(buf, sizeof(tmp), "%s/%s", tmp, tmp_nm);
 
215
        snprintf(buf, sizeof(buf), "%s/%s", tmp, tmp_nm);
210
216
        free(tmp_nm);
211
217
        if (rename(dir, buf)) {
212
 
                logger(0, errno, "Can't move %s -> %s", dir, buf);
 
218
                logger(-1, errno, "Can't move %s -> %s", dir, buf);
213
219
                rmdir(buf);
214
220
                return VZ_FS_DEL_PRVT;
215
221
        }
243
249
                _unlock(fd_lock, buf);
244
250
                exit(0);
245
251
        } else if (pid < 0)  {
246
 
                logger(0, errno, "destroydir: Unable to fork");
 
252
                logger(-1, errno, "destroydir: Unable to fork");
247
253
                ret = VZ_RESOURCE_ERROR;
248
254
        }
249
255
        sleep(1);
259
265
                return VZ_VE_PRIVATE_NOTSET;
260
266
        if (check_var(fs->root, "VE_ROOT is not set"))
261
267
                return VZ_VE_ROOT_NOTSET;
 
268
        if (vps_is_run(h, veid)) {
 
269
                logger(0, 0, "VE is currently runing."
 
270
                        " Stop it before proceeding.");
 
271
                return VZ_VE_RUNNING;
 
272
        }
262
273
        if (vps_is_mounted(fs->root)) {
263
 
                logger(0, 0, "VPS is currently mounted (umount first)");
264
 
                return VZ_FS_MOUNTED;
 
274
                logger(0, 0, "VE is currently mounted (umount first)");
 
275
                return VZ_FS_MOUNTED;
265
276
        }
266
 
        logger(0, 0, "Destroying VPS private area: %s", fs->private);
 
277
        logger(0, 0, "Destroying VE private area: %s", fs->private);
267
278
        if ((ret = vps_destroy_dir(veid, fs->private)))
268
279
                return ret;
269
280
        move_config(veid, BACKUP);
270
281
        rmdir(fs->root);
271
 
        logger(0, 0, "VPS private area was destroyed");
 
282
        logger(0, 0, "VE private area was destroyed");
272
283
 
273
284
        return 0;
274
285
}