<< " dropping " << ccap_string(dropping)
<< dendl;
- cap->issued &= retain;
- cap->implemented &= cap->issued | used;
+ if (cct->_conf->client_inject_release_failure && revoking) {
+ // Simulated bug:
+ // - tell the server we think issued is whatever they issued plus whatever we implemented
+ // - leave what we have implemented in place
+ ldout(cct, 20) << __func__ << " injecting failure to release caps" << dendl;
+ cap->issued = cap->issued | cap->implemented;
+ } else {
+ // Normal behaviour
+ cap->issued &= retain;
+ cap->implemented &= cap->issued | used;
+ }
uint64_t flush_tid = 0;
snapid_t follows = 0;
p != mds_sessions.end();
++p) {
if (p->second->release && mdsmap->is_clientreplay_or_active_or_stopping(p->first)) {
- p->second->con->send_message(p->second->release);
+ if (cct->_conf->client_inject_release_failure) {
+ ldout(cct, 20) << __func__ << " injecting failure to send cap release message" << dendl;
+ p->second->release->put();
+ } else {
+ p->second->con->send_message(p->second->release);
+ }
p->second->release = 0;
}
}
OPTION(client_debug_force_sync_read, OPT_BOOL, false) // always read synchronously (go to osds)
OPTION(client_debug_inject_tick_delay, OPT_INT, 0) // delay the client tick for a number of seconds
OPTION(client_max_inline_size, OPT_U64, 4096)
+OPTION(client_inject_release_failure, OPT_BOOL, false) // synthetic client bug for testing
// note: the max amount of "in flight" dirty data is roughly (max - target)
OPTION(fuse_use_invalidate_cb, OPT_BOOL, false) // use fuse 2.8+ invalidate callback to keep page cache consistent
OPTION(fuse_allow_other, OPT_BOOL, true)