[libvirt] [PATCH 4/4] Addition of XenAPI support to libvirt

Daniel P. Berrange berrange at redhat.com
Sat Feb 20 16:21:38 UTC 2010


On Fri, Feb 19, 2010 at 11:24:56AM +0000, Sharadha Prabhakar (3P) wrote:
> diff -Nur ./libvirt_org/src/xenapi/xenapi_utils.c ./libvirt/src/xenapi/xenapi_utils.c
> --- ./libvirt_org/src/xenapi/xenapi_utils.c     1970-01-01 01:00:00.000000000 +0100
> +++ ./libvirt/src/xenapi/xenapi_utils.c 2010-02-18 16:26:52.000000000 +0000
> +/* obtains the CPU bitmap from the string passed */
> +void
> +getCpuBitMapfromString(char *mask, unsigned char *cpumap, int maplen)
> +{
> +    int pos;
> +    int max_bits = maplen * 8;
> +    char *num = NULL;
> +    bzero(cpumap, maplen);
> +    num = strtok (mask, ",");
> +    while (num != NULL) {
> +        sscanf (num, "%d", &pos);
> +        if (pos<0 || pos>max_bits-1)
> +            printf ("number in str %d exceeds cpumap's max bits %d\n", pos, max_bits);
> +        else
> +            (cpumap)[pos/8] |= (1<<(pos%8));
> +            num = strtok (NULL, ",");
> +    }
> +}

Don't printf() if you find problems. If it is a non-fatal problem then
use either VIR_INFO/VIR_WARN/VIR_DEBUG from logging.h. If it is fatal
then use the error reporting API.

The strtok() API is not allowed in libvirt, since it is not threadsafe.
You'll likely want to use strtok_r() instead.

