]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
dsync: Don't log unnecessary errors about not being able to delete \Noselect mailbox...
authorTimo Sirainen <tss@iki.fi>
Tue, 3 Jan 2012 12:33:20 +0000 (14:33 +0200)
committerTimo Sirainen <tss@iki.fi>
Tue, 3 Jan 2012 12:33:20 +0000 (14:33 +0200)
src/doveadm/dsync/dsync-worker-local.c

index b26689547d87ae2ba89c2b1ffbfc643f6b1474d6..00754f79b45dd891230ba17ae9de474cd6b2d2ee 100644 (file)
@@ -94,7 +94,7 @@ struct local_dsync_worker {
        struct hash_table *dir_changes_hash;
 
        char alt_char;
-       ARRAY_DEFINE(subs_namespaces, struct mail_namespace *);
+       ARRAY_DEFINE(wanted_namespaces, struct mail_namespace *);
 
        mailbox_guid_t selected_box_guid;
        struct mailbox *selected_box;
@@ -151,56 +151,23 @@ static unsigned int mailbox_guid_hash(const void *p)
        return h;
 }
 
-static struct mail_namespace *
-namespace_find_set(struct mail_user *user,
-                  const struct mail_namespace_settings *set)
+static bool local_worker_want_namespace(struct mail_namespace *ns)
 {
-       struct mail_namespace *ns;
-
-       for (ns = user->namespaces; ns != NULL; ns = ns->next) {
-               /* compare settings pointers so that it'll work
-                  for shared namespaces */
-               if (ns->set == set)
-                       return ns;
-       }
-       return NULL;
+       return strcmp(ns->unexpanded_set->location,
+                     SETTING_STRVAR_UNEXPANDED) == 0;
 }
 
-static void dsync_drop_extra_namespaces(struct local_dsync_worker *worker)
+static void dsync_check_namespaces(struct local_dsync_worker *worker)
 {
-       struct mail_user *user = worker->user;
-       struct mail_namespace_settings *const *ns_unset, *const *ns_set;
        struct mail_namespace *ns;
-       unsigned int i, count, count2;
-
-       if (!array_is_created(&user->unexpanded_set->namespaces))
-               return;
-
-       /* drop all namespaces that have a location defined internally */
-       ns_unset = array_get(&user->unexpanded_set->namespaces, &count);
-       ns_set = array_get(&user->set->namespaces, &count2);
-       i_assert(count == count2);
-       for (i = 0; i < count; i++) {
-               if (strcmp(ns_unset[i]->location,
-                          SETTING_STRVAR_UNEXPANDED) == 0)
-                       continue;
 
-               ns = namespace_find_set(user, ns_set[i]);
-               i_assert(ns != NULL);
-               if ((ns->flags & NAMESPACE_FLAG_SUBSCRIPTIONS) == 0) {
-                       /* remember the subscriptions=no namespaces so we can
-                          handle their subscriptions in parent namespaces
-                          properly */
-                       mail_namespace_ref(ns);
-                       array_append(&worker->subs_namespaces, &ns, 1);
-               }
-               mail_namespace_destroy(ns);
-       }
-       if (user->namespaces == NULL) {
-               i_fatal("All your namespaces have a location setting. "
-                       "It should be empty (default mail_location) in the "
-                       "namespace to be converted.");
+       for (ns = worker->user->namespaces; ns != NULL; ns = ns->next) {
+               if (local_worker_want_namespace(ns))
+                       return;
        }
+       i_fatal("All your namespaces have a location setting. "
+               "It should be empty (default mail_location) in the "
+               "namespace to be converted.");
 }
 
 struct dsync_worker *
@@ -220,8 +187,8 @@ dsync_worker_init_local(struct mail_user *user, char alt_char)
                                  mailbox_guid_hash, mailbox_guid_cmp);
        i_array_init(&worker->saved_uids, 128);
        i_array_init(&worker->msg_get_queue, 32);
-       p_array_init(&worker->subs_namespaces, pool, 8);
-       dsync_drop_extra_namespaces(worker);
+       p_array_init(&worker->wanted_namespaces, pool, 8);
+       dsync_check_namespaces(worker);
 
        mail_user_ref(worker->user);
        return &worker->worker;
