1 #define _GNU_SOURCE
2 
3 #include <stdlib.h>
4 #include <stdint.h>
5 #include <string.h>
6 #include <stdio.h>
7 
8 #include <xenctrl.h>
9 #include <xenstore.h>
10 #include <libxl.h>
11 
12 #include "init-dom-json.h"
13 
14 #define DOMNAME_PATH   "/local/domain/0/name"
15 #define DOMID_PATH     "/local/domain/0/domid"
16 
clear_domid_history(void)17 static int clear_domid_history(void)
18 {
19     int rc = 1;
20     xentoollog_logger_stdiostream *logger;
21     libxl_ctx *ctx;
22 
23     logger = xtl_createlogger_stdiostream(stderr, XTL_ERROR, 0);
24     if (!logger)
25         return 1;
26 
27     if (libxl_ctx_alloc(&ctx, LIBXL_VERSION, 0,
28                         (xentoollog_logger *)logger)) {
29         fprintf(stderr, "cannot init libxl context\n");
30         goto outlog;
31     }
32 
33     if (!libxl_clear_domid_history(ctx))
34         rc = 0;
35 
36     libxl_ctx_free(ctx);
37 
38 outlog:
39     xtl_logger_destroy((xentoollog_logger *)logger);
40     return rc;
41 }
42 
main(int argc,char ** argv)43 int main(int argc, char **argv)
44 {
45     int rc;
46     struct xs_handle *xsh = NULL;
47     xc_interface *xch = NULL;
48     char *domname_string = NULL, *domid_string = NULL,
49          *pool_path = NULL, *pool_name = NULL;
50     xc_cpupoolinfo_t *xcinfo;
51     unsigned int pool_id = 0;
52     libxl_uuid uuid;
53 
54     /* Accept 0 or 1 argument */
55     if (argc > 2) {
56         fprintf(stderr, "too many arguments\n");
57         rc = 1;
58         goto out;
59     }
60 
61     xsh = xs_open(0);
62     if (!xsh) {
63         perror("cannot open xenstore connection");
64         rc = 1;
65         goto out;
66     }
67 
68     xch = xc_interface_open(NULL, NULL, 0);
69     if (!xch) {
70         perror("xc_interface_open() failed");
71         rc = 1;
72         goto out;
73     }
74 
75     /* Sanity check: this program can only be run once. */
76     domid_string = xs_read(xsh, XBT_NULL, DOMID_PATH, NULL);
77     domname_string = xs_read(xsh, XBT_NULL, DOMNAME_PATH, NULL);
78     if (domid_string && domname_string) {
79         fprintf(stderr, "Dom0 is already set up\n");
80         rc = 0;
81         goto out;
82     }
83 
84     libxl_uuid_clear(&uuid);
85 
86     /* If UUID is supplied, parse it. */
87     if (argc == 2 && libxl_uuid_from_string(&uuid, argv[1])) {
88         fprintf(stderr, "failed to parse UUID %s\n", argv[1]);
89         rc = 1;
90         goto out;
91     }
92 
93     if (!libxl_uuid_is_nil(&uuid) &&
94         xc_domain_sethandle(xch, 0, libxl_uuid_bytearray(&uuid))) {
95         perror("failed to set Dom0 UUID");
96         rc = 1;
97         goto out;
98     }
99 
100     rc = gen_stub_json_config(0, &uuid);
101     if (rc)
102         goto out;
103 
104     rc = clear_domid_history();
105     if (rc)
106         goto out;
107 
108     /* Write xenstore entries. */
109     if (!xs_write(xsh, XBT_NULL, DOMID_PATH, "0", strlen("0"))) {
110         fprintf(stderr, "cannot set domid for Dom0\n");
111         rc = 1;
112         goto out;
113     }
114 
115     if (!xs_write(xsh, XBT_NULL, DOMNAME_PATH, "Domain-0",
116                   strlen("Domain-0"))) {
117         fprintf(stderr, "cannot set domain name for Dom0\n");
118         rc = 1;
119         goto out;
120     }
121 
122     /* Create an entry in xenstore for each cpupool on the system */
123     do {
124         xcinfo = xc_cpupool_getinfo(xch, pool_id);
125         if (xcinfo != NULL) {
126             if (xcinfo->cpupool_id != pool_id)
127                 pool_id = xcinfo->cpupool_id;
128             xc_cpupool_infofree(xch, xcinfo);
129             if (asprintf(&pool_path, "/local/pool/%d/name", pool_id) <= 0) {
130                 fprintf(stderr, "cannot allocate memory for pool path\n");
131                 rc = 1;
132                 goto out;
133             }
134             if (asprintf(&pool_name, "Pool-%d", pool_id) <= 0) {
135                 fprintf(stderr, "cannot allocate memory for pool name\n");
136                 rc = 1;
137                 goto out;
138             }
139             pool_id++;
140             if (!xs_write(xsh, XBT_NULL, pool_path, pool_name,
141                           strlen(pool_name))) {
142                 fprintf(stderr, "cannot set pool name\n");
143                 rc = 1;
144                 goto out;
145             }
146             free(pool_name);
147             free(pool_path);
148             pool_path = pool_name = NULL;
149         }
150     } while(xcinfo != NULL);
151 
152     printf("Done setting up Dom0\n");
153 
154 out:
155     free(pool_path);
156     free(pool_name);
157     free(domid_string);
158     free(domname_string);
159     xs_close(xsh);
160     xc_interface_close(xch);
161     return rc;
162 }
163 
164 /*
165  * Local variables:
166  * mode: C
167  * c-basic-offset: 4
168  * indent-tabs-mode: nil
169  * End:
170  */
171