multipath-tools: Introducing multipath C API
[multipath-tools/.git] / libdmmp / libdmmp_path.c
1 /*
2  * Copyright (C) 2015 - 2016 Red Hat, Inc.
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  *
17  * Author: Gris Ge <fge@redhat.com>
18  *         Todd Gill <tgill@redhat.com>
19  */
20
21 #include <stdlib.h>
22 #include <inttypes.h>
23 #include <string.h>
24 #include <assert.h>
25 #include <json.h>
26
27 #include "libdmmp/libdmmp.h"
28 #include "libdmmp_private.h"
29
30 #define _DMMP_SHOW_PS_INDEX_BLK_NAME    0
31 #define _DMMP_SHOW_PS_INDEX_SATAUS      1
32 #define _DMMP_SHOW_PS_INDEX_WWID        2
33 #define _DMMP_SHOW_PS_INDEX_PGID        3
34
35 struct dmmp_path {
36         char *blk_name;
37         uint32_t status;
38 };
39
40 static const struct _num_str_conv _DMMP_PATH_STATUS_CONV[] = {
41         {DMMP_PATH_STATUS_UNKNOWN, "undef"},
42         {DMMP_PATH_STATUS_UP, "ready"},
43         {DMMP_PATH_STATUS_DOWN, "faulty"},
44         {DMMP_PATH_STATUS_SHAKY, "shaky"},
45         {DMMP_PATH_STATUS_GHOST, "ghost"},
46         {DMMP_PATH_STATUS_PENDING, "i/o pending"},
47         {DMMP_PATH_STATUS_TIMEOUT, "i/o timeout"},
48         {DMMP_PATH_STATUS_DELAYED, "delayed"},
49 };
50
51 _dmmp_str_func_gen(dmmp_path_status_str, uint32_t, path_status,
52                    _DMMP_PATH_STATUS_CONV);
53 _dmmp_str_conv_func_gen(_dmmp_path_status_str_conv, ctx, path_status_str,
54                         uint32_t, DMMP_PATH_STATUS_UNKNOWN,
55                         _DMMP_PATH_STATUS_CONV);
56
57 _dmmp_getter_func_gen(dmmp_path_blk_name_get, struct dmmp_path, dmmp_p,
58                       blk_name, const char *);
59 _dmmp_getter_func_gen(dmmp_path_status_get, struct dmmp_path, dmmp_p,
60                       status, uint32_t);
61
62 struct dmmp_path *_dmmp_path_new(void)
63 {
64         struct dmmp_path *dmmp_p = NULL;
65
66         dmmp_p = (struct dmmp_path *) malloc(sizeof(struct dmmp_path));
67
68         if (dmmp_p != NULL) {
69                 dmmp_p->blk_name = NULL;
70                 dmmp_p->status = DMMP_PATH_STATUS_UNKNOWN;
71         }
72         return dmmp_p;
73 }
74
75 int _dmmp_path_update(struct dmmp_context *ctx, struct dmmp_path *dmmp_p,
76                       json_object *j_obj_p)
77 {
78         int rc = DMMP_OK;
79         const char *blk_name = NULL;
80         const char *status_str = NULL;
81
82         assert(ctx != NULL);
83         assert(dmmp_p != NULL);
84         assert(j_obj_p != NULL);
85
86         _json_obj_get_value(ctx, j_obj_p, blk_name, "dev",
87                             json_type_string, json_object_get_string, rc, out);
88         _json_obj_get_value(ctx, j_obj_p, status_str, "chk_st",
89                             json_type_string, json_object_get_string, rc, out);
90
91         _dmmp_null_or_empty_str_check(ctx, blk_name, rc, out);
92         _dmmp_null_or_empty_str_check(ctx, status_str, rc, out);
93
94         dmmp_p->blk_name = strdup(blk_name);
95         _dmmp_alloc_null_check(ctx, dmmp_p->blk_name, rc, out);
96
97         dmmp_p->status = _dmmp_path_status_str_conv(ctx, status_str);
98
99         _debug(ctx, "Got path blk_name: '%s'", dmmp_p->blk_name);
100         _debug(ctx, "Got path status: %s(%" PRIu32 ")",
101                dmmp_path_status_str(dmmp_p->status), dmmp_p->status);
102
103 out:
104         if (rc != DMMP_OK)
105                 _dmmp_path_free(dmmp_p);
106         return rc;
107 }
108
109 void _dmmp_path_free(struct dmmp_path *dmmp_p)
110 {
111         if (dmmp_p == NULL)
112                 return;
113         free(dmmp_p->blk_name);
114         free(dmmp_p);
115 }