debuggers.hg

annotate tools/misc/xen-hptool.c @ 22848:6341fe0f4e5a

Added tag 4.1.0-rc2 for changeset 9dca60d88c63
author Keir Fraser <keir@xen.org>
date Tue Jan 25 14:06:55 2011 +0000 (2011-01-25)
parents c3b5924919e3
children
rev   line source
keir@21255 1 #include <xenctrl.h>
keir@21255 2 #include <xc_private.h>
keir@21255 3 #include <xc_core.h>
keir@21475 4 #include <errno.h>
keir@22799 5 #include <unistd.h>
keir@21255 6
keir@21255 7 #define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
keir@21255 8
keir@21529 9 static xc_interface *xch;
keir@21255 10
keir@21255 11 void show_help(void)
keir@21255 12 {
keir@21255 13 fprintf(stderr,
keir@21475 14 "xen-hptool: Xen CPU/memory hotplug tool\n"
keir@21475 15 "Usage: xen-hptool <command> [args]\n"
keir@21475 16 "Commands:\n"
keir@21475 17 " help display this help\n"
keir@21475 18 " cpu-online <cpuid> online CPU <cpuid>\n"
keir@21475 19 " cpu-offline <cpuid> offline CPU <cpuid>\n"
keir@21475 20 " mem-online <mfn> online MEMORY <mfn>\n"
keir@21475 21 " mem-offline <mfn> offline MEMORY <mfn>\n"
keir@21475 22 " mem-status <mfn> query Memory status<mfn>\n"
keir@21255 23 );
keir@21255 24 }
keir@21255 25
keir@21255 26 /* wrapper function */
keir@21255 27 static int help_func(int argc, char *argv[])
keir@21255 28 {
keir@21255 29 show_help();
keir@21255 30 return 0;
keir@21255 31 }
keir@21255 32
keir@21255 33 static int hp_mem_online_func(int argc, char *argv[])
keir@21255 34 {
keir@21255 35 uint32_t status;
keir@21255 36 int ret;
keir@21255 37 unsigned long mfn;
keir@21255 38
keir@21255 39 if (argc != 1)
keir@21255 40 {
keir@21255 41 show_help();
keir@21255 42 return -1;
keir@21255 43 }
keir@21255 44
keir@21255 45 sscanf(argv[0], "%lx", &mfn);
keir@21255 46 printf("Prepare to online MEMORY mfn %lx\n", mfn);
keir@21255 47
keir@21529 48 ret = xc_mark_page_online(xch, mfn, mfn, &status);
keir@21255 49
keir@21255 50 if (ret < 0)
keir@21255 51 fprintf(stderr, "Onlining page mfn %lx failed, error %x", mfn, ret);
keir@21255 52 else if (status & (PG_ONLINE_FAILED |PG_ONLINE_BROKEN)) {
keir@21255 53 fprintf(stderr, "Onlining page mfn %lx is broken, "
keir@21255 54 "Memory online failed\n", mfn);
keir@21255 55 ret = -1;
keir@21255 56 }
keir@21255 57 else if (status & PG_ONLINE_ONLINED)
keir@21255 58 printf("Memory mfn %lx onlined successfully\n", mfn);
keir@21255 59 else
keir@21255 60 printf("Memory is already onlined!\n");
keir@21255 61
keir@21255 62 return ret;
keir@21255 63 }
keir@21255 64
keir@21255 65 static int hp_mem_query_func(int argc, char *argv[])
keir@21255 66 {
keir@21255 67 uint32_t status;
keir@21255 68 int ret;
keir@21255 69 unsigned long mfn;
keir@21255 70
keir@21255 71 if (argc != 1)
keir@21255 72 {
keir@21255 73 show_help();
keir@21255 74 return -1;
keir@21255 75 }
keir@21255 76
keir@21255 77 sscanf(argv[0], "%lx", &mfn);
keir@21255 78 printf("Querying MEMORY mfn %lx status\n", mfn);
keir@21529 79 ret = xc_query_page_offline_status(xch, mfn, mfn, &status);
keir@21255 80
keir@21255 81 if (ret < 0)
keir@21255 82 fprintf(stderr, "Querying page mfn %lx failed, error %x", mfn, ret);
keir@21255 83 else
keir@21255 84 {
keir@21255 85 printf("Memory Status %x: [", status);
keir@21255 86 if ( status & PG_OFFLINE_STATUS_OFFLINE_PENDING)
keir@21255 87 printf(" PAGE_OFFLINE_PENDING ");
keir@21255 88 if ( status & PG_OFFLINE_STATUS_BROKEN )
keir@21255 89 printf(" PAGE_BROKEND ");
keir@21255 90 if ( status & PG_OFFLINE_STATUS_OFFLINED )
keir@21255 91 printf(" PAGE_OFFLINED ");
keir@21255 92 else
keir@21255 93 printf(" PAGE_ONLINED ");
keir@21255 94 printf("]\n");
keir@21255 95 }
keir@21255 96
keir@21255 97 return ret;
keir@21255 98 }
keir@21255 99
keir@21255 100 extern int xs_suspend_evtchn_port(int domid);
keir@21255 101
ian@22624 102 static int suspend_guest(xc_interface *xch, xc_evtchn *xce, int domid, int *evtchn)
keir@21255 103 {
keir@21255 104 int port, rc, suspend_evtchn = -1;
keir@21255 105
keir@21255 106 if (!evtchn)
keir@21255 107 return -1;
keir@21255 108
keir@21255 109 port = xs_suspend_evtchn_port(domid);
keir@21255 110 if (port < 0)
keir@21255 111 {
keir@21255 112 fprintf(stderr, "DOM%d: No suspend port, try live migration\n", domid);
keir@21255 113 goto failed;
keir@21255 114 }
keir@21529 115 suspend_evtchn = xc_suspend_evtchn_init(xch, xce, domid, port);
keir@21255 116 if (suspend_evtchn < 0)
keir@21255 117 {
keir@21255 118 fprintf(stderr, "Suspend evtchn initialization failed\n");
keir@21255 119 goto failed;
keir@21255 120 }
keir@21255 121 *evtchn = suspend_evtchn;
keir@21255 122
keir@21255 123 rc = xc_evtchn_notify(xce, suspend_evtchn);
keir@21255 124 if (rc < 0)
keir@21255 125 {
keir@21255 126 fprintf(stderr, "Failed to notify suspend channel: errno %d\n", rc);
keir@21255 127 goto failed;
keir@21255 128 }
keir@21529 129 if (xc_await_suspend(xch, xce, suspend_evtchn) < 0)
keir@21255 130 {
keir@21255 131 fprintf(stderr, "Suspend Failed\n");
keir@21255 132 goto failed;
keir@21255 133 }
keir@21255 134 return 0;
keir@21255 135
keir@21255 136 failed:
keir@21255 137 if (suspend_evtchn != -1)
keir@21529 138 xc_suspend_evtchn_release(xch, xce, domid, suspend_evtchn);
keir@21255 139
keir@21255 140 return -1;
keir@21255 141 }
keir@21255 142
keir@21255 143 static int hp_mem_offline_func(int argc, char *argv[])
keir@21255 144 {
keir@21255 145 uint32_t status, domid;
keir@21255 146 int ret;
keir@21255 147 unsigned long mfn;
keir@21255 148
keir@21255 149 if (argc != 1)
keir@21255 150 {
keir@21255 151 show_help();
keir@21255 152 return -1;
keir@21255 153 }
keir@21255 154
keir@21255 155 sscanf(argv[0], "%lx", &mfn);
keir@21255 156 printf("Prepare to offline MEMORY mfn %lx\n", mfn);
keir@21529 157 ret = xc_mark_page_offline(xch, mfn, mfn, &status);
keir@21255 158 if (ret < 0) {
keir@21255 159 fprintf(stderr, "Offlining page mfn %lx failed, error %x\n", mfn, ret);
keir@21255 160 if (status & (PG_OFFLINE_XENPAGE | PG_OFFLINE_FAILED))
keir@21255 161 fprintf(stderr, "XEN_PAGE is not permitted be offlined\n");
keir@21255 162 else if (status & (PG_OFFLINE_FAILED | PG_OFFLINE_NOT_CONV_RAM))
keir@21255 163 fprintf(stderr, "RESERVED RAM is not permitted to be offlined\n");
keir@21255 164 }
keir@21255 165 else
keir@21255 166 {
keir@21255 167 switch(status & PG_OFFLINE_STATUS_MASK)
keir@21255 168 {
keir@21255 169 case PG_OFFLINE_OFFLINED:
keir@21255 170 {
keir@21255 171 printf("Memory mfn %lx offlined successfully, current state is"
keir@21255 172 " [PG_OFFLINE_OFFLINED]\n", mfn);
keir@21255 173 if (status & PG_OFFLINE_BROKEN)
keir@21255 174 printf("And this offlined PAGE is already marked broken"
keir@21255 175 " before!\n");
keir@21255 176 break;
keir@21255 177 }
keir@21255 178 case PG_OFFLINE_FAILED:
keir@21255 179 {
keir@21255 180 fprintf(stderr, "Memory mfn %lx offline failed\n", mfn);
keir@21255 181 if ( status & PG_OFFLINE_ANONYMOUS)
keir@21255 182 fprintf(stderr, "the memory is an anonymous page!\n");
keir@21255 183 ret = -1;
keir@21255 184 break;
keir@21255 185 }
keir@21255 186 case PG_OFFLINE_PENDING:
keir@21255 187 {
keir@21255 188 if (status & PG_OFFLINE_XENPAGE) {
keir@21255 189 ret = -1;
keir@21255 190 fprintf(stderr, "Memory mfn %lx offlined succssefully,"
keir@21255 191 "this page is xen page, current state is"
keir@21255 192 " [PG_OFFLINE_PENDING, PG_OFFLINE_XENPAGE]\n", mfn);
keir@21255 193 }
keir@21255 194 else if (status & PG_OFFLINE_OWNED)
keir@21255 195 {
ian@22624 196 int result, suspend_evtchn = -1;
ian@22624 197 xc_evtchn *xce;
ian@22624 198 xce = xc_evtchn_open(NULL, 0);
keir@21255 199
ian@22624 200 if (xce == NULL)
keir@21255 201 {
keir@21255 202 fprintf(stderr, "When exchange page, fail"
keir@21255 203 " to open evtchn\n");
keir@21255 204 return -1;
keir@21255 205 }
keir@21255 206
keir@21255 207 domid = status >> PG_OFFLINE_OWNER_SHIFT;
keir@21529 208 if (suspend_guest(xch, xce, domid, &suspend_evtchn))
keir@21255 209 {
keir@21255 210 fprintf(stderr, "Failed to suspend guest %d for"
keir@21255 211 " mfn %lx\n", domid, mfn);
keir@21255 212 xc_evtchn_close(xce);
keir@21255 213 return -1;
keir@21255 214 }
keir@21255 215
keir@21529 216 result = xc_exchange_page(xch, domid, mfn);
keir@21255 217
keir@21255 218 /* Exchange page successfully */
keir@21255 219 if (result == 0)
keir@21255 220 printf("Memory mfn %lx offlined successfully, this "
keir@21255 221 "page is DOM%d page and being swapped "
keir@21255 222 "successfully, current state is "
keir@21255 223 "[PG_OFFLINE_OFFLINED, PG_OFFLINE_OWNED]\n",
keir@21255 224 mfn, domid);
keir@21255 225 else {
keir@21255 226 ret = -1;
keir@21255 227 fprintf(stderr, "Memory mfn %lx offlined successfully"
keir@21255 228 " , this page is DOM%d page yet failed to be "
keir@21255 229 "exchanged. current state is "
keir@21255 230 "[PG_OFFLINE_PENDING, PG_OFFLINE_OWNED]\n",
keir@21255 231 mfn, domid);
keir@21255 232 }
keir@21529 233 xc_domain_resume(xch, domid, 1);
keir@21529 234 xc_suspend_evtchn_release(xch, xce, domid, suspend_evtchn);
keir@21255 235 xc_evtchn_close(xce);
keir@21255 236 }
keir@21255 237 break;
keir@21255 238 }
keir@21255 239 }//end of switch
keir@21255 240 }//end of if
keir@21255 241
keir@21255 242 return ret;
keir@21255 243 }
keir@21255 244
keir@22799 245 static int exec_cpu_hp_fn(int (*hp_fn)(xc_interface *, int), int cpu)
keir@22799 246 {
keir@22799 247 int ret;
keir@22799 248
keir@22799 249 for ( ; ; )
keir@22799 250 {
keir@22799 251 ret = (*hp_fn)(xch, cpu);
keir@22799 252 if ( (ret >= 0) || (errno != EBUSY) )
keir@22799 253 break;
keir@22799 254 usleep(100000); /* 100ms */
keir@22799 255 }
keir@22799 256
keir@22799 257 return ret;
keir@22799 258 }
keir@21255 259
keir@21255 260 static int hp_cpu_online_func(int argc, char *argv[])
keir@21255 261 {
keir@21255 262 int cpu, ret;
keir@21255 263
keir@21475 264 if ( argc != 1 )
keir@21255 265 {
keir@21255 266 show_help();
keir@21255 267 return -1;
keir@21255 268 }
keir@21255 269
keir@21255 270 cpu = atoi(argv[0]);
keir@21255 271 printf("Prepare to online CPU %d\n", cpu);
keir@22799 272 ret = exec_cpu_hp_fn(xc_cpu_online, cpu);
keir@21255 273 if (ret < 0)
keir@21475 274 fprintf(stderr, "CPU %d online failed (error %d: %s)\n",
keir@21475 275 cpu, errno, strerror(errno));
keir@21255 276 else
keir@21255 277 printf("CPU %d onlined successfully\n", cpu);
keir@21255 278
keir@21255 279 return ret;
keir@21255 280
keir@21255 281 }
keir@21255 282 static int hp_cpu_offline_func(int argc, char *argv[])
keir@21255 283 {
keir@21255 284 int cpu, ret;
keir@21255 285
keir@21475 286 if (argc != 1 )
keir@21255 287 {
keir@21255 288 show_help();
keir@21255 289 return -1;
keir@21255 290 }
keir@21255 291 cpu = atoi(argv[0]);
keir@21255 292 printf("Prepare to offline CPU %d\n", cpu);
keir@22799 293 ret = exec_cpu_hp_fn(xc_cpu_offline, cpu);
keir@21255 294 if (ret < 0)
keir@21475 295 fprintf(stderr, "CPU %d offline failed (error %d: %s)\n",
keir@21475 296 cpu, errno, strerror(errno));
keir@21255 297 else
keir@21255 298 printf("CPU %d offlined successfully\n", cpu);
keir@21255 299
keir@21255 300 return ret;
keir@21255 301 }
keir@21255 302
keir@21255 303 struct {
keir@21255 304 const char *name;
keir@21255 305 int (*function)(int argc, char *argv[]);
keir@21255 306 } main_options[] = {
keir@21255 307 { "help", help_func },
keir@21255 308 { "cpu-online", hp_cpu_online_func },
keir@21255 309 { "cpu-offline", hp_cpu_offline_func },
keir@21255 310 { "mem-status", hp_mem_query_func},
keir@21255 311 { "mem-online", hp_mem_online_func},
keir@21255 312 { "mem-offline", hp_mem_offline_func},
keir@21255 313 };
keir@21255 314
keir@21255 315
keir@21255 316 int main(int argc, char *argv[])
keir@21255 317 {
keir@21255 318 int i, ret;
keir@21475 319
keir@21255 320 if (argc < 2)
keir@21255 321 {
keir@21255 322 show_help();
keir@21255 323 return 0;
keir@21255 324 }
keir@21255 325
keir@21529 326 xch = xc_interface_open(0,0,0);
keir@21529 327 if ( !xch )
keir@21255 328 {
keir@21255 329 fprintf(stderr, "failed to get the handler\n");
keir@21255 330 return 0;
keir@21255 331 }
keir@21255 332
keir@21475 333 for ( i = 0; i < ARRAY_SIZE(main_options); i++ )
keir@21255 334 if (!strncmp(main_options[i].name, argv[1], strlen(argv[1])))
keir@21255 335 break;
keir@21475 336 if ( i == ARRAY_SIZE(main_options) )
keir@21475 337 {
keir@21475 338 fprintf(stderr, "Unrecognised command '%s' -- try "
keir@21475 339 "'xen-hptool help'\n", argv[1]);
keir@21475 340 return 1;
keir@21255 341 }
keir@21475 342
keir@21475 343 ret = main_options[i].function(argc -2, argv + 2);
keir@21255 344
keir@21529 345 xc_interface_close(xch);
keir@21255 346
keir@21475 347 return !!ret;
keir@21255 348 }