@@ -231,13 +198,9 @@ static void local_worker_deinit(struct dsync_worker *_worker)
 {
        struct local_dsync_worker *worker =
                (struct local_dsync_worker *)_worker;
-       struct mail_namespace **nsp;
 
        i_assert(worker->save_input == NULL);
 
-       array_foreach_modifiable(&worker->subs_namespaces, nsp)
-               mail_namespace_unref(nsp);
-
        local_worker_msg_box_close(worker);
        local_worker_mailbox_close(worker);
        mail_user_unref(&worker->user);
@@ -417,7 +380,7 @@ static int dsync_worker_get_mailbox_log(struct local_dsync_worker *worker)
                hash_table_create(default_pool, worker->pool, 0,
                                  dir_change_hash, dir_change_cmp);
        for (ns = worker->user->namespaces; ns != NULL; ns = ns->next) {
-               if (ns->alias_for != NULL)
+               if (ns->alias_for != NULL || !local_worker_want_namespace(ns))
                        continue;
 
                if (dsync_worker_get_list_mailbox_log(worker, ns->list) < 0)
@@ -537,7 +500,10 @@ local_worker_mailbox_iter_next(struct dsync_worker_mailbox_iter *_iter,
 
        memset(dsync_box_r, 0, sizeof(*dsync_box_r));
 
-       info = mailbox_list_iter_next(iter->list_iter);
+       while ((info = mailbox_list_iter_next(iter->list_iter)) != NULL) {
+               if (local_worker_want_namespace(info->ns))
+                       break;
+       }
        if (info == NULL)
                return iter_next_deleted(iter, worker, dsync_box_r);
 
@@ -646,16 +612,18 @@ local_worker_subs_iter_init(struct dsync_worker *_worker)
        struct local_dsync_worker *worker =
                (struct local_dsync_worker *)_worker;
        struct local_dsync_worker_subs_iter *iter;
-       enum mailbox_list_iter_flags list_flags =
+       const enum mailbox_list_iter_flags list_flags =
                MAILBOX_LIST_ITER_SKIP_ALIASES |
                MAILBOX_LIST_ITER_SELECT_SUBSCRIBED;
+       const enum namespace_type namespace_mask =
+               NAMESPACE_PRIVATE | NAMESPACE_SHARED | NAMESPACE_PUBLIC;
        static const char *patterns[] = { "*", NULL };
 
        iter = i_new(struct local_dsync_worker_subs_iter, 1);
        iter->iter.worker = _worker;
        iter->list_iter =
                mailbox_list_iter_init_namespaces(worker->user->namespaces,
-                                                 patterns, NAMESPACE_PRIVATE,
+                                                 patterns, namespace_mask,
                                                  list_flags);
        (void)dsync_worker_get_mailbox_log(worker);
        return &iter->iter;
@@ -675,11 +643,18 @@ local_worker_subs_iter_next(struct dsync_worker_subs_iter *_iter,
 
        memset(rec_r, 0, sizeof(*rec_r));
 
-       info = mailbox_list_iter_next(iter->list_iter);
+       while ((info = mailbox_list_iter_next(iter->list_iter)) != NULL) {
+               if (local_worker_want_namespace(info->ns) ||
+                   (info->ns->flags & NAMESPACE_FLAG_SUBSCRIPTIONS) == 0)
+                       break;
+       }
        if (info == NULL)
                return -1;
 
        storage_name = mailbox_list_get_storage_name(info->ns->list, info->name);
+       if ((info->ns->flags & NAMESPACE_FLAG_SUBSCRIPTIONS) == 0)
+               storage_name = t_strconcat(info->ns->prefix, storage_name, NULL);
+
        dsync_str_sha_to_guid(storage_name, &change_lookup.name_sha1);
        change_lookup.list = info->ns->list;
 
@@ -691,7 +666,10 @@ local_worker_subs_iter_next(struct dsync_worker_subs_iter *_iter,
                change->unsubscribed = FALSE;
                rec_r->last_change = change->last_subs_change;
        }
-       rec_r->ns_prefix = info->ns->prefix;
+       if ((info->ns->flags & NAMESPACE_FLAG_SUBSCRIPTIONS) == 0)
+               rec_r->ns_prefix = "";
+       else
+               rec_r->ns_prefix = info->ns->prefix;
        rec_r->vname = info->name;
        rec_r->storage_name = storage_name;
        return 1;
@@ -1288,15 +1266,24 @@ local_worker_delete_dir(struct dsync_worker *_worker,
                (struct local_dsync_worker *)_worker;
        struct mail_namespace *ns;
        const char *storage_name;
+       enum mail_error error;
 
        ns = mail_namespace_find(worker->user->namespaces, dsync_box->name);
        storage_name = mailbox_list_get_storage_name(ns->list, dsync_box->name);
 
        mailbox_list_set_changelog_timestamp(ns->list, dsync_box->last_change);
        if (mailbox_list_delete_dir(ns->list, storage_name) < 0) {
-               i_error("Can't delete mailbox directory %s: %s",
-                       dsync_box->name,
-                       mailbox_list_get_last_error(ns->list, NULL));
+               (void)mailbox_list_get_last_error(ns->list, &error);
+               if (error == MAIL_ERROR_EXISTS) {
+                       /* we're probably doing Maildir++ -> FS layout sync,
+                          where a nonexistent Maildir++ mailbox had to be
+                          created as \Noselect FS directory.
+                          just ignore this. */
+               } else {
+                       i_error("Can't delete mailbox directory %s: %s",
+                               dsync_box->name,
+                               mailbox_list_get_last_error(ns->list, NULL));
+               }
        }
        mailbox_list_set_changelog_timestamp(ns->list, (time_t)-1);
 }