Update copyright dates (again)
[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 #include <string.h>
29 #include <getopt.h>
30
31 extern char     *optarg;
32 extern int       optind, opterr, optopt;
33 extern int       errno;
34
35 int              Verbose;
36 char            *Progname;
37
38 extern void     err_msg(char *, ...);
39 extern void     errno_msg(char *, ...);
40
41 int             get_sessions(dm_sessid_t **, u_int *);
42 int             get_tokens(dm_sessid_t, dm_token_t **, u_int *);
43 void            print_session(dm_sessid_t);
44 void            print_tokens(dm_sessid_t);
45 void            kill_session(dm_sessid_t);
46
47 void
48 usage(char *s)
49 {
50         fprintf(stderr, "Usage: %s <options>\n", s);
51         fprintf(stderr, "\t-t   list tokens\n");
52         fprintf(stderr, "\t-l   list sessions\n");
53         fprintf(stderr, "\t-k   kill sessions\n");
54         fprintf(stderr, "\t-s   <specific_sid>\n");
55         fprintf(stderr, "\t-v   verbose (for kill)\n");
56 }
57
58 int
59 main(
60         int      argc,
61         char    *argv[])
62 {
63         int              c;
64         int              error;
65         u_int            i, nsids;
66         int              list_flag, kill_flag, token_flag, sid_flag;
67         dm_sessid_t     *sidbuf, *sidp, onesid;
68         char            *cp;
69
70
71         Progname = argv[0];
72         list_flag = sid_flag = kill_flag = token_flag = 0;
73
74         while ((c = getopt(argc, argv, "vlkts:")) != EOF) {
75                 switch (c) {
76                 case 'l':
77                         list_flag = 1;
78                         break;
79                 case 'k':
80                         kill_flag = 1;
81                         break;
82                 case 't':
83                         token_flag = 1;
84                         break;
85                 case 's':
86                         if (sscanf(optarg, "%d", &onesid) <=0 ) {
87                                 err_msg("Can't convert sid %s", optarg);
88                                 exit(2);
89                         }
90                         sid_flag = 1;
91                         break;
92                 case 'v':
93                         Verbose = 1;
94                         break;
95                 case '?':
96                 default:
97                         usage(Progname);
98                         exit(1);
99                 }
100         }
101         if (!list_flag && !sid_flag && !kill_flag && !token_flag) {
102                 usage(Progname);
103                 exit(1);
104         }
105
106         if (dm_init_service(&cp) == -1)  {
107                 err_msg("Can't init dmapi");
108                 return(1);
109         }
110         if (strcmp(cp, DM_VER_STR_CONTENTS)) {
111                 err_msg("Compiled for a different version");
112                 return(1);
113         }
114
115
116         /*
117          * Get the list of all sessions in the system
118          */
119         error = get_sessions(&sidbuf, &nsids);
120         if (error)
121                 exit(1);
122
123         /*
124          * Walk through the list of sessions do what is right
125          */
126         sidp = sidbuf;
127         for (i=0; i<nsids; i++, sidp++) {
128                 if (sid_flag) {
129                         /*
130                          * If we're only looking for one sid, then
131                          * we can skip this one if there's no match
132                          */
133                         if (onesid != *sidp)
134                                 continue;
135                 }
136                 if (list_flag)
137                         print_session(*sidp);
138                 if (token_flag)
139                         print_tokens(*sidp);
140                 if (kill_flag)
141                         kill_session(*sidp);
142         }
143         return(0);
144 }
145
146 /*
147  * Print out info about a sessions
148  */
149 void
150 print_session(dm_sessid_t sid)
151 {
152         char    buf[DM_SESSION_INFO_LEN];
153         size_t  ret;
154
155         if (dm_query_session(sid,DM_SESSION_INFO_LEN,(void *)buf, &ret) == -1) {
156                 errno_msg("Can't get session info");
157                 return;
158         }
159
160         printf("Session (%d) name: %s\n", sid, buf);
161         return;
162 }
163
164 /*
165  * Get all the tokens for a session
166  */
167 void
168 print_tokens(dm_sessid_t sid)
169 {
170         dm_token_t      *tbuf;
171         int              error;
172         u_int            i, ntokens;
173
174         error = get_tokens(sid, &tbuf, &ntokens);
175         if (error)
176                 return;
177
178         printf("\tTokens (%d): ", ntokens);
179         for (i=0; i<ntokens; i++) 
180                 printf("%d ", *tbuf++);
181
182         printf("\n");
183
184         free(tbuf);
185         return;
186 }
187
188 /*
189  * Try and kill a session
190  */
191 void
192 kill_session(dm_sessid_t sid)
193 {
194         dm_token_t      *tbuf;
195         int              error;
196         u_int            i, ntokens;
197
198         /*
199          * Get all the tokens in the system so we can respond to them
200          */
201         error = get_tokens(sid, &tbuf, &ntokens);
202         if (error)
203                 return;
204
205         if (ntokens && Verbose) 
206                 printf("\tResponding to events for sid %d, tokens: \n", sid);
207
208         for (i=0; i<ntokens; i++) {
209                 if (Verbose)
210                         printf("\t\t%d ", *tbuf);
211
212                 if (dm_respond_event(sid, *tbuf, DM_RESP_ABORT, EIO, 0, NULL) == -1) 
213                         errno_msg("Can't respond to event, sid %d token %d", 
214                                    sid, *tbuf);
215                 tbuf++;
216         }
217
218         if (Verbose)
219                 printf("\tDestroying session %d\n", sid);
220         if (dm_destroy_session(sid) == -1) 
221                 errno_msg("Can't shut down session %d", sid);
222         return;
223 }
224
225 int
226 get_sessions(
227         dm_sessid_t **sidpp,
228         u_int        *nsidp)
229 {
230         dm_sessid_t     *sidbuf;
231         int              error;
232         u_int            nsids, nret;
233
234         /*
235          * Pick an arbitrary number of sessions to get info for.
236          * If it's not enough, then we can always resize our buffer
237          */
238         error = 0;
239         nsids = 32;
240         sidbuf = malloc(nsids * sizeof(dm_sessid_t));
241         if (sidbuf == NULL) {
242                 err_msg("Can't malloc memory");
243                 error = 1;
244                 goto out;
245         }
246                 
247         if (dm_getall_sessions(nsids, sidbuf, &nret) == -1) {
248                 if (errno != E2BIG) {
249                         errno_msg("Can't get list of sessions");
250                         error = 1;
251                         goto out;
252                 }
253                 free(sidbuf);
254                 nsids = nret;
255                 sidbuf = malloc(nsids * sizeof(dm_sessid_t));
256                 if (sidbuf == NULL) {
257                         err_msg("Can't malloc memory");
258                         error = 1;
259                         goto out;
260                 }
261                 if (dm_getall_sessions(nsids, sidbuf, &nret) == -1) {
262                         if (error == -1) {
263                                 errno_msg("Can't get sessions with new buf");
264                                 error = 1;
265                                 goto out;
266                         }
267                 }
268         }
269 out:
270         if (error && (sidbuf != NULL) )
271                 free(sidbuf);
272         else {
273                 *sidpp = sidbuf;
274                 *nsidp = nret;
275         }
276         
277         return(error);
278 }
279
280
281 /*
282  * Get all tokens in the session
283  */
284 int
285 get_tokens(
286         dm_sessid_t       sid,
287         dm_token_t      **bufpp,
288         u_int            *nretp)
289 {
290         dm_token_t      *tbuf;
291         u_int            ntokens, nret;
292         int              error;
293
294         error   = 0;
295         ntokens = 1024;
296         tbuf = (dm_token_t *)malloc(ntokens * sizeof(dm_token_t));
297         if (tbuf == NULL)  
298                 goto out;
299         
300         if (dm_getall_tokens(sid, ntokens, tbuf, &nret) == -1) {
301                 if (errno != E2BIG) {
302                         errno_msg("Can't get all tokens");
303                         goto out;
304                 }
305                 free(tbuf);
306                 ntokens = nret;
307                 tbuf = (dm_token_t *)malloc(ntokens * sizeof(dm_token_t));
308                 if (tbuf == NULL)  
309                         goto out;
310                 
311                 if (dm_getall_tokens(sid, ntokens, tbuf, &nret) == -1) {
312                         errno_msg("Can't get all tokens");
313                         goto out;
314                 }
315         }
316 out:
317         if (error && (tbuf != NULL))
318                 free(tbuf);
319         else {
320                 *bufpp = tbuf;
321                 *nretp = nret;
322         }
323
324         return(error);
325 }