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