3 * (C) Copyright 2008 Hewlett-Packard Development Company, L.P
5 * This file is released under the GPL
9 * Prioritizer for device mapper multipath, where specific paths and the
10 * corresponding priority values are provided as arguments.
12 * This prioritizer assigns the priority value provided in the configuration
13 * file based on the comparison made between the specified paths and the path
14 * instance for which this is called.
15 * Paths can be specified as a regular expression of devname of the path or
16 * as hbtl information of the path.
19 * prio "weightedpath hbtl 1:.:.:. 2 4:.:.:. 4"
20 * prio "weightedpath devname sda 10 sde 20"
22 * Returns zero as the default priority.
29 #include "weightedpath.h"
34 #include "structs_vec.h"
40 build_serial_path(struct path *pp, struct strbuf *buf)
42 int rc = snprint_path_serial(buf, pp);
44 return rc < 0 ? rc : 0;
48 build_wwn_path(struct path *pp, struct strbuf *buf)
52 if ((rc = snprint_host_wwnn(buf, pp)) < 0 ||
53 (rc = fill_strbuf(buf, ':', 1)) < 0 ||
54 (rc = snprint_host_wwpn(buf, pp)) < 0 ||
55 (rc = fill_strbuf(buf, ':', 1)) < 0 ||
56 (rc = snprint_tgt_wwnn(buf, pp) < 0) ||
57 (rc = fill_strbuf(buf, ':', 1) < 0) ||
58 (rc = snprint_tgt_wwpn(buf, pp) < 0))
63 /* main priority routine */
64 int prio_path_weight(struct path *pp, char *prio_args)
66 STRBUF_ON_STACK(path);
67 char *arg __attribute__((cleanup(cleanup_charp))) = NULL;
68 char *temp, *regex, *prio;
69 char split_char[] = " \t";
70 int priority = DEFAULT_PRIORITY, path_found = 0;
73 /* Return default priority if there is no argument */
77 arg = strdup(prio_args);
80 regex = get_next_string(&temp, split_char);
82 /* Return default priority if the argument is not parseable */
87 if (!strcmp(regex, HBTL)) {
88 if (print_strbuf(&path, "%d:%d:%d:%" PRIu64, pp->sg_id.host_no,
89 pp->sg_id.channel, pp->sg_id.scsi_id,
92 } else if (!strcmp(regex, DEV_NAME)) {
93 if (append_strbuf_str(&path, pp->dev) < 0)
95 } else if (!strcmp(regex, SERIAL)) {
96 if (build_serial_path(pp, &path) != 0)
98 } else if (!strcmp(regex, WWN)) {
99 if (build_wwn_path(pp, &path) != 0)
102 condlog(0, "%s: %s - Invalid arguments", pp->dev,
107 while (!path_found) {
110 if (!(regex = get_next_string(&temp, split_char)))
112 if (!(prio = get_next_string(&temp, split_char)))
115 if (!regcomp(&pathe, regex, REG_EXTENDED|REG_NOSUB)) {
116 if (!regexec(&pathe, get_strbuf_str(&path), 0,
119 priority = atoi(prio);
128 int getprio(struct path *pp, char *args)
130 return prio_path_weight(pp, args);