~ubuntu-branches/ubuntu/utopic/xfsprogs/utopic-proposed

« back to all changes in this revision

Viewing changes to quota/project.c

  • Committer: Bazaar Package Importer
  • Author(s): Nathan Scott
  • Date: 2009-05-06 11:29:18 UTC
  • mfrom: (8.1.1 jaunty)
  • Revision ID: james.westby@ubuntu.com-20090506112918-uzoyzcp90rtr8td7
Tags: 3.0.2
New bugfix release

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
 
24
24
static cmdinfo_t project_cmd;
25
25
static prid_t prid;
 
26
static int recurse_depth = -1;
26
27
 
27
28
enum {
28
29
        CHECK_PROJECT   = 0x1,
31
32
};
32
33
 
33
34
#define EXCLUDED_FILE_TYPES(x) \
34
 
           S_ISCHR((x)) \
 
35
           (S_ISCHR((x)) \
35
36
        || S_ISBLK((x)) \
36
37
        || S_ISFIFO((x)) \
37
38
        || S_ISLNK((x)) \
38
 
        || S_ISSOCK((x))
 
39
        || S_ISSOCK((x)))
39
40
 
40
41
static void
41
42
project_help(void)
62
63
" Once this has been done, new files created in the tree will automatically\n"
63
64
" be accounted to the tree based on their project identifier.  An attempt to\n"
64
65
" create a hard link to a file in the tree will only succeed if the project\n"
65
 
" identifier matches the project identifer for the tree.  The xfs_io utility\n"
 
66
" identifier matches the project identifier for the tree.  The xfs_io utility\n"
66
67
" can be used to set the project ID for an arbitrary file, but this can only\n"
67
68
" be done by a privileged user.\n"
68
69
"\n"
75
76
" which do not have the project ID of the rest of the tree, or if the inode\n"
76
77
" flag is not set.\n"
77
78
"\n"
 
79
" The -p <path> option can be used to manually specify project path without\n"
 
80
" need to create /etc/projects file. This option can be used multiple times\n"
 
81
" to specify multiple paths. When using this option only one projid/name can\n"
 
82
" be specified at command line. Note that /etc/projects is also used if exists.\n"
 
83
"\n"
 
84
" The -d <depth> option allows to descend at most <depth> levels of directories\n"
 
85
" below the command line arguments. -d 0 means only apply the actions\n"
 
86
" to the top level of the projects. -d -1 means no recursion limit (default).\n"
 
87
"\n"
78
88
" The /etc/projid and /etc/projects file formats are simple, and described\n"
79
89
" on the xfs_quota man page.\n"
80
90
"\n"));
90
100
        struct fsxattr          fsx;
91
101
        int                     fd;
92
102
 
 
103
        if (recurse_depth >= 0 && data->level > recurse_depth)
 
104
                return -1;
 
105
 
93
106
        if (flag == FTW_NS ){
 
107
                exitcode = 1;
94
108
                fprintf(stderr, _("%s: cannot stat file %s\n"), progname, path);
95
109
                return 0;
96
110
        }
99
113
                return 0;
100
114
        }
101
115
 
102
 
        if ((fd = open(path, O_RDONLY|O_NOCTTY)) == -1)
 
