On Mon, Aug 28, 2006 at 04:55:09AM -0400, Daniel Veillard wrote: > On Mon, Aug 28, 2006 at 12:18:52AM +0100, Daniel P. Berrange wrote: > > There is intended to be one qemud instance per UNIX user - the so called > > 'session' instance, and optionally one system global instance runing as > > root (or a system daemon account?) - the so called 'system' instance. When > > using libvirt, the URIs for each are 'qemu:///session' and 'qemu:///system' > > respectively. > > I'm wondering what would be the role of the system instance. Aggregate > the informations from the set of users running qemu when running as root ? Well, the session instance is intended to fill the desktop user use-case, while the system instance is more aimed at a data-center use case where an admin might set up a bunch of persistently running QEMU instances on a server. > > The UNIX socket for session instances is $HOME/.qemud and is > > chmod 0700 - no support is provided for users connecting to each other's > > instances. Although we could trivially extend to create a read-only socket > > $HOME/.qemud-ro if desired. The system instance is currently not finished > > but intended to run in /var/run/qemud or some such. > > hum .... I'm not too fond of putting the socket directly in the user > home directory, I would feel better with a .qemud directory, protected 700 > by default and then have the socket mapped in that directory, I think it is > more secure, a bit cleaner to not have socket in home dir, and gives a place > to store informations if needed. Actually you already create .qemud.d for > storage, can we just make it .qemud and store the socket there ? > > Or we can use a socket not mapped in the filesystem at all, based on the > user name, which usually avoid the race when checking and then opening. Actually, the socket is already in the abstract namespace - i use the abstract path '\0$HOME/.qemud' - could easily put it in a dir below though > > +static int qemudParseUUID(const char *uuid, > > + unsigned char *rawuuid) { > > Should we make a lib subdir to avoid duplicating code like this ? > Alone that doesn't sound worth it, but if there is more routines duplicated > could be useful. Ues, as karel pointed out, there are a number of utility functions from libvirt that I duplicated in the qemud/ directory primarily because I wanted to avoid the circular depedancy back onto libvirt from the daemon. I think it would be worthwhile having the various helper routines in some lib that we can then pull into both libvirt & the daemon as needed. > > > + //virXMLError(VIR_ERR_NO_SOURCE, (const char *) target, 0); > > + //virXMLError(VIR_ERR_NO_TARGET, (const char *) source, 0); > > + printf("Bogus floppy\n"); > > + printf("Bogus cdomr\n"); > > + printf("alse %s %s\n", device, target); > > Need to unify and make the usual wrappers for error code. > Even if not linked in the libvirt lib, so that error messages > could be carried back at the protocol level, if we put much logic in > the qemud we will need some logging facilities, or transport errors, right ? Yes, I need to rip out the debug code & formalize the set of error codes which can be returned to libvirt. Currently I catch every error and just return a generic -1, internal error. Obviously this needs to be better before the patch is merged. > > + obj = xmlXPathEval(BAD_CAST "/domain/devices/graphics", ctxt); > > + if ((obj == NULL) || (obj->type != XPATH_NODESET) || > > + (obj->nodesetval == NULL) || (obj->nodesetval->nodeNr == 0)) { > > + vm->def.graphicsType = QEMUD_GRAPHICS_NONE; > > + } else { > > + prop = xmlGetProp(obj->nodesetval->nodeTab[0], BAD_CAST "type"); > > + if (!strcmp((char *)prop, "vnc")) { > > + vm->def.graphicsType = QEMUD_GRAPHICS_VNC; > > + prop = xmlGetProp(obj->nodesetval->nodeTab[0], BAD_CAST "port"); > > + if (prop) { > > + conv = NULL; > > + vm->def.vncPort = strtoll((const char*)prop, &conv, 10); > > + } else { > > + vm->def.vncPort = 0; > > + } > > + } > > + } > > Hum ... if we have no graphic device what's going on ? the QEmu process > is forked by a daemon, so there is no way to get back to the console... > The console access is something we didn't tried to address so far in libvirt. > At least some console logs would be useful, otherwise we have the > problem of hitting asynchronous interface is we really want to give interactive > access... Well we can probably live without :-) There's a couple of different ways this can work - the VNC console, or we can hook up a serial device to the guest (and assume user puts appropriate kernl boot command line args in 'console=ttyS0'. I also expect to save the stderr and stdout from QEMU to a log file so user can see if stuff goes wrong. I expect VNC is the primary console though. > > + if (stat(server->configDir, &sb) < 0) { > > + if (errno == ENOENT) { > > + if (mkdir(server->configDir, 0700) < 0) > > + return -1; > > + } else { > > + return -1; > > + } > > + } else if (!S_ISDIR(sb.st_mode)) { > > + return -1; > > + } > > Shouldn't we check the mode and owner if the directory already exists ? > that should be in the stat informations. Yes, worthwhile doing. > > > + if (qemudFindVMByUUID(server, vm->def.uuid)) { > > + qemudFreeVM(vm); > > + printf("Duplicate domains, discarding %s\n", file); > > + return NULL; > > + } > > UUID clashes due to users manually copying files may be more frequent than > expected. Cloning is gonna be fun in general ... Yes, I'm not entirely sure what we can do there - either document - "do not do that", or automatically re-generate the UUID if they have a duplicate (re-saving the cofig file to disk with the new UUID). I believe VMWare automatically re-generates the UUID if you manually copy a file, so its a reasonable approach to take. Could do the same with the Name if neccessary - just append '-1', '-2', or something on to the end of it. > > + if (qemudFindVMByName(server, vm->def.name)) { > > + qemudFreeVM(vm); > > + printf("Duplicate domains, discarding %s\n", file); > > + return NULL; > > + } > [...] > > +int qemudScanConfigs(struct qemud_server *server) { > > 2 things here: > 1/ caching if the modification timestamps of the directory and file > didn't changed. I don't know how often the scanning will be done > but it's not lightweight since it reparses everything > 2/ name and uuid clashes could be detected here or when adding some. If we wanted to be really clever we could use INotify to automatically re-scan. A simple approach though would just re-scan the directory comparing timestamps every minute or so & re-loading configs which have changed. > I scanned quickly the protocol part but I need to get my head around it :-) There's a couple of important assumptions I apply in the network code which I should document further to help explain the way it works. > That's a lot of code ! One think I would like is to try to get all commenting > at the same level, i.e. having every function carrying a comment header, > That's something I will help with, maybe as a side effect of reviewing the > code. Tell me how we could do that ? Maybe I could start with the simplest > code from qemud. > > > -#define MAX_DRIVERS 5 > > +#define MAX_DRIVERS 10 > > I didn't expect that initially :-) Hehe - took me a little while to track down that issue too - I just could not work out why nothing was working at first :-) Dan. -- |=- Red Hat, Engineering, Emerging Technologies, Boston. +1 978 392 2496 -=| |=- Perl modules: http://search.cpan.org/~danberr/ -=| |=- Projects: http://freshmeat.net/~danielpb/ -=| |=- GnuPG: 7D3B9505 F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 -=|