2 * Copyright (c) 2004, 2005 Christophe Varoqui
3 * Copyright (c) 2005 Stefan Bader, IBM
4 * Copyright (c) 2005 Edward Goggin, EMC
20 merge_words (char ** dst, char * word, int space)
25 len = strlen(*dst) + strlen(word) + space;
26 *dst = REALLOC(*dst, len + 1);
41 strncpy(p, word, strlen(word) + 1);
47 * Transforms the path group vector into a proper device map string
50 assemble_map (struct multipath * mp)
56 struct pathgroup * pgp;
61 freechar = sizeof(mp->params);
63 shift = snprintf(p, freechar, "%s %s %i %i",
64 mp->features, mp->hwhandler,
65 VECTOR_SIZE(mp->pg), mp->bestpg);
67 if (shift >= freechar) {
68 fprintf(stderr, "mp->params too small\n");
74 vector_foreach_slot (mp->pg, pgp, i) {
75 pgp = VECTOR_SLOT(mp->pg, i);
76 shift = snprintf(p, freechar, " %s %i 1", mp->selector,
77 VECTOR_SIZE(pgp->paths));
78 if (shift >= freechar) {
79 fprintf(stderr, "mp->params too small\n");
85 vector_foreach_slot (pgp->paths, pp, j) {
86 int tmp_minio = minio;
88 if (mp->rr_weight == RR_WEIGHT_PRIO
90 tmp_minio = minio * pp->priority;
92 shift = snprintf(p, freechar, " %s %d",
93 pp->dev_t, tmp_minio);
94 if (shift >= freechar) {
95 fprintf(stderr, "mp->params too small\n");
103 fprintf(stderr, "mp->params too small\n");
106 snprintf(p, 1, "\n");
111 disassemble_map (vector pathvec, char * params, struct multipath * mpp)
116 int num_features = 0;
117 int num_hwhandler = 0;
121 int num_paths_args = 0;
124 struct pathgroup * pgp;
131 p += get_word(p, &mpp->features);
136 num_features = atoi(mpp->features);
138 for (i = 0; i < num_features; i++) {
139 p += get_word(p, &word);
144 if (merge_words(&mpp->features, word, 1)) {
154 p += get_word(p, &mpp->hwhandler);
159 num_hwhandler = atoi(mpp->hwhandler);
161 for (i = 0; i < num_hwhandler; i++) {
162 p += get_word(p, &word);
167 if (merge_words(&mpp->hwhandler, word, 1)) {
177 p += get_word(p, &word);
185 if (num_pg > 0 && !mpp->pg)
186 mpp->pg = vector_alloc();
193 p += get_word(p, &word);
198 mpp->nextpg = atoi(word);
201 for (i = 0; i < num_pg; i++) {
206 if (!mpp->selector) {
207 p += get_word(p, &mpp->selector);
215 p += get_word(p, &word);
220 num_pg_args = atoi(word);
222 if (merge_words(&mpp->selector, word, 1)) {
228 p += get_word(p, NULL);
229 p += get_word(p, NULL);
232 for (j = 0; j < num_pg_args; j++)
233 p += get_word(p, NULL);
238 pgp = alloc_pathgroup();
243 if (store_pathgroup(mpp->pg, pgp))
246 p += get_word(p, &word);
251 num_paths = atoi(word);
254 p += get_word(p, &word);
259 num_paths_args = atoi(word);
262 for (j = 0; j < num_paths; j++) {
264 p += get_word(p, &word);
270 pp = find_path_by_devt(pathvec, word);
278 strncpy(pp->dev_t, word, BLK_DEV_SIZE);
280 /* Only call this in multipath client mode */
281 if (!mpp->waiter && store_path(pathvec, pp))
286 if (store_path(pgp->paths, pp))
290 * Update wwid for multipaths which are not setup
291 * in the get_dm_mpvec() code path
293 if (!strlen(mpp->wwid))
294 strncpy(mpp->wwid, pp->wwid, WWID_SIZE);
297 * Update wwid for paths which may not have been
298 * active at the time the getuid callout was run
300 else if (!strlen(pp->wwid))
301 strncpy(pp->wwid, mpp->wwid, WWID_SIZE);
306 for (k = 0; k < num_paths_args; k++)
307 if (k == 0 && !strncmp(mpp->selector,
308 "round-robin", 11)) {
309 p += get_word(p, &word);
310 def_minio = atoi(word);
312 if (mpp->rr_weight == RR_WEIGHT_PRIO
314 def_minio /= pp->priority;
317 if (def_minio != mpp->minio)
318 mpp->minio = def_minio;
321 p += get_word(p, NULL);
329 free_pgvec(mpp->pg, KEEP_PATHS);
334 disassemble_status (char * params, struct multipath * mpp)
339 int num_feature_args;
340 int num_hwhandler_args;
345 struct pathgroup * pgp;
352 p += get_word(p, &word);
357 num_feature_args = atoi(word);
360 for (i = 0; i < num_feature_args; i++) {
362 p += get_word(p, &word);
367 mpp->queuedio = atoi(word);
372 p += get_word(p, NULL);
377 p += get_word(p, &word);
382 num_hwhandler_args = atoi(word);
385 for (i = 0; i < num_hwhandler_args; i++)
386 p += get_word(p, NULL);
391 p += get_word(p, &word);
402 p += get_word(p, NULL);
404 if (VECTOR_SIZE(mpp->pg) < num_pg)
407 for (i = 0; i < num_pg; i++) {
408 pgp = VECTOR_SLOT(mpp->pg, i);
412 p += get_word(p, &word);
419 pgp->status = PGSTATE_DISABLED;
422 pgp->status = PGSTATE_ACTIVE;
425 pgp->status = PGSTATE_ENABLED;
428 pgp->status = PGSTATE_UNDEF;
436 p += get_word(p, NULL);
438 p += get_word(p, &word);
443 num_paths = atoi(word);
446 p += get_word(p, &word);
451 num_pg_args = atoi(word);
454 if (VECTOR_SIZE(pgp->paths) < num_paths)
457 for (j = 0; j < num_paths; j++) {
458 pp = VECTOR_SLOT(pgp->paths, j);
462 p += get_word(p, NULL);
467 p += get_word(p, &word);
474 pp->dmstate = PSTATE_FAILED;
477 pp->dmstate = PSTATE_ACTIVE;
486 p += get_word(p, &word);
491 pp->failcount = atoi(word);
497 for (k = 0; k < num_pg_args; k++)
498 p += get_word(p, NULL);