Example #1
0
int libvirt_connect(int driver)
{
    if (g_conn != NULL) {
        logwarn(_("conneted already.\n"));
        return -1;
    }

    virSetErrorFunc(NULL, __customErrorFunc);

    const char * URI;
    if (driver == HYPERVISOR_IS_KVM)
        URI = HYPERVISOR_URI_KVM;
    else if (driver == HYPERVISOR_IS_XEN)
        URI = HYPERVISOR_URI_XEN;
    else {
        logerror(_("unrecognized hypervisor driver(%d).\n"), driver);
        return -1;
    }

    __this_lock();
    g_conn = virConnectOpen(URI);
    __this_unlock();
    if (g_conn == NULL) {
        logerror(_("Connet to %s error.\n"), URI);
        return -1;
    } 
    else {
        loginfo(_("Connect to %s success!\n"), URI);
    }

    return 0;
}
Example #2
0
static int
mymain(void)
{
    int id = 0;
    int ro = 0;
    virConnectPtr conn;
    virDomainPtr dom;
    int status;
    virCommandPtr cmd;
    struct utsname ut;

    /* Skip test if xend is not running.  Calling xend on a non-xen
       kernel causes some versions of xend to issue a crash report, so
       we first probe uname results.  */
    uname(&ut);
    if (strstr(ut.release, "xen") == NULL)
        return EXIT_AM_SKIP;
    cmd = virCommandNewArgList("/usr/sbin/xend", "status", NULL);
    if (virCommandRun(cmd, &status) != 0 || status != 0) {
        virCommandFree(cmd);
        return EXIT_AM_SKIP;
    }
    virCommandFree(cmd);

    virSetErrorFunc(NULL, errorHandler);

    conn = virConnectOpen(NULL);
    if (conn == NULL) {
        ro = 1;
        conn = virConnectOpenReadOnly(NULL);
    }
    if (conn == NULL) {
        fprintf(stderr, "First virConnectOpen() failed\n");
        return EXIT_FAILURE;
    }
    dom = virDomainLookupByID(conn, id);
    if (dom == NULL) {
        fprintf(stderr, "First lookup for domain %d failed\n", id);
        return EXIT_FAILURE;
    }
    virDomainFree(dom);
    virConnectClose(conn);
    if (ro == 1)
        conn = virConnectOpenReadOnly(NULL);
    else
        conn = virConnectOpen(NULL);
    if (conn == NULL) {
        fprintf(stderr, "Second virConnectOpen() failed\n");
        return EXIT_FAILURE;
    }
    dom = virDomainLookupByID(conn, id);
    if (dom == NULL) {
        fprintf(stderr, "Second lookup for domain %d failed\n", id);
        return EXIT_FAILURE;
    }
    virDomainFree(dom);
    virConnectClose(conn);

    return EXIT_SUCCESS;
}
Example #3
0
int libvirt_check(int driver)
{
    virSetErrorFunc(NULL, __customErrorFunc);

    const char * URI;
    if (driver == HYPERVISOR_IS_KVM)
        URI = HYPERVISOR_URI_KVM;
    else if (driver == HYPERVISOR_IS_XEN)
        URI = HYPERVISOR_URI_XEN;
    else {
        logerror(_("unrecognized hypervisor driver(%d).\n"), driver);
        return -1;
    }

    virConnectPtr conn = virConnectOpen(URI);
    if (conn == NULL) {
        logerror(_("Connect to %s error.\n"), URI);
        return -1;
    }

    int numDomains = virConnectNumOfDomains(conn);
    if (numDomains < 0) {
        logerror(_("Connect to %s error.\n"), URI);
        return -1;
    }

    virConnectClose(conn);

    return 0;
}
Example #4
0
static PromiseResult VerifyVirtDomain(EvalContext *ctx, char *uri, enum cfhypervisors envtype, Attributes a, const Promise *pp)
{
    int num, i;

/* set up the library error handler */
    virSetErrorFunc(NULL, (void *) EnvironmentErrorHandler);

    if (CFVC[envtype] == NULL)
    {
        if ((CFVC[envtype] = virConnectOpenAuth(uri, virConnectAuthPtrDefault, 0)) == NULL)
        {
            Log(LOG_LEVEL_ERR, "Failed to connect to virtualization monitor '%s'", uri);
            return PROMISE_RESULT_NOOP;
        }
    }

    for (i = 0; i < CF_MAX_CONCURRENT_ENVIRONMENTS; i++)
    {
        CF_RUNNING[i] = -1;
        CF_SUSPENDED[i] = NULL;
    }

    num = virConnectListDomains(CFVC[envtype], CF_RUNNING, CF_MAX_CONCURRENT_ENVIRONMENTS);
    Log(LOG_LEVEL_VERBOSE, "Found %d running guest environments on this host (including enclosure)", num);
    ShowRunList(CFVC[envtype]);
    num = virConnectListDefinedDomains(CFVC[envtype], CF_SUSPENDED, CF_MAX_CONCURRENT_ENVIRONMENTS);
    Log(LOG_LEVEL_VERBOSE, "Found %d dormant guest environments on this host", num);
    ShowDormant();

    PromiseResult result = PROMISE_RESULT_NOOP;
    switch (a.env.state)
    {
    case ENVIRONMENT_STATE_CREATE:
        result = PromiseResultUpdate(result, CreateVirtDom(ctx, CFVC[envtype], a, pp));
        break;
    case ENVIRONMENT_STATE_DELETE:
        result = PromiseResultUpdate(result, DeleteVirt(ctx, CFVC[envtype], a, pp));
        break;
    case ENVIRONMENT_STATE_RUNNING:
        result = PromiseResultUpdate(result, RunningVirt(ctx, CFVC[envtype], a, pp));
        break;
    case ENVIRONMENT_STATE_SUSPENDED:
        result = PromiseResultUpdate(result, SuspendedVirt(ctx, CFVC[envtype], a, pp));
        break;
    case ENVIRONMENT_STATE_DOWN:
        result = PromiseResultUpdate(result, DownVirt(ctx, CFVC[envtype], a, pp));
        break;
    default:
        Log(LOG_LEVEL_INFO, "No state specified for this environment");
        break;
    }

    return result;
}
Example #5
0
static void VerifyVirtDomain(char *uri, enum cfhypervisors envtype, Attributes a, Promise *pp)
{
    int num, i;

/* set up the library error handler */
    virSetErrorFunc(NULL, (void *) EnvironmentErrorHandler);

    if (CFVC[envtype] == NULL)
    {
        if ((CFVC[envtype] = virConnectOpenAuth(uri, virConnectAuthPtrDefault, 0)) == NULL)
        {
            CfOut(cf_error, "", " !! Failed to connect to virtualization monitor \"%s\"", uri);
            return;
        }
    }

    for (i = 0; i < CF_MAX_CONCURRENT_ENVIRONMENTS; i++)
    {
        CF_RUNNING[i] = -1;
        CF_SUSPENDED[i] = NULL;
    }

    num = virConnectListDomains(CFVC[envtype], CF_RUNNING, CF_MAX_CONCURRENT_ENVIRONMENTS);
    CfOut(cf_verbose, "", " -> Found %d running guest environments on this host (including enclosure)", num);
    ShowRunList(CFVC[envtype]);
    num = virConnectListDefinedDomains(CFVC[envtype], CF_SUSPENDED, CF_MAX_CONCURRENT_ENVIRONMENTS);
    CfOut(cf_verbose, "", " -> Found %d dormant guest environments on this host", num);
    ShowDormant(CFVC[envtype]);

    switch (a.env.state)
    {
    case cfvs_create:
        CreateVirtDom(CFVC[envtype], uri, a, pp);
        break;
    case cfvs_delete:
        DeleteVirt(CFVC[envtype], uri, a, pp);
        break;
    case cfvs_running:
        RunningVirt(CFVC[envtype], uri, a, pp);
        break;
    case cfvs_suspended:
        SuspendedVirt(CFVC[envtype], uri, a, pp);
        break;
    case cfvs_down:
        DownVirt(CFVC[envtype], uri, a, pp);
        break;
    default:
        CfOut(cf_inform, "", " !! No state specified for this environment");
        break;
    }
}
Example #6
0
static void VerifyVirtDomain(EvalContext *ctx, char *uri, enum cfhypervisors envtype, Attributes a, Promise *pp)
{
    int num, i;

/* set up the library error handler */
    virSetErrorFunc(NULL, (void *) EnvironmentErrorHandler);

    if (CFVC[envtype] == NULL)
    {
        if ((CFVC[envtype] = virConnectOpenAuth(uri, virConnectAuthPtrDefault, 0)) == NULL)
        {
            CfOut(OUTPUT_LEVEL_ERROR, "", " !! Failed to connect to virtualization monitor \"%s\"", uri);
            return;
        }
    }

    for (i = 0; i < CF_MAX_CONCURRENT_ENVIRONMENTS; i++)
    {
        CF_RUNNING[i] = -1;
        CF_SUSPENDED[i] = NULL;
    }

    num = virConnectListDomains(CFVC[envtype], CF_RUNNING, CF_MAX_CONCURRENT_ENVIRONMENTS);
    CfOut(OUTPUT_LEVEL_VERBOSE, "", " -> Found %d running guest environments on this host (including enclosure)", num);
    ShowRunList(CFVC[envtype]);
    num = virConnectListDefinedDomains(CFVC[envtype], CF_SUSPENDED, CF_MAX_CONCURRENT_ENVIRONMENTS);
    CfOut(OUTPUT_LEVEL_VERBOSE, "", " -> Found %d dormant guest environments on this host", num);
    ShowDormant();

    switch (a.env.state)
    {
    case ENVIRONMENT_STATE_CREATE:
        CreateVirtDom(ctx, CFVC[envtype], a, pp);
        break;
    case ENVIRONMENT_STATE_DELETE:
        DeleteVirt(ctx, CFVC[envtype], a, pp);
        break;
    case ENVIRONMENT_STATE_RUNNING:
        RunningVirt(ctx, CFVC[envtype], a, pp);
        break;
    case ENVIRONMENT_STATE_SUSPENDED:
        SuspendedVirt(ctx, CFVC[envtype], a, pp);
        break;
    case ENVIRONMENT_STATE_DOWN:
        DownVirt(ctx, CFVC[envtype], a, pp);
        break;
    default:
        CfOut(OUTPUT_LEVEL_INFORM, "", " !! No state specified for this environment");
        break;
    }
}
Example #7
0
/*
 * Initialize connection.
 */
