Esempio n. 1
0
static ptree_walk_res_t
write_pending(const void *node, int level, void *arg, void *pwra)
{
	id_pde_map_t *ipm = (id_pde_map_t *)node;
	pds_session_t *pdss = arg;
	int buflen;
	char errdesc[256];
	char *buf;

	if (!pdss->pdss_write)
		goto freeing;
	buflen = pasprintf(&buf, "%s%s200-%s is pending, key %s "
	    "latest value \"%s\" (%s)\n", pdss->pdss_report_cmdtag ?
	    pdss->pdss_report_cmdtag : "", pdss->pdss_report_cmdtag ?
	    " " : "", ipm->ipm_id, ipm->ipm_key, ipm->ipm_val,
	    pdict_reason_str(ipm->ipm_reason));
	if (buf) {
#ifndef _MSC_EXTENSIONS
#ifdef DEBUG_PROTOCOL
		if (debug_protocol)
			write(1, buf, buflen);
#endif
#endif
		if (!pdss->pdss_write(pdss->pdss_wfd, buf, buflen +
		    pdss->pdss_client_cr_null, errdesc, sizeof (errdesc))) {
#ifdef DEBUG_PROTOCOL
			pu_log(PUL_WARN, pdss->pdss_id,
			    "write error while reporting:");
			pu_log(PUL_WARN, pdss->pdss_id, errdesc);
#endif
		}
		free(buf); buf = NULL;
	} else {
		pu_log(PUL_WARN, pdss->pdss_id,
		    "some notifications dropped due to low-memory condition");
	}
freeing:
	free((void *)ipm->ipm_key); ipm->ipm_key = NULL;
	free((void *)ipm->ipm_val); ipm->ipm_val = NULL;
	free(ipm); ipm = NULL;

	return 1;
}
Esempio n. 2
0
int switch_qemu_logdirty(int domid, unsigned enable, void *data)
{
    char *path = NULL;
    struct xs_handle *xsh = NULL;
    bool rc;

    pasprintf(&path, "/local/domain/0/device-model/%u/logdirty/cmd", domid);

    xsh = xs_daemon_open();
    if (xsh == NULL)
        errx(1, "Couldn't contact xenstore");

    if (enable)
        rc = xs_write(xsh, XBT_NULL, path, "enable", strlen("enable"));
    else
        rc = xs_write(xsh, XBT_NULL, path, "disable", strlen("disable"));

    xs_daemon_close(xsh);
    free(path);
    return rc ? 0 : 1;

}
Esempio n. 3
0
static ptree_walk_res_t
write_pending(const void *node, int level, void *a, void *pwra)
{
	//void **arg = a;
	id_pde_map_t *ipm = (id_pde_map_t *)node;
	pds_session_t *pdss = (pds_session_t *)a;
	//ptree_node_t **pending = arg[1];
	int buflen;
	char errdesc[256];
	char *buf;
	void *ov;
	
	if (!pdss->pdss_write)
		goto freeing;
	buflen = pasprintf(&buf, "%s%s200-%s is pending, key %s "
					   "latest value \"%s\" (%s)\n", pdss->pdss_report_cmdtag ?
					   pdss->pdss_report_cmdtag : "", pdss->pdss_report_cmdtag ?
					   " " : "", ipm->ipm_id, ipm->ipm_key, ipm->ipm_val,
					   pdict_reason_str(ipm->ipm_reason));
	if (buf) {
		if (!pdss->pdss_write(pdss->pdss_wfd, buf, buflen +
							  pdss->pdss_client_cr_null, errdesc, sizeof (errdesc))) {
			//pu_log(PUL_WARN, pdss->pdss_id, "write error while reporting: %s",errdesc);
		}
		free(buf); buf = NULL;
	} else {
		pu_log(PUL_WARN, pdss->pdss_id, "some notifications dropped due to low-memory condition");
	}
freeing:
	ptree_inorder_walk_remove(&pdss->pdss_pending, &ov, pwra, ipmcmp);
	assert(node == ov);
	free((void *)ipm->ipm_key); //ipm->ipm_key = NULL;
	free((void *)ipm->ipm_val); //ipm->ipm_val = NULL;
	free(ov); ov = NULL;
	
	return 1;
}
Esempio n. 4
0
void xenstore_parse_domain_config(int domid)
{
    char **e = NULL;
    char *buf = NULL, *path;
    char *fpath = NULL, *bpath = NULL,
        *dev = NULL, *params = NULL, *type = NULL, *drv = NULL;
    int i, is_scsi, is_hdN = 0;
    unsigned int len, num, hd_index;
    BlockDriverState *bs;

    for(i = 0; i < MAX_DISKS + MAX_SCSI_DISKS; i++)
        media_filename[i] = NULL;

    xsh = xs_daemon_open();
    if (xsh == NULL) {
        fprintf(logfile, "Could not contact xenstore for domain config\n");
        return;
    }

    path = xs_get_domain_path(xsh, domid);
    if (path == NULL) {
        fprintf(logfile, "xs_get_domain_path() error\n");
        goto out;
    }

    if (pasprintf(&buf, "%s/device/vbd", path) == -1)
        goto out;

    e = xs_directory(xsh, XBT_NULL, buf, &num);
    if (e == NULL)
        goto out;

    for (i = 0; i < num; i++) {
        /* read the backend path */
        if (pasprintf(&buf, "%s/device/vbd/%s/backend", path, e[i]) == -1)
            continue;
        free(bpath);
        bpath = xs_read(xsh, XBT_NULL, buf, &len);
        if (bpath == NULL)
            continue;
        /* read the name of the device */
        if (pasprintf(&buf, "%s/dev", bpath) == -1)
            continue;
        free(dev);
        dev = xs_read(xsh, XBT_NULL, buf, &len);
        if (dev == NULL)
            continue;
        if (!strncmp(dev, "hd", 2)) {
            is_hdN = 1;
            break;
        }
    }
        
    for (i = 0; i < num; i++) {
        /* read the backend path */
        if (pasprintf(&buf, "%s/device/vbd/%s/backend", path, e[i]) == -1)
            continue;
        free(bpath);
        bpath = xs_read(xsh, XBT_NULL, buf, &len);
        if (bpath == NULL)
            continue;
        /* read the name of the device */
        if (pasprintf(&buf, "%s/dev", bpath) == -1)
            continue;
        free(dev);
        dev = xs_read(xsh, XBT_NULL, buf, &len);
        if (dev == NULL)
            continue;
        /* Change xvdN to look like hdN */
        if (!is_hdN && !strncmp(dev, "xvd", 3)) {
            fprintf(logfile, "Change xvd%c to look like hd%c\n",
                    dev[3], dev[3]);
            memmove(dev, dev+1, strlen(dev));
            dev[0] = 'h';
            dev[1] = 'd';
        }
        is_scsi = !strncmp(dev, "sd", 2);
        if ((strncmp(dev, "hd", 2) && !is_scsi) || strlen(dev) != 3 )
            continue;
        hd_index = dev[2] - 'a';
        if (hd_index >= (is_scsi ? MAX_SCSI_DISKS : MAX_DISKS))
            continue;
        /* read the type of the device */
        if (pasprintf(&buf, "%s/device/vbd/%s/device-type", path, e[i]) == -1)
            continue;
        free(type);
        type = xs_read(xsh, XBT_NULL, buf, &len);
        if (pasprintf(&buf, "%s/params", bpath) == -1)
            continue;
        free(params);
        params = xs_read(xsh, XBT_NULL, buf, &len);
        if (params == NULL)
            continue;
        /* read the name of the device */
        if (pasprintf(&buf, "%s/type", bpath) == -1)
            continue;
        free(drv);
        drv = xs_read(xsh, XBT_NULL, buf, &len);
        if (drv == NULL)
            continue;
        /* Strip off blktap sub-type prefix aio: - QEMU can autodetect this */
        if (!strcmp(drv, "tap") && params[0]) {
            char *offset = strchr(params, ':'); 
            if (!offset)
                continue ;
            memmove(params, offset+1, strlen(offset+1)+1 );
            fprintf(logfile, "Strip off blktap sub-type prefix to %s\n", params); 
        }
        /* Prefix with /dev/ if needed */
        if (!strcmp(drv, "phy") && params[0] != '/') {
            char *newparams = malloc(5 + strlen(params) + 1);
            sprintf(newparams, "/dev/%s", params);
            free(params);
            params = newparams;
        }

        /* 
         * check if device has a phantom vbd; the phantom is hooked
         * to the frontend device (for ease of cleanup), so lookup 
         * the frontend device, and see if there is a phantom_vbd
         * if there is, we will use resolution as the filename
         */
        if (pasprintf(&buf, "%s/device/vbd/%s/phantom_vbd", path, e[i]) == -1)
            continue;
        free(fpath);
        fpath = xs_read(xsh, XBT_NULL, buf, &len);
        if (fpath) {
            if (pasprintf(&buf, "%s/dev", fpath) == -1)
                continue;
            free(params);
            params = xs_read(xsh, XBT_NULL, buf , &len);
            if (params) {
                /* 
                 * wait for device, on timeout silently fail because we will 
                 * fail to open below
                 */
                waitForDevice(params);
            }
        }

        bs = bs_table[hd_index + (is_scsi ? MAX_DISKS : 0)] = bdrv_new(dev);
        /* check if it is a cdrom */
        if (type && !strcmp(type, "cdrom")) {
            bdrv_set_type_hint(bs, BDRV_TYPE_CDROM);
            if (pasprintf(&buf, "%s/params", bpath) != -1)
                xs_watch(xsh, buf, dev);
        }

        /* open device now if media present */
        if (params[0]) {
            if (bdrv_open(bs, params, 0 /* snapshot */) < 0)
                fprintf(stderr, "qemu: could not open hard disk image '%s'\n",
                        params);
        }
    }

    /* Set a watch for log-dirty requests from the migration tools */
    if (pasprintf(&buf, "/local/domain/0/device-model/%u/logdirty/next-active",
                  domid) != -1) {
        xs_watch(xsh, buf, "logdirty");
        fprintf(logfile, "Watching %s\n", buf);
    }

    /* Set a watch for suspend requests from the migration tools */
    if (pasprintf(&buf, 
                  "/local/domain/0/device-model/%u/command", domid) != -1) {
        xs_watch(xsh, buf, "dm-command");
        fprintf(logfile, "Watching %s\n", buf);
    }

 out:
    free(type);
    free(params);
    free(dev);
    free(bpath);
    free(buf);
    free(path);
    free(e);
    free(drv);
    return;
}
Esempio n. 5
0
void xenstore_process_event(void *opaque)
{
    char **vec, *offset, *bpath = NULL, *buf = NULL, *drv = NULL, *image = NULL;
    unsigned int len, num, hd_index;

    vec = xs_read_watch(xsh, &num);
    if (!vec)
        return;

    if (!strcmp(vec[XS_WATCH_TOKEN], "logdirty")) {
        xenstore_process_logdirty_event();
        goto out;
    }

    if (!strcmp(vec[XS_WATCH_TOKEN], "dm-command")) {
        xenstore_process_dm_command_event();
        goto out;
    }

    if (strncmp(vec[XS_WATCH_TOKEN], "hd", 2) ||
        strlen(vec[XS_WATCH_TOKEN]) != 3)
        goto out;
    hd_index = vec[XS_WATCH_TOKEN][2] - 'a';
    image = xs_read(xsh, XBT_NULL, vec[XS_WATCH_PATH], &len);
    if (image == NULL)
        goto out;  /* gone */

    /* Strip off blktap sub-type prefix */
    bpath = strdup(vec[XS_WATCH_PATH]); 
    if (bpath == NULL)
        goto out;
    if ((offset = strrchr(bpath, '/')) != NULL) 
        *offset = '\0';
    if (pasprintf(&buf, "%s/type", bpath) == -1) 
        goto out;
    drv = xs_read(xsh, XBT_NULL, buf, &len);
    if (drv && !strcmp(drv, "tap") && ((offset = strchr(image, ':')) != NULL))
        memmove(image, offset+1, strlen(offset+1)+1);

    if (!strcmp(image, bs_table[hd_index]->filename))
        goto out;  /* identical */

    do_eject(0, vec[XS_WATCH_TOKEN]);
    bs_table[hd_index]->filename[0] = 0;
    if (media_filename[hd_index]) {
        free(media_filename[hd_index]);
        media_filename[hd_index] = NULL;
    }

    if (image[0]) {
        media_filename[hd_index] = strdup(image);
        xenstore_check_new_media_present(5000);
    }

 out:
    free(drv);
    free(buf);
    free(bpath);
    free(image);
    free(vec);
}
Esempio n. 6
0
void xenstore_process_logdirty_event(void)
{
    char *act;
    static char *active_path = NULL;
    static char *next_active_path = NULL;
    static char *seg = NULL;
    unsigned int len;
    int i;

    if (!seg) {
        char *path = NULL, *key_ascii, key_terminated[17] = {0,};
        key_t key;
        int shmid;

        /* Find and map the shared memory segment for log-dirty bitmaps */
        if (pasprintf(&path, 
                      "/local/domain/0/device-model/%u/logdirty/key", 
                      domid) == -1) {
            fprintf(logfile, "Log-dirty: out of memory\n");
            exit(1);
        }
        
        key_ascii = xs_read(xsh, XBT_NULL, path, &len);
        free(path);

        if (!key_ascii) 
            /* No key yet: wait for the next watch */
            return;

        strncpy(key_terminated, key_ascii, 16);
        free(key_ascii);
        key = (key_t) strtoull(key_terminated, NULL, 16);

        /* Figure out how bit the log-dirty bitmaps are */
        logdirty_bitmap_size = xc_memory_op(xc_handle, 
                                            XENMEM_maximum_gpfn, &domid) + 1;
        logdirty_bitmap_size = ((logdirty_bitmap_size + HOST_LONG_BITS - 1)
                                / HOST_LONG_BITS); /* longs */
        logdirty_bitmap_size *= sizeof (unsigned long); /* bytes */

        /* Map the shared-memory segment */
        fprintf(logfile, "%s: key=%16.16llx size=%lu\n", __FUNCTION__,
                (unsigned long long)key, logdirty_bitmap_size);
        shmid = shmget(key, 2 * logdirty_bitmap_size, S_IRUSR|S_IWUSR);
        if (shmid == -1) {
            fprintf(logfile, "Log-dirty: shmget failed: segment %16.16llx "
                    "(%s)\n", (unsigned long long)key, strerror(errno));
            exit(1);
        }

        seg = shmat(shmid, NULL, 0);
        if (seg == (void *)-1) {
            fprintf(logfile, "Log-dirty: shmat failed: segment %16.16llx "
                    "(%s)\n", (unsigned long long)key, strerror(errno));
            exit(1);
        }

        fprintf(logfile, "Log-dirty: mapped segment at %p\n", seg);

        /* Double-check that the bitmaps are the size we expect */
        if (logdirty_bitmap_size != *(uint32_t *)seg) {
            fprintf(logfile, "Log-dirty: got %u, calc %lu\n", 
                    *(uint32_t *)seg, logdirty_bitmap_size);
            /* Stale key: wait for next watch */
            shmdt(seg);
            seg = NULL;
            return;
        }

        /* Remember the paths for the next-active and active entries */
        if (pasprintf(&active_path, 
                      "/local/domain/0/device-model/%u/logdirty/active",
                      domid) == -1) {
            fprintf(logfile, "Log-dirty: out of memory\n");
            exit(1);
        }
        if (pasprintf(&next_active_path, 
                      "/local/domain/0/device-model/%u/logdirty/next-active",
                      domid) == -1) {
            fprintf(logfile, "Log-dirty: out of memory\n");
            exit(1);
        }
    }

    fprintf(logfile, "Triggered log-dirty buffer switch\n");
    
    /* Read the required active buffer from the store */
    act = xs_read(xsh, XBT_NULL, next_active_path, &len);
    if (!act) {
        fprintf(logfile, "Log-dirty: can't read next-active\n");
        exit(1);
    }

    /* Switch buffers */
    i = act[0] - '0';
    if (i != 0 && i != 1) {
        fprintf(logfile, "Log-dirty: bad next-active entry: %s\n", act);
        exit(1);
    }
    logdirty_bitmap = (unsigned long *)(seg + i * logdirty_bitmap_size);

    /* Ack that we've switched */
    xs_write(xsh, XBT_NULL, active_path, act, len);
    free(act);
}