> +/* create boot order string as understood by libvirt */
> +void
> +createXmlBootOrderString(char **order, char *key)
> +{
> +    int sz = ((*order)==NULL)?0:(strlen(*order)+1);
> +    const char *temp=NULL;
> +    if (strcmp(key,"fd")==0)
> +        temp="a";
> +    else if (strcmp(key,"hd")==0)
> +        temp="c";
> +    else if (strcmp(key,"cdrom")==0)
> +        temp="d";
> +    else if (strcmp(key,"network")==0)
> +        temp="n";

Instead of strcmp(), use  STREQ() for these.

> +
> +/* Create a VM record from the XML description */
> +int
> +createVMRecordFromXml (virConnectPtr conn, const char *xmlDesc,
> +                       xen_vm_record **record, xen_vm *vm)

This method is one that should accept a virDomainDefPtr rather
than the raw XML document. That lets you re-use the standard
XML parsing routines that are shared between drivers

> +{
> +    xmlDocPtr doc;
> +    xmlNodePtr cur,child,temp;
> +    doc = xmlParseMemory(xmlDesc,strlen(xmlDesc));
> +    if (doc == NULL) {
> +        xenapiSessionErrorHandler(conn,VIR_ERR_XML_ERROR ,"", __FILE__, __FUNCTION__, __LINE__);
> +        return -1;
> +    }
> +    cur = xmlDocGetRootElement(doc);
> +    if (cur == NULL) {
> +        xenapiSessionErrorHandler(conn,VIR_ERR_XML_ERROR ,"", __FILE__, __FUNCTION__, __LINE__);
> +        xmlFreeDoc(doc);
> +        return -1;
> +    }
> +    if (xmlStrcmp(cur->name, (const xmlChar *) "domain")) {
> +        xenapiSessionErrorHandler(conn,VIR_ERR_XML_ERROR ,"root node not domain", __FILE__, __FUNCTION__, __LINE__);
> +        xmlFreeDoc(doc);
> +        return -1;
> +    }
> +    *record = xen_vm_record_alloc();
> +    char *name = getXmlChildValue(doc,cur,"name");
> +    (*record)->name_label = strdup(name);
> +    child = cur->xmlChildrenNode;
> +    while (child!=NULL) {
> +        if ((!xmlStrcmp(child->name, (const xmlChar *)"os"))) {
> +            char *ostype = getXmlChildValue(doc,child,"type");
> +            if (ostype!=NULL) {
> +                if (STREQ(ostype,"hvm")) {
> +                    (*record)->hvm_boot_policy = strdup("BIOS order");
> +                     temp = child;
> +                     child = child->xmlChildrenNode;
> +                     char *boot_order = NULL;
> +                     while (child != NULL) {
> +                         if ((!xmlStrcmp(child->name, (const xmlChar *)"boot"))){
> +                             xmlChar *key;
> +                             key = xmlGetProp(child, (const xmlChar *)"dev");
> +                             if (key!=NULL) {
> +                                 createXmlBootOrderString(&boot_order,(char *)key);
> +                                 xmlFree(key);
> +                             }
> +                         }
> +                         child = child->next;
> +                     }
> +                     if (boot_order!=NULL) {
> +                        xen_string_string_map *hvm_boot_params=NULL;
> +                        allocStringMap(&hvm_boot_params, (char *)"order",boot_order);
> +                        //int size = sizeof(xen_string_string_map) +
> +                        //          (hvm_boot_params->size * sizeof(xen_string_string_map_contents));
> +                        //(*record)->hvm_boot_params = (xen_string_string_map *) malloc(size);
> +                        //memcpy((char *)(*record)->hvm_boot_params, (char *)hvm_boot_params, size);
> +                         (*record)->hvm_boot_params = hvm_boot_params;
> +                        VIR_FREE(boot_order);
> +                         //freeStringMap(hvm_boot_params);
> +                     }
> +                    child = temp;
> +                } else if (STREQ(ostype,"linux")) {
> +                    (*record)->pv_bootloader = strdup("pygrub");
> +                    char *kernel = getXmlChildValue(doc,child,"kernel");
> +                    if (kernel != NULL){
> +                        (*record)->pv_kernel = kernel;
> +                        //strcpy((*record)->pv_kernel,kernel);
> +                        //free(kernel);
> +                    }
> +                    char *initrd = getXmlChildValue(doc,child,"initrd");
> +                    if (initrd != NULL) {
> +                        (*record)->pv_ramdisk = initrd;//(char *)malloc(strlen(initrd)+1);
> +                        //strcpy((*record)->pv_ramdisk,initrd);
> +                        //free(initrd);
> +                    }
> +                    char *cmdline = getXmlChildValue(doc,child,"cmdline");
> +                    if (cmdline != NULL) {
> +                        (*record)->pv_args = cmdline; //(char *)malloc(strlen(cmdline)+1);
> +                        //strcpy((*record)->pv_args,cmdline);
> +                        //free(cmdline);
> +                    }
> +                    (*record)->hvm_boot_params = xen_string_string_map_alloc(0);
> +                }
> +                VIR_FREE(ostype);
> +            }
> +        }
> +        child = child->next;
> +    }
> +    char *bootload_args =  getXmlChildValue(doc,cur,"bootloader_args");
> +    if (bootload_args!=NULL) {
> +        (*record)->pv_bootloader_args =bootload_args; //(char *)malloc(strlen(bootload_args)+1);
> +       //strcpy((*record)->pv_bootloader_args,bootload_args);
> +       //free(bootload_args);
> +    }
> +    char *memory = getXmlChildValue(doc,cur,"memory");
> +    if (memory!=NULL) {
> +        int64_t static_max=0;
> +        static_max = atoll(memory);
> +        (*record)->memory_static_max = static_max * 1024;
> +        VIR_FREE(memory);
> +    }
> +    char *curmemory = getXmlChildValue(doc,cur,"currentmemory");
> +    if (curmemory!=NULL) {
> +        int64_t dy_max=0;
> +        dy_max = atoll(curmemory);
> +        (*record)->memory_dynamic_max = dy_max * 1024;
> +        VIR_FREE(curmemory);
> +    } else {
> +        (*record)->memory_dynamic_max = (*record)->memory_static_max;
> +    }
> +    char *vcpu =  getXmlChildValue(doc, cur, "vcpu");
> +    if (vcpu!=NULL) {
> +        (*record)->vcpus_max = atoll(vcpu);
> +       (*record)->vcpus_at_startup =  atoll(vcpu);
> +       VIR_FREE(vcpu);
> +    }
> +    char *on_poweroff = getXmlChildValue(doc,cur,"on_poweroff");
> +    if (on_poweroff!=NULL) {
> +        (*record)->actions_after_shutdown = actionShutdownStringtoEnum(on_poweroff);
> +        VIR_FREE(on_poweroff);
> +    }
> +    char *on_reboot = getXmlChildValue(doc,cur,"on_reboot");
> +    if (on_reboot!=NULL) {
> +        (*record)->actions_after_reboot = actionShutdownStringtoEnum(on_reboot);
> +        VIR_FREE(on_reboot);
> +    }
> +    char *on_crash = getXmlChildValue(doc,cur,"on_crash");
> +    if (on_crash!=NULL) {
> +        (*record)->actions_after_crash = actionCrashStringtoEnum(on_crash);
> +        VIR_FREE(on_crash);
> +    }
> +    temp = cur;
> +    cur = cur->xmlChildrenNode;
> +    xen_string_string_map *strings=NULL;
> +    while (cur != NULL) {
> +        if ((!xmlStrcmp(cur->name, (const xmlChar *)"features"))){
> +            for (child=cur->children;child!=NULL;child=child->next) {
> +                allocStringMap(&strings,(char *)child->name,(char *)"true");
> +            }
> +        }
> +        cur = cur->next;
> +    }
> +    cur = temp;
> +    if (strings!=NULL) {
> +        //int size = sizeof(xen_string_string_map)+ sizeof(xen_string_string_map_contents)*strings->size;
> +        (*record)->platform = strings; //(xen_string_string_map *)malloc(size);
> +        //memcpy((void *)(*record)->platform,(void *)strings,size);
> +    }
> +    (*record)->vcpus_params = xen_string_string_map_alloc(0);
> +    (*record)->other_config = xen_string_string_map_alloc(0);
> +    (*record)->last_boot_cpu_flags = xen_string_string_map_alloc(0);
> +    (*record)->xenstore_data = xen_string_string_map_alloc(0);
> +    (*record)->hvm_shadow_multiplier = 1.000;
> +    if (!xen_vm_create(((struct _xenapiPrivate *)(conn->privateData))->session,
> +                        vm, *record)) {
> +        xmlFreeDoc(doc);
> +        xenapiSessionErrorHandler(conn,VIR_ERR_INTERNAL_ERROR ,NULL, __FILE__, __FUNCTION__, __LINE__);
> +        return -1;
> +    }
> +    cur = cur->xmlChildrenNode;
> +    int device_number=0;
> +    xmlChar *bridge=NULL,*mac=NULL;
> +    while (cur != NULL) {
> +        if ((!xmlStrcmp(cur->name, (const xmlChar *)"interface"))){
> +            for (child=cur->children;child!=NULL;child=child->next) {
> +                if ((!xmlStrcmp(child->name, (const xmlChar *)"source"))) {
> +                    bridge = xmlGetProp(child, (const xmlChar *)"bridge");
> +                }
> +                if ((!xmlStrcmp(child->name, (const xmlChar *)"mac"))) {
> +                    mac = xmlGetProp(child, (const xmlChar *)"address");
> +                }
> +            }
> +           if (mac!=NULL && bridge!=NULL) {
> +               char device[NETWORK_DEVID_SIZE]="\0";
> +               sprintf(device,"%d",device_number);
> +               createVifNetwork(conn, *vm, device, (char *)bridge, (char *)mac);
> +               xmlFree(bridge);
> +               device_number++;
> +           }
> +        }
> +       cur = cur->next;
> +    }
> +    xmlFreeDoc(doc);
> +    return 0;
> +}
> +


Regards,
Daniel
-- 
|: Red Hat, Engineering, London    -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://deltacloud.org :|
|: http://autobuild.org        -o-         http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-   F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|




More information about the libvir-list mailing list