alua: Handle LBA_DEPENDENT state
[multipath-tools/.git] / libmultipath / prioritizers / weightedpath.c
1 /*
2  *
3  *  (C)  Copyright 2008 Hewlett-Packard Development Company, L.P
4  *
5  *  This file is released under the GPL
6  */
7
8 /*
9  * Prioritizer for device mapper multipath, where specific paths and the
10  * corresponding priority values are provided as arguments.
11  *
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.
17  *
18  * Examples:
19  *      prio            "weightedpath hbtl 1:.:.:. 2 4:.:.:. 4"
20  *      prio            "weightedpath devname sda 10 sde 20"
21  *
22  * Returns zero as the default priority.
23  */
24
25 #include <stdio.h>
26 #include <string.h>
27
28 #include <prio.h>
29 #include "weightedpath.h"
30 #include <config.h>
31 #include <structs.h>
32 #include <memory.h>
33 #include <debug.h>
34 #include <regex.h>
35
36 char *get_next_string(char **temp, char *split_char)
37 {
38         char *token = NULL;
39         token = strsep(temp, split_char);
40         while (token != NULL && !strcmp(token, ""))
41                 token = strsep(temp, split_char);
42         return token;
43 }
44
45 /* main priority routine */
46 int prio_path_weight(struct path *pp, char *prio_args)
47 {
48         char path[FILE_NAME_SIZE];
49         char *arg;
50         char *temp, *regex, *prio;
51         char split_char[] = " \t";
52         int priority = DEFAULT_PRIORITY, path_found = 0;
53         regex_t pathe;
54
55         /* Return default priority if there is no argument */
56         if (!prio_args)
57                 return priority;
58
59         arg = temp = STRDUP(prio_args);
60
61         regex = get_next_string(&temp, split_char);
62
63         if (!strcmp(regex, HBTL)) {
64                 sprintf(path, "%d:%d:%d:%d", pp->sg_id.host_no,
65                         pp->sg_id.channel, pp->sg_id.scsi_id, pp->sg_id.lun);
66         } else if (!strcmp(regex, DEV_NAME)) {
67                 strcpy(path, pp->dev);
68         } else {
69                 condlog(0, "%s: %s - Invalid arguments", pp->dev,
70                         pp->prio->name);
71                 return priority;
72         }
73
74         while (!path_found) {
75                 if (!temp)
76                         break;
77                 if (!(regex = get_next_string(&temp, split_char)))
78                         break;
79                 if (!(prio = get_next_string(&temp, split_char)))
80                         break;
81
82                 if (!regcomp(&pathe, regex, REG_EXTENDED|REG_NOSUB)) {
83                         if (!regexec(&pathe, path, 0, NULL, 0)) {
84                                 path_found = 1;
85                                 priority = atoi(prio);
86                         }
87                         regfree(&pathe);
88                 }
89         }
90
91         FREE(arg);
92         return priority;
93 }
94
95 int getprio(struct path *pp, char *args)
96 {
97         return prio_path_weight(pp, args);
98 }
99