116
        if ((fd = open(path, O_RDONLY|O_NOCTTY)) == -1) {
 
117
                exitcode = 1;
103
118
                fprintf(stderr, _("%s: cannot open %s: %s\n"),
104
119
                        progname, path, strerror(errno));
105
 
        else if ((xfsctl(path, fd, XFS_IOC_FSGETXATTR, &fsx)) < 0)
 
120
        } else if ((xfsctl(path, fd, XFS_IOC_FSGETXATTR, &fsx)) < 0) {
 
121
                exitcode = 1;
106
122
                fprintf(stderr, _("%s: cannot get flags on %s: %s\n"),
107
123
                        progname, path, strerror(errno));
108
 
        else {
 
124
        } else {
109
125
                if (fsx.fsx_projid != prid)
110
126
                        printf(_("%s - project identifier is not set"
111
127
                                 " (inode=%u, tree=%u)\n"),
129
145
        struct fsxattr          fsx;
130
146
        int                     fd;
131
147
 
 
148
        if (recurse_depth >= 0 && data->level > recurse_depth)
 
149
                return -1;
 
150
 
132
151
        if (flag == FTW_NS ){
 
152
                exitcode = 1;
133
153
                fprintf(stderr, _("%s: cannot stat file %s\n"), progname, path);
134
154
                return 0;
135
155
        }
139
159
        }
140
160
 
141
161
        if ((fd = open(path, O_RDONLY|O_NOCTTY)) == -1) {
 
162
                exitcode = 1;
142
163
                fprintf(stderr, _("%s: cannot open %s: %s\n"),
143
164
                        progname, path, strerror(errno));
144
165
                return 0;
145
166
        } else if (xfsctl(path, fd, XFS_IOC_FSGETXATTR, &fsx) < 0) {
 
167
                exitcode = 1;
146
168
                fprintf(stderr, _("%s: cannot get flags on %s: %s\n"),
147
169
                        progname, path, strerror(errno));
148
170
                close(fd);
151
173
 
152
174
        fsx.fsx_projid = 0;
153
175
        fsx.fsx_xflags &= ~XFS_XFLAG_PROJINHERIT;
154
 
        if (xfsctl(path, fd, XFS_IOC_FSSETXATTR, &fsx) < 0)
 
176
        if (xfsctl(path, fd, XFS_IOC_FSSETXATTR, &fsx) < 0) {
 
177
                exitcode = 1;
155
178
                fprintf(stderr, _("%s: cannot clear project on %s: %s\n"),
156
179
                        progname, path, strerror(errno));
 
180
        }
157
181
        close(fd);
158
182
        return 0;
159
183
}
168
192
        struct fsxattr          fsx;
169
193
        int                     fd;
170
194
 
 
195
        if (recurse_depth >= 0 && data->level > recurse_depth)
 
196
                return -1;
 
197
 
171
198
        if (flag == FTW_NS ){
 
199
                exitcode = 1;
172
200
                fprintf(stderr, _("%s: cannot stat file %s\n"), progname, path);
173
201
                return 0;
174
202
        }
178
206
        }
179
207
 
180
208
        if ((fd = open(path, O_RDONLY|O_NOCTTY)) == -1) {
 
209
                exitcode = 1;
181
210
                fprintf(stderr, _("%s: cannot open %s: %s\n"),
182
211
                        progname, path, strerror(errno));
183
212
                return 0;
184
213
        } else if (xfsctl(path, fd, XFS_IOC_FSGETXATTR, &fsx) < 0) {
 
214
                exitcode = 1;
185
215
                fprintf(stderr, _("%s: cannot get flags on %s: %s\n"),
186
216
                        progname, path, strerror(errno));
187
217
                close(fd);
190
220
 
191
221
        fsx.fsx_projid = prid;
192
222
        fsx.fsx_xflags |= XFS_XFLAG_PROJINHERIT;
193
 
        if (xfsctl(path, fd, XFS_IOC_FSSETXATTR, &fsx) < 0)
 
223
        if (xfsctl(path, fd, XFS_IOC_FSSETXATTR, &fsx) < 0) {
 
224
                exitcode = 1;
194
225
                fprintf(stderr, _("%s: cannot set project on %s: %s\n"),
195
226
                        progname, path, strerror(errno));
 
227
        }
196
228
        close(fd);
197
229
        return 0;
198
230
}
206
238
        switch (type) {
207
239
        case CHECK_PROJECT:
208
240
                printf(_("Checking project %s (path %s)...\n"), project, dir);
209
 
                nftw(dir, check_project, 100, FTW_PHYS|FTW_MOUNT|FTW_DEPTH);
 
241
                nftw(dir, check_project, 100, FTW_PHYS|FTW_MOUNT);
210
242
                break;
211
243
        case SETUP_PROJECT:
212
244
                printf(_("Setting up project %s (path %s)...\n"), project, dir);
213
 
                nftw(dir, setup_project, 100, FTW_PHYS|FTW_MOUNT|FTW_DEPTH);
 
245
                nftw(dir, setup_project, 100, FTW_PHYS|FTW_MOUNT);
214
246
                break;
215
247
        case CLEAR_PROJECT:
216
248
                printf(_("Clearing project %s (path %s)...\n"), project, dir);
217
 
                nftw(dir, clear_project, 100, FTW_PHYS|FTW_MOUNT|FTW_DEPTH);
 
249
                nftw(dir, clear_project, 100, FTW_PHYS|FTW_MOUNT);
218
250
                break;
219
251
        }
220
252
}
230
262
 
