diff options
author | Jonathan Brassow <jbrassow@redhat.com> | 2009-09-04 15:40:34 -0400 |
---|---|---|
committer | Alasdair G Kergon <agk@redhat.com> | 2009-09-04 15:40:34 -0400 |
commit | 7ec23d50949d5062b5b749638dd9380ed75e58e5 (patch) | |
tree | 28183b6468683cf28abd63b9c322b9f31bcddc5e /drivers/md/dm-log-userspace-base.c | |
parent | d2b698644c97cb033261536a4f2010924a00eac9 (diff) |
dm log: userspace add luid to distinguish between concurrent log instances
Device-mapper userspace logs (like the clustered log) are
identified by a universally unique identifier (UUID). This
identifier is used to associate requests from the kernel to
a specific log in userspace. The UUID must be unique everywhere,
since multiple machines may use this identifier when communicating
about a particular log, as is the case for cluster logs.
Sometimes, device-mapper/LVM may re-use a UUID. This is the
case during pvmoves, when moving from one segment of an LV
to another, or when resizing a mirror, etc. In these cases,
a new log is created with the same UUID and loaded in the
"inactive" slot. When a device-mapper "resume" is issued,
the "live" table is deactivated and the new "inactive" table
becomes "live". (The "inactive" table can also be removed
via a device-mapper 'clear' command.)
The above two issues were colliding. More than one log was being
created with the same UUID, and there was no way to distinguish
between them. So, sometimes the wrong log would be swapped
out during the exchange.
The solution is to create a locally unique identifier,
'luid', to go along with the UUID. This new identifier is used
to determine exactly which log is being referenced by the kernel
when the log exchange is made. The identifier is not
universally safe, but it does not need to be, since
create/destroy/suspend/resume operations are bound to a specific
machine; and these are the operations that make up the exchange.
Signed-off-by: Jonathan Brassow <jbrassow@redhat.com>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Diffstat (limited to 'drivers/md/dm-log-userspace-base.c')
-rw-r--r-- | drivers/md/dm-log-userspace-base.c | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/drivers/md/dm-log-userspace-base.c b/drivers/md/dm-log-userspace-base.c index c49da0a41c8e..6e186b1a062d 100644 --- a/drivers/md/dm-log-userspace-base.c +++ b/drivers/md/dm-log-userspace-base.c | |||
@@ -21,6 +21,7 @@ struct log_c { | |||
21 | struct dm_target *ti; | 21 | struct dm_target *ti; |
22 | uint32_t region_size; | 22 | uint32_t region_size; |
23 | region_t region_count; | 23 | region_t region_count; |
24 | uint64_t luid; | ||
24 | char uuid[DM_UUID_LEN]; | 25 | char uuid[DM_UUID_LEN]; |
25 | 26 | ||
26 | char *usr_argv_str; | 27 | char *usr_argv_str; |
@@ -63,7 +64,7 @@ static int userspace_do_request(struct log_c *lc, const char *uuid, | |||
63 | * restored. | 64 | * restored. |
64 | */ | 65 | */ |
65 | retry: | 66 | retry: |
66 | r = dm_consult_userspace(uuid, request_type, data, | 67 | r = dm_consult_userspace(uuid, lc->luid, request_type, data, |
67 | data_size, rdata, rdata_size); | 68 | data_size, rdata, rdata_size); |
68 | 69 | ||
69 | if (r != -ESRCH) | 70 | if (r != -ESRCH) |
@@ -74,14 +75,15 @@ retry: | |||
74 | set_current_state(TASK_INTERRUPTIBLE); | 75 | set_current_state(TASK_INTERRUPTIBLE); |
75 | schedule_timeout(2*HZ); | 76 | schedule_timeout(2*HZ); |
76 | DMWARN("Attempting to contact userspace log server..."); | 77 | DMWARN("Attempting to contact userspace log server..."); |
77 | r = dm_consult_userspace(uuid, DM_ULOG_CTR, lc->usr_argv_str, | 78 | r = dm_consult_userspace(uuid, lc->luid, DM_ULOG_CTR, |
79 | lc->usr_argv_str, | ||
78 | strlen(lc->usr_argv_str) + 1, | 80 | strlen(lc->usr_argv_str) + 1, |
79 | NULL, NULL); | 81 | NULL, NULL); |
80 | if (!r) | 82 | if (!r) |
81 | break; | 83 | break; |
82 | } | 84 | } |
83 | DMINFO("Reconnected to userspace log server... DM_ULOG_CTR complete"); | 85 | DMINFO("Reconnected to userspace log server... DM_ULOG_CTR complete"); |
84 | r = dm_consult_userspace(uuid, DM_ULOG_RESUME, NULL, | 86 | r = dm_consult_userspace(uuid, lc->luid, DM_ULOG_RESUME, NULL, |
85 | 0, NULL, NULL); | 87 | 0, NULL, NULL); |
86 | if (!r) | 88 | if (!r) |
87 | goto retry; | 89 | goto retry; |
@@ -153,6 +155,9 @@ static int userspace_ctr(struct dm_dirty_log *log, struct dm_target *ti, | |||
153 | return -ENOMEM; | 155 | return -ENOMEM; |
154 | } | 156 | } |
155 | 157 | ||
158 | /* The ptr value is sufficient for local unique id */ | ||
159 | lc->luid = (uint64_t)lc; | ||
160 | |||
156 | lc->ti = ti; | 161 | lc->ti = ti; |
157 | 162 | ||
158 | if (strlen(argv[0]) > (DM_UUID_LEN - 1)) { | 163 | if (strlen(argv[0]) > (DM_UUID_LEN - 1)) { |
@@ -172,7 +177,7 @@ static int userspace_ctr(struct dm_dirty_log *log, struct dm_target *ti, | |||
172 | } | 177 | } |
173 | 178 | ||
174 | /* Send table string */ | 179 | /* Send table string */ |
175 | r = dm_consult_userspace(lc->uuid, DM_ULOG_CTR, | 180 | r = dm_consult_userspace(lc->uuid, lc->luid, DM_ULOG_CTR, |
176 | ctr_str, str_size, NULL, NULL); | 181 | ctr_str, str_size, NULL, NULL); |
177 | 182 | ||
178 | if (r == -ESRCH) { | 183 | if (r == -ESRCH) { |
@@ -182,7 +187,7 @@ static int userspace_ctr(struct dm_dirty_log *log, struct dm_target *ti, | |||
182 | 187 | ||
183 | /* Since the region size does not change, get it now */ | 188 | /* Since the region size does not change, get it now */ |
184 | rdata_size = sizeof(rdata); | 189 | rdata_size = sizeof(rdata); |
185 | r = dm_consult_userspace(lc->uuid, DM_ULOG_GET_REGION_SIZE, | 190 | r = dm_consult_userspace(lc->uuid, lc->luid, DM_ULOG_GET_REGION_SIZE, |
186 | NULL, 0, (char *)&rdata, &rdata_size); | 191 | NULL, 0, (char *)&rdata, &rdata_size); |
187 | 192 | ||
188 | if (r) { | 193 | if (r) { |
@@ -211,7 +216,7 @@ static void userspace_dtr(struct dm_dirty_log *log) | |||
211 | int r; | 216 | int r; |
212 | struct log_c *lc = log->context; | 217 | struct log_c *lc = log->context; |
213 | 218 | ||
214 | r = dm_consult_userspace(lc->uuid, DM_ULOG_DTR, | 219 | r = dm_consult_userspace(lc->uuid, lc->luid, DM_ULOG_DTR, |
215 | NULL, 0, | 220 | NULL, 0, |
216 | NULL, NULL); | 221 | NULL, NULL); |
217 | 222 | ||
@@ -226,7 +231,7 @@ static int userspace_presuspend(struct dm_dirty_log *log) | |||
226 | int r; | 231 | int r; |
227 | struct log_c *lc = log->context; | 232 | struct log_c *lc = log->context; |
228 | 233 | ||
229 | r = dm_consult_userspace(lc->uuid, DM_ULOG_PRESUSPEND, | 234 | r = dm_consult_userspace(lc->uuid, lc->luid, DM_ULOG_PRESUSPEND, |
230 | NULL, 0, | 235 | NULL, 0, |
231 | NULL, NULL); | 236 | NULL, NULL); |
232 | 237 | ||
@@ -238,7 +243,7 @@ static int userspace_postsuspend(struct dm_dirty_log *log) | |||
238 | int r; | 243 | int r; |
239 | struct log_c *lc = log->context; | 244 | struct log_c *lc = log->context; |
240 | 245 | ||
241 | r = dm_consult_userspace(lc->uuid, DM_ULOG_POSTSUSPEND, | 246 | r = dm_consult_userspace(lc->uuid, lc->luid, DM_ULOG_POSTSUSPEND, |
242 | NULL, 0, | 247 | NULL, 0, |
243 | NULL, NULL); | 248 | NULL, NULL); |
244 | 249 | ||
@@ -251,7 +256,7 @@ static int userspace_resume(struct dm_dirty_log *log) | |||
251 | struct log_c *lc = log->context; | 256 | struct log_c *lc = log->context; |
252 | 257 | ||
253 | lc->in_sync_hint = 0; | 258 | lc->in_sync_hint = 0; |
254 | r = dm_consult_userspace(lc->uuid, DM_ULOG_RESUME, | 259 | r = dm_consult_userspace(lc->uuid, lc->luid, DM_ULOG_RESUME, |
255 | NULL, 0, | 260 | NULL, 0, |
256 | NULL, NULL); | 261 | NULL, NULL); |
257 | 262 | ||