]>
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"
20 #include <sys/types.h>
27 static cmdinfo_t dump_cmd
;
28 static cmdinfo_t report_cmd
;
33 dump_cmd
.args
= _("[-gpu] [-f file]");
34 dump_cmd
.oneline
= _("dump quota information for backup utilities");
37 " create a backup file which contains quota limits information\n"
38 " -g -- dump out group quota limits\n"
39 " -p -- dump out project quota limits\n"
40 " -u -- dump out user quota limits (default)\n"
41 " -f -- write the dump out to the specified file\n"
48 report_cmd
.args
= _("[-bir] [-gpu] [-ahntLNU] [-f file]");
49 report_cmd
.oneline
= _("report filesystem quota information");
52 " report used space and inodes, and quota limits, for a filesystem\n"
55 " (reports inode usage for all groups, in an easy-to-read format)\n"
56 " This command is the equivalent of the traditional repquota command, which\n"
57 " prints a summary of the disk usage and quotas for the current filesystem,\n"
58 " or all filesystems.\n"
59 " -a -- report for all mounted filesystems with quota enabled\n"
60 " -h -- report in a human-readable format\n"
61 " -n -- skip identifier-to-name translations, just report IDs\n"
62 " -N -- suppress the header from the output\n"
63 " -t -- terse output format, hides rows which are all zero\n"
64 " -L -- lower ID bound to report on\n"
65 " -U -- upper ID bound to report on\n"
66 " -g -- report group usage and quota information\n"
67 " -p -- report project usage and quota information\n"
68 " -u -- report user usage and quota information\n"
69 " -b -- report blocks-used information only\n"
70 " -i -- report inodes-used information only\n"
71 " -r -- report realtime-blocks-used information only\n"
84 if (xfsquotactl(XFS_GETQUOTA
, dev
, type
, id
, (void *)&d
) < 0) {
85 if (errno
!= ENOENT
&& errno
!= ENOSYS
&& errno
!= ESRCH
)
86 perror("XFS_GETQUOTA");
89 if (!d
.d_blk_softlimit
&& !d
.d_blk_hardlimit
&&
90 !d
.d_ino_softlimit
&& !d
.d_ino_hardlimit
&&
91 !d
.d_rtb_softlimit
&& !d
.d_rtb_hardlimit
)
93 fprintf(fp
, "fs = %s\n", dev
);
94 /* this branch is for backward compatibility reasons */
95 if (d
.d_rtb_softlimit
|| d
.d_rtb_hardlimit
)
96 fprintf(fp
, "%-10d %7llu %7llu %7llu %7llu %7llu %7llu\n", id
,
97 (unsigned long long)d
.d_blk_softlimit
,
98 (unsigned long long)d
.d_blk_hardlimit
,
99 (unsigned long long)d
.d_ino_softlimit
,
100 (unsigned long long)d
.d_ino_hardlimit
,
101 (unsigned long long)d
.d_rtb_softlimit
,
102 (unsigned long long)d
.d_rtb_hardlimit
);
104 fprintf(fp
, "%-10d %7llu %7llu %7llu %7llu\n", id
,
105 (unsigned long long)d
.d_blk_softlimit
,
106 (unsigned long long)d
.d_blk_hardlimit
,
107 (unsigned long long)d
.d_ino_softlimit
,
108 (unsigned long long)d
.d_ino_hardlimit
);
112 dump_limits_any_type(
122 if ((mount
= fs_table_lookup(dir
, FS_MOUNT_POINT
)) == NULL
) {
124 fprintf(stderr
, "%s: cannot find mount point %s\n",
130 for (id
= lower
; id
<= upper
; id
++)
131 dump_file(fp
, id
, type
, mount
->fs_name
);
136 case XFS_GROUP_QUOTA
: {
139 while ((g
= getgrent()) != NULL
)
140 dump_file(fp
, g
->gr_gid
, type
, mount
->fs_name
);
144 case XFS_PROJ_QUOTA
: {
145 struct fs_project
*p
;
147 while ((p
= getprent()) != NULL
)
148 dump_file(fp
, p
->pr_prid
, type
, mount
->fs_name
);
152 case XFS_USER_QUOTA
: {
155 while ((u
= getpwent()) != NULL
)
156 dump_file(fp
, u
->pw_uid
, type
, mount
->fs_name
);
170 uint lower
= 0, upper
= 0;
171 int c
, type
= XFS_USER_QUOTA
;
173 while ((c
= getopt(argc
, argv
, "f:gpuL:U:")) != EOF
) {
179 type
= XFS_GROUP_QUOTA
;
182 type
= XFS_PROJ_QUOTA
;
185 type
= XFS_USER_QUOTA
;
188 lower
= (uint
)atoi(optarg
);
191 upper
= (uint
)atoi(optarg
);
194 return command_usage(&dump_cmd
);
199 return command_usage(&dump_cmd
);
201 if ((fp
= fopen_write_secure(fname
)) == NULL
)
204 dump_limits_any_type(fp
, type
, fs_path
->fs_dir
, lower
, upper
);
220 char *typename
= type_to_string(type
);
224 if (flags
& NO_HEADER_FLAG
)
228 fprintf(fp
, _("%s quota on %s (%s)\n"),
229 typename
, mount
->fs_dir
, mount
->fs_name
);
232 for (i
= 0; i
< 10; i
++)
234 if (form
& XFS_BLOCK_QUOTA
)
235 fprintf(fp
, (flags
& HUMAN_FLAG
) ?
236 "%13c %s %13c" : "%20c %s %20c",
237 ' ', form_to_string(XFS_BLOCK_QUOTA
), ' ');
238 if (form
& XFS_INODE_QUOTA
)
239 fprintf(fp
, (flags
& HUMAN_FLAG
) ?
240 "%13c %s %13c" : "%20c %s %20c",
241 ' ', form_to_string(XFS_INODE_QUOTA
), ' ');
242 if (form
& XFS_RTBLOCK_QUOTA
)
243 fprintf(fp
, (flags
& HUMAN_FLAG
) ?
244 "%9c %s %9c" : "%15c %s %15c",
245 ' ', form_to_string(XFS_RTBLOCK_QUOTA
), ' ');
249 snprintf(scratch
, sizeof(scratch
), "%s ID", typename
);
250 fprintf(fp
, "%-10s ", scratch
);
251 if (form
& XFS_BLOCK_QUOTA
)
252 fprintf(fp
, (flags
& HUMAN_FLAG
) ?
253 _(" Used Soft Hard Warn/Grace ") :
254 _(" Used Soft Hard Warn/Grace "));
255 if (form
& XFS_INODE_QUOTA
)
256 fprintf(fp
, (flags
& HUMAN_FLAG
) ?
257 _(" Used Soft Hard Warn/Grace ") :
258 _(" Used Soft Hard Warn/ Grace "));
259 if (form
& XFS_RTBLOCK_QUOTA
)
260 fprintf(fp
, (flags
& HUMAN_FLAG
) ?
261 _(" Used Soft Hard Warn/Grace ") :
262 _(" Used Soft Hard Warn/Grace "));
266 for (i
= 0; i
< 10; i
++)
269 count
= (flags
& HUMAN_FLAG
) ? 33 : 50;
270 if (form
& XFS_BLOCK_QUOTA
) {
271 for (i
= 0; i
< count
; i
++)
275 if (form
& XFS_INODE_QUOTA
) {
276 for (i
= 0; i
< count
; i
++)
280 if (form
& XFS_RTBLOCK_QUOTA
) {
281 for (i
= 0; i
< count
; i
++)
299 char *dev
= mount
->fs_name
;
300 char c
[8], h
[8], s
[8];
304 if (xfsquotactl(XFS_GETQUOTA
, dev
, type
, id
, (void *)&d
) < 0) {
305 if (errno
!= ENOENT
&& errno
!= ENOSYS
&& errno
!= ESRCH
)
306 perror("XFS_GETQUOTA");
310 if (flags
& TERSE_FLAG
) {
312 if ((form
& XFS_BLOCK_QUOTA
) && d
.d_bcount
)
314 if ((form
& XFS_INODE_QUOTA
) && d
.d_icount
)
316 if ((form
& XFS_RTBLOCK_QUOTA
) && d
.d_rtbcount
)
322 if (!(flags
& NO_HEADER_FLAG
))
323 report_header(fp
, form
, type
, mount
, flags
);
325 fprintf(fp
, "%-10s", name
);
326 if (form
& XFS_BLOCK_QUOTA
) {
327 qflags
= (flags
& HUMAN_FLAG
);
328 if (d
.d_blk_hardlimit
&& d
.d_bcount
> d
.d_blk_hardlimit
)
329 qflags
|= LIMIT_FLAG
;
330 if (d
.d_blk_softlimit
&& d
.d_bcount
> d
.d_blk_softlimit
)
331 qflags
|= QUOTA_FLAG
;
332 if (flags
& HUMAN_FLAG
)
333 fprintf(fp
, " %6s %6s %6s %02d %8s",
334 bbs_to_string(d
.d_bcount
, c
, sizeof(c
)),
335 bbs_to_string(d
.d_blk_softlimit
, s
, sizeof(s
)),
336 bbs_to_string(d
.d_blk_hardlimit
, h
, sizeof(h
)),
338 time_to_string(d
.d_btimer
, qflags
));
340 fprintf(fp
, " %10llu %10llu %10llu %02d %9s",
341 (unsigned long long)d
.d_bcount
>> 1,
342 (unsigned long long)d
.d_blk_softlimit
>> 1,
343 (unsigned long long)d
.d_blk_hardlimit
>> 1,
345 time_to_string(d
.d_btimer
, qflags
));
347 if (form
& XFS_INODE_QUOTA
) {
348 qflags
= (flags
& HUMAN_FLAG
);
349 if (d
.d_ino_hardlimit
&& d
.d_icount
> d
.d_ino_hardlimit
)
350 qflags
|= LIMIT_FLAG
;
351 if (d
.d_ino_softlimit
&& d
.d_icount
> d
.d_ino_softlimit
)
352 qflags
|= QUOTA_FLAG
;
353 if (flags
& HUMAN_FLAG
)
354 fprintf(fp
, " %6s %6s %6s %02d %8s",
355 num_to_string(d
.d_icount
, c
, sizeof(c
)),
356 num_to_string(d
.d_ino_softlimit
, s
, sizeof(s
)),
357 num_to_string(d
.d_ino_hardlimit
, h
, sizeof(h
)),
359 time_to_string(d
.d_itimer
, qflags
));
361 fprintf(fp
, " %10llu %10llu %10llu %02d %9s",
362 (unsigned long long)d
.d_icount
,
363 (unsigned long long)d
.d_ino_softlimit
,
364 (unsigned long long)d
.d_ino_hardlimit
,
366 time_to_string(d
.d_itimer
, qflags
));
368 if (form
& XFS_RTBLOCK_QUOTA
) {
369 qflags
= (flags
& HUMAN_FLAG
);
370 if (d
.d_rtb_hardlimit
&& d
.d_rtbcount
> d
.d_rtb_hardlimit
)
371 qflags
|= LIMIT_FLAG
;
372 if (d
.d_rtb_softlimit
&& d
.d_rtbcount
> d
.d_rtb_softlimit
)
373 qflags
|= QUOTA_FLAG
;
374 if (flags
& HUMAN_FLAG
)
375 fprintf(fp
, " %6s %6s %6s %02d %8s",
376 bbs_to_string(d
.d_rtbcount
, c
, sizeof(c
)),
377 bbs_to_string(d
.d_rtb_softlimit
, s
, sizeof(s
)),
378 bbs_to_string(d
.d_rtb_hardlimit
, h
, sizeof(h
)),
380 time_to_string(d
.d_rtbtimer
, qflags
));
382 fprintf(fp
, " %10llu %10llu %10llu %02d %9s",
383 (unsigned long long)d
.d_rtbcount
>> 1,
384 (unsigned long long)d
.d_rtb_softlimit
>> 1,
385 (unsigned long long)d
.d_rtb_hardlimit
>> 1,
387 time_to_string(d
.d_rtbtimer
, qflags
));
406 if (upper
) { /* identifier range specified */
407 for (id
= lower
; id
<= upper
; id
++) {
408 snprintf(n
, sizeof(n
)-1, "#%u", id
);
409 if (report_mount(fp
, id
, n
,
410 form
, XFS_USER_QUOTA
, mount
, flags
))
411 flags
|= NO_HEADER_FLAG
;
415 while ((u
= getpwent()) != NULL
) {
416 if (flags
& NO_LOOKUP_FLAG
)
417 snprintf(n
, sizeof(n
)-1, "#%u", u
->pw_uid
);
419 strncpy(n
, u
->pw_name
, sizeof(n
)-1);
420 if (report_mount(fp
, u
->pw_uid
, n
,
421 form
, XFS_USER_QUOTA
, mount
, flags
))
422 flags
|= NO_HEADER_FLAG
;
427 if (flags
& NO_HEADER_FLAG
)
444 if (upper
) { /* identifier range specified */
445 for (id
= lower
; id
<= upper
; id
++) {
446 snprintf(n
, sizeof(n
)-1, "#%u", id
);
447 if (report_mount(fp
, id
, n
,
448 form
, XFS_GROUP_QUOTA
, mount
, flags
))
449 flags
|= NO_HEADER_FLAG
;
453 while ((g
= getgrent()) != NULL
) {
454 if (flags
& NO_LOOKUP_FLAG
)
455 snprintf(n
, sizeof(n
)-1, "#%u", g
->gr_gid
);
457 strncpy(n
, g
->gr_name
, sizeof(n
)-1);
458 if (report_mount(fp
, g
->gr_gid
, n
,
459 form
, XFS_GROUP_QUOTA
, mount
, flags
))
460 flags
|= NO_HEADER_FLAG
;
463 if (flags
& NO_HEADER_FLAG
)
469 report_project_mount(
481 if (upper
) { /* identifier range specified */
482 for (id
= lower
; id
<= upper
; id
++) {
483 snprintf(n
, sizeof(n
)-1, "#%u", id
);
484 if (report_mount(fp
, id
, n
,
485 form
, XFS_PROJ_QUOTA
, mount
, flags
))
486 flags
|= NO_HEADER_FLAG
;
490 while ((p
= getprent()) != NULL
) {
491 if (flags
& NO_LOOKUP_FLAG
)
492 snprintf(n
, sizeof(n
)-1, "#%u",
493 (unsigned int)p
->pr_prid
);
495 strncpy(n
, p
->pr_name
, sizeof(n
)-1);
496 if (report_mount(fp
, p
->pr_prid
, n
,
497 form
, XFS_PROJ_QUOTA
, mount
, flags
))
498 flags
|= NO_HEADER_FLAG
;
503 if (flags
& NO_HEADER_FLAG
)
520 if (type
& XFS_USER_QUOTA
) {
521 fs_cursor_initialise(dir
, FS_MOUNT_POINT
, &cursor
);
522 while ((mount
= fs_cursor_next_entry(&cursor
))) {
523 if (xfsquotactl(XFS_QSYNC
, mount
->fs_name
,
524 XFS_USER_QUOTA
, 0, NULL
) < 0
525 && errno
!= ENOENT
&& errno
!= ENOSYS
)
526 perror("XFS_QSYNC user quota");
527 report_user_mount(fp
, form
, mount
,
528 lower
, upper
, flags
);
531 if (type
& XFS_GROUP_QUOTA
) {
532 fs_cursor_initialise(dir
, FS_MOUNT_POINT
, &cursor
);
533 while ((mount
= fs_cursor_next_entry(&cursor
))) {
534 if (xfsquotactl(XFS_QSYNC
, mount
->fs_name
,
535 XFS_GROUP_QUOTA
, 0, NULL
) < 0
536 && errno
!= ENOENT
&& errno
!= ENOSYS
)
537 perror("XFS_QSYNC group quota");
538 report_group_mount(fp
, form
, mount
,
539 lower
, upper
, flags
);
542 if (type
& XFS_PROJ_QUOTA
) {
543 fs_cursor_initialise(dir
, FS_MOUNT_POINT
, &cursor
);
544 while ((mount
= fs_cursor_next_entry(&cursor
))) {
545 if (xfsquotactl(XFS_QSYNC
, mount
->fs_name
,
546 XFS_PROJ_QUOTA
, 0, NULL
) < 0
547 && errno
!= ENOENT
&& errno
!= ENOSYS
)
548 perror("XFS_QSYNC proj quota");
549 report_project_mount(fp
, form
, mount
,
550 lower
, upper
, flags
);
562 uint lower
= 0, upper
= 0;
563 int c
, flags
= 0, type
= 0, form
= 0;
565 while ((c
= getopt(argc
, argv
, "abf:ghiL:NnprtuU:")) != EOF
) {
571 form
|= XFS_BLOCK_QUOTA
;
574 form
|= XFS_INODE_QUOTA
;
577 form
|= XFS_RTBLOCK_QUOTA
;
580 type
|= XFS_GROUP_QUOTA
;
583 type
|= XFS_PROJ_QUOTA
;
586 type
|= XFS_USER_QUOTA
;
589 flags
|= ALL_MOUNTS_FLAG
;
595 flags
|= NO_LOOKUP_FLAG
;
598 flags
|= NO_HEADER_FLAG
;
604 lower
= (uint
)atoi(optarg
);
607 upper
= (uint
)atoi(optarg
);
610 return command_usage(&report_cmd
);
615 form
= XFS_BLOCK_QUOTA
;
618 type
= XFS_USER_QUOTA
| XFS_GROUP_QUOTA
| XFS_PROJ_QUOTA
;
620 if ((fp
= fopen_write_secure(fname
)) == NULL
)
623 if (argc
== optind
) {
624 if (flags
& ALL_MOUNTS_FLAG
)
625 report_any_type(fp
, form
, type
, NULL
,
626 lower
, upper
, flags
);
627 else if (fs_path
&& (fs_path
->fs_flags
& FS_MOUNT_POINT
))
628 report_any_type(fp
, form
, type
, fs_path
->fs_dir
,
629 lower
, upper
, flags
);
630 } else while (argc
> optind
) {
631 report_any_type(fp
, form
, type
, argv
[optind
++],
632 lower
, upper
, flags
);
643 dump_cmd
.name
= "dump";
644 dump_cmd
.cfunc
= dump_f
;
646 dump_cmd
.argmax
= -1;
647 dump_cmd
.args
= _("[-gpu] [-f file]");
648 dump_cmd
.oneline
= _("dump quota information for backup utilities");
649 dump_cmd
.help
= dump_help
;
651 report_cmd
.name
= "report";
652 report_cmd
.altname
= "repquota";
653 report_cmd
.cfunc
= report_f
;
654 report_cmd
.argmin
= 0;
655 report_cmd
.argmax
= -1;
656 report_cmd
.flags
= CMD_FLAG_GLOBAL
;
657 report_cmd
.args
= _("[-bir] [-gpu] [-ahnt] [-f file]");
658 report_cmd
.oneline
= _("report filesystem quota information");
659 report_cmd
.help
= report_help
;
662 add_command(&dump_cmd
);
663 add_command(&report_cmd
);