231
263
        fs_cursor_initialise(NULL, FS_PROJECT_PATH, &cursor);
232
264
        while ((path = fs_cursor_next_entry(&cursor))) {
233
 
                if (prid != path->fs_prid)
 
265
                if (prid != path->fs_prid && path->fs_prid != -1)
234
266
                        continue;
235
267
                project_operations(project, path->fs_dir, type);
236
268
                count++;
237
269
        }
238
270
 
239
 
        printf(_("Processed %d %s paths for project %s\n"),
240
 
                 count, projects_file, project);
 
271
        printf(_("Processed %d (%s and cmdline) paths for project %s with recursion depth %s (%d).\n"),
 
272
                 count, projects_file, project,
 
273
                 recurse_depth < 0 ? _("infinite") : _("limited"), recurse_depth);
241
274
}
242
275
 
243
276
static int
245
278
        int             argc,
246
279
        char            **argv)
247
280
{
248
 
        int             c, type = 0;
 
281
        int             c, type = 0, ispath = 0;
249
282
 
250
 
        while ((c = getopt(argc, argv, "csC")) != EOF) {
 
283
        while ((c = getopt(argc, argv, "cd:p:sC")) != EOF) {
251
284
                switch (c) {
252
285
                case 'c':
253
286
                        type = CHECK_PROJECT;
254
287
                        break;
 
288
                case 'd':
 
289
                        recurse_depth = atoi(optarg);
 
290
                        if (recurse_depth < 0)
 
291
                                recurse_depth = -1;
 
292
                        break;
 
293
                case 'p':
 
294
                        ispath = 1;
 
295
                        fs_table_insert_project_path(optarg, -1);
 
296
                        break;
255
297
                case 's':
256
298
                        type = SETUP_PROJECT;
257
299
                        break;
271
313
                type = CHECK_PROJECT;
272
314
 
273
315
        setprfiles();
274
 
        if (access(projects_file, F_OK) != 0) {
 
316
        if (!ispath && access(projects_file, F_OK) != 0) {
 
317
                exitcode = 1;
275
318
                fprintf(stderr, _("projects file \"%s\" doesn't exist\n"),
276
319
                        projects_file);
277
320
                return 0;
278
321
        }
279
322
 
 
323
        if (ispath && argc - optind > 1) {
 
324
                exitcode = 1;
 
325
                fprintf(stderr, _("%s: only one projid/name can be specified when using -p <path>, %d found.\n"),
 
326
                                progname, argc - optind);
 
327
                return 0;
 
328
        }
 
329
 
280
330
        while (argc > optind) {
281
331
                prid = prid_from_string(argv[optind]);
282
 
                if (prid == -1)
 
332
                if (prid == -1) {
 
333
                        exitcode = 1;
283
334
                        fprintf(stderr, _("%s - no such project in %s\n"),
284
335
                                argv[optind], projects_file);
285
 
                else
 
336
                } else
286
337
                        project(argv[optind], type);
287
338
                optind++;
288
339
        }
296
347
        project_cmd.name = _("project");
297
348
        project_cmd.altname = _("tree");
298
349
        project_cmd.cfunc = project_f;
299
 
        project_cmd.args = _("[-c|-s|-C] project ...");
 
350
        project_cmd.args = _("[-c|-s|-C|-d <depth>|-p <path>] project ...");
300
351
        project_cmd.argmin = 1;
301
352
        project_cmd.argmax = -1;
302
353
        project_cmd.oneline = _("check, setup or clear project quota trees");