Esempio n. 1
0
//!
//! Generates the XML content for a given volume
//!
//! @param[in] volumeId the volume identifier string (vol-XXXXXXXX)
//! @param[in] instance a pointer to our instance structure
//! @param[in] localDevReal a string containing the target device name
//! @param[in] remoteDev a string containing the disk path.
//!
//! @return The results of calling write_xml_file()
//!
//! @see write_xml_file()
//!
int gen_volume_xml(const char *volumeId, const ncInstance * instance, const char *localDevReal, const char *remoteDev)
{
    int ret = EUCA_ERROR;
    char bitness[4] = "";
    char path[MAX_PATH] = "";
    xmlDocPtr doc = NULL;
    xmlNodePtr volumeNode = NULL;
    xmlNodePtr hypervisor = NULL;
    xmlNodePtr os = NULL;
    xmlNodePtr backing = NULL;
    xmlNodePtr root = NULL;
    xmlNodePtr disk = NULL;

    INIT();

    pthread_mutex_lock(&xml_mutex);
    {
        doc = xmlNewDoc(BAD_CAST "1.0");
        volumeNode = xmlNewNode(NULL, BAD_CAST "volume");
        xmlDocSetRootElement(doc, volumeNode);

        // hypervisor-related specs
        hypervisor = xmlNewChild(volumeNode, NULL, BAD_CAST "hypervisor", NULL);
        _ATTRIBUTE(hypervisor, "type", instance->hypervisorType);
        _ATTRIBUTE(hypervisor, "capability", hypervsorCapabilityTypeNames[instance->hypervisorCapability]);
        snprintf(bitness, 4, "%d", instance->hypervisorBitness);
        _ATTRIBUTE(hypervisor, "bitness", bitness);

        _ELEMENT(volumeNode, "id", volumeId);
        _ELEMENT(volumeNode, "user", instance->userId);
        _ELEMENT(volumeNode, "instancePath", instance->instancePath);

        // OS-related specs
        os = _NODE(volumeNode, "os");
        _ATTRIBUTE(os, "platform", instance->platform);
        _ATTRIBUTE(os, "virtioRoot", _BOOL(config_use_virtio_root));
        _ATTRIBUTE(os, "virtioDisk", _BOOL(config_use_virtio_disk));
        _ATTRIBUTE(os, "virtioNetwork", _BOOL(config_use_virtio_net));

        //! backing specification (@todo maybe expand this with device maps or whatnot?)
        backing = xmlNewChild(volumeNode, NULL, BAD_CAST "backing", NULL);
        root = xmlNewChild(backing, NULL, BAD_CAST "root", NULL);
        assert(instance->params.root);
        _ATTRIBUTE(root, "type", ncResourceTypeName[instance->params.root->type]);

        // volume information
        disk = _ELEMENT(volumeNode, "diskPath", remoteDev);
        _ATTRIBUTE(disk, "targetDeviceType", "disk");
        _ATTRIBUTE(disk, "targetDeviceName", localDevReal);
        _ATTRIBUTE(disk, "targetDeviceBus", "scsi");
        _ATTRIBUTE(disk, "sourceType", "block");

        snprintf(path, sizeof(path), EUCALYPTUS_VOLUME_XML_PATH_FORMAT, instance->instancePath, volumeId);
        ret = write_xml_file(doc, instance->instanceId, path, "volume");
        xmlFreeDoc(doc);
    }
    pthread_mutex_unlock(&xml_mutex);
    return (ret);
}
Esempio n. 2
0
int gen_libvirt_attach_xml (const char *volumeId, const ncInstance *instance, const char * localDevReal, const char * remoteDev, char * xml, unsigned int xml_size)
{
    INIT();

    int ret = 1;
    pthread_mutex_lock (&xml_mutex);
    xmlDocPtr doc = xmlNewDoc (BAD_CAST "1.0");
    xmlNodePtr volumeNode = xmlNewNode (NULL, BAD_CAST "volume");
    xmlDocSetRootElement (doc, volumeNode);

    { // hypervisor-related specs
        xmlNodePtr hypervisor = xmlNewChild (volumeNode, NULL, BAD_CAST "hypervisor", NULL);
        _ATTRIBUTE(hypervisor, "type", instance->hypervisorType);
        _ATTRIBUTE(hypervisor, "capability", hypervsorCapabilityTypeNames[instance->hypervisorCapability]);
        char bitness[4];
        snprintf(bitness, 4,"%d", instance->hypervisorBitness);
        _ATTRIBUTE(hypervisor, "bitness", bitness);
    }

    _ELEMENT(volumeNode, "id", volumeId);
    _ELEMENT(volumeNode, "user", instance->userId);
    _ELEMENT(volumeNode, "instancePath", instance->instancePath);

    { // OS-related specs
        xmlNodePtr os = _NODE(volumeNode, "os");
        _ATTRIBUTE(os, "platform", instance->platform);
        _ATTRIBUTE(os, "virtioRoot", _BOOL(config_use_virtio_root));
        _ATTRIBUTE(os, "virtioDisk", _BOOL(config_use_virtio_disk));
        _ATTRIBUTE(os, "virtioNetwork", _BOOL(config_use_virtio_net));
    }

    { // backing specification (TODO: maybe expand this with device maps or whatnot?)
        xmlNodePtr backing = xmlNewChild (volumeNode, NULL, BAD_CAST "backing", NULL);
        xmlNodePtr root = xmlNewChild (backing, NULL, BAD_CAST "root", NULL);
        assert (instance->params.root);
        _ATTRIBUTE(root, "type", ncResourceTypeName[instance->params.root->type]);
    }

    { // volume information
        xmlNodePtr disk = _ELEMENT(volumeNode, "diskPath", remoteDev);
        _ATTRIBUTE(disk, "targetDeviceType", "disk");
        _ATTRIBUTE(disk, "targetDeviceName", localDevReal);
        _ATTRIBUTE(disk, "targetDeviceBus", "scsi");
        _ATTRIBUTE(disk, "sourceType", "block");
        
    }

    char path [MAX_PATH];
    snprintf (path, sizeof (path), EUCALYPTUS_VOLUME_XML_PATH_FORMAT, instance->instancePath, volumeId);
    ret = write_xml_file (doc, instance->instanceId, path, "volume")
        || apply_xslt_stylesheet (xslt_path, path, NULL, xml, xml_size);
    logprintfl (EUCATRACE, "XML={%s}\n", xml);

    xmlFreeDoc(doc);
    pthread_mutex_unlock (&xml_mutex);

    return ret;
}
Esempio n. 3
0
// Encodes instance metadata (contained in ncInstance struct) in XML
// and writes it to file instance->xmlFilePath (/path/to/instance/instance.xml)
// That file gets processed through tools/libvirt.xsl (/etc/eucalyptus/libvirt.xsl)
// to produce /path/to/instance/libvirt.xml file that is passed to libvirt create.
int gen_instance_xml (const ncInstance * instance)
{
    INIT();

    int ret = 1;
    pthread_mutex_lock (&xml_mutex);
    xmlDocPtr doc = xmlNewDoc (BAD_CAST "1.0");
    xmlNodePtr instanceNode = xmlNewNode (NULL, BAD_CAST "instance");
    xmlDocSetRootElement (doc, instanceNode);

    { // hypervisor-related specs
        xmlNodePtr hypervisor = xmlNewChild (instanceNode, NULL, BAD_CAST "hypervisor", NULL);
        _ATTRIBUTE(hypervisor, "type", instance->hypervisorType);
        _ATTRIBUTE(hypervisor, "capability", hypervsorCapabilityTypeNames[instance->hypervisorCapability]);
        char bitness[4];
        snprintf(bitness, 4,"%d", instance->hypervisorBitness);
        _ATTRIBUTE(hypervisor, "bitness", bitness);
    }

    { // backing specification (TODO: maybe expand this with device maps or whatnot?)
        xmlNodePtr backing = xmlNewChild (instanceNode, NULL, BAD_CAST "backing", NULL);
        xmlNodePtr root = xmlNewChild (backing, NULL, BAD_CAST "root", NULL);
        assert (instance->params.root);
        _ATTRIBUTE(root, "type", ncResourceTypeName[instance->params.root->type]);
    }

    _ELEMENT(instanceNode, "name", instance->instanceId);
    _ELEMENT(instanceNode, "uuid", instance->uuid);
    _ELEMENT(instanceNode, "reservation", instance->reservationId);
    _ELEMENT(instanceNode, "user", instance->userId);
    _ELEMENT(instanceNode, "dnsName", instance->dnsName);
    _ELEMENT(instanceNode, "privateDnsName", instance->privateDnsName);
    _ELEMENT(instanceNode, "instancePath", instance->instancePath);
    if (instance->params.kernel) {
        char * path = instance->params.kernel->backingPath;
        if (path_check (path, "kernel")) goto free; // sanity check 
        _ELEMENT(instanceNode, "kernel", path);
    }
    if (instance->params.ramdisk) {
        char * path = instance->params.ramdisk->backingPath;
        if (path_check (path, "ramdisk")) goto free; // sanity check
        _ELEMENT(instanceNode, "ramdisk", path);
    }
    _ELEMENT(instanceNode, "consoleLogPath", instance->consoleFilePath);
    _ELEMENT(instanceNode, "userData", instance->userData);
    _ELEMENT(instanceNode, "launchIndex", instance->launchIndex);
    
    char cores_s  [10]; snprintf (cores_s,  sizeof (cores_s),  "%d", instance->params.cores);  _ELEMENT(instanceNode, "cores", cores_s);
    char memory_s [10]; snprintf (memory_s, sizeof (memory_s), "%d", instance->params.mem * 1024); _ELEMENT(instanceNode, "memoryKB", memory_s);

    { // SSH-key related
        xmlNodePtr key = _NODE(instanceNode, "key");
        _ATTRIBUTE(key, "isKeyInjected", _BOOL(instance->do_inject_key));
        _ATTRIBUTE(key, "sshKey", instance->keyName);
    }

    { // OS-related specs
        xmlNodePtr os = _NODE(instanceNode, "os");
        _ATTRIBUTE(os, "platform", instance->platform);
        _ATTRIBUTE(os, "virtioRoot", _BOOL(config_use_virtio_root));
        _ATTRIBUTE(os, "virtioDisk", _BOOL(config_use_virtio_disk));
        _ATTRIBUTE(os, "virtioNetwork", _BOOL(config_use_virtio_net));
    }

    { // disks specification
        xmlNodePtr disks = _NODE(instanceNode, "disks");

        // the first disk should be the root disk (at least for Windows)
        for (int root=1; root>=0; root--){ 
           for (int i=0; i<EUCA_MAX_VBRS && i<instance->params.virtualBootRecordLen; i++) {
               const virtualBootRecord * vbr = &(instance->params.virtualBootRecord[i]); 
               // skip empty entries, if any
               if (vbr==NULL)
                   continue;
               // do EMI on the first iteration of the outer loop
               if (root && vbr->type != NC_RESOURCE_IMAGE) 
                   continue;
               // ignore EMI on the second iteration of the outer loop
               if (!root && vbr->type == NC_RESOURCE_IMAGE)
                   continue;
               // skip anything without a device on the guest, e.g., kernel and ramdisk
               if (!strcmp ("none", vbr->guestDeviceName)) 
                   continue;
               // for Linux instances on Xen, partitions can be used directly, so disks can be skipped unless booting from EBS
               if (strstr (instance->platform, "linux") && strstr (instance->hypervisorType, "xen")) {
                   if (vbr->partitionNumber == 0 && vbr->type == NC_RESOURCE_IMAGE) {
                       continue;
                   }
               } else { // on all other os + hypervisor combinations, disks are used, so partitions must be skipped
                   if (vbr->partitionNumber > 0) {
                       continue;
                   }
               }
            
               xmlNodePtr disk = _ELEMENT(disks, "diskPath", vbr->backingPath);
               _ATTRIBUTE(disk, "targetDeviceType", libvirtDevTypeNames[vbr->guestDeviceType]);
               _ATTRIBUTE(disk, "targetDeviceName", vbr->guestDeviceName);
               char devstr[SMALL_CHAR_BUFFER_SIZE];
               snprintf(devstr, SMALL_CHAR_BUFFER_SIZE, "%s", vbr->guestDeviceName);             
               if (config_use_virtio_root) {
                   devstr[0] = 'v';
                   _ATTRIBUTE(disk, "targetDeviceNameVirtio", devstr);
                   _ATTRIBUTE(disk, "targetDeviceBusVirtio", "virtio");     
               }
               _ATTRIBUTE(disk, "targetDeviceBus", libvirtBusTypeNames[vbr->guestDeviceBus]);
               _ATTRIBUTE(disk, "sourceType", libvirtSourceTypeNames[vbr->backingType]);

               if (root) {
                   xmlNodePtr rootNode = _ELEMENT(disks, "root", NULL);
                   _ATTRIBUTE(rootNode, "device", devstr);
                   char root_uuid[64] = "";
                   if (get_blkid (vbr->backingPath, root_uuid, sizeof(root_uuid)) == 0) {
                       assert (strlen (root_uuid));
                       _ATTRIBUTE(rootNode, "uuid", root_uuid);
                   }
               }
           }
           if (strlen (instance->floppyFilePath)) {
               _ELEMENT(disks, "floppyPath", instance->floppyFilePath);
           }
       }
    }

    if (instance->params.nicType!=NIC_TYPE_NONE) { // NIC specification
        xmlNodePtr nics = _NODE(instanceNode, "nics");
        xmlNodePtr nic =  _NODE(nics, "nic");
        _ATTRIBUTE(nic, "bridgeDeviceName", instance->params.guestNicDeviceName);
        _ATTRIBUTE(nic, "mac", instance->ncnet.privateMac);
    }

    ret = write_xml_file (doc, instance->instanceId, instance->xmlFilePath, "instance");
 free:
    xmlFreeDoc(doc);
    pthread_mutex_unlock (&xml_mutex);

    return ret;
}