aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorPhilipp Reisner <philipp.reisner@linbit.com>2011-03-25 10:11:30 -0400
committerPhilipp Reisner <philipp.reisner@linbit.com>2012-11-08 10:44:57 -0500
commit435693e89b7a918b14ea67968971a2d8d9e88df2 (patch)
treebe2d9272bec975aef6b2392eb4a967ffdda2dcb0 /drivers/block
parent88ef594ed7367a76e53f4a33b3d866f4dfb1d4ff (diff)
drbd: Print common state changes of all volumes as connection state changes
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com> Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/drbd/drbd_state.c159
-rw-r--r--drivers/block/drbd/drbd_state.h19
2 files changed, 70 insertions, 108 deletions
diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c
index 2a170bf7cc29..164a7f821c78 100644
--- a/drivers/block/drbd/drbd_state.c
+++ b/drivers/block/drbd/drbd_state.c
@@ -350,29 +350,29 @@ void print_st_err(struct drbd_conf *mdev, union drbd_state os,
350 print_st(mdev, "wanted", ns); 350 print_st(mdev, "wanted", ns);
351} 351}
352 352
353static void print_state_change(struct drbd_conf *mdev, union drbd_state os, union drbd_state ns, 353static long print_state_change(char *pb, union drbd_state os, union drbd_state ns,
354 enum chg_state_flags flags) 354 enum chg_state_flags flags)
355{ 355{
356 char *pbp, pb[300]; 356 char *pbp;
357 pbp = pb; 357 pbp = pb;
358 *pbp = 0; 358 *pbp = 0;
359 if (ns.role != os.role) 359 if (ns.role != os.role && flags & CS_DC_ROLE)
360 pbp += sprintf(pbp, "role( %s -> %s ) ", 360 pbp += sprintf(pbp, "role( %s -> %s ) ",
361 drbd_role_str(os.role), 361 drbd_role_str(os.role),
362 drbd_role_str(ns.role)); 362 drbd_role_str(ns.role));
363 if (ns.peer != os.peer) 363 if (ns.peer != os.peer && flags & CS_DC_PEER)
364 pbp += sprintf(pbp, "peer( %s -> %s ) ", 364 pbp += sprintf(pbp, "peer( %s -> %s ) ",
365 drbd_role_str(os.peer), 365 drbd_role_str(os.peer),
366 drbd_role_str(ns.peer)); 366 drbd_role_str(ns.peer));
367 if (ns.conn != os.conn && !(flags & CS_NO_CSTATE_CHG)) 367 if (ns.conn != os.conn && flags & CS_DC_CONN)
368 pbp += sprintf(pbp, "conn( %s -> %s ) ", 368 pbp += sprintf(pbp, "conn( %s -> %s ) ",
369 drbd_conn_str(os.conn), 369 drbd_conn_str(os.conn),
370 drbd_conn_str(ns.conn)); 370 drbd_conn_str(ns.conn));
371 if (ns.disk != os.disk) 371 if (ns.disk != os.disk && flags & CS_DC_DISK)
372 pbp += sprintf(pbp, "disk( %s -> %s ) ", 372 pbp += sprintf(pbp, "disk( %s -> %s ) ",
373 drbd_disk_str(os.disk), 373 drbd_disk_str(os.disk),
374 drbd_disk_str(ns.disk)); 374 drbd_disk_str(ns.disk));
375 if (ns.pdsk != os.pdsk) 375 if (ns.pdsk != os.pdsk && flags & CS_DC_PDSK)
376 pbp += sprintf(pbp, "pdsk( %s -> %s ) ", 376 pbp += sprintf(pbp, "pdsk( %s -> %s ) ",
377 drbd_disk_str(os.pdsk), 377 drbd_disk_str(os.pdsk),
378 drbd_disk_str(ns.pdsk)); 378 drbd_disk_str(ns.pdsk));
@@ -392,10 +392,29 @@ static void print_state_change(struct drbd_conf *mdev, union drbd_state os, unio
392 pbp += sprintf(pbp, "user_isp( %d -> %d ) ", 392 pbp += sprintf(pbp, "user_isp( %d -> %d ) ",
393 os.user_isp, 393 os.user_isp,
394 ns.user_isp); 394 ns.user_isp);
395 if (pbp != pb) 395
396 return pbp - pb;
397}
398
399static void drbd_pr_state_change(struct drbd_conf *mdev, union drbd_state os, union drbd_state ns,
400 enum chg_state_flags flags)
401{
402 char pb[300];
403
404 if (print_state_change(pb, os, ns, flags ^ CS_DC_MASK))
396 dev_info(DEV, "%s\n", pb); 405 dev_info(DEV, "%s\n", pb);
397} 406}
398 407
408static void conn_pr_state_change(struct drbd_tconn *tconn, union drbd_state os, union drbd_state ns,
409 enum chg_state_flags flags)
410{
411 char pb[300];
412
413 if (print_state_change(pb, os, ns, flags))
414 conn_info(tconn, "%s\n", pb);
415}
416
417
399/** 418/**
400 * is_valid_state() - Returns an SS_ error code if ns is not valid 419 * is_valid_state() - Returns an SS_ error code if ns is not valid
401 * @mdev: DRBD device. 420 * @mdev: DRBD device.
@@ -827,7 +846,7 @@ __drbd_set_state(struct drbd_conf *mdev, union drbd_state ns,
827 if (warn_sync_abort) 846 if (warn_sync_abort)
828 dev_warn(DEV, "%s aborted.\n", warn_sync_abort); 847 dev_warn(DEV, "%s aborted.\n", warn_sync_abort);
829 848
830 print_state_change(mdev, os, ns, flags); 849 drbd_pr_state_change(mdev, os, ns, flags);
831 850
832 /* if we are going -> D_FAILED or D_DISKLESS, grab one extra reference 851 /* if we are going -> D_FAILED or D_DISKLESS, grab one extra reference
833 * on the ldev here, to be sure the transition -> D_DISKLESS resp. 852 * on the ldev here, to be sure the transition -> D_DISKLESS resp.
@@ -1364,98 +1383,41 @@ static int w_after_conn_state_ch(struct drbd_work *w, int unused)
1364 return 0; 1383 return 0;
1365} 1384}
1366 1385
1367static void print_conn_state_change(struct drbd_tconn *tconn, enum drbd_conns oc, enum drbd_conns nc) 1386void conn_old_common_state(struct drbd_tconn *tconn, union drbd_state *pcs, enum chg_state_flags *pf)
1368{
1369 char *pbp, pb[300];
1370 pbp = pb;
1371 *pbp = 0;
1372 if (nc != oc)
1373 pbp += sprintf(pbp, "conn( %s -> %s ) ",
1374 drbd_conn_str(oc),
1375 drbd_conn_str(nc));
1376
1377 conn_info(tconn, "%s\n", pb);
1378}
1379
1380enum sp_state {
1381 OC_UNINITIALIZED,
1382 OC_CONSISTENT,
1383 OC_INCONSISTENT,
1384} oc_state;
1385
1386static void common_state_part(enum sp_state *sps, int *sp, int nsp)
1387{
1388 switch (*sps) {
1389 case OC_UNINITIALIZED:
1390 *sp = nsp;
1391 *sps = OC_CONSISTENT;
1392 break;
1393 case OC_CONSISTENT:
1394 if (*sp != nsp)
1395 *sps = OC_INCONSISTENT;
1396 break;
1397 case OC_INCONSISTENT:
1398 break;
1399 }
1400}
1401
1402void conn_old_common_state(struct drbd_tconn *tconn, union drbd_state *pcs, union drbd_state *pmask)
1403{ 1387{
1404 union drbd_state css = {}; /* common state state */ 1388 enum chg_state_flags flags = ~0;
1405 union drbd_state os, cs = {}; /* old_state, common_state */ 1389 union drbd_state os, cs = {}; /* old_state, common_state */
1406 union drbd_state mask = {};
1407 enum sp_state sps; /* state part state */
1408 int sp; /* state part */
1409 struct drbd_conf *mdev; 1390 struct drbd_conf *mdev;
1410 int vnr; 1391 int vnr, first_vol = 1;
1411 1392
1412 idr_for_each_entry(&tconn->volumes, mdev, vnr) { 1393 idr_for_each_entry(&tconn->volumes, mdev, vnr) {
1413 os = mdev->state; 1394 os = mdev->state;
1414 1395
1415 sps = css.role; 1396 if (first_vol) {
1416 sp = cs.role; 1397 cs = os;
1417 common_state_part(&sps, &sp, os.role); 1398 first_vol = 0;
1418 css.role = sps; 1399 continue;
1419 cs.role = sp; 1400 }
1420 1401
1421 sps = css.peer; 1402 if (cs.role != os.role)
1422 sp = cs.peer; 1403 flags &= ~CS_DC_ROLE;
1423 common_state_part(&sps, &sp, os.peer); 1404
1424 css.peer = sps; 1405 if (cs.peer != os.peer)
1425 cs.peer = sp; 1406 flags &= ~CS_DC_PEER;
1426 1407
1427 sps = css.conn; 1408 if (cs.conn != os.conn)
1428 sp = cs.conn; 1409 flags &= ~CS_DC_CONN;
1429 common_state_part(&sps, &sp, os.conn);
1430 css.conn = sps;
1431 cs.conn = sp;
1432
1433 sps = css.disk;
1434 sp = cs.disk;
1435 common_state_part(&sps, &sp, os.disk);
1436 css.disk = sps;
1437 cs.disk = sp;
1438
1439 sps = css.pdsk;
1440 sp = cs.pdsk;
1441 common_state_part(&sps, &sp, os.pdsk);
1442 css.pdsk = sps;
1443 cs.pdsk = sp;
1444 }
1445 1410
1446 if (css.role == OC_CONSISTENT) 1411 if (cs.disk != os.disk)
1447 mask.role = R_MASK; 1412 flags &= ~CS_DC_DISK;
1448 if (css.peer == OC_CONSISTENT)
1449 mask.peer = R_MASK;
1450 if (css.conn == OC_CONSISTENT)
1451 mask.conn = C_MASK;
1452 if (css.disk == OC_CONSISTENT)
1453 mask.disk = D_MASK;
1454 if (css.pdsk == OC_CONSISTENT)
1455 mask.pdsk = D_MASK;
1456 1413
1414 if (cs.pdsk != os.pdsk)
1415 flags &= ~CS_DC_PDSK;
1416 }
1417
1418 *pf |= CS_DC_MASK;
1419 *pf &= flags;
1457 *pcs = cs; 1420 *pcs = cs;
1458 *pmask = mask;
1459} 1421}
1460 1422
1461static enum drbd_state_rv 1423static enum drbd_state_rv
@@ -1541,7 +1503,7 @@ _conn_rq_cond(struct drbd_tconn *tconn, union drbd_state mask, union drbd_state
1541 rv = tconn->cstate != C_WF_REPORT_PARAMS ? SS_CW_NO_NEED : SS_UNKNOWN_ERROR; 1503 rv = tconn->cstate != C_WF_REPORT_PARAMS ? SS_CW_NO_NEED : SS_UNKNOWN_ERROR;
1542 1504
1543 if (rv == SS_UNKNOWN_ERROR) 1505 if (rv == SS_UNKNOWN_ERROR)
1544 rv = conn_is_valid_transition(tconn, mask, val, CS_NO_CSTATE_CHG); 1506 rv = conn_is_valid_transition(tconn, mask, val, 0);
1545 1507
1546 if (rv == SS_SUCCESS) 1508 if (rv == SS_SUCCESS)
1547 rv = SS_UNKNOWN_ERROR; /* cont waiting, otherwise fail. */ 1509 rv = SS_UNKNOWN_ERROR; /* cont waiting, otherwise fail. */
@@ -1583,7 +1545,7 @@ _conn_request_state(struct drbd_tconn *tconn, union drbd_state mask, union drbd_
1583 enum drbd_state_rv rv = SS_SUCCESS; 1545 enum drbd_state_rv rv = SS_SUCCESS;
1584 struct after_conn_state_chg_work *acscw; 1546 struct after_conn_state_chg_work *acscw;
1585 enum drbd_conns oc = tconn->cstate; 1547 enum drbd_conns oc = tconn->cstate;
1586 union drbd_state ms, os_val, os_mask; 1548 union drbd_state ms, os;
1587 1549
1588 rv = is_valid_conn_transition(oc, val.conn); 1550 rv = is_valid_conn_transition(oc, val.conn);
1589 if (rv < SS_SUCCESS) 1551 if (rv < SS_SUCCESS)
@@ -1600,19 +1562,14 @@ _conn_request_state(struct drbd_tconn *tconn, union drbd_state mask, union drbd_
1600 goto abort; 1562 goto abort;
1601 } 1563 }
1602 1564
1603 conn_old_common_state(tconn, &os_val, &os_mask); 1565 conn_old_common_state(tconn, &os, &flags);
1604 if (os_mask.conn == C_MASK) {
1605 oc = os_val.conn;
1606 print_conn_state_change(tconn, oc, val.conn);
1607 flags |= CS_NO_CSTATE_CHG;
1608 }
1609
1610 ms = conn_set_state(tconn, mask, val, flags); 1566 ms = conn_set_state(tconn, mask, val, flags);
1611 ms.conn = val.conn; 1567 ms.conn = val.conn;
1568 conn_pr_state_change(tconn, os, ms, flags);
1612 1569
1613 acscw = kmalloc(sizeof(*acscw), GFP_ATOMIC); 1570 acscw = kmalloc(sizeof(*acscw), GFP_ATOMIC);
1614 if (acscw) { 1571 if (acscw) {
1615 acscw->oc = oc; 1572 acscw->oc = os.conn;
1616 acscw->nms = ms; 1573 acscw->nms = ms;
1617 acscw->flags = flags; 1574 acscw->flags = flags;
1618 acscw->w.cb = w_after_conn_state_ch; 1575 acscw->w.cb = w_after_conn_state_ch;
diff --git a/drivers/block/drbd/drbd_state.h b/drivers/block/drbd/drbd_state.h
index 394a1998acd9..11fd0f897bdb 100644
--- a/drivers/block/drbd/drbd_state.h
+++ b/drivers/block/drbd/drbd_state.h
@@ -57,13 +57,18 @@ struct drbd_tconn;
57 __ns.T2 = (S2); __ns.T3 = (S3); __ns; }) 57 __ns.T2 = (S2); __ns.T3 = (S3); __ns; })
58 58
59enum chg_state_flags { 59enum chg_state_flags {
60 CS_HARD = 1, 60 CS_HARD = 1 << 0,
61 CS_VERBOSE = 2, 61 CS_VERBOSE = 1 << 1,
62 CS_WAIT_COMPLETE = 4, 62 CS_WAIT_COMPLETE = 1 << 2,
63 CS_SERIALIZE = 8, 63 CS_SERIALIZE = 1 << 3,
64 CS_ORDERED = CS_WAIT_COMPLETE + CS_SERIALIZE, 64 CS_ORDERED = CS_WAIT_COMPLETE + CS_SERIALIZE,
65 CS_NO_CSTATE_CHG = 16, /* Do not display changes in cstate. Internal to drbd_state.c */ 65 CS_LOCAL_ONLY = 1 << 4, /* Do not consider a device pair wide state change */
66 CS_LOCAL_ONLY = 32, /* Do not consider a device pair wide state change */ 66 CS_DC_ROLE = 1 << 5, /* DC = display as connection state change */
67 CS_DC_PEER = 1 << 6,
68 CS_DC_CONN = 1 << 7,
69 CS_DC_DISK = 1 << 8,
70 CS_DC_PDSK = 1 << 9,
71 CS_DC_MASK = CS_DC_ROLE + CS_DC_PEER + CS_DC_CONN + CS_DC_DISK + CS_DC_PDSK,
67}; 72};
68 73
69extern enum drbd_state_rv drbd_change_state(struct drbd_conf *mdev, 74extern enum drbd_state_rv drbd_change_state(struct drbd_conf *mdev,