我目前正在使用 DRBD 在两台机器上复制 samba 文件服务器。有时主服务器上的写入会失败,发生这种情况时资源状态(使用 cat /proc/drbd)为:
0: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate A r---n
当一切正常时,状态是:
0: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate A r----
我能看到的唯一区别是行尾的“n”。我认为这与拥塞无关,因为它发生在资源上没有活动时。使用 drbdadm 断开连接并重新连接可以解决问题。
所以,我的问题是:那个‘n’代表什么?
感谢您的帮助!
答案1
我还没有找到关于这些位的文档,所以我深入研究了 drbd-8.3.4 源代码。'n' 实际上与同步拥塞有关。以下是代码:
这是更新 /proc/drbd 的调用
在 drdb/drbd_main.c 中
seq_printf(seq,
201 "%2d: cs:%s ro:%s/%s ds:%s/%s %c %c%c%c%c%c\n"
202 " ns:%u nr:%u dw:%u dr:%u al:%u bm:%u "
203 "lo:%d pe:%d ua:%d ap:%d ep:%d wo:%c",
204 i, sn,
205 drbd_role_str(mdev->state.role),
206 drbd_role_str(mdev->state.peer),
207 drbd_disk_str(mdev->state.disk),
208 drbd_disk_str(mdev->state.pdsk),
209 (mdev->net_conf == NULL ? ' ' :
210 (mdev->net_conf->wire_protocol - DRBD_PROT_A+'A')),
211 mdev->state.susp ? 's' : 'r',
212 mdev->state.aftr_isp ? 'a' : '-',
213 mdev->state.peer_isp ? 'p' : '-',
214 mdev->state.user_isp ? 'u' : '-',
215 mdev->congestion_reason ?: '-',
216 mdev->send_cnt/2,
217 mdev->recv_cnt/2,
218 mdev->writ_cnt/2,
219 mdev->read_cnt/2,
220 mdev->al_writ_cnt,
221 mdev->bm_writ_cnt,
222 atomic_read(&mdev->local_cnt),
223 atomic_read(&mdev->ap_pending_cnt) +
224 atomic_read(&mdev->rs_pending_cnt),
225 atomic_read(&mdev->unacked_cnt),
226 atomic_read(&mdev->ap_bio_cnt),
227 mdev->epochs,
228 write_ordering_chars[mdev->write_ordering]
229 );
这意味着 'n' 字段来自 congestion_reason。这是在以下代码中设置的(第 3171 行):
在 drdb/drbd_main.c 中
3140 /**
3141 * drbd_congested() - Callback for pdflush
3142 * @congested_data: User data
3143 * @bdi_bits: Bits pdflush is currently interested in
3144 *
3145 * Returns 1<<BDI_async_congested and/or 1<<BDI_sync_congested if we are congested.
3146 */
3147 static int drbd_congested(void *congested_data, int bdi_bits)
3148 {
3149 struct drbd_conf *mdev = congested_data;
3150 struct request_queue *q;
3151 char reason = '-';
3152 int r = 0;
3153
3154 if (!__inc_ap_bio_cond(mdev)) {
3155 /* DRBD has frozen IO */
3156 r = bdi_bits;
3157 reason = 'd';
3158 goto out;
3159 }
3160
3161 if (get_ldev(mdev)) {
3162 q = bdev_get_queue(mdev->ldev->backing_bdev);
3163 r = bdi_congested(&q->backing_dev_info, bdi_bits);
3164 put_ldev(mdev);
3165 if (r)
3166 reason = 'b';
3167 }
3168
3169 if (bdi_bits & (1 << BDI_async_congested) && test_bit(NET_CONGESTED, &mdev->flags)) {
3170 r |= (1 << BDI_async_congested);
3171 reason = reason == 'b' ? 'a' : 'n';
3172 }
3173
3174 out:
3175 mdev->congestion_reason = reason;
3176 return r;
3177 }
希望这可以帮助