/*
 *  Copyright (c) 2006 Stratus Technologies, Inc
 *  Copyright (C) International Business Machines  Corp., 2005
 *  Author(s): Simon Graham <simon.graham@stratus.com>
 *  	       Anthony Liguori <aliguori@us.ibm.com>
 *
 *  Xen Dump Utility
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; under version 2 of the License.
 * 
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 * 
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <getopt.h>
#include <err.h>
#include <ctype.h>
#include <string.h>

#include "xenctrl.h"
#include "xs.h"

static int find_domain_id_by_name(struct xs_handle *xs_handle, const char *name)
{
	int domain_id=-1, id, i, num;
	char path[80];
	char *domain_name;
    
	char **list = xs_directory(xs_handle, XBT_NULL, "/local/domain", &num);
	if (list == NULL)
		return 0;
    
	for (i=0; i<num; i++) {
		id = strtol(list[i], NULL, 10);
		if (id == 0)
			continue;

		snprintf(path, sizeof(path), "/local/domain/%i/name", id);
		domain_name = xs_read(xs_handle, XBT_NULL, path, NULL);

		if (strcmp(domain_name, name) == 0) 
			domain_id = id;
	}

	return domain_id;
}

static int get_domain_id(const char *value)
{
	int domid;
	struct xs_handle *xs;
	xs = xs_daemon_open_readonly();
	domid = find_domain_id_by_name(xs, value);
	xs_daemon_close(xs);

	return domid;
}

static void dumpDomU(int domid, const char *dumpname)
{
	int xc_handle;
	int rc;

	xc_handle = xc_interface_open();
	if (xc_handle == -1) {
		err(errno, "xc_interface_open()");
	}

	printf("Dumping domain id %d to %s\n",domid,dumpname);

	rc = xc_domain_dumpcore(xc_handle, domid, dumpname);
	if (rc < 0) {
		err(-rc,"failed to dump core");
	}
}

static void usage(const char *program) {
	printf("Usage: %s [options] domain-name dump-path\n"
	       "Dumps specified domain to named file\n"
	       "\n"
	       "  -h, --help       display this help and exit\n"
	       , program);
}

int main(int argc, char **argv)
{
	int domid;
	char *end;
	char *sopt = "h";
	int ch;
	int opt_ind=0;
	struct option lopt[] = {
		{ "help",    0, 0, 'h' },
		{ 0 },

	};
	while((ch = getopt_long(argc, argv, sopt, lopt, &opt_ind)) != -1) {
		switch(ch) {
		case 'h':
			usage(argv[0]);
			exit(0);
			break;
		}
	}
	
	if ((argc - optind) != 2) {
		fprintf(stderr, "Invalid number of arguments\n");
		fprintf(stderr, "Try `%s --help' for more information.\n", 
			argv[0]);
		exit(EINVAL);
	}

	// Did use specify a numeric domid?
	domid = strtol(argv[optind], &end, 10);
	if (end && *end) {
		// no - treat as name instead
		domid = get_domain_id(argv[optind]);

		if (domid < 0) {
			err(EINVAL,"domain not found");
		}
	}

	dumpDomU(domid, argv[optind+1]);

	return 0;
}

/*
 * Local variables:
 *  c-file-style: "linux"
 *  indent-tabs-mode: t
 *  c-indent-level: 8
 *  c-basic-offset: 8
 *  tab-width: 8
 * End:
 */
