user-runtime-dir: correct quota size calculation (#36884)
This commit is contained in:
@@ -268,6 +268,10 @@ executables += [
|
||||
'dependencies' : lib_openssl_or_gcrypt,
|
||||
'conditions' : ['HAVE_OPENSSL_OR_GCRYPT'],
|
||||
},
|
||||
test_template + {
|
||||
'sources' : files('test-display-quota.c'),
|
||||
'type' : 'manual',
|
||||
},
|
||||
test_template + {
|
||||
'sources' : files('test-dlopen-so.c'),
|
||||
'dependencies' : [
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "bitfield.h"
|
||||
#include "fd-util.h"
|
||||
#include "log.h"
|
||||
#include "main-func.h"
|
||||
#include "missing_syscall.h"
|
||||
#include "quota-util.h"
|
||||
#include "userdb.h"
|
||||
|
||||
static int show_quota(uid_t uid, const char *path) {
|
||||
int r;
|
||||
|
||||
_cleanup_close_ int fd = open(path, O_DIRECTORY|O_CLOEXEC);
|
||||
if (fd < 0)
|
||||
return log_error_errno(errno, "Failed to open '%s': %m", path);
|
||||
|
||||
struct dqblk req;
|
||||
r = quotactl_fd_with_fallback(fd, QCMD_FIXED(Q_GETQUOTA, USRQUOTA), uid, &req);
|
||||
if (r == -ESRCH) {
|
||||
log_info_errno(r, "No quota set on %s for UID "UID_FMT": %m", path, uid);
|
||||
return 0;
|
||||
}
|
||||
if (ERRNO_IS_NEG_NOT_SUPPORTED(r))
|
||||
return log_warning_errno(r, "No UID quota support on %s: %m", path);
|
||||
if (ERRNO_IS_NEG_PRIVILEGE(r))
|
||||
return log_error_errno(r, "Lacking privileges to query UID quota on %s: %m", path);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to query disk quota on %s for UID "UID_FMT": %m", path, uid);
|
||||
|
||||
printf("** Quota on %s for UID "UID_FMT" **\n"
|
||||
"block hardlimit: %"PRIu64"\n"
|
||||
"block softlimit: %"PRIu64"\n"
|
||||
"blocks current: %"PRIu64"\n"
|
||||
"inodes hardlimit: %"PRIu64"\n"
|
||||
"inodes softlimit: %"PRIu64"\n"
|
||||
"inodes current: %"PRIu64"\n"
|
||||
"excess block time: %"PRIu64"\n"
|
||||
"excess inode time: %"PRIu64"\n"
|
||||
"validity mask: 0x%"PRIx32,
|
||||
path, uid,
|
||||
req.dqb_bhardlimit,
|
||||
req.dqb_bsoftlimit,
|
||||
req.dqb_curspace,
|
||||
req.dqb_ihardlimit,
|
||||
req.dqb_isoftlimit,
|
||||
req.dqb_curinodes,
|
||||
req.dqb_btime,
|
||||
req.dqb_itime,
|
||||
req.dqb_valid);
|
||||
|
||||
const char* fields[] = {"BLIMITS", "SPACE", "INODES", "BTIME", "ITIME"};
|
||||
bool first = true;
|
||||
for (size_t i = 0; i < ELEMENTSOF(fields); i++)
|
||||
if (BIT_SET(req.dqb_valid, i)) {
|
||||
printf("%c%s", first ? ' ' : '|', fields[i]);
|
||||
first = false;
|
||||
}
|
||||
printf("%s\n", first ? "(none)" : "");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int run(int argc, char **argv) {
|
||||
int r;
|
||||
|
||||
if (argc < 2)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"This program requires at least one argument\n"
|
||||
"syntax: test-display-quota USER PATH…");
|
||||
|
||||
const char *user = argv[1];
|
||||
_cleanup_(user_record_unrefp) UserRecord *ur = NULL;
|
||||
r = userdb_by_name(user, /* match= */ NULL, USERDB_PARSE_NUMERIC|USERDB_SUPPRESS_SHADOW, &ur);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to resolve user '%s': %m", user);
|
||||
|
||||
if (!uid_is_valid(ur->uid))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(ENOMSG), "User '%s' lacks UID.", ur->user_name);
|
||||
|
||||
r = 0;
|
||||
STRV_FOREACH(path, strv_skip(argv, 2))
|
||||
RET_GATHER(r, show_quota(ur->uid, *path));
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
DEFINE_MAIN_FUNCTION(run);
|
||||
Reference in New Issue
Block a user