1 /*
2 * Copyright (c) 2017 Oracle and/or its affiliates. All rights reserved.
3 */
4
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <err.h>
8 #include <errno.h>
9 #include <unistd.h>
10 #include <string.h>
11 #include <xenctrl.h>
12
13 #include <xen/errno.h>
14 #include <xen-tools/libs.h>
15
16 static xc_interface *xch;
17
show_help(void)18 void show_help(void)
19 {
20 fprintf(stderr,
21 "xen-diag: xen diagnostic utility\n"
22 "Usage: xen-diag command [args]\n"
23 "Commands:\n"
24 " help display this help\n"
25 " gnttab_query_size <domid> dump the current and max grant frames for <domid>\n");
26 }
27
28 /* wrapper function */
help_func(int argc,char * argv[])29 static int help_func(int argc, char *argv[])
30 {
31 show_help();
32 return 0;
33 }
34
gnttab_query_size_func(int argc,char * argv[])35 static int gnttab_query_size_func(int argc, char *argv[])
36 {
37 int domid, rc = 1;
38 struct gnttab_query_size query;
39
40 if ( argc != 1 )
41 {
42 show_help();
43 return rc;
44 }
45
46 domid = strtol(argv[0], NULL, 10);
47 query.dom = domid;
48 rc = xc_gnttab_query_size(xch, &query);
49
50 if ( rc == 0 && (query.status == GNTST_okay) )
51 printf("domid=%d: nr_frames=%d, max_nr_frames=%d\n",
52 query.dom, query.nr_frames, query.max_nr_frames);
53
54 return rc == 0 && (query.status == GNTST_okay) ? 0 : 1;
55 }
56
57 struct {
58 const char *name;
59 int (*function)(int argc, char *argv[]);
60 } main_options[] = {
61 { "help", help_func },
62 { "gnttab_query_size", gnttab_query_size_func},
63 };
64
main(int argc,char * argv[])65 int main(int argc, char *argv[])
66 {
67 int ret, i;
68
69 /*
70 * Set stdout to be unbuffered to avoid having to fflush when
71 * printing without a newline.
72 */
73 setvbuf(stdout, NULL, _IONBF, 0);
74
75 if ( argc <= 1 )
76 {
77 show_help();
78 return 0;
79 }
80
81 for ( i = 0; i < ARRAY_SIZE(main_options); i++ )
82 if ( !strncmp(main_options[i].name, argv[1], strlen(argv[1])) )
83 break;
84
85 if ( i == ARRAY_SIZE(main_options) )
86 {
87 show_help();
88 return 0;
89 }
90 else
91 {
92 xch = xc_interface_open(0, 0, 0);
93 if ( !xch )
94 {
95 fprintf(stderr, "failed to get the handler\n");
96 return 0;
97 }
98
99 ret = main_options[i].function(argc - 2, argv + 2);
100
101 xc_interface_close(xch);
102 }
103
104 /*
105 * Exitcode 0 for success.
106 * Exitcode 1 for an error.
107 * Exitcode 2 if the operation should be retried for any reason (e.g. a
108 * timeout or because another operation was in progress).
109 */
110
111 #define EXIT_TIMEOUT (EXIT_FAILURE + 1)
112
113 BUILD_BUG_ON(EXIT_SUCCESS != 0);
114 BUILD_BUG_ON(EXIT_FAILURE != 1);
115 BUILD_BUG_ON(EXIT_TIMEOUT != 2);
116
117 switch ( ret )
118 {
119 case 0:
120 return EXIT_SUCCESS;
121 case EAGAIN:
122 case EBUSY:
123 return EXIT_TIMEOUT;
124 default:
125 return EXIT_FAILURE;
126 }
127 }
128