diff options
author | Lars Ellenberg <lars.ellenberg@linbit.com> | 2011-01-20 07:25:21 -0500 |
---|---|---|
committer | Philipp Reisner <philipp.reisner@linbit.com> | 2011-03-10 05:48:01 -0500 |
commit | 62b0da3a244ac33d25a77861ef1cc0080103f2ff (patch) | |
tree | a4313df7c46ac50d751fb0798323e34a3e4efbee /drivers/block | |
parent | d07c9c10e5620c632aae9cac2b609033398f6139 (diff) |
drbd: log UUIDs whenever they change
All decisions about sync, sync direction, and wether or not to
allow a connect or attach are based on our set of UUIDs to tag a
data generation.
Log changes to the UUIDs whenever they occur,
logging "new current UUID P:Q:R:S" is more useful
than "Creating new current UUID".
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_int.h | 6 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_main.c | 71 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_nl.c | 1 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_receiver.c | 11 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_worker.c | 20 |
5 files changed, 58 insertions, 51 deletions
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index cfe7fff459e3..0a9059eb94db 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h | |||
@@ -1240,11 +1240,11 @@ extern int _drbd_send_bitmap(struct drbd_conf *mdev); | |||
1240 | extern int drbd_send_sr_reply(struct drbd_conf *mdev, enum drbd_state_rv retcode); | 1240 | extern int drbd_send_sr_reply(struct drbd_conf *mdev, enum drbd_state_rv retcode); |
1241 | extern void drbd_free_bc(struct drbd_backing_dev *ldev); | 1241 | extern void drbd_free_bc(struct drbd_backing_dev *ldev); |
1242 | extern void drbd_mdev_cleanup(struct drbd_conf *mdev); | 1242 | extern void drbd_mdev_cleanup(struct drbd_conf *mdev); |
1243 | void drbd_print_uuids(struct drbd_conf *mdev, const char *text); | ||
1243 | 1244 | ||
1244 | /* drbd_meta-data.c (still in drbd_main.c) */ | 1245 | /* drbd_meta-data.c (still in drbd_main.c) */ |
1245 | extern void drbd_md_sync(struct drbd_conf *mdev); | 1246 | extern void drbd_md_sync(struct drbd_conf *mdev); |
1246 | extern int drbd_md_read(struct drbd_conf *mdev, struct drbd_backing_dev *bdev); | 1247 | extern int drbd_md_read(struct drbd_conf *mdev, struct drbd_backing_dev *bdev); |
1247 | /* maybe define them below as inline? */ | ||
1248 | extern void drbd_uuid_set(struct drbd_conf *mdev, int idx, u64 val) __must_hold(local); | 1248 | extern void drbd_uuid_set(struct drbd_conf *mdev, int idx, u64 val) __must_hold(local); |
1249 | extern void _drbd_uuid_set(struct drbd_conf *mdev, int idx, u64 val) __must_hold(local); | 1249 | extern void _drbd_uuid_set(struct drbd_conf *mdev, int idx, u64 val) __must_hold(local); |
1250 | extern void drbd_uuid_new_current(struct drbd_conf *mdev) __must_hold(local); | 1250 | extern void drbd_uuid_new_current(struct drbd_conf *mdev) __must_hold(local); |
@@ -2360,9 +2360,11 @@ static inline void dec_ap_bio(struct drbd_conf *mdev) | |||
2360 | } | 2360 | } |
2361 | } | 2361 | } |
2362 | 2362 | ||
2363 | static inline void drbd_set_ed_uuid(struct drbd_conf *mdev, u64 val) | 2363 | static inline int drbd_set_ed_uuid(struct drbd_conf *mdev, u64 val) |
2364 | { | 2364 | { |
2365 | int changed = mdev->ed_uuid != val; | ||
2365 | mdev->ed_uuid = val; | 2366 | mdev->ed_uuid = val; |
2367 | return changed; | ||
2366 | } | 2368 | } |
2367 | 2369 | ||
2368 | static inline int seq_cmp(u32 a, u32 b) | 2370 | static inline int seq_cmp(u32 a, u32 b) |
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index e0be4077d564..b68332a0e73e 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c | |||
@@ -1159,6 +1159,10 @@ __drbd_set_state(struct drbd_conf *mdev, union drbd_state ns, | |||
1159 | atomic_inc(&mdev->local_cnt); | 1159 | atomic_inc(&mdev->local_cnt); |
1160 | 1160 | ||
1161 | mdev->state = ns; | 1161 | mdev->state = ns; |
1162 | |||
1163 | if (os.disk == D_ATTACHING && ns.disk >= D_NEGOTIATING) | ||
1164 | drbd_print_uuids(mdev, "attached to UUIDs"); | ||
1165 | |||
1162 | wake_up(&mdev->misc_wait); | 1166 | wake_up(&mdev->misc_wait); |
1163 | wake_up(&mdev->state_wait); | 1167 | wake_up(&mdev->state_wait); |
1164 | 1168 | ||
@@ -2035,6 +2039,24 @@ int drbd_send_uuids_skip_initial_sync(struct drbd_conf *mdev) | |||
2035 | return _drbd_send_uuids(mdev, 8); | 2039 | return _drbd_send_uuids(mdev, 8); |
2036 | } | 2040 | } |
2037 | 2041 | ||
2042 | void drbd_print_uuids(struct drbd_conf *mdev, const char *text) | ||
2043 | { | ||
2044 | if (get_ldev_if_state(mdev, D_NEGOTIATING)) { | ||
2045 | u64 *uuid = mdev->ldev->md.uuid; | ||
2046 | dev_info(DEV, "%s %016llX:%016llX:%016llX:%016llX\n", | ||
2047 | text, | ||
2048 | (unsigned long long)uuid[UI_CURRENT], | ||
2049 | (unsigned long long)uuid[UI_BITMAP], | ||
2050 | (unsigned long long)uuid[UI_HISTORY_START], | ||
2051 | (unsigned long long)uuid[UI_HISTORY_END]); | ||
2052 | put_ldev(mdev); | ||
2053 | } else { | ||
2054 | dev_info(DEV, "%s effective data uuid: %016llX\n", | ||
2055 | text, | ||
2056 | (unsigned long long)mdev->ed_uuid); | ||
2057 | } | ||
2058 | } | ||
2059 | |||
2038 | int drbd_gen_and_send_sync_uuid(struct drbd_conf *mdev) | 2060 | int drbd_gen_and_send_sync_uuid(struct drbd_conf *mdev) |
2039 | { | 2061 | { |
2040 | struct p_rs_uuid p; | 2062 | struct p_rs_uuid p; |
@@ -2044,6 +2066,7 @@ int drbd_gen_and_send_sync_uuid(struct drbd_conf *mdev) | |||
2044 | 2066 | ||
2045 | uuid = mdev->ldev->md.uuid[UI_BITMAP] + UUID_NEW_BM_OFFSET; | 2067 | uuid = mdev->ldev->md.uuid[UI_BITMAP] + UUID_NEW_BM_OFFSET; |
2046 | drbd_uuid_set(mdev, UI_BITMAP, uuid); | 2068 | drbd_uuid_set(mdev, UI_BITMAP, uuid); |
2069 | drbd_print_uuids(mdev, "updated sync UUID"); | ||
2047 | drbd_md_sync(mdev); | 2070 | drbd_md_sync(mdev); |
2048 | p.uuid = cpu_to_be64(uuid); | 2071 | p.uuid = cpu_to_be64(uuid); |
2049 | 2072 | ||
@@ -3749,28 +3772,6 @@ int drbd_md_read(struct drbd_conf *mdev, struct drbd_backing_dev *bdev) | |||
3749 | return rv; | 3772 | return rv; |
3750 | } | 3773 | } |
3751 | 3774 | ||
3752 | static void debug_drbd_uuid(struct drbd_conf *mdev, enum drbd_uuid_index index) | ||
3753 | { | ||
3754 | static char *uuid_str[UI_EXTENDED_SIZE] = { | ||
3755 | [UI_CURRENT] = "CURRENT", | ||
3756 | [UI_BITMAP] = "BITMAP", | ||
3757 | [UI_HISTORY_START] = "HISTORY_START", | ||
3758 | [UI_HISTORY_END] = "HISTORY_END", | ||
3759 | [UI_SIZE] = "SIZE", | ||
3760 | [UI_FLAGS] = "FLAGS", | ||
3761 | }; | ||
3762 | |||
3763 | if (index >= UI_EXTENDED_SIZE) { | ||
3764 | dev_warn(DEV, " uuid_index >= EXTENDED_SIZE\n"); | ||
3765 | return; | ||
3766 | } | ||
3767 | |||
3768 | dynamic_dev_dbg(DEV, " uuid[%s] now %016llX\n", | ||
3769 | uuid_str[index], | ||
3770 | (unsigned long long)mdev->ldev->md.uuid[index]); | ||
3771 | } | ||
3772 | |||
3773 | |||
3774 | /** | 3775 | /** |
3775 | * drbd_md_mark_dirty() - Mark meta data super block as dirty | 3776 | * drbd_md_mark_dirty() - Mark meta data super block as dirty |
3776 | * @mdev: DRBD device. | 3777 | * @mdev: DRBD device. |
@@ -3800,10 +3801,8 @@ static void drbd_uuid_move_history(struct drbd_conf *mdev) __must_hold(local) | |||
3800 | { | 3801 | { |
3801 | int i; | 3802 | int i; |
3802 | 3803 | ||
3803 | for (i = UI_HISTORY_START; i < UI_HISTORY_END; i++) { | 3804 | for (i = UI_HISTORY_START; i < UI_HISTORY_END; i++) |
3804 | mdev->ldev->md.uuid[i+1] = mdev->ldev->md.uuid[i]; | 3805 | mdev->ldev->md.uuid[i+1] = mdev->ldev->md.uuid[i]; |
3805 | debug_drbd_uuid(mdev, i+1); | ||
3806 | } | ||
3807 | } | 3806 | } |
3808 | 3807 | ||
3809 | void _drbd_uuid_set(struct drbd_conf *mdev, int idx, u64 val) __must_hold(local) | 3808 | void _drbd_uuid_set(struct drbd_conf *mdev, int idx, u64 val) __must_hold(local) |
@@ -3818,7 +3817,6 @@ void _drbd_uuid_set(struct drbd_conf *mdev, int idx, u64 val) __must_hold(local) | |||
3818 | } | 3817 | } |
3819 | 3818 | ||
3820 | mdev->ldev->md.uuid[idx] = val; | 3819 | mdev->ldev->md.uuid[idx] = val; |
3821 | debug_drbd_uuid(mdev, idx); | ||
3822 | drbd_md_mark_dirty(mdev); | 3820 | drbd_md_mark_dirty(mdev); |
3823 | } | 3821 | } |
3824 | 3822 | ||
@@ -3828,7 +3826,6 @@ void drbd_uuid_set(struct drbd_conf *mdev, int idx, u64 val) __must_hold(local) | |||
3828 | if (mdev->ldev->md.uuid[idx]) { | 3826 | if (mdev->ldev->md.uuid[idx]) { |
3829 | drbd_uuid_move_history(mdev); | 3827 | drbd_uuid_move_history(mdev); |
3830 | mdev->ldev->md.uuid[UI_HISTORY_START] = mdev->ldev->md.uuid[idx]; | 3828 | mdev->ldev->md.uuid[UI_HISTORY_START] = mdev->ldev->md.uuid[idx]; |
3831 | debug_drbd_uuid(mdev, UI_HISTORY_START); | ||
3832 | } | 3829 | } |
3833 | _drbd_uuid_set(mdev, idx, val); | 3830 | _drbd_uuid_set(mdev, idx, val); |
3834 | } | 3831 | } |
@@ -3843,14 +3840,16 @@ void drbd_uuid_set(struct drbd_conf *mdev, int idx, u64 val) __must_hold(local) | |||
3843 | void drbd_uuid_new_current(struct drbd_conf *mdev) __must_hold(local) | 3840 | void drbd_uuid_new_current(struct drbd_conf *mdev) __must_hold(local) |
3844 | { | 3841 | { |
3845 | u64 val; | 3842 | u64 val; |
3843 | unsigned long long bm_uuid = mdev->ldev->md.uuid[UI_BITMAP]; | ||
3844 | |||
3845 | if (bm_uuid) | ||
3846 | dev_warn(DEV, "bm UUID was already set: %llX\n", bm_uuid); | ||
3846 | 3847 | ||
3847 | dev_info(DEV, "Creating new current UUID\n"); | ||
3848 | D_ASSERT(mdev->ldev->md.uuid[UI_BITMAP] == 0); | ||
3849 | mdev->ldev->md.uuid[UI_BITMAP] = mdev->ldev->md.uuid[UI_CURRENT]; | 3848 | mdev->ldev->md.uuid[UI_BITMAP] = mdev->ldev->md.uuid[UI_CURRENT]; |
3850 | debug_drbd_uuid(mdev, UI_BITMAP); | ||
3851 | 3849 | ||
3852 | get_random_bytes(&val, sizeof(u64)); | 3850 | get_random_bytes(&val, sizeof(u64)); |
3853 | _drbd_uuid_set(mdev, UI_CURRENT, val); | 3851 | _drbd_uuid_set(mdev, UI_CURRENT, val); |
3852 | drbd_print_uuids(mdev, "new current UUID"); | ||
3854 | /* get it to stable storage _now_ */ | 3853 | /* get it to stable storage _now_ */ |
3855 | drbd_md_sync(mdev); | 3854 | drbd_md_sync(mdev); |
3856 | } | 3855 | } |
@@ -3864,16 +3863,12 @@ void drbd_uuid_set_bm(struct drbd_conf *mdev, u64 val) __must_hold(local) | |||
3864 | drbd_uuid_move_history(mdev); | 3863 | drbd_uuid_move_history(mdev); |
3865 | mdev->ldev->md.uuid[UI_HISTORY_START] = mdev->ldev->md.uuid[UI_BITMAP]; | 3864 | mdev->ldev->md.uuid[UI_HISTORY_START] = mdev->ldev->md.uuid[UI_BITMAP]; |
3866 | mdev->ldev->md.uuid[UI_BITMAP] = 0; | 3865 | mdev->ldev->md.uuid[UI_BITMAP] = 0; |
3867 | debug_drbd_uuid(mdev, UI_HISTORY_START); | ||
3868 | debug_drbd_uuid(mdev, UI_BITMAP); | ||
3869 | } else { | 3866 | } else { |
3870 | if (mdev->ldev->md.uuid[UI_BITMAP]) | 3867 | unsigned long long bm_uuid = mdev->ldev->md.uuid[UI_BITMAP]; |
3871 | dev_warn(DEV, "bm UUID already set"); | 3868 | if (bm_uuid) |
3872 | 3869 | dev_warn(DEV, "bm UUID was already set: %llX\n", bm_uuid); | |
3873 | mdev->ldev->md.uuid[UI_BITMAP] = val; | ||
3874 | mdev->ldev->md.uuid[UI_BITMAP] &= ~((u64)1); | ||
3875 | 3870 | ||
3876 | debug_drbd_uuid(mdev, UI_BITMAP); | 3871 | mdev->ldev->md.uuid[UI_BITMAP] = val & ~((u64)1); |
3877 | } | 3872 | } |
3878 | drbd_md_mark_dirty(mdev); | 3873 | drbd_md_mark_dirty(mdev); |
3879 | } | 3874 | } |
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index ffe3a97fef9b..ce6f2fe80852 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c | |||
@@ -2151,6 +2151,7 @@ static int drbd_nl_new_c_uuid(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nl | |||
2151 | if (skip_initial_sync) { | 2151 | if (skip_initial_sync) { |
2152 | drbd_send_uuids_skip_initial_sync(mdev); | 2152 | drbd_send_uuids_skip_initial_sync(mdev); |
2153 | _drbd_uuid_set(mdev, UI_BITMAP, 0); | 2153 | _drbd_uuid_set(mdev, UI_BITMAP, 0); |
2154 | drbd_print_uuids(mdev, "cleared bitmap UUID"); | ||
2154 | spin_lock_irq(&mdev->req_lock); | 2155 | spin_lock_irq(&mdev->req_lock); |
2155 | _drbd_set_state(_NS2(mdev, disk, D_UP_TO_DATE, pdsk, D_UP_TO_DATE), | 2156 | _drbd_set_state(_NS2(mdev, disk, D_UP_TO_DATE, pdsk, D_UP_TO_DATE), |
2156 | CS_VERBOSE, NULL); | 2157 | CS_VERBOSE, NULL); |
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index e9354931eace..e5686a81f42c 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c | |||
@@ -3024,7 +3024,7 @@ static int receive_uuids(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned | |||
3024 | { | 3024 | { |
3025 | struct p_uuids *p = &mdev->data.rbuf.uuids; | 3025 | struct p_uuids *p = &mdev->data.rbuf.uuids; |
3026 | u64 *p_uuid; | 3026 | u64 *p_uuid; |
3027 | int i; | 3027 | int i, updated_uuids = 0; |
3028 | 3028 | ||
3029 | p_uuid = kmalloc(sizeof(u64)*UI_EXTENDED_SIZE, GFP_NOIO); | 3029 | p_uuid = kmalloc(sizeof(u64)*UI_EXTENDED_SIZE, GFP_NOIO); |
3030 | 3030 | ||
@@ -3059,13 +3059,14 @@ static int receive_uuids(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned | |||
3059 | _drbd_set_state(_NS2(mdev, disk, D_UP_TO_DATE, pdsk, D_UP_TO_DATE), | 3059 | _drbd_set_state(_NS2(mdev, disk, D_UP_TO_DATE, pdsk, D_UP_TO_DATE), |
3060 | CS_VERBOSE, NULL); | 3060 | CS_VERBOSE, NULL); |
3061 | drbd_md_sync(mdev); | 3061 | drbd_md_sync(mdev); |
3062 | updated_uuids = 1; | ||
3062 | } | 3063 | } |
3063 | put_ldev(mdev); | 3064 | put_ldev(mdev); |
3064 | } else if (mdev->state.disk < D_INCONSISTENT && | 3065 | } else if (mdev->state.disk < D_INCONSISTENT && |
3065 | mdev->state.role == R_PRIMARY) { | 3066 | mdev->state.role == R_PRIMARY) { |
3066 | /* I am a diskless primary, the peer just created a new current UUID | 3067 | /* I am a diskless primary, the peer just created a new current UUID |
3067 | for me. */ | 3068 | for me. */ |
3068 | drbd_set_ed_uuid(mdev, p_uuid[UI_CURRENT]); | 3069 | updated_uuids = drbd_set_ed_uuid(mdev, p_uuid[UI_CURRENT]); |
3069 | } | 3070 | } |
3070 | 3071 | ||
3071 | /* Before we test for the disk state, we should wait until an eventually | 3072 | /* Before we test for the disk state, we should wait until an eventually |
@@ -3074,7 +3075,10 @@ static int receive_uuids(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned | |||
3074 | new disk state... */ | 3075 | new disk state... */ |
3075 | wait_event(mdev->misc_wait, !test_bit(CLUSTER_ST_CHANGE, &mdev->flags)); | 3076 | wait_event(mdev->misc_wait, !test_bit(CLUSTER_ST_CHANGE, &mdev->flags)); |
3076 | if (mdev->state.conn >= C_CONNECTED && mdev->state.disk < D_INCONSISTENT) | 3077 | if (mdev->state.conn >= C_CONNECTED && mdev->state.disk < D_INCONSISTENT) |
3077 | drbd_set_ed_uuid(mdev, p_uuid[UI_CURRENT]); | 3078 | updated_uuids |= drbd_set_ed_uuid(mdev, p_uuid[UI_CURRENT]); |
3079 | |||
3080 | if (updated_uuids) | ||
3081 | drbd_print_uuids(mdev, "receiver updated UUIDs to"); | ||
3078 | 3082 | ||
3079 | return true; | 3083 | return true; |
3080 | } | 3084 | } |
@@ -3305,6 +3309,7 @@ static int receive_sync_uuid(struct drbd_conf *mdev, enum drbd_packets cmd, unsi | |||
3305 | _drbd_uuid_set(mdev, UI_CURRENT, be64_to_cpu(p->uuid)); | 3309 | _drbd_uuid_set(mdev, UI_CURRENT, be64_to_cpu(p->uuid)); |
3306 | _drbd_uuid_set(mdev, UI_BITMAP, 0UL); | 3310 | _drbd_uuid_set(mdev, UI_BITMAP, 0UL); |
3307 | 3311 | ||
3312 | drbd_print_uuids(mdev, "updated sync uuid"); | ||
3308 | drbd_start_resync(mdev, C_SYNC_TARGET); | 3313 | drbd_start_resync(mdev, C_SYNC_TARGET); |
3309 | 3314 | ||
3310 | put_ldev(mdev); | 3315 | put_ldev(mdev); |
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c index ec42e04bb517..ff0eb308ee4a 100644 --- a/drivers/block/drbd/drbd_worker.c +++ b/drivers/block/drbd/drbd_worker.c | |||
@@ -871,14 +871,18 @@ int drbd_resync_finished(struct drbd_conf *mdev) | |||
871 | } | 871 | } |
872 | } | 872 | } |
873 | 873 | ||
874 | drbd_uuid_set_bm(mdev, 0UL); | 874 | if (!(os.conn == C_VERIFY_S || os.conn == C_VERIFY_T)) { |
875 | 875 | /* for verify runs, we don't update uuids here, | |
876 | if (mdev->p_uuid) { | 876 | * so there would be nothing to report. */ |
877 | /* Now the two UUID sets are equal, update what we | 877 | drbd_uuid_set_bm(mdev, 0UL); |
878 | * know of the peer. */ | 878 | drbd_print_uuids(mdev, "updated UUIDs"); |
879 | int i; | 879 | if (mdev->p_uuid) { |
880 | for (i = UI_CURRENT ; i <= UI_HISTORY_END ; i++) | 880 | /* Now the two UUID sets are equal, update what we |
881 | mdev->p_uuid[i] = mdev->ldev->md.uuid[i]; | 881 | * know of the peer. */ |
882 | int i; | ||
883 | for (i = UI_CURRENT ; i <= UI_HISTORY_END ; i++) | ||
884 | mdev->p_uuid[i] = mdev->ldev->md.uuid[i]; | ||
885 | } | ||
882 | } | 886 | } |
883 | } | 887 | } |
884 | 888 | ||