]>
git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - quota/report.c
2 * Copyright (c) 2005 Silicon Graphics, Inc.
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 #include <xfs/command.h>
26 static cmdinfo_t dump_cmd
;
27 static cmdinfo_t report_cmd
;
32 dump_cmd
.args
= _("[-gpu] [-f file]");
33 dump_cmd
.oneline
= _("dump quota information for backup utilities");
36 " create a backup file which contains quota limits information\n"
37 " -g -- dump out group quota limits\n"
38 " -p -- dump out project quota limits\n"
39 " -u -- dump out user quota limits (default)\n"
40 " -f -- write the dump out to the specified file\n"
47 report_cmd
.args
= _("[-bir] [-gpu] [-ahnt] [-f file]");
48 report_cmd
.oneline
= _("report filesystem quota information");
51 " report used space and inodes, and quota limits, for a filesystem\n"
54 " (reports inode usage for all groups, in an easy-to-read format)\n"
55 " This command is the equivalent of the traditional repquota command, which\n"
56 " prints a summary of the disk usage and quotas for the current filesystem,\n"
57 " or all filesystems.\n"
58 " -a -- report for all mounted filesystems with quota enabled\n"
59 " -h -- report in a human-readable format\n"
60 " -n -- skip identifier-to-name translations, just report IDs\n"
61 " -N -- suppress the header from the output\n"
62 " -t -- terse output format, hides rows which are all zero\n"
63 " -g -- report group usage and quota information\n"
64 " -p -- report project usage and quota information\n"
65 " -u -- report user usage and quota information\n"
66 " -b -- report blocks-used information only\n"
67 " -i -- report inodes-used information only\n"
68 " -r -- report realtime-blocks-used information only\n"
81 if (xfsquotactl(XFS_GETQUOTA
, dev
, type
, id
, (void *)&d
) < 0)
83 if (!d
.d_blk_softlimit
&& !d
.d_blk_hardlimit
&&
84 !d
.d_ino_softlimit
&& !d
.d_ino_hardlimit
&&
85 !d
.d_rtb_softlimit
&& !d
.d_rtb_hardlimit
)
87 fprintf(fp
, "fs = %s\n", dev
);
88 /* this branch is for backward compatibility reasons */
89 if (d
.d_rtb_softlimit
|| d
.d_rtb_hardlimit
)
90 fprintf(fp
, "%-10d %7llu %7llu %7llu %7llu %7llu %7llu\n", id
,
91 (unsigned long long)d
.d_blk_softlimit
,
92 (unsigned long long)d
.d_blk_hardlimit
,
93 (unsigned long long)d
.d_ino_softlimit
,
94 (unsigned long long)d
.d_ino_hardlimit
,
95 (unsigned long long)d
.d_rtb_softlimit
,
96 (unsigned long long)d
.d_rtb_hardlimit
);
98 fprintf(fp
, "%-10d %7llu %7llu %7llu %7llu\n", id
,
99 (unsigned long long)d
.d_blk_softlimit
,
100 (unsigned long long)d
.d_blk_hardlimit
,
101 (unsigned long long)d
.d_ino_softlimit
,
102 (unsigned long long)d
.d_ino_hardlimit
);
106 dump_limits_any_type(
116 if ((mount
= fs_table_lookup(dir
, FS_MOUNT_POINT
)) == NULL
) {
117 fprintf(stderr
, "%s: cannot find mount point %s\n",
123 for (id
= lower
; id
< upper
; id
++)
124 dump_file(fp
, id
, type
, mount
->fs_name
);
129 case XFS_GROUP_QUOTA
: {
132 while ((g
= getgrent()) != NULL
)
133 dump_file(fp
, g
->gr_gid
, type
, mount
->fs_name
);
137 case XFS_PROJ_QUOTA
: {
138 struct fs_project
*p
;
140 while ((p
= getprent()) != NULL
)
141 dump_file(fp
, p
->pr_prid
, type
, mount
->fs_name
);
145 case XFS_USER_QUOTA
: {
148 while ((u
= getpwent()) != NULL
)
149 dump_file(fp
, u
->pw_uid
, type
, mount
->fs_name
);
163 uint lower
= 0, upper
= 0;
164 int c
, type
= XFS_USER_QUOTA
;
166 while ((c
= getopt(argc
, argv
, "f:gpuL:U:")) != EOF
) {
172 type
= XFS_GROUP_QUOTA
;
175 type
= XFS_PROJ_QUOTA
;
178 type
= XFS_USER_QUOTA
;
181 lower
= (uint
)atoi(optarg
);
184 upper
= (uint
)atoi(optarg
);
187 return command_usage(&dump_cmd
);
192 return command_usage(&dump_cmd
);
194 if ((fp
= fopen_write_secure(fname
)) == NULL
)
197 dump_limits_any_type(fp
, type
, fs_path
->fs_dir
, lower
, upper
);
213 char *typename
= type_to_string(type
);
217 if (flags
& NO_HEADER_FLAG
)
221 fprintf(fp
, _("%s quota on %s (%s)\n"),
222 typename
, mount
->fs_dir
, mount
->fs_name
);
225 for (i
= 0; i
< 10; i
++)
227 if (form
& XFS_BLOCK_QUOTA
)
228 fprintf(fp
, (flags
& HUMAN_FLAG
) ?
229 "%13c %s %13c" : "%20c %s %20c",
230 ' ', form_to_string(XFS_BLOCK_QUOTA
), ' ');
231 if (form
& XFS_INODE_QUOTA
)
232 fprintf(fp
, (flags
& HUMAN_FLAG
) ?
233 "%13c %s %13c" : "%20c %s %20c",
234 ' ', form_to_string(XFS_INODE_QUOTA
), ' ');
235 if (form
& XFS_RTBLOCK_QUOTA
)
236 fprintf(fp
, (flags
& HUMAN_FLAG
) ?
237 "%9c %s %9c" : "%15c %s %15c",
238 ' ', form_to_string(XFS_RTBLOCK_QUOTA
), ' ');
242 snprintf(scratch
, sizeof(scratch
), "%s ID", typename
);
243 fprintf(fp
, "%-10s ", scratch
);
244 if (form
& XFS_BLOCK_QUOTA
)
245 fprintf(fp
, (flags
& HUMAN_FLAG
) ?
246 _(" Used Soft Hard Warn/Grace ") :
247 _(" Used Soft Hard Warn/Grace "));
248 if (form
& XFS_INODE_QUOTA
)
249 fprintf(fp
, (flags
& HUMAN_FLAG
) ?
250 _(" Used Soft Hard Warn/Grace ") :
251 _(" Used Soft Hard Warn/ Grace "));
252 if (form
& XFS_RTBLOCK_QUOTA
)
253 fprintf(fp
, (flags
& HUMAN_FLAG
) ?
254 _(" Used Soft Hard Warn/Grace ") :
255 _(" Used Soft Hard Warn/Grace "));
259 for (i
= 0; i
< 10; i
++)
262 count
= (flags
& HUMAN_FLAG
) ? 33 : 50;
263 if (form
& XFS_BLOCK_QUOTA
) {
264 for (i
= 0; i
< count
; i
++)
268 if (form
& XFS_INODE_QUOTA
) {
269 for (i
= 0; i
< count
; i
++)
273 if (form
& XFS_RTBLOCK_QUOTA
) {
274 for (i
= 0; i
< count
; i
++)
292 char *dev
= mount
->fs_name
;
293 char c
[8], h
[8], s
[8];
297 if (xfsquotactl(XFS_GETQUOTA
, dev
, type
, id
, (void *)&d
) < 0)
300 if (flags
& TERSE_FLAG
) {
302 if ((form
& XFS_BLOCK_QUOTA
) && d
.d_bcount
)
304 if ((form
& XFS_INODE_QUOTA
) && d
.d_icount
)
306 if ((form
& XFS_RTBLOCK_QUOTA
) && d
.d_rtbcount
)
312 if (!(flags
& NO_HEADER_FLAG
))
313 report_header(fp
, form
, type
, mount
, flags
);
315 fprintf(fp
, "%-10s", name
);
316 if (form
& XFS_BLOCK_QUOTA
) {
317 qflags
= (flags
& HUMAN_FLAG
);
318 if (d
.d_blk_hardlimit
&& d
.d_bcount
> d
.d_blk_hardlimit
)
319 qflags
|= LIMIT_FLAG
;
320 if (d
.d_blk_softlimit
&& d
.d_bcount
> d
.d_blk_softlimit
)
321 qflags
|= QUOTA_FLAG
;
322 if (flags
& HUMAN_FLAG
)
323 fprintf(fp
, " %6s %6s %6s %02d %8s",
324 bbs_to_string(d
.d_bcount
, c
, sizeof(c
)),
325 bbs_to_string(d
.d_blk_softlimit
, s
, sizeof(s
)),
326 bbs_to_string(d
.d_blk_hardlimit
, h
, sizeof(h
)),
328 time_to_string(d
.d_btimer
, qflags
));
330 fprintf(fp
, " %10llu %10llu %10llu %02d %9s",
331 (unsigned long long)d
.d_bcount
>> 1,
332 (unsigned long long)d
.d_blk_softlimit
>> 1,
333 (unsigned long long)d
.d_blk_hardlimit
>> 1,
335 time_to_string(d
.d_btimer
, qflags
));
337 if (form
& XFS_INODE_QUOTA
) {
338 qflags
= (flags
& HUMAN_FLAG
);
339 if (d
.d_ino_hardlimit
&& d
.d_icount
> d
.d_ino_hardlimit
)
340 qflags
|= LIMIT_FLAG
;
341 if (d
.d_ino_softlimit
&& d
.d_icount
> d
.d_ino_softlimit
)
342 qflags
|= QUOTA_FLAG
;
343 if (flags
& HUMAN_FLAG
)
344 fprintf(fp
, " %6s %6s %6s %02d %8s",
345 num_to_string(d
.d_icount
, c
, sizeof(c
)),
346 num_to_string(d
.d_ino_softlimit
, s
, sizeof(s
)),
347 num_to_string(d
.d_ino_hardlimit
, h
, sizeof(h
)),
349 time_to_string(d
.d_itimer
, qflags
));
351 fprintf(fp
, " %10llu %10llu %10llu %02d %9s",
352 (unsigned long long)d
.d_icount
,
353 (unsigned long long)d
.d_ino_softlimit
,
354 (unsigned long long)d
.d_ino_hardlimit
,
356 time_to_string(d
.d_itimer
, qflags
));
358 if (form
& XFS_RTBLOCK_QUOTA
) {
359 qflags
= (flags
& HUMAN_FLAG
);
360 if (d
.d_rtb_hardlimit
&& d
.d_rtbcount
> d
.d_rtb_hardlimit
)
361 qflags
|= LIMIT_FLAG
;
362 if (d
.d_rtb_softlimit
&& d
.d_rtbcount
> d
.d_rtb_softlimit
)
363 qflags
|= QUOTA_FLAG
;
364 if (flags
& HUMAN_FLAG
)
365 fprintf(fp
, " %6s %6s %6s %02d %8s",
366 bbs_to_string(d
.d_rtbcount
, c
, sizeof(c
)),
367 bbs_to_string(d
.d_rtb_softlimit
, s
, sizeof(s
)),
368 bbs_to_string(d
.d_rtb_hardlimit
, h
, sizeof(h
)),
370 time_to_string(d
.d_rtbtimer
, qflags
));
372 fprintf(fp
, " %10llu %10llu %10llu %02d %9s",
373 (unsigned long long)d
.d_rtbcount
>> 1,
374 (unsigned long long)d
.d_rtb_softlimit
>> 1,
375 (unsigned long long)d
.d_rtb_hardlimit
>> 1,
377 time_to_string(d
.d_rtbtimer
, qflags
));
396 if (upper
) { /* identifier range specified */
397 for (id
= lower
; id
< upper
; id
++) {
398 snprintf(n
, sizeof(n
)-1, "#%u", id
);
399 if (report_mount(fp
, id
, n
,
400 form
, XFS_USER_QUOTA
, mount
, flags
))
401 flags
|= NO_HEADER_FLAG
;
405 while ((u
= getpwent()) != NULL
) {
406 if (flags
& NO_LOOKUP_FLAG
)
407 snprintf(n
, sizeof(n
)-1, "#%u", u
->pw_uid
);
409 strncpy(n
, u
->pw_name
, sizeof(n
)-1);
410 if (report_mount(fp
, u
->pw_uid
, n
,
411 form
, XFS_USER_QUOTA
, mount
, flags
))
412 flags
|= NO_HEADER_FLAG
;
417 if (flags
& NO_HEADER_FLAG
)
434 if (upper
) { /* identifier range specified */
435 for (id
= lower
; id
< upper
; id
++) {
436 snprintf(n
, sizeof(n
)-1, "#%u", id
);
437 if (report_mount(fp
, id
, n
,
438 form
, XFS_GROUP_QUOTA
, mount
, flags
))
439 flags
|= NO_HEADER_FLAG
;
443 while ((g
= getgrent()) != NULL
) {
444 if (flags
& NO_LOOKUP_FLAG
)
445 snprintf(n
, sizeof(n
)-1, "#%u", g
->gr_gid
);
447 strncpy(n
, g
->gr_name
, sizeof(n
)-1);
448 if (report_mount(fp
, g
->gr_gid
, n
,
449 form
, XFS_GROUP_QUOTA
, mount
, flags
))
450 flags
|= NO_HEADER_FLAG
;
453 if (flags
& NO_HEADER_FLAG
)
459 report_project_mount(
471 if (upper
) { /* identifier range specified */
472 for (id
= lower
; id
< upper
; id
++) {
473 snprintf(n
, sizeof(n
)-1, "#%u", id
);
474 if (report_mount(fp
, id
, n
,
475 form
, XFS_PROJ_QUOTA
, mount
, flags
))
476 flags
|= NO_HEADER_FLAG
;
480 while ((p
= getprent()) != NULL
) {
481 if (flags
& NO_LOOKUP_FLAG
)
482 snprintf(n
, sizeof(n
)-1, "#%u",
483 (unsigned int)p
->pr_prid
);
485 strncpy(n
, p
->pr_name
, sizeof(n
)-1);
486 if (report_mount(fp
, p
->pr_prid
, n
,
487 form
, XFS_PROJ_QUOTA
, mount
, flags
))
488 flags
|= NO_HEADER_FLAG
;
493 if (flags
& NO_HEADER_FLAG
)
510 if (type
& XFS_USER_QUOTA
) {
511 fs_cursor_initialise(dir
, FS_MOUNT_POINT
, &cursor
);
512 while ((mount
= fs_cursor_next_entry(&cursor
))) {
513 xfsquotactl(XFS_QSYNC
, mount
->fs_name
,
514 XFS_USER_QUOTA
, 0, NULL
);
515 report_user_mount(fp
, form
, mount
,
516 lower
, upper
, flags
);
519 if (type
& XFS_GROUP_QUOTA
) {
520 fs_cursor_initialise(dir
, FS_MOUNT_POINT
, &cursor
);
521 while ((mount
= fs_cursor_next_entry(&cursor
))) {
522 xfsquotactl(XFS_QSYNC
, mount
->fs_name
,
523 XFS_GROUP_QUOTA
, 0, NULL
);
524 report_group_mount(fp
, form
, mount
,
525 lower
, upper
, flags
);
528 if (type
& XFS_PROJ_QUOTA
) {
529 fs_cursor_initialise(dir
, FS_MOUNT_POINT
, &cursor
);
530 while ((mount
= fs_cursor_next_entry(&cursor
))) {
531 xfsquotactl(XFS_QSYNC
, mount
->fs_name
,
532 XFS_PROJ_QUOTA
, 0, NULL
);
533 report_project_mount(fp
, form
, mount
,
534 lower
, upper
, flags
);
546 uint lower
= 0, upper
= 0;
547 int c
, flags
= 0, type
= 0, form
= 0;
549 while ((c
= getopt(argc
, argv
, "abf:ghiL:NnprtuU:")) != EOF
) {
555 form
|= XFS_BLOCK_QUOTA
;
558 form
|= XFS_INODE_QUOTA
;
561 form
|= XFS_RTBLOCK_QUOTA
;
564 type
|= XFS_GROUP_QUOTA
;
567 type
|= XFS_PROJ_QUOTA
;
570 type
|= XFS_USER_QUOTA
;
573 flags
|= ALL_MOUNTS_FLAG
;
579 flags
|= NO_LOOKUP_FLAG
;
582 flags
|= NO_HEADER_FLAG
;
588 lower
= (uint
)atoi(optarg
);
591 upper
= (uint
)atoi(optarg
);
594 return command_usage(&report_cmd
);
599 form
= XFS_BLOCK_QUOTA
;
602 type
= XFS_USER_QUOTA
| XFS_GROUP_QUOTA
| XFS_PROJ_QUOTA
;
604 if ((fp
= fopen_write_secure(fname
)) == NULL
)
607 if (argc
== optind
) {
608 if (flags
& ALL_MOUNTS_FLAG
)
609 report_any_type(fp
, form
, type
, NULL
,
610 lower
, upper
, flags
);
611 else if (fs_path
->fs_flags
& FS_MOUNT_POINT
)
612 report_any_type(fp
, form
, type
, fs_path
->fs_dir
,
613 lower
, upper
, flags
);
614 } else while (argc
> optind
) {
615 report_any_type(fp
, form
, type
, argv
[optind
++],
616 lower
, upper
, flags
);
627 dump_cmd
.name
= _("dump");
628 dump_cmd
.cfunc
= dump_f
;
630 dump_cmd
.argmax
= -1;
631 dump_cmd
.args
= _("[-gpu] [-f file]");
632 dump_cmd
.oneline
= _("dump quota information for backup utilities");
633 dump_cmd
.help
= dump_help
;
635 report_cmd
.name
= _("report");
636 report_cmd
.altname
= _("repquota");
637 report_cmd
.cfunc
= report_f
;
638 report_cmd
.argmin
= 0;
639 report_cmd
.argmax
= -1;
640 report_cmd
.args
= _("[-bir] [-gpu] [-ahnt] [-f file]");
641 report_cmd
.oneline
= _("report filesystem quota information");
642 report_cmd
.help
= report_help
;
645 add_command(&dump_cmd
);
646 add_command(&report_cmd
);