4b02eb5c347c47190094a9e36bdc5b55095e46a5
[xfstests-dev.git] / dmapi / src / sample_hsm / mrmean.c
1 /*
2  * Simple Mr. Mean that can manipulate and torch sessions
3  *
4  * This code was written by Peter Lawthers, and placed in the public
5  * domain for use by DMAPI implementors and app writers.
6  *
7  * Standard disclaimer:
8  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
9  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
10  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
11  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE
12  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
13  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
14  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
15  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
16  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
17  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
18  * SUCH DAMAGE.
19  */
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <sys/types.h>
24 #include <sys/errno.h>
25
26 #include <lib/dmport.h>
27
28 extern char     *optarg;
29 extern int       optind, opterr, optopt;
30 extern int       errno;
31
32 int              Verbose;
33 char            *Progname;
34
35 extern void     err_msg(char *, ...);
36 extern void     errno_msg(char *, ...);
37
38 int             get_sessions(dm_sessid_t **, u_int *);
39 int             get_tokens(dm_sessid_t, dm_token_t **, u_int *);
40 void            print_session(dm_sessid_t);
41 void            print_tokens(dm_sessid_t);
42 void            kill_session(dm_sessid_t);
43
44 void
45 usage(char *s)
46 {
47         fprintf(stderr, "Usage: %s <options>\n", s);
48         fprintf(stderr, "\t-t   list tokens\n");
49         fprintf(stderr, "\t-l   list sessions\n");
50         fprintf(stderr, "\t-k   kill sessions\n");
51         fprintf(stderr, "\t-s   <specific_sid>\n");
52         fprintf(stderr, "\t-v   verbose (for kill)\n");
53 }
54
55 int
56 main(
57         int      argc,
58         char    *argv[])
59 {
60         int              c;
61         int              error;
62         u_int            i, nsids;
63         int              list_flag, kill_flag, token_flag, sid_flag;
64         dm_sessid_t     *sidbuf, *sidp, onesid;
65         char            *cp;
66
67
68         Progname = argv[0];
69         list_flag = sid_flag = kill_flag = token_flag = 0;
70
71         while ((c = getopt(argc, argv, "vlkts:")) != EOF) {
72                 switch (c) {
73                 case 'l':
74                         list_flag = 1;
75                         break;
76                 case 'k':
77                         kill_flag = 1;
78                         break;
79                 case 't':
80                         token_flag = 1;
81                         break;
82                 case 's':
83                         if (sscanf(optarg, "%d", &onesid) <=0 ) {
84                                 err_msg("Can't convert sid %s", optarg);
85                                 exit(2);
86                         }
87                         sid_flag = 1;
88                         break;
89                 case 'v':
90                         Verbose = 1;
91                         break;
92                 case '?':
93                 default:
94                         usage(Progname);
95                         exit(1);
96                 }
97         }
98         if (!list_flag && !sid_flag && !kill_flag && !token_flag) {
99                 usage(Progname);
100                 exit(1);
101         }
102
103         if (dm_init_service(&cp) == -1)  {
104                 err_msg("Can't init dmapi");
105                 return(1);
106         }
107         if (strcmp(cp, DM_VER_STR_CONTENTS)) {
108                 err_msg("Compiled for a different version");
109                 return(1);
110         }
111
112
113         /*
114          * Get the list of all sessions in the system
115          */
116         error = get_sessions(&sidbuf, &nsids);
117         if (error)
118                 exit(1);
119
120         /*
121          * Walk through the list of sessions do what is right
122          */
123         sidp = sidbuf;
124         for (i=0; i<nsids; i++, sidp++) {
125                 if (sid_flag) {
126                         /*
127                          * If we're only looking for one sid, then
128                          * we can skip this one if there's no match
129                          */
130                         if (onesid != *sidp)
131                                 continue;
132                 }
133                 if (list_flag)
134                         print_session(*sidp);
135                 if (token_flag)
136                         print_tokens(*sidp);
137                 if (kill_flag)
138                         kill_session(*sidp);
139         }
140         return(0);
141 }
142
143 /*
144  * Print out info about a sessions
145  */
146 void
147 print_session(dm_sessid_t sid)
148 {
149         char    buf[DM_SESSION_INFO_LEN];
150         size_t  ret;
151
152         if (dm_query_session(sid,DM_SESSION_INFO_LEN,(void *)buf, &ret) == -1) {
153                 errno_msg("Can't get session info");
154                 return;
155         }
156
157         printf("Session (%d) name: %s\n", sid, buf);
158         return;
159 }
160
161 /*
162  * Get all the tokens for a session
163  */
164 void
165 print_tokens(dm_sessid_t sid)
166 {
167         dm_token_t      *tbuf;
168         int              error;
169         u_int            i, ntokens;
170
171         error = get_tokens(sid, &tbuf, &ntokens);
172         if (error)
173                 return;
174
175         printf("\tTokens (%d): ", ntokens);
176         for (i=0; i<ntokens; i++) 
177                 printf("%d ", *tbuf++);
178
179         printf("\n");
180
181         free(tbuf);
182         return;
183 }
184
185 /*
186  * Try and kill a session
187  */
188 void
189 kill_session(dm_sessid_t sid)
190 {
191         dm_token_t      *tbuf;
192         int              error;
193         u_int            i, ntokens;
194
195         /*
196          * Get all the tokens in the system so we can respond to them
197          */
198         error = get_tokens(sid, &tbuf, &ntokens);
199         if (error)
200                 return;
201
202         if (ntokens && Verbose) 
203                 printf("\tResponding to events for sid %d, tokens: \n", sid);
204
205         for (i=0; i<ntokens; i++) {
206                 if (Verbose)
207                         printf("\t\t%d ", *tbuf);
208
209                 if (dm_respond_event(sid, *tbuf, DM_RESP_ABORT, EIO, 0, NULL) == -1) 
210                         errno_msg("Can't respond to event, sid %d token %d", 
211                                    sid, *tbuf);
212                 tbuf++;
213         }
214
215         if (Verbose)
216                 printf("\tDestroying session %d\n", sid);
217         if (dm_destroy_session(sid) == -1) 
218                 errno_msg("Can't shut down session %d", sid);
219         return;
220 }
221
222 int
223 get_sessions(
224         dm_sessid_t **sidpp,
225         u_int        *nsidp)
226 {
227         dm_sessid_t     *sidbuf;
228         int              more, error;
229         u_int            nsids, nret;
230
231         /*
232          * Pick an arbitrary number of sessions to get info for.
233          * If it's not enough, then we can always resize our buffer
234          */
235         error = 0;
236         nsids = 32;
237         sidbuf = malloc(nsids * sizeof(dm_sessid_t));
238         if (sidbuf == NULL) {
239                 err_msg("Can't malloc memory");
240                 error = 1;
241                 goto out;
242         }
243                 
244         if (dm_getall_sessions(nsids, sidbuf, &nret) == -1) {
245                 if (errno != E2BIG) {
246                         errno_msg("Can't get list of sessions");
247                         error = 1;
248                         goto out;
249                 }
250                 free(sidbuf);
251                 nsids = nret;
252                 sidbuf = malloc(nsids * sizeof(dm_sessid_t));
253                 if (sidbuf == NULL) {
254                         err_msg("Can't malloc memory");
255                         error = 1;
256                         goto out;
257                 }
258                 if (dm_getall_sessions(nsids, sidbuf, &nret) == -1) {
259                         if (error == -1) {
260                                 errno_msg("Can't get sessions with new buf");
261                                 error = 1;
262                                 goto out;
263                         }
264                 }
265         }
266 out:
267         if (error && (sidbuf != NULL) )
268                 free(sidbuf);
269         else {
270                 *sidpp = sidbuf;
271                 *nsidp = nret;
272         }
273         
274         return(error);
275 }
276
277
278 /*
279  * Get all tokens in the session
280  */
281 int
282 get_tokens(
283         dm_sessid_t       sid,
284         dm_token_t      **bufpp,
285         u_int            *nretp)
286 {
287         dm_token_t      *tbuf;
288         u_int            ntokens, nret;
289         int              error;
290
291         error   = 0;
292         ntokens = 1024;
293         tbuf = (dm_token_t *)malloc(ntokens * sizeof(dm_token_t));
294         if (tbuf == NULL)  
295                 goto out;
296         
297         if (dm_getall_tokens(sid, ntokens, tbuf, &nret) == -1) {
298                 if (errno != E2BIG) {
299                         errno_msg("Can't get all tokens");
300                         goto out;
301                 }
302                 free(tbuf);
303                 ntokens = nret;
304                 tbuf = (dm_token_t *)malloc(ntokens * sizeof(dm_token_t));
305                 if (tbuf == NULL)  
306                         goto out;
307                 
308                 if (dm_getall_tokens(sid, ntokens, tbuf, &nret) == -1) {
309                         errno_msg("Can't get all tokens");
310                         goto out;
311                 }
312         }
313 out:
314         if (error && (tbuf != NULL))
315                 free(tbuf);
316         else {
317                 *bufpp = tbuf;
318                 *nretp = nret;
319         }
320
321         return(error);
322 }