/* * This file is subject to the terms and conditions of the GNU General * Public License. See the file "COPYING" in the main directory of * this archive for more details. * * Copyright (C) 2006 Christian Limpach * Copyright (C) 2006 XenSource Ltd. * */ #include "vl.h" #include "block_int.h" #include #include #include #include #include #include struct xs_handle *xsh = NULL; static char *media_filename[MAX_DISKS + MAX_SCSI_DISKS]; static QEMUTimer *insert_timer = NULL; #define UWAIT_MAX (30*1000000) /* thirty seconds */ #define UWAIT (100000) /* 1/10th second */ static int pasprintf(char **buf, const char *fmt, ...) { va_list ap; int ret = 0; if (*buf) free(*buf); va_start(ap, fmt); if (vasprintf(buf, fmt, ap) == -1) { buf = NULL; ret = -1; } va_end(ap); return ret; } static void insert_media(void *opaque) { int i; for (i = 0; i < MAX_DISKS + MAX_SCSI_DISKS; i++) { if (media_filename[i] && bs_table[i]) { do_change(bs_table[i]->device_name, media_filename[i]); free(media_filename[i]); media_filename[i] = NULL; } } } void xenstore_check_new_media_present(int timeout) { if (insert_timer == NULL) insert_timer = qemu_new_timer(rt_clock, insert_media, NULL); qemu_mod_timer(insert_timer, qemu_get_clock(rt_clock) + timeout); } static void waitForDevice(char *fn) { struct stat sbuf; int status; int uwait = UWAIT_MAX; do { status = stat(fn, &sbuf); if (!status) break; usleep(UWAIT); uwait -= UWAIT; } while (uwait > 0); return; } 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; 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
module tb;

reg clk, rst;
wire [7:0] out;
wire [4:0] counter;

uut uut (clk, rst, out, counter);

initial begin
	#5 clk <= 0;
	repeat (100) #5 clk <= ~clk;
	#5 $finish;
end

initial begin
	rst <= 1;
	repeat (2) @(posedge clk);
	rst <= 0;
end

always @(posedge clk)
	$display("%d %d %d", rst, out, counter);

initial begin
	$dumpfile("mem_simple_4x1_tb.vcd");
	$dumpvars(0, uut);
end

endmodule
t of memory recording dm state\n"); goto out; } if (!xs_write(xsh, XBT_NULL, path, state, strlen(state))) fprintf(logfile, "error recording dm state\n"); out: free(path); } void xenstore_process_event(void *opaque) { char **vec, *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 || !strcmp(image, bs_table[hd_index]->filename)) goto out; /* gone or 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(image); free(vec); } void xenstore_write_vncport(int display) { char *buf = NULL, *path; char *portstr = NULL; if (xsh == NULL) 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/console/vnc-port", path) == -1) goto out; if (pasprintf(&portstr, "%d", display) == -1) goto out; if (xs_write(xsh, XBT_NULL, buf, portstr, strlen(portstr)) == 0) fprintf(logfile, "xs_write() vncport failed\n"); out: free(portstr); free(buf); } int xenstore_read_vncpasswd(int domid, char *pwbuf, size_t pwbuflen) { char *buf = NULL, *path, *uuid = NULL, *passwd = NULL; unsigned int i, len, rc = 0; if (xsh == NULL) { return -1; } path = xs_get_domain_path(xsh, domid); if (path == NULL) { fprintf(logfile, "xs_get_domain_path() error. domid %d.\n", domid); return -1; } pasprintf(&buf, "%s/vm", path); uuid = xs_read(xsh, XBT_NULL, buf, &len); if (uuid == NULL) { fprintf(logfile, "xs_read(): uuid get error. %s.\n", buf); free(path); return -1; } pasprintf(&buf, "%s/vncpasswd", uuid); passwd = xs_read(xsh, XBT_NULL, buf, &len); if (passwd == NULL) { fprintf(logfile, "xs_read(): vncpasswd get error. %s.\n", buf); pwbuf[0] = '\0'; free(uuid); free(path); return rc; } for (i=0; i