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; }
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; }
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; }
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; }
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); }
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); }