static bool
virshInit(vshControl *ctl)
{
    virshControlPtr priv = ctl->privData;

    /* Since we have the commandline arguments parsed, we need to
     * reload our initial settings to make debugging and readline
     * work properly */
    vshInitReload(ctl);

    if (priv->conn)
        return false;

    /* set up the library error handler */
    virSetErrorFunc(NULL, vshErrorHandler);

    if (virEventRegisterDefaultImpl() < 0) {
        vshReportError(ctl);
        return false;
    }

    if (virThreadCreate(&ctl->eventLoop, true, vshEventLoop, ctl) < 0) {
        vshReportError(ctl);
        return false;
    }
    ctl->eventLoopStarted = true;

    if ((ctl->eventTimerId = virEventAddTimeout(-1, vshEventTimeout, ctl,
                                                NULL)) < 0) {
        vshReportError(ctl);
        return false;
    }

    if (ctl->connname) {
        /* Connecting to a named connection must succeed, but we delay
         * connecting to the default connection until we need it
         * (since the first command might be 'connect' which allows a
         * non-default connection, or might be 'help' which needs no
         * connection).
         */
        if (virshReconnect(ctl, NULL, false, false) < 0) {
            vshReportError(ctl);
            return false;
        }
    }

    return true;
}
Example #8
0
virConnectPtr libvirtConnect(char *uri)
{
	virConnectPtr cp;

	virSetErrorFunc("vmrunner", errHandler);
	domainIsOff = 0;
	lastErrorCode = 0;
	DPRINTF("Opening connection to hypervisor, uri %s\n", uri ? uri : "probed");
	cp = virConnectOpen(uri);
	if (cp == NULL) {
		DPRINTF("virConnectOpen call failed\n");
		return NULL;
	}

	DPRINTF("Connected to %s\n", virConnectGetURI(cp));
	return cp;
}
Example #9
0
static int
mymain(void)
{
    int ret = 0;
    int status;
    virCommandPtr cmd;
    struct utsname ut;

    /* Skip test if xend is not running.  Calling xend on a non-xen
       kernel causes some versions of xend to issue a crash report, so
       we first probe uname results.  */
    uname(&ut);
    if (strstr(ut.release, "xen") == NULL)
        return EXIT_AM_SKIP;
    cmd = virCommandNewArgList("/usr/sbin/xend", "status", NULL);
    if (virCommandRun(cmd, &status) != 0 || status != 0) {
        virCommandFree(cmd);
        return EXIT_AM_SKIP;
    }
    virCommandFree(cmd);

    /* Some of our tests deliberately test failure cases, so
     * register a handler to stop error messages cluttering
     * up display
     */
    if (!virTestGetDebug())
        virSetErrorFunc(NULL, testQuietError);

#define DO_TEST(dev, num)                                              \
    do {                                                               \
        struct testInfo info = { dev, num };                           \
        if (virtTestRun("Device " dev " -> " # num,                    \
                        1, testDeviceHelper, &info) < 0)               \
            ret = -1;                                                  \
    } while (0)

    /********************************
     * Xen paravirt disks
     ********************************/

    DO_TEST("xvd", -1);

    /* first valid disk */
    DO_TEST("xvda", 51712);
    DO_TEST("xvda1", 51713);
    DO_TEST("xvda15", 51727);
    /* Last non-extended disk */
    DO_TEST("xvdp", 51952);
    DO_TEST("xvdp1", 51953);
    DO_TEST("xvdp15", 51967);

    /* First extended disk */
    DO_TEST("xvdq", 268439552);
    DO_TEST("xvdq1", 268439553);
    DO_TEST("xvdq15", 268439567);
    /* Last extended disk */
    DO_TEST("xvdiz", 268501760);
    DO_TEST("xvdiz1", 268501761);
    DO_TEST("xvdiz15", 268501775);

    /* Disk letter too large */
    DO_TEST("xvdja", -1);

    /* missing disk letter */
    DO_TEST("xvd1", -1);
    /* partition too large */
    DO_TEST("xvda16", -1);
    /* partition too small */
    DO_TEST("xvda0", -1);
    /* leading zeros */
    DO_TEST("xvda01", -1);
    /* leading + */
    DO_TEST("xvda+1", -1);
    /* leading - */
    DO_TEST("xvda-1", -1);

    /********************************
     * IDE disks
     ********************************/

    DO_TEST("hd", -1);

    /* first numbered disk */
    DO_TEST("hda", 768);
    DO_TEST("hda1", 769);
    DO_TEST("hda63", 831);
    /* second numbered disk */
    DO_TEST("hdb", 832);
    DO_TEST("hdb1", 833);
    DO_TEST("hdb63", 895);
    /* third numbered disk */
    DO_TEST("hdc", 5632);
    DO_TEST("hdc1", 5633);
    DO_TEST("hdc63", 5695);
    /* fourth numbered disk */
    DO_TEST("hdd", 5696);
    DO_TEST("hdd1", 5697);
    DO_TEST("hdd63", 5759);
    /* last valid disk */
    DO_TEST("hdt", 23360);
    DO_TEST("hdt1", 23361);
    DO_TEST("hdt63", 23423);

    /* Disk letter to large */
    DO_TEST("hdu", -1);
    /* missing disk letter */
    DO_TEST("hd1", -1);
    /* partition too large */
    DO_TEST("hda64", -1);
    /* partition too small */
    DO_TEST("hda0", -1);



    /********************************
     * SCSI disks
     ********************************/

    DO_TEST("sd", -1);

    /* first valid disk */
    DO_TEST("sda", 2048);
    DO_TEST("sda1", 2049);
    DO_TEST("sda15", 2063);
    /* last valid disk of first SCSI major number */
    DO_TEST("sdp", 2288);
    DO_TEST("sdp1", 2289);
    DO_TEST("sdp15", 2303);
    /* first valid disk of second SCSI major number */
    DO_TEST("sdq", 16640);
    DO_TEST("sdq1", 16641);
    DO_TEST("sdq15", 16655);
    /* last valid single letter disk */
    DO_TEST("sdz", 16784);
    DO_TEST("sdz1", 16785);
    DO_TEST("sdz15", 16799);
    /* first valid dual letter disk */
    DO_TEST("sdaa", 16800);
    DO_TEST("sdaa1", 16801);
    DO_TEST("sdaa15", 16815);
    /* second valid dual letter disk */
    DO_TEST("sdab", 16816);
    DO_TEST("sdab1", 16817);
    DO_TEST("sdab15", 16831);
    /* first letter of second sequence of dual letter disk */
    DO_TEST("sdba", 17216);
    DO_TEST("sdba1", 17217);
    DO_TEST("sdba15", 17231);
    /* last valid dual letter disk */
    DO_TEST("sdiv", 34800);
    DO_TEST("sdiv1", 34801);
    DO_TEST("sdiv15", 34815);

    /* Disk letter too large */
    DO_TEST("sdix", -1);
    /* missing disk letter */
    DO_TEST("sd1", -1);
    /* partition too large */
    DO_TEST("sda16", -1);
    /* partition too small */
    DO_TEST("sda0", -1);


    /* Path stripping */
    DO_TEST("/dev", -1);
    DO_TEST("/dev/", -1);
    DO_TEST("/dev/xvd", -1);
    DO_TEST("/dev/xvda", 51712);
    DO_TEST("/dev/xvda1", 51713);
    DO_TEST("/dev/xvda15", 51727);

    return ret==0 ? EXIT_SUCCESS : EXIT_FAILURE;
}
Example #10
0
void adopt_instances()
{
	int dom_ids[MAXDOMS];
	int num_doms = 0;
	int i;
       	virDomainPtr dom = NULL;

	if (! check_hypervisor_conn())
		return;
        
	logprintfl (EUCAINFO, "looking for existing domains\n");
	virSetErrorFunc (NULL, libvirt_error_handler);
        
	num_doms = virConnectListDomains(nc_state.conn, dom_ids, MAXDOMS);
	if (num_doms == 0) {
		logprintfl (EUCAINFO, "no currently running domains to adopt\n");
		return;
	} if (num_doms < 0) {
		logprintfl (EUCAWARN, "WARNING: failed to find out about running domains\n");
		return;
	}

	for ( i=0; i<num_doms; i++) {
		int error;
		virDomainInfo info;
		const char * dom_name;
		ncInstance * instance;

		sem_p(hyp_sem);
		dom = virDomainLookupByID(nc_state.conn, dom_ids[i]);
		sem_v(hyp_sem);
		if (!dom) {
			logprintfl (EUCAWARN, "WARNING: failed to lookup running domain #%d, ignoring it\n", dom_ids[i]);
			continue;
		}

		sem_p(hyp_sem);
		error = virDomainGetInfo(dom, &info);
		sem_v(hyp_sem);
		if (error < 0 || info.state == VIR_DOMAIN_NOSTATE) {
			logprintfl (EUCAWARN, "WARNING: failed to get info on running domain #%d, ignoring it\n", dom_ids[i]);
			continue;
		}

		if (info.state == VIR_DOMAIN_SHUTDOWN ||
				info.state == VIR_DOMAIN_SHUTOFF ||
				info.state == VIR_DOMAIN_CRASHED ) {
			logprintfl (EUCADEBUG, "ignoring non-running domain #%d\n", dom_ids[i]);
			continue;
		}

		sem_p(hyp_sem);
		if ((dom_name = virDomainGetName(dom))==NULL) {
		        sem_v(hyp_sem);
		        logprintfl (EUCAWARN, "WARNING: failed to get name of running domain #%d, ignoring it\n", dom_ids[i]);
			continue;
		}
		sem_v(hyp_sem);

		if (!strcmp(dom_name, "Domain-0"))
			continue;

		if ((instance = scRecoverInstanceInfo (dom_name))==NULL) {
			logprintfl (EUCAWARN, "WARNING: failed to recover Eucalyptus metadata of running domain %s, ignoring it\n", dom_name);
			continue;
		}

		change_state (instance, info.state);                    
		sem_p (inst_sem);
		int err = add_instance (&global_instances, instance);
		sem_v (inst_sem);
		if (err) {
			free_instance (&instance);
			continue;
		}

		logprintfl (EUCAINFO, "- adopted running domain %s from user %s\n", instance->instanceId, instance->userId);
		/* TODO: try to look up IPs? */

		sem_p(hyp_sem);
		virDomainFree (dom);
		sem_v(hyp_sem);
	}
}
Example #11
0
static int
mymain(void)
{
    int ret = 0;
    /* Some of our tests deliberately test failure cases, so
     * register a handler to stop error messages cluttering
     * up display
     */
    if (!virTestGetDebug())
        virSetErrorFunc(NULL, testQuietError);

#define DO_TEST_PARSE(addrstr, family, pass)                            \
    do {                                                                \
        virSocketAddr addr;                                             \
        struct testParseData data = { &addr, addrstr, family, pass };   \
        memset(&addr, 0, sizeof(addr));                                 \
        if (virtTestRun("Test parse " addrstr,                          \
                        1, testParseHelper, &data) < 0)                 \
            ret = -1;                                                   \
    } while (0)

#define DO_TEST_PARSE_AND_FORMAT(addrstr, family, pass)                 \
    do {                                                                \
        virSocketAddr addr;                                             \
        struct testParseData data = { &addr, addrstr, family, pass };   \
        memset(&addr, 0, sizeof(addr));                                 \
        if (virtTestRun("Test parse " addrstr " family " #family,       \
                        1, testParseHelper, &data) < 0)                 \
            ret = -1;                                                   \
        struct testFormatData data2 = { &addr, addrstr, pass };         \
        if (virtTestRun("Test format " addrstr " family " #family,      \
                        1, testFormatHelper, &data2) < 0)               \
            ret = -1;                                                   \
    } while (0)

#define DO_TEST_RANGE(saddr, eaddr, size, pass)                         \
    do {                                                                \
        struct testRangeData data = { saddr, eaddr, size, pass };       \
        if (virtTestRun("Test range " saddr " -> " eaddr " size " #size, \
                        1, testRangeHelper, &data) < 0)                 \
            ret = -1;                                                   \
    } while (0)

#define DO_TEST_NETMASK(addr1, addr2, netmask, pass)                    \
    do {                                                                \
        struct testNetmaskData data = { addr1, addr2, netmask, pass };  \
        if (virtTestRun("Test netmask " addr1 " + " addr2 " in " netmask, \
                        1, testNetmaskHelper, &data) < 0)               \
            ret = -1;                                                   \
    } while (0)


    DO_TEST_PARSE_AND_FORMAT("127.0.0.1", AF_UNSPEC, true);
    DO_TEST_PARSE_AND_FORMAT("127.0.0.1", AF_INET, true);
    DO_TEST_PARSE_AND_FORMAT("127.0.0.1", AF_INET6, false);
    DO_TEST_PARSE_AND_FORMAT("127.0.0.1", AF_UNIX, false);
    DO_TEST_PARSE_AND_FORMAT("127.0.0.256", AF_UNSPEC, false);

    DO_TEST_PARSE_AND_FORMAT("::1", AF_UNSPEC, true);
    DO_TEST_PARSE_AND_FORMAT("::1", AF_INET, false);
    DO_TEST_PARSE_AND_FORMAT("::1", AF_INET6, true);
    DO_TEST_PARSE_AND_FORMAT("::1", AF_UNIX, false);
    DO_TEST_PARSE_AND_FORMAT("::ffff", AF_UNSPEC, true);

    DO_TEST_RANGE("192.168.122.1", "192.168.122.1", 1, true);
    DO_TEST_RANGE("192.168.122.1", "192.168.122.20", 20, true);
    DO_TEST_RANGE("192.168.122.0", "192.168.122.255", 256, true);
    DO_TEST_RANGE("192.168.122.20", "192.168.122.1", -1, false);
    DO_TEST_RANGE("10.0.0.1", "192.168.122.20", -1, false);
    DO_TEST_RANGE("192.168.122.20", "10.0.0.1", -1, false);

    DO_TEST_RANGE("2000::1", "2000::1", 1, true);
    DO_TEST_RANGE("2000::1", "2000::2", 2, true);
    DO_TEST_RANGE("2000::2", "2000::1", -1, false);
    DO_TEST_RANGE("2000::1", "9001::1", -1, false);

    DO_TEST_NETMASK("192.168.122.1", "192.168.122.2",
                    "255.255.255.0", true);
    DO_TEST_NETMASK("192.168.122.1", "192.168.122.4",
                    "255.255.255.248", true);
    DO_TEST_NETMASK("192.168.122.1", "192.168.123.2",
                    "255.255.255.0", false);
    DO_TEST_NETMASK("192.168.122.1", "192.168.123.2",
                    "255.255.0.0", true);

    DO_TEST_NETMASK("2000::1:1", "2000::1:1",
                    "ffff:ffff:ffff:ffff:ffff:ffff:ffff:0", true);
    DO_TEST_NETMASK("2000::1:1", "2000::2:1",
                    "ffff:ffff:ffff:ffff:ffff:ffff:ffff:0", false);
    DO_TEST_NETMASK("2000::1:1", "2000::2:1",
                    "ffff:ffff:ffff:ffff:ffff:ffff:fff8:0", true);
    DO_TEST_NETMASK("2000::1:1", "9000::1:1",
                    "ffff:ffff:ffff:ffff:ffff:ffff:ffff:0", false);

    return(ret==0 ? EXIT_SUCCESS : EXIT_FAILURE);
}
Example #12
0
int
main(int argc, char **argv)
{
    virConfPtr conf = NULL;
    const char *login_shell_path = conf_file;
    pid_t cpid = -1;
    int ret = EXIT_CANCELED;
    int status;
    uid_t uid = getuid();
    gid_t gid = getgid();
    char *name = NULL;
    char **shargv = NULL;
    virSecurityModelPtr secmodel = NULL;
    virSecurityLabelPtr seclabel = NULL;
    virDomainPtr dom = NULL;
    virConnectPtr conn = NULL;
    char *homedir = NULL;
    int arg;
    int longindex = -1;
    int ngroups;
    gid_t *groups = NULL;
    ssize_t nfdlist = 0;
    int *fdlist = NULL;
    int openmax;
    size_t i;

    struct option opt[] = {
        {"help", no_argument, NULL, 'h'},
        {"version", optional_argument, NULL, 'V'},
        {NULL, 0, NULL, 0}
    };
    if (virInitialize() < 0) {
        fprintf(stderr, _("Failed to initialize libvirt error handling"));
        return EXIT_CANCELED;
    }

    setenv("PATH", "/bin:/usr/bin", 1);

    virSetErrorFunc(NULL, NULL);
    virSetErrorLogPriorityFunc(NULL);

    progname = argv[0];
    if (!setlocale(LC_ALL, "")) {
        perror("setlocale");
        /* failure to setup locale is not fatal */
    }
    if (!bindtextdomain(PACKAGE, LOCALEDIR)) {
        perror("bindtextdomain");
        return ret;
    }
    if (!textdomain(PACKAGE)) {
        perror("textdomain");
        return ret;
    }

    while ((arg = getopt_long(argc, argv, "hV", opt, &longindex)) != -1) {
        switch (arg) {
        case 'h':
            usage();
            exit(EXIT_SUCCESS);

        case 'V':
            show_version();
            exit(EXIT_SUCCESS);

        case '?':
        default:
            usage();
            exit(EXIT_CANCELED);
        }
    }

    if (argc > optind) {
        virReportSystemError(EINVAL, _("%s takes no options"), progname);
        goto cleanup;
    }

    if (uid == 0) {
        virReportSystemError(EPERM, _("%s must be run by non root users"),
                             progname);
        goto cleanup;
    }

    name = virGetUserName(uid);
    if (!name)
        goto cleanup;

    homedir = virGetUserDirectoryByUID(uid);
    if (!homedir)
        goto cleanup;

    if (!(conf = virConfReadFile(login_shell_path, 0)))
        goto cleanup;

    if ((ngroups = virGetGroupList(uid, gid, &groups)) < 0)
        goto cleanup;

    if (virLoginShellAllowedUser(conf, name, groups) < 0)
        goto cleanup;

    if (!(shargv = virLoginShellGetShellArgv(conf)))
        goto cleanup;

    conn = virConnectOpen("lxc:///");
    if (!conn)
        goto cleanup;

    dom = virDomainLookupByName(conn, name);
    if (!dom)
        goto cleanup;

    if (!virDomainIsActive(dom) && virDomainCreate(dom)) {
        virErrorPtr last_error;
        last_error = virGetLastError();
        if (last_error->code != VIR_ERR_OPERATION_INVALID) {
            virReportSystemError(last_error->code,
                                 _("Can't create %s container: %s"),
                                 name, last_error->message);
            goto cleanup;
        }
    }

    openmax = sysconf(_SC_OPEN_MAX);
    if (openmax < 0) {
        virReportSystemError(errno,  "%s",
                             _("sysconf(_SC_OPEN_MAX) failed"));
        goto cleanup;
    }

    if ((nfdlist = virDomainLxcOpenNamespace(dom, &fdlist, 0)) < 0)
        goto cleanup;
    if (VIR_ALLOC(secmodel) < 0)
        goto cleanup;
    if (VIR_ALLOC(seclabel) < 0)
        goto cleanup;
    if (virNodeGetSecurityModel(conn, secmodel) < 0)
        goto cleanup;
    if (virDomainGetSecurityLabel(dom, seclabel) < 0)
        goto cleanup;
    if (virSetUIDGID(0, 0, NULL, 0) < 0)
        goto cleanup;
    if (virDomainLxcEnterSecurityLabel(secmodel, seclabel, NULL, 0) < 0)
        goto cleanup;
    if (nfdlist > 0 &&
        virDomainLxcEnterNamespace(dom, nfdlist, fdlist, NULL, NULL, 0) < 0)
        goto cleanup;
    if (virSetUIDGID(uid, gid, groups, ngroups) < 0)
        goto cleanup;
    if (chdir(homedir) < 0) {
        virReportSystemError(errno, _("Unable to chdir(%s)"), homedir);
        goto cleanup;
    }

    /* A fork is required to create new process in correct pid namespace.  */
    if ((cpid = virFork()) < 0)
        goto cleanup;

    if (cpid == 0) {
        int tmpfd;

        for (i = 3; i < openmax; i++) {
            tmpfd = i;
            VIR_MASS_CLOSE(tmpfd);
        }
        if (execv(shargv[0], (char *const*) shargv) < 0) {
            virReportSystemError(errno, _("Unable to exec shell %s"),
                                 shargv[0]);
            virDispatchError(NULL);
            return errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE;
        }
    }

    /* At this point, the parent is now waiting for the child to exit,
     * but as that may take a long time, we release resources now.  */
 cleanup:
    if (nfdlist > 0)
        for (i = 0; i < nfdlist; i++)
            VIR_FORCE_CLOSE(fdlist[i]);
    VIR_FREE(fdlist);
    virConfFree(conf);
    if (dom)
        virDomainFree(dom);
    if (conn)
        virConnectClose(conn);
    virStringFreeList(shargv);
    VIR_FREE(name);
    VIR_FREE(homedir);
    VIR_FREE(seclabel);
    VIR_FREE(secmodel);
    VIR_FREE(groups);

    if (virProcessWait(cpid, &status, true) == 0)
        virProcessExitWithStatus(status);

    if (virGetLastError())
        virDispatchError(NULL);
    return ret;
}