root/source4/wrepl_server/wrepl_out_pull.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. wreplsrv_out_pull_reschedule
  2. wreplsrv_pull_handler_creq
  3. wreplsrv_out_partner_pull
  4. wreplsrv_out_pull_run

   1 /* 
   2    Unix SMB/CIFS implementation.
   3    
   4    WINS Replication server
   5    
   6    Copyright (C) Stefan Metzmacher      2005
   7    
   8    This program is free software; you can redistribute it and/or modify
   9    it under the terms of the GNU General Public License as published by
  10    the Free Software Foundation; either version 3 of the License, or
  11    (at your option) any later version.
  12    
  13    This program is distributed in the hope that it will be useful,
  14    but WITHOUT ANY WARRANTY; without even the implied warranty of
  15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16    GNU General Public License for more details.
  17    
  18    You should have received a copy of the GNU General Public License
  19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  20 */
  21 
  22 #include "includes.h"
  23 #include "librpc/gen_ndr/winsrepl.h"
  24 #include "wrepl_server/wrepl_server.h"
  25 #include "libcli/composite/composite.h"
  26 
  27 static void wreplsrv_out_pull_reschedule(struct wreplsrv_partner *partner, uint32_t interval)
     /* [<][>][^][v][top][bottom][index][help] */
  28 {
  29         NTSTATUS status;
  30 
  31         partner->pull.next_run = timeval_current_ofs(interval, 0);
  32         status = wreplsrv_periodic_schedule(partner->service, interval);
  33         if (!NT_STATUS_IS_OK(status)) {
  34                 DEBUG(0,("wreplsrv_periodic_schedule() failed\n"));
  35         }
  36 }
  37 
  38 static void wreplsrv_pull_handler_creq(struct composite_context *creq)
     /* [<][>][^][v][top][bottom][index][help] */
  39 {
  40         struct wreplsrv_partner *partner = talloc_get_type(creq->async.private_data, struct wreplsrv_partner);
  41         struct wreplsrv_pull_cycle_io *old_cycle_io;
  42         struct wrepl_table inform_in;
  43 
  44         partner->pull.last_status = wreplsrv_pull_cycle_recv(partner->pull.creq);
  45         partner->pull.creq = NULL;
  46 
  47         old_cycle_io = partner->pull.cycle_io;
  48         partner->pull.cycle_io = NULL;
  49 
  50         if (NT_STATUS_IS_OK(partner->pull.last_status)) {
  51                 partner->pull.error_count = 0;
  52                 DEBUG(1,("wreplsrv_pull_cycle(%s): %s\n",
  53                          partner->address, nt_errstr(partner->pull.last_status)));
  54                 goto done;
  55         }
  56 
  57         partner->pull.error_count++;
  58 
  59         if (partner->pull.error_count > 1) {
  60                 uint32_t retry_interval;
  61 
  62                 retry_interval = partner->pull.error_count * partner->pull.retry_interval;
  63                 retry_interval = MIN(retry_interval, partner->pull.interval);
  64 
  65                 DEBUG(0,("wreplsrv_pull_cycle(%s): %s: error_count: %u: reschedule(%u)\n",
  66                          partner->address, nt_errstr(partner->pull.last_status),
  67                          partner->pull.error_count, retry_interval));
  68 
  69                 wreplsrv_out_pull_reschedule(partner, retry_interval);
  70                 goto done;
  71         }
  72 
  73         DEBUG(0,("wreplsrv_pull_cycle(%s): %s: error_count:%u retry\n",
  74                  partner->address, nt_errstr(partner->pull.last_status),
  75                  partner->pull.error_count));
  76         inform_in.partner_count = old_cycle_io->in.num_owners;
  77         inform_in.partners      = old_cycle_io->in.owners;
  78         wreplsrv_out_partner_pull(partner, &inform_in);
  79 done:
  80         talloc_free(old_cycle_io);
  81 }
  82 
  83 void wreplsrv_out_partner_pull(struct wreplsrv_partner *partner, struct wrepl_table *inform_in)
     /* [<][>][^][v][top][bottom][index][help] */
  84 {
  85         /* there's already a pull in progress, so we're done */
  86         if (partner->pull.creq) return;
  87 
  88         partner->pull.cycle_io = talloc(partner, struct wreplsrv_pull_cycle_io);
  89         if (!partner->pull.cycle_io) {
  90                 goto nomem;
  91         }
  92 
  93         partner->pull.cycle_io->in.partner      = partner;
  94         partner->pull.cycle_io->in.wreplconn    = NULL;
  95         if (inform_in) {
  96                 partner->pull.cycle_io->in.num_owners   = inform_in->partner_count;
  97                 partner->pull.cycle_io->in.owners       = inform_in->partners;
  98                 talloc_steal(partner->pull.cycle_io, inform_in->partners);
  99         } else {
 100                 partner->pull.cycle_io->in.num_owners   = 0;
 101                 partner->pull.cycle_io->in.owners       = NULL;
 102         }
 103         partner->pull.creq = wreplsrv_pull_cycle_send(partner->pull.cycle_io, partner->pull.cycle_io);
 104         if (!partner->pull.creq) {
 105                 DEBUG(1,("wreplsrv_pull_cycle_send(%s) failed\n",
 106                          partner->address));
 107                 goto nomem;
 108         }
 109 
 110         partner->pull.creq->async.fn            = wreplsrv_pull_handler_creq;
 111         partner->pull.creq->async.private_data  = partner;
 112 
 113         return;
 114 nomem:
 115         talloc_free(partner->pull.cycle_io);
 116         partner->pull.cycle_io = NULL;
 117         DEBUG(0,("wreplsrv_out_partner_pull(%s): no memory? (ignoring)\n",
 118                 partner->address));
 119         return;
 120 }
 121 
 122 NTSTATUS wreplsrv_out_pull_run(struct wreplsrv_service *service)
     /* [<][>][^][v][top][bottom][index][help] */
 123 {
 124         struct wreplsrv_partner *partner;
 125 
 126         for (partner = service->partners; partner; partner = partner->next) {
 127                 /* if it's not a pull partner, go to the next partner */
 128                 if (!(partner->type & WINSREPL_PARTNER_PULL)) continue;
 129 
 130                 /* if pulling is disabled for the partner, go to the next one */
 131                 if (partner->pull.interval == 0) continue;
 132 
 133                 /* if the next timer isn't reached, go to the next partner */
 134                 if (!timeval_expired(&partner->pull.next_run)) continue;
 135 
 136                 wreplsrv_out_pull_reschedule(partner, partner->pull.interval);
 137 
 138                 wreplsrv_out_partner_pull(partner, NULL);
 139         }
 140 
 141         return NT_STATUS_OK;
 142 }

/* [<][>][^][v][top][bottom][index][help] */