Skip to content

Commit

Permalink
quota: Add error_r to quota_get_resource()
Browse files Browse the repository at this point in the history
  • Loading branch information
mrannanj authored and Timo Sirainen committed Oct 19, 2017
1 parent efd2917 commit cf41318
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 26 deletions.
9 changes: 6 additions & 3 deletions src/plugins/imap-quota/imap-quota-plugin.c
Expand Up @@ -35,7 +35,7 @@ static int
quota_reply_write(string_t *str, struct mail_user *user,
struct mail_user *owner, struct quota_root *root)
{
const char *name, *const *list;
const char *name, *const *list, *error;
unsigned int i;
uint64_t value, limit;
size_t prefix_len, orig_len = str_len(str);
Expand All @@ -49,9 +49,12 @@ quota_reply_write(string_t *str, struct mail_user *user,
prefix_len = str_len(str);
list = quota_root_get_resources(root);
for (i = 0; *list != NULL; list++) {
ret = quota_get_resource(root, "", *list, &value, &limit);
if (ret == QUOTA_GET_RESULT_INTERNAL_ERROR)
ret = quota_get_resource(root, "", *list, &value, &limit, &error);
if (ret == QUOTA_GET_RESULT_INTERNAL_ERROR) {
i_error("Failed to get quota resource %s: %s",
*list, error);
break;
}
if (ret == QUOTA_GET_RESULT_LIMITED) {
if (i > 0)
str_append_c(str, ' ');
Expand Down
12 changes: 8 additions & 4 deletions src/plugins/quota-clone/quota-clone-plugin.c
Expand Up @@ -62,15 +62,19 @@ static void quota_clone_flush_real(struct mailbox *box)

/* get new values first */
ret_bytes = quota_get_resource(root, "", QUOTA_NAME_STORAGE_BYTES,
&bytes_value, &limit);
&bytes_value, &limit, &error);
if (ret_bytes == QUOTA_GET_RESULT_INTERNAL_ERROR) {
i_error("quota_clone_plugin: Failed to lookup current quota bytes");
i_error("quota_clone_plugin: "
"Failed to get quota resource "QUOTA_NAME_STORAGE_BYTES": %s",
error);
return;
}
ret_count = quota_get_resource(root, "", QUOTA_NAME_MESSAGES,
&count_value, &limit);
&count_value, &limit, &error);
if (ret_count == QUOTA_GET_RESULT_INTERNAL_ERROR) {
i_error("quota_clone_plugin: Failed to lookup current quota count");
i_error("quota_clone_plugin: "
"Failed to get quota resource "QUOTA_NAME_MESSAGES": %s",
error);
return;
}
if (ret_bytes == QUOTA_GET_RESULT_UNKNOWN_RESOURCE &&
Expand Down
5 changes: 4 additions & 1 deletion src/plugins/quota/doveadm-quota.c
Expand Up @@ -15,12 +15,13 @@ void doveadm_quota_plugin_deinit(void);
static void cmd_quota_get_root(struct quota_root *root)
{
const char *const *res;
const char *error;
uint64_t value, limit;
enum quota_get_result ret;

res = quota_root_get_resources(root);
for (; *res != NULL; res++) {
ret = quota_get_resource(root, "", *res, &value, &limit);
ret = quota_get_resource(root, "", *res, &value, &limit, &error);
doveadm_print(root->set->name);
doveadm_print(*res);
if (ret == QUOTA_GET_RESULT_LIMITED) {
Expand All @@ -35,6 +36,8 @@ static void cmd_quota_get_root(struct quota_root *root)
doveadm_print("-");
doveadm_print("0");
} else {
i_error("Failed to get quota resource %s: %s",
*res, error);
doveadm_print("error");
doveadm_print("error");
doveadm_print("error");
Expand Down
54 changes: 37 additions & 17 deletions src/plugins/quota/quota.c
Expand Up @@ -753,7 +753,8 @@ bool quota_root_is_hidden(struct quota_root *root)

enum quota_get_result
quota_get_resource(struct quota_root *root, const char *mailbox_name,
const char *name, uint64_t *value_r, uint64_t *limit_r)
const char *name, uint64_t *value_r, uint64_t *limit_r,
const char **error_r)
{
uint64_t bytes_limit, count_limit;
bool ignored, kilobytes = FALSE;
Expand All @@ -769,16 +770,24 @@ quota_get_resource(struct quota_root *root, const char *mailbox_name,
/* Get the value first. This call may also update quota limits if
they're defined externally. */
ret = root->backend.v.get_resource(root, name, value_r);
if (ret < 0)
if (ret < 0) {
*error_r = t_strdup_printf(
"Could not get %s from quota backend for mailbox %s",
name, mailbox_name);
return QUOTA_GET_RESULT_INTERNAL_ERROR;
if (ret == 0)
} else if (ret == 0) {
*error_r = t_strdup_printf(
"Requested resource %s for mailbox %s is unkown",
name, mailbox_name);
return QUOTA_GET_RESULT_UNKNOWN_RESOURCE;
}

const char *error;
if (quota_root_get_rule_limits(root, mailbox_name,
&bytes_limit, &count_limit,
&ignored, &error) < 0) {
i_error("Failed to get quota root rule limits: %s", error);
*error_r = t_strdup_printf(
"Failed to get quota root rule limits: %s", error);
return QUOTA_GET_RESULT_INTERNAL_ERROR;
}

Expand Down Expand Up @@ -932,7 +941,7 @@ int quota_transaction_set_limits(struct quota_transaction_context *ctx,
if (bytes_limit > 0) {
ret = quota_get_resource(roots[i], mailbox_name,
QUOTA_NAME_STORAGE_BYTES,
&current, &limit);
&current, &limit, &error);
if (ret == QUOTA_GET_RESULT_LIMITED) {
if (limit <= current) {
/* over quota */
Expand All @@ -952,15 +961,18 @@ int quota_transaction_set_limits(struct quota_transaction_context *ctx,
}
} else if (ret == QUOTA_GET_RESULT_INTERNAL_ERROR) {
ctx->failed = TRUE;
*error_r = "Failed to get quota resource";
*error_r = t_strdup_printf(
"Failed to get quota resource "
QUOTA_NAME_STORAGE_BYTES": %s",
error);
return -1;
}
}

if (count_limit > 0) {
ret = quota_get_resource(roots[i], mailbox_name,
QUOTA_NAME_MESSAGES,
&current, &limit);
&current, &limit, &error);
if (ret == QUOTA_GET_RESULT_LIMITED) {
if (limit <= current) {
/* over quota */
Expand All @@ -975,7 +987,10 @@ int quota_transaction_set_limits(struct quota_transaction_context *ctx,
}
} else if (ret == QUOTA_GET_RESULT_INTERNAL_ERROR) {
ctx->failed = TRUE;
*error_r = "Failed to get quota resource";
*error_r = t_strdup_printf(
"Failed to get quota resource "
QUOTA_NAME_MESSAGES" : %s",
error);
return -1;
}
}
Expand Down Expand Up @@ -1045,18 +1060,24 @@ static void quota_warnings_execute(struct quota_transaction_context *ctx,
unsigned int i, count;
uint64_t bytes_current, bytes_before, bytes_limit;
uint64_t count_current, count_before, count_limit;
const char *reason;
const char *reason, *error;

warnings = array_get_modifiable(&root->set->warning_rules, &count);
if (count == 0)
return;

if (quota_get_resource(root, "", QUOTA_NAME_STORAGE_BYTES,
&bytes_current, &bytes_limit) == QUOTA_GET_RESULT_INTERNAL_ERROR)
&bytes_current, &bytes_limit, &error) == QUOTA_GET_RESULT_INTERNAL_ERROR) {
i_error("Failed to get quota resource "QUOTA_NAME_STORAGE_BYTES
": %s", error);
return;
}
if (quota_get_resource(root, "", QUOTA_NAME_MESSAGES,
&count_current, &count_limit) == QUOTA_GET_RESULT_INTERNAL_ERROR)
&count_current, &count_limit, &error) == QUOTA_GET_RESULT_INTERNAL_ERROR) {
i_error("Failed to get quota resource "QUOTA_NAME_MESSAGES
": %s", error);
return;
}

if (ctx->bytes_used > 0 && bytes_current < (uint64_t)ctx->bytes_used)
bytes_before = 0;
Expand Down Expand Up @@ -1174,7 +1195,7 @@ static bool quota_over_flag_init_root(struct quota_root *root,

static void quota_over_flag_check_root(struct quota_root *root)
{
const char *quota_over_script, *quota_over_flag;
const char *quota_over_script, *quota_over_flag, *error;
const char *const *resources;
unsigned int i;
uint64_t value, limit;
Expand Down Expand Up @@ -1210,13 +1231,12 @@ static void quota_over_flag_check_root(struct quota_root *root)

resources = quota_root_get_resources(root);
for (i = 0; resources[i] != NULL; i++) {
ret = quota_get_resource(root, "", resources[i], &value, &limit);
ret = quota_get_resource(root, "", resources[i], &value,
&limit, &error);
if (ret == QUOTA_GET_RESULT_INTERNAL_ERROR) {
/* can't reliably verify this */
if (root->quota->set->debug) {
i_debug("quota: Quota %s lookup failed - can't verify quota_over_flag",
resources[i]);
}
i_error("quota: Quota %s lookup failed - can't verify quota_over_flag: %s",
resources[i], error);
return;
}
if (root->quota->set->debug) {
Expand Down
3 changes: 2 additions & 1 deletion src/plugins/quota/quota.h
Expand Up @@ -102,7 +102,8 @@ bool quota_root_is_hidden(struct quota_root *root);
exist or isn't enabled, -1 if error. */
enum quota_get_result
quota_get_resource(struct quota_root *root, const char *mailbox_name,
const char *name, uint64_t *value_r, uint64_t *limit_r);
const char *name, uint64_t *value_r, uint64_t *limit_r,
const char **error_r);
/* Returns 0 if OK, -1 if error (eg. permission denied, invalid name). */
int quota_set_resource(struct quota_root *root, const char *name,
uint64_t value, const char **error_r);
Expand Down

0 comments on commit cf41318

Please sign in to comment.