Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / osd / Session.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3
4 #include "PG.h"
5 #include "Session.h"
6
7 #include "common/debug.h"
8
9 #define dout_context cct
10 #define dout_subsys ceph_subsys_osd
11
12 void Session::clear_backoffs()
13 {
14   map<spg_t,map<hobject_t,set<BackoffRef>>> ls;
15   {
16     Mutex::Locker l(backoff_lock);
17     ls.swap(backoffs);
18     backoff_count = 0;
19   }
20   for (auto& i : ls) {
21     for (auto& p : i.second) {
22       for (auto& b : p.second) {
23         Mutex::Locker l(b->lock);
24         if (b->pg) {
25           assert(b->session == this);
26           assert(b->is_new() || b->is_acked());
27           b->pg->rm_backoff(b);
28           b->pg.reset();
29           b->session.reset();
30         } else if (b->session) {
31           assert(b->session == this);
32           assert(b->is_deleting());
33           b->session.reset();
34         }
35       }
36     }
37   }
38 }
39
40 void Session::ack_backoff(
41   CephContext *cct,
42   spg_t pgid,
43   uint64_t id,
44   const hobject_t& begin,
45   const hobject_t& end)
46 {
47   Mutex::Locker l(backoff_lock);
48   auto p = backoffs.find(pgid);
49   if (p == backoffs.end()) {
50     dout(20) << __func__ << " " << pgid << " " << id << " [" << begin << ","
51              << end << ") pg not found" << dendl;
52     return;
53   }
54   auto q = p->second.find(begin);
55   if (q == p->second.end()) {
56     dout(20) << __func__ << " " << pgid << " " << id << " [" << begin << ","
57              << end << ") begin not found" << dendl;
58     return;
59   }
60   for (auto i = q->second.begin(); i != q->second.end(); ++i) {
61     Backoff *b = (*i).get();
62     if (b->id == id) {
63       if (b->is_new()) {
64         b->state = Backoff::STATE_ACKED;
65         dout(20) << __func__ << " now " << *b << dendl;
66       } else if (b->is_deleting()) {
67         dout(20) << __func__ << " deleting " << *b << dendl;
68         q->second.erase(i);
69         --backoff_count;
70       }
71       break;
72     }
73   }
74   if (q->second.empty()) {
75     dout(20) << __func__ << " clearing begin bin " << q->first << dendl;
76     p->second.erase(q);
77     if (p->second.empty()) {
78       dout(20) << __func__ << " clearing pg bin " << p->first << dendl;
79       backoffs.erase(p);
80     }
81   }
82   assert(!backoff_count == backoffs.empty());
83 }
84
85 bool Session::check_backoff(
86   CephContext *cct, spg_t pgid, const hobject_t& oid, const Message *m)
87 {
88   BackoffRef b(have_backoff(pgid, oid));
89   if (b) {
90     dout(10) << __func__ << " session " << this << " has backoff " << *b
91              << " for " << *m << dendl;
92     assert(!b->is_acked() || !g_conf->osd_debug_crash_on_ignored_backoff);
93     return true;
94   }
95   // we may race with ms_handle_reset.  it clears session->con before removing
96   // backoffs, so if we see con is cleared here we have to abort this
97   // request.
98   if (!con) {
99     dout(10) << __func__ << " session " << this << " disconnected" << dendl;
100     return true;
101   }
102   return false;
103 }