static int doInitialize (struct nc_state_t *nc) { char *s = NULL; virNodeInfo ni; long long dom0_min_mem; logprintfl(EUCADEBUG, "doInitialized() invoked\n"); /* set up paths of Eucalyptus commands NC relies on */ snprintf (nc->gen_libvirt_cmd_path, MAX_PATH, EUCALYPTUS_GEN_LIBVIRT_XML, nc->home, nc->home); snprintf (nc->get_info_cmd_path, MAX_PATH, EUCALYPTUS_GET_XEN_INFO, nc->home, nc->home); snprintf (nc->virsh_cmd_path, MAX_PATH, EUCALYPTUS_VIRSH, nc->home); snprintf (nc->xm_cmd_path, MAX_PATH, EUCALYPTUS_XM); snprintf (nc->detach_cmd_path, MAX_PATH, EUCALYPTUS_DETACH, nc->home, nc->home); snprintf (nc->connect_storage_cmd_path, MAX_PATH, EUCALYPTUS_CONNECT_ISCSI, nc->home, nc->home); snprintf (nc->disconnect_storage_cmd_path, MAX_PATH, EUCALYPTUS_DISCONNECT_ISCSI, nc->home, nc->home); snprintf (nc->get_storage_cmd_path, MAX_PATH, EUCALYPTUS_GET_ISCSI, nc->home, nc->home); strcpy(nc->uri, HYPERVISOR_URI); nc->convert_to_disk = 0; /* check connection is fresh */ if (!check_hypervisor_conn()) { return ERROR_FATAL; } /* get resources */ if (virNodeGetInfo(nc->conn, &ni)) { logprintfl (EUCAFATAL, "error: failed to discover resources\n"); return ERROR_FATAL; } /* dom0-min-mem has to come from xend config file */ s = system_output (nc->get_info_cmd_path); if (get_value (s, "dom0-min-mem", &dom0_min_mem)) { logprintfl (EUCAFATAL, "error: did not find dom0-min-mem in output from %s\n", nc->get_info_cmd_path); free (s); return ERROR_FATAL; } free (s); /* calculate the available memory */ nc->mem_max = ni.memory/1024 - 32 - dom0_min_mem; /* calculate the available cores */ nc->cores_max = ni.cpus; /* let's adjust the values based on the config values */ if (nc->config_max_mem && nc->config_max_mem < nc->mem_max) nc->mem_max = nc->config_max_mem; if (nc->config_max_cores) nc->cores_max = nc->config_max_cores; logprintfl(EUCAINFO, "Using %lld cores\n", nc->cores_max); logprintfl(EUCAINFO, "Using %lld memory\n", nc->mem_max); return OK; }
/* * Retrieves a translated label from <fault> block. * * NOTE: The pointer returned by this function must be free()'d by the * caller. * * FIXME: Consolidate with get_common_var()? * * FIXME: Gosh this looks messy. */ static char * get_fault_var (const char *var, const xmlNode *f_node) { if ((f_node == NULL) || (var == NULL)) { logprintfl (EUCAWARN, "get_fault_var() called with one or more NULL arguments.\n"); return NULL; } // Just in case we're matching the top-level node. // FIXME: Move this into a new tmfunction to eliminate repeated logic below? if ((f_node->type == XML_ELEMENT_NODE) && !strcasecmp ((const char *)f_node->name, var)) { xmlChar *value = xmlGetProp ((xmlNode *)f_node, (const xmlChar *)LOCALIZED_TAG); if (value == NULL) { value = xmlGetProp ((xmlNode *)f_node, (const xmlChar *)MESSAGE_TAG); } // This is a special (parent) case, so it doesn't handle // message/localized text in a child node. return (char *)value; } for (xmlNode *node = xmlFirstElementChild ((xmlNode *)f_node); node; node = node->next) { if ((node->type == XML_ELEMENT_NODE) && !strcasecmp ((const char *)node->name, var)) { xmlChar *value = xmlGetProp (node, (const xmlChar *)LOCALIZED_TAG); if (value == NULL) { value = xmlGetProp (node, (const xmlChar *)MESSAGE_TAG); } if (value == NULL) { // May be a child node, e.g. for "resolution" for (xmlNode *subnode = xmlFirstElementChild (node); subnode; subnode = subnode->next) { if ((node->type == XML_ELEMENT_NODE) && !strcasecmp ((const char *)subnode->name, LOCALIZED_TAG)) { return (char *)xmlNodeGetContent (subnode); } } // FIXME: More elegant method than another list walk? for (xmlNode *subnode = xmlFirstElementChild (node); subnode; subnode = subnode->next) { if ((node->type == XML_ELEMENT_NODE) && !strcasecmp ((const char *)subnode->name, MESSAGE_TAG)) { return (char *)xmlNodeGetContent (subnode); } } } return (char *)value; } } logprintfl (EUCAWARN, "Did not find <%s> message in get_fault_var().\n", var); return NULL; }
void libvirt_error_handler ( void *userData, virErrorPtr error) { if ( error==NULL) { logprintfl (EUCAERROR, "libvirt error handler was given a NULL pointer\n"); } else { logprintfl (EUCAERROR, "libvirt: %s (code=%d)\n", error->message, error->code); } }
int instNetParamsSet(ccInstance *inst, void *in) { int rc, ret=0, i; char userToken[64], *cleanGroupName=NULL; if (!inst) { return(1); } else if ( (strcmp(inst->state, "Pending") && strcmp(inst->state, "Extant")) ) { return(0); } logprintfl(EUCADEBUG, "instNetParamsSet(): instanceId=%s publicIp=%s privateIp=%s privateMac=%s vlan=%d\n", inst->instanceId, inst->ccnet.publicIp, inst->ccnet.privateIp, inst->ccnet.privateMac, inst->ccnet.vlan); if (inst->ccnet.vlan >= 0) { // activate network vnetconfig->networks[inst->ccnet.vlan].active = 1; // set up groupName and userName if (inst->groupNames[0][0] != '\0' && inst->accountId[0] != '\0') { // logic to strip the username from the supplied network name snprintf(userToken, 63, "%s-", inst->accountId); cleanGroupName = strstr(inst->groupNames[0], userToken); if (cleanGroupName) { cleanGroupName = cleanGroupName + strlen(userToken); } else { cleanGroupName = inst->groupNames[0]; } // if ( (vnetconfig->users[inst->ccnet.vlan].netName[0] != '\0' && strcmp(vnetconfig->users[inst->ccnet.vlan].netName, inst->groupNames[0])) || (vnetconfig->users[inst->ccnet.vlan].userName[0] != '\0' && strcmp(vnetconfig->users[inst->ccnet.vlan].userName, inst->accountId)) ) { if ( (vnetconfig->users[inst->ccnet.vlan].netName[0] != '\0' && strcmp(vnetconfig->users[inst->ccnet.vlan].netName, cleanGroupName)) || (vnetconfig->users[inst->ccnet.vlan].userName[0] != '\0' && strcmp(vnetconfig->users[inst->ccnet.vlan].userName, inst->accountId)) ) { // this means that there is a pre-existing network with the passed in vlan tag, but with a different netName or userName logprintfl(EUCAERROR, "instNetParamsSet(): input instance vlan<->user<->netname mapping is incompatible with internal state. Internal - userName=%s netName=%s vlan=%d. Instance - userName=%s netName=%s vlan=%d\n", vnetconfig->users[inst->ccnet.vlan].userName, vnetconfig->users[inst->ccnet.vlan].netName, inst->ccnet.vlan, inst->accountId, cleanGroupName, inst->ccnet.vlan); ret = 1; } else { // snprintf(vnetconfig->users[inst->ccnet.vlan].netName, 32, "%s", inst->groupNames[0]); snprintf(vnetconfig->users[inst->ccnet.vlan].netName, 64, "%s", cleanGroupName); snprintf(vnetconfig->users[inst->ccnet.vlan].userName, 48, "%s", inst->accountId); } } } if (!ret) { // so far so good rc = vnetGenerateNetworkParams(vnetconfig, inst->instanceId, inst->ccnet.vlan, inst->ccnet.networkIndex, inst->ccnet.privateMac, inst->ccnet.publicIp, inst->ccnet.privateIp); if (rc) { print_ccInstance("instNetParamsSet(): failed to (re)generate network parameters: ", inst); ret = 1; } } if (ret) { logprintfl(EUCADEBUG, "instNetParamsSet(): sync of network cache with instance data FAILED (instanceId=%s, publicIp=%s, privateIp=%s, vlan=%d, networkIndex=%d\n", inst->instanceId, inst->ccnet.publicIp, inst->ccnet.privateIp, inst->ccnet.vlan, inst->ccnet.networkIndex); } else { logprintfl(EUCADEBUG, "instNetParamsSet(): sync of network cache with instance data SUCCESS (instanceId=%s, publicIp=%s, privateIp=%s, vlan=%d, networkIndex=%d\n", inst->instanceId, inst->ccnet.publicIp, inst->ccnet.privateIp, inst->ccnet.vlan, inst->ccnet.networkIndex); } return(0); }
int create_instance_backing (ncInstance * instance) { int ret = ERROR; virtualMachine * vm = &(instance->params); // ensure instance directory exists set_path (instance->instancePath, sizeof (instance->instancePath), instance, NULL); if (ensure_directories_exist (instance->instancePath, 0, NULL, "root", BACKING_DIRECTORY_PERM) == -1) goto out; // set various instance-directory-relative paths in the instance struct set_path (instance->xmlFilePath, sizeof (instance->xmlFilePath), instance, "instance.xml"); set_path (instance->libvirtFilePath, sizeof (instance->libvirtFilePath), instance, "libvirt.xml"); set_path (instance->consoleFilePath, sizeof (instance->consoleFilePath), instance, "console.log"); if (strstr (instance->platform, "windows")) { // generate the floppy file for windows instances if (makeWindowsFloppy (nc_state.home, instance->instancePath, instance->keyName, instance->instanceId)) { logprintfl (EUCAERROR, "[%s] error: could not create windows bootup script floppy\n", instance->instanceId); goto out; } else { set_path (instance->floppyFilePath, sizeof (instance->floppyFilePath), instance, "floppy"); } } char work_prefix [1024]; // {userId}/{instanceId} set_id (instance, NULL, work_prefix, sizeof (work_prefix)); // compute tree of dependencies artifact * sentinel = vbr_alloc_tree (vm, // the struct containing the VBR FALSE, // for Xen and KVM we do not need to make disk bootable TRUE, // make working copy of runtime-modifiable files (instance->do_inject_key)?(instance->keyName):(NULL), // the SSH key instance->instanceId); // ID is for logging if (sentinel == NULL) { logprintfl (EUCAERROR, "[%s] error: failed to prepare backing for instance\n", instance->instanceId); goto out; } sem_p (disk_sem); // download/create/combine the dependencies int rc = art_implement_tree (sentinel, work_bs, cache_bs, work_prefix, INSTANCE_PREP_TIMEOUT_USEC); sem_v (disk_sem); if (rc != OK) { logprintfl (EUCAERROR, "[%s] error: failed to implement backing for instance\n", instance->instanceId); goto out; } if (save_instance_struct (instance)) // update instance checkpoint now that the struct got updated goto out; ret = OK; out: if (sentinel) art_free (sentinel); return ret; }
/* caller must free the returned string */ char * euca_get_cert (unsigned char options) { if (!initialized) euca_init_cert (); char * cert_str = NULL; int s, fp; struct stat st; if (stat (cert_file, &st) != 0) { logprintfl (EUCAERROR, "error: cannot stat the certificate file %s\n", cert_file); } else if ( (s = st.st_size*2) < 1) { /* *2 because we'll add characters */ logprintfl (EUCAERROR, "error: certificate file %s is too small\n", cert_file); } else if ( (cert_str = malloc (s+1)) == NULL ) { logprintfl (EUCAERROR, "error: out of memory\n"); } else if ( (fp = open (cert_file, O_RDONLY)) < 0 ) { logprintfl (EUCAERROR, "error: failed to open certificate file %s\n", cert_file); free (cert_str); cert_str = NULL; } else { ssize_t ret = -1; int got = 0; while ( got < s && (ret = read (fp, cert_str + got, 1) ) == 1 ) { if ( options & CONCATENATE_CERT ) { /* omit all newlines */ if ( cert_str [got] == '\n' ) continue; } else { if ( options & INDENT_CERT ) /* indent lines 2 through N with TABs */ if ( cert_str [got] == '\n' ) cert_str [++got] = '\t'; } got++; } if (ret != 0) { logprintfl (EUCAERROR, "error: failed to read whole certificate file %s\n", cert_file); free (cert_str); cert_str = NULL; } else { if ( options & TRIM_CERT ) { if ( cert_str [got-1] == '\t' || cert_str [got-1] == '\n' ) got--; if ( cert_str [got-1] == '\n' ) got--; /* because of indenting */ } cert_str [got] = '\0'; } close (fp); } return cert_str; }
int diskutil_init (int require_grub) // 0 = not required, 1 = required { int ret = 0; if (require_grub > 0) require_grub = 1; if (initialized < 1+require_grub) { // if init was called without grub requirement, it will run again if grub is needed now bzero (helpers_path, sizeof (helpers_path)); int missing_handlers = verify_helpers (helpers, helpers_path, LASTHELPER); if (helpers_path [GRUB]) grub_version = 1; else missing_handlers--; if (helpers_path [GRUB_SETUP]) {// don't need it, but grub-setup only exists on v2 if (grub_version != 1) grub_version = 2; // prefer 1 until 2 is implemented } else missing_handlers--; if (require_grub && grub_version == 0) { logprintfl (EUCAERROR, "ERROR: cannot find either grub 1 or grub 2\n"); ret = 1; } else if (grub_version == 1) { // grub 1 commands seem present, check for stage files, which we will be copying if (try_stage_dir ("/usr/lib/grub/x86_64-pc") || try_stage_dir ("/usr/lib/grub/i386-pc") || try_stage_dir ("/usr/lib/grub") || try_stage_dir ("/boot/grub")) { logprintfl (EUCAINFO, "found grub 1 stage files in %s\n", stage_files_dir); } else if (require_grub) { logprintfl (EUCAERROR, "ERROR: failed to find grub 1 stage files (in /boot/grub et al)\n"); ret = 1; } } else if (grub_version == 2) { logprintfl (EUCAINFO, "detected grub 2\n"); } // flag missing handlers if (missing_handlers) { for (int i=0; i<LASTHELPER; i++) { if (helpers_path [i] == NULL && i!=GRUB && i!=GRUB_SETUP) { logprintfl (EUCAERROR, "ERROR: missing a required handler: %s\n", helpers[i]); ret = 1; } } } if (initialized < 1) loop_sem = sem_alloc (1, "mutex"); initialized = 1 + require_grub; } return ret; }
static int doTerminateInstance( struct nc_state_t *nc, ncMetadata *meta, char *instanceId, int *shutdownState, int *previousState) { ncInstance *instance, *vninstance; virConnectPtr *conn; int err; sem_p (inst_sem); instance = find_instance(&global_instances, instanceId); sem_v (inst_sem); if (instance == NULL) return NOT_FOUND; /* try stopping the KVM domain */ conn = check_hypervisor_conn(); if (conn) { sem_p(hyp_sem); virDomainPtr dom = virDomainLookupByName(*conn, instanceId); sem_v(hyp_sem); if (dom) { /* also protect 'destroy' commands, just in case */ sem_p (hyp_sem); err = virDomainDestroy (dom); sem_v (hyp_sem); if (err==0) { logprintfl (EUCAINFO, "destroyed domain for instance %s\n", instanceId); } sem_p(hyp_sem); virDomainFree(dom); /* necessary? */ sem_v(hyp_sem); } else { if (instance->state != BOOTING) logprintfl (EUCAWARN, "warning: domain %s to be terminated not running on hypervisor\n", instanceId); } } /* change the state and let the monitoring_thread clean up state */ sem_p (inst_sem); if (instance->state==BOOTING) { change_state (instance, CANCELED); } else { change_state (instance, SHUTOFF); } sem_v (inst_sem); *previousState = instance->stateCode; *shutdownState = instance->stateCode; return OK; }
int ncDescribeInstancesStub (ncStub *st, ncMetadata *meta, char **instIds, int instIdsLen, ncInstance ***outInsts, int *outInstsLen) { axutil_env_t * env = st->env; axis2_stub_t * stub = st->stub; adb_ncDescribeInstances_t * input = adb_ncDescribeInstances_create(env); adb_ncDescribeInstancesType_t * request = adb_ncDescribeInstancesType_create(env); /* set input fields */ adb_ncDescribeInstancesType_set_nodeName(request, env, st->node_name); if (meta) { adb_ncDescribeInstancesType_set_correlationId(request, env, CORRELATION_ID); adb_ncDescribeInstancesType_set_userId(request, env, meta->userId); } int i; for (i=0; i<instIdsLen; i++) { adb_ncDescribeInstancesType_add_instanceIds(request, env, instIds[i]); } adb_ncDescribeInstances_set_ncDescribeInstances(input, env, request); int status = 0; { adb_ncDescribeInstancesResponse_t * output = axis2_stub_op_EucalyptusNC_ncDescribeInstances(stub, env, input); if (!output) { logprintfl (EUCAERROR, "ERROR: DescribeInstances" NULL_ERROR_MSG); status = -1; } else { adb_ncDescribeInstancesResponseType_t * response = adb_ncDescribeInstancesResponse_get_ncDescribeInstancesResponse(output, env); if ( adb_ncDescribeInstancesResponseType_get_return(response, env) == AXIS2_FALSE ) { logprintfl (EUCAERROR, "ERROR: DescribeInstances returned an error\n"); status = 1; } * outInstsLen = adb_ncDescribeInstancesResponseType_sizeof_instances(response, env); if (* outInstsLen) { * outInsts = malloc (sizeof(ncInstance *) * *outInstsLen); if ( * outInsts == NULL ) { logprintfl (EUCAERROR, "ERROR: out of memory in ncDescribeInstancesStub()\n"); * outInstsLen = 0; status = 2; } else { for (i=0; i<*outInstsLen; i++) { adb_instanceType_t * instance = adb_ncDescribeInstancesResponseType_get_instances_at(response, env, i); (* outInsts)[i] = copy_instance_from_adb (instance, env); } } } } } return status; }
int ncDescribeResourceStub (ncStub *st, ncMetadata *meta, char *resourceType, ncResource **outRes) { axutil_env_t * env = st->env; axis2_stub_t * stub = st->stub; adb_ncDescribeResource_t * input = adb_ncDescribeResource_create(env); adb_ncDescribeResourceType_t * request = adb_ncDescribeResourceType_create(env); /* set input fields */ adb_ncDescribeResourceType_set_nodeName(request, env, st->node_name); if (meta) { adb_ncDescribeResourceType_set_correlationId(request, env, CORRELATION_ID); adb_ncDescribeResourceType_set_userId(request, env, meta->userId); } if (resourceType) { adb_ncDescribeResourceType_set_resourceType(request, env, resourceType); } adb_ncDescribeResource_set_ncDescribeResource(input, env, request); int status = 0; { adb_ncDescribeResourceResponse_t * output = axis2_stub_op_EucalyptusNC_ncDescribeResource(stub, env, input); if (!output) { logprintfl (EUCAERROR, "ERROR: DescribeResource" NULL_ERROR_MSG); status = -1; } else { adb_ncDescribeResourceResponseType_t * response = adb_ncDescribeResourceResponse_get_ncDescribeResourceResponse(output, env); if ( adb_ncDescribeResourceResponseType_get_return(response, env) == AXIS2_FALSE ) { logprintfl (EUCAERROR, "ERROR: DescribeResource returned an error\n"); status = 1; } ncResource * res = allocate_resource( (char *)adb_ncDescribeResourceResponseType_get_nodeStatus(response, env), (int)adb_ncDescribeResourceResponseType_get_memorySizeMax(response, env), (int)adb_ncDescribeResourceResponseType_get_memorySizeAvailable(response, env), (int)adb_ncDescribeResourceResponseType_get_diskSizeMax(response, env), (int)adb_ncDescribeResourceResponseType_get_diskSizeAvailable(response, env), (int)adb_ncDescribeResourceResponseType_get_numberOfCoresMax(response, env), (int)adb_ncDescribeResourceResponseType_get_numberOfCoresAvailable(response, env), (char *)adb_ncDescribeResourceResponseType_get_publicSubnets(response, env)); if (!res) { logprintfl (EUCAERROR, "ERROR: out of memory in ncDescribeResourceStub()\n"); status = 2; } * outRes = res; } } return status; }
// deletes on disk state for the item, but does nothing in memory int delete_disk_item (disk_item * di) { int ret = 0; if (unlink (di->path)) { logprintfl (EUCAERROR, "error: failed to delete '%s'\n", di->path); ret = 1; } if (unlink (di->summ)) { logprintfl (EUCAWARN, "warning: failed to delete summary file '%s'\n", di->summ); } if (di->cache_item) { if (rmdir (di->base)) { logprintfl (EUCAERROR, "error: failed to delete '%s'\n", di->base); ret = 1; } } return ret; }
ncInstance * scRecoverInstanceInfo (const char *instanceId) { const int file_size = sizeof(struct ncInstance_t); ncInstance * instance = malloc(file_size); char file_path [BUFSIZE]; struct dirent * dir_entry; DIR * insts_dir; char * userId = NULL; int fd; if (instance==NULL) { logprintfl(EUCADEBUG, "scRecoverInstanceInfo: NULL instance!\n"); return NULL; } /* we don't know userId, so we'll look for instanceId in every user's * directory (we're assuming that instanceIds are unique in the system) */ if ((insts_dir=opendir(sc_instance_path))==NULL) { logprintfl(EUCADEBUG, "scRecoverInstanceInfo: failed to open %s!\n", sc_instance_path); free(instance); return NULL; } while ((dir_entry=readdir(insts_dir))!=NULL) { char tmp_path [BUFSIZE]; struct stat mystat; snprintf(tmp_path, BUFSIZE, "%s/%s/%s", sc_instance_path, dir_entry->d_name, instanceId); if (stat(tmp_path, &mystat)==0) { userId = strdup (dir_entry->d_name); break; /* we got it! */ } } closedir(insts_dir); if (userId==NULL) { logprintfl(EUCADEBUG, "scRecoverInstanceInfo: didn't find instance %s!\n", instanceId); free(instance); return NULL; } snprintf(file_path, BUFSIZE, "%s/%s/%s/instance-checkpoint", sc_instance_path, userId, instanceId); free(userId); if ((fd=open(file_path, O_RDONLY))<0 || read(fd, instance, file_size)<file_size) { perror(file_path); free (instance); logprintfl(EUCADEBUG, "scRecoverInstanceInfo: fail to read recover file for %s!\n", instanceId); return NULL; } close (fd); instance->stateCode = NO_STATE; return instance; }
int diskutil_loop (const char * path, const long long offset, char * lodev, int lodev_size) { int found = 0; int done = 0; int ret = OK; char * output; // we retry because we cannot atomically obtain a free loopback // device on all distros (some versions of 'losetup' allow a file // argument with '-f' options, but some do not) for (int i=0; i<LOOP_RETRIES; i++) { sem_p (loop_sem); output = pruntf (TRUE, "%s %s -f", helpers_path[ROOTWRAP], helpers_path[LOSETUP]); sem_v (loop_sem); if (output==NULL) // there was a problem break; if (strstr (output, "/dev/loop")) { strncpy (lodev, output, lodev_size); char * ptr = strrchr (lodev, '\n'); if (ptr) { *ptr = '\0'; found = 1; } } free (output); if (found) { boolean do_log = ((i+1)==LOOP_RETRIES); // log error on last try only logprintfl (EUCADEBUG, "{%u} attaching file %s\n", (unsigned int)pthread_self(), path); logprintfl (EUCADEBUG, "{%u} to %s at offset %lld\n", (unsigned int)pthread_self(), lodev, offset); sem_p (loop_sem); output = pruntf (do_log, "%s %s -o %lld %s %s", helpers_path[ROOTWRAP], helpers_path[LOSETUP], offset, lodev, path); sem_v (loop_sem); if (output==NULL) { logprintfl (EUCADEBUG, "{%u} cannot attach to loop device %s (will retry)\n", (unsigned int)pthread_self(), lodev); } else { free (output); done = 1; break; } } sleep (1); found = 0; } if (!done) { logprintfl (EUCAINFO, "{%u} error: cannot find free loop device or attach to one\n", (unsigned int)pthread_self()); ret = ERROR; } return ret; }
char* get_iscsi_target(const char *storage_cmd_path, char *dev_string) { char buf [MAX_PATH]; char *retval; snprintf (buf, MAX_PATH, "%s %s", storage_cmd_path, dev_string); logprintfl (EUCAINFO, "get_iscsi_target invoked (dev_string=%s)\n", dev_string); if ((retval = system_output(buf)) == NULL) { logprintfl (EUCAERROR, "ERROR: get_iscsi_target failed\n"); } else { logprintfl (EUCAINFO, "Device: %s\n", retval); } return retval; }
void err (const char *format, ...) { va_list ap; va_start(ap, format); char buf [1024]; vsnprintf (buf, sizeof (buf), format, ap); va_end(ap); logprintfl (EUCAERROR, "%s\n", buf); logprintfl (EUCAINFO, "imager done (exit code=1)\n"); exit (1); }
/* * EXTERNAL ENTRY POINT * * Logs a fault, initializing the fault registry, if necessary. * * Returns TRUE if fault successfully logged, FALSE otherwise. */ boolean log_eucafault_map (const char *fault_id, const char_map **map) { int load = init_eucafaults (NULL); logprintfl (EUCATRACE, "init_eucafaults() returned %d\n", load); if (is_suppressed_eucafault (fault_id)) { logprintfl (EUCADEBUG, "Fault %s detected, but it is being actively suppressed.\n", fault_id); return FALSE; } return format_eucafault (fault_id, map); }
static int write_xml_file (const xmlDocPtr doc, const char * instanceId, const char * path, const char * type) { mode_t old_umask = umask (~BACKING_FILE_PERM); // ensure the generated XML file has the right perms chmod (path, BACKING_FILE_PERM); // ensure perms in case when XML file exists int ret = xmlSaveFormatFileEnc (path, doc, "UTF-8", 1); if (ret > 0) { logprintfl (EUCAINFO, "[%s] wrote %s XML to %s\n", instanceId, type, path); } else { logprintfl (EUCAERROR, "[%s] failed to write %s XML to %s\n", instanceId, type, path); } umask (old_umask); return (ret > 0) ? (OK) : (ERROR); }
static int doInitialize (struct nc_state_t *nc) { char *s = NULL; virNodeInfo ni; long long dom0_min_mem; // set up paths of Eucalyptus commands NC relies on snprintf (nc->get_info_cmd_path, MAX_PATH, EUCALYPTUS_GET_XEN_INFO, nc->home, nc->home); snprintf (nc->virsh_cmd_path, MAX_PATH, EUCALYPTUS_VIRSH, nc->home); snprintf (nc->xm_cmd_path, MAX_PATH, EUCALYPTUS_XM); snprintf (nc->detach_cmd_path, MAX_PATH, EUCALYPTUS_DETACH, nc->home, nc->home); strcpy(nc->uri, HYPERVISOR_URI); nc->convert_to_disk = 0; nc->capability = HYPERVISOR_XEN_AND_HARDWARE; // TODO: set to XEN_PARAVIRTUALIZED if on older Xen kernel // check connection is fresh if (!check_hypervisor_conn()) { return ERROR_FATAL; } // get resources if (virNodeGetInfo(nc->conn, &ni)) { logprintfl (EUCAFATAL, "failed to discover resources\n"); return ERROR_FATAL; } // dom0-min-mem has to come from xend config file s = system_output (nc->get_info_cmd_path); if (get_value (s, "dom0-min-mem", &dom0_min_mem)) { logprintfl (EUCAFATAL, "did not find dom0-min-mem in output from %s\n", nc->get_info_cmd_path); free (s); return ERROR_FATAL; } free (s); // calculate the available memory nc->mem_max = ni.memory/1024 - 32 - dom0_min_mem; // calculate the available cores nc->cores_max = ni.cpus; // let's adjust the values based on the config values if (nc->config_max_mem && nc->config_max_mem < nc->mem_max) nc->mem_max = nc->config_max_mem; if (nc->config_max_cores) nc->cores_max = nc->config_max_cores; return OK; }
/* caller must free the returned string */ char * euca_sign_url (const char * verb, const char * date, const char * url) { if (!initialized) euca_init_cert (); char * sig_str = NULL; RSA * rsa = NULL; FILE * fp = NULL; if ( verb==NULL || date==NULL || url==NULL ) return NULL; if ( ( rsa = RSA_new() ) == NULL ) { logprintfl (EUCAERROR, "error: RSA_new() failed\n"); } else if ( ( fp = fopen (pk_file, "r") ) == NULL) { logprintfl (EUCAERROR, "error: failed to open private key file %s\n", pk_file); RSA_free (rsa); } else { logprintfl (EUCADEBUG2, "euca_sign_url(): reading private key file %s\n", pk_file); PEM_read_RSAPrivateKey(fp, &rsa, NULL, NULL); /* read the PEM-encoded file into rsa struct */ if ( rsa==NULL ) { logprintfl (EUCAERROR, "error: failed to read private key file %s\n", pk_file); } else { unsigned char * sig; // RSA_print_fp (stdout, rsa, 0); /* (for debugging) */ if ( (sig = malloc(RSA_size(rsa))) == NULL) { logprintfl (EUCAERROR, "error: out of memory (for RSA key)\n"); } else { unsigned char sha1 [SHA_DIGEST_LENGTH]; #define BUFSIZE 2024 char input [BUFSIZE]; unsigned int siglen; int ret; /* finally, SHA1 and sign with PK */ assert ((strlen(verb)+strlen(date)+strlen(url)+4)<=BUFSIZE); snprintf (input, BUFSIZE, "%s\n%s\n%s\n", verb, date, url); logprintfl (EUCADEBUG2, "euca_sign_url(): signing input %s\n", get_string_stats(input)); SHA1 ((unsigned char *)input, strlen(input), sha1); if ((ret = RSA_sign (NID_sha1, sha1, SHA_DIGEST_LENGTH, sig, &siglen, rsa))!=1) { logprintfl (EUCAERROR, "error: RSA_sign() failed\n"); } else { logprintfl (EUCADEBUG2, "euca_sign_url(): signing output %d\n", sig[siglen-1]); sig_str = base64_enc (sig, siglen); logprintfl (EUCADEBUG2, "euca_sign_url(): base64 signature %s\n", get_string_stats((char *)sig_str)); } free (sig); } RSA_free (rsa); } fclose(fp); } return sig_str; }
void LogprintfCache (void) { struct stat mystat; cache_entry * e; if (cache_head) { logprintfl (EUCAINFO, "cached images (free=%lld of %lldMB):\n", cache_free_mb, cache_size_mb); } else { logprintfl (EUCAINFO, "cached images (free=%lld of %lldMB): none\n", cache_free_mb, cache_size_mb); } for ( e = cache_head; e; e=e->next) { bzero (&mystat, sizeof (mystat)); stat (e->path, &mystat); logprintfl (EUCAINFO, "\t%5dMB %8dsec %s\n", e->size_mb, mystat.st_mtime, e->path); } }
static int getRemoteURI (struct nc_state_t *nc, char *target, char *result, size_t max_result_size) { /* TODO: Put URI format to eucalyptus.con */ logprintfl(EUCADEBUG, "getRemoteURI() invoked\n"); if (!strcmp(nc->H->name, "xen")) snprintf(result, max_result_size, "xen+ssh://eucalyptus@%s", target); else if (!strcmp(nc->H->name, "kvm")) snprintf(result, max_result_size, "qemu+ssh://eucalyptus@%s/system", target); else { strncpy(result, target, max_result_size); result = strdup(target); } logprintfl(EUCADEBUG, "getRemoteURI(): result=%s\n", result); return (OK); }
static int doAttachSystemDisk ( struct nc_state_t *nc, ncMetadata *meta, char *instanceId, char *isoPath) { ncInstance *instance; virConnectPtr *conn; virDomainPtr dom = NULL; char xml[MAX_PATH]={'\0'}; int err; snprintf (xml, sizeof(xml), "<disk type='block' device='cdrom'><source dev='%s'/><target dev='hdc' bus='ide'/><readonly/></disk>", isoPath); //logprintfl(EUCAINFO, "doAttachSystemDisk(): founded %s [%s---%s---%d]\n", instanceId,__FILE__, __FUNCTION__, __LINE__); sem_p(inst_sem); instance = find_instance(&global_instances, instanceId); sem_v(inst_sem); if (instance == NULL || (instance->state != RUNNING&& instance->state != BLOCKED&& instance->state !=PAUSED)) { logprintfl(EUCAINFO, "doAttachSystemDisk(): found %s failed or instance->state!=RUNNING||BLOCKED||PAUSED [file:%s---line:%d]\n", instanceId, __FILE__, __LINE__); return NOT_FOUND; } conn = check_hypervisor_conn(); if (conn) { /* snprintf(cmd, sizeof(cmd), "virsh attach-disk %s %s hdc --type cdrom --mode readonly",instanceId, isoPath); logprintfl(EUCAINFO, "xiongm: cmd=%s [%s---%s---%d]\n",cmd, __FILE__, __FUNCTION__, __LINE__); system(cmd); */ dom = NULL; sem_p(hyp_sem); dom = virDomainLookupByName(*conn, instanceId); sem_v(hyp_sem); if (dom) { sem_p (hyp_sem); err = virDomainAttachDevice (dom, xml); sem_v (hyp_sem); if(err != 0) { logprintfl(EUCAINFO,"virDomainAttachDevice failed. err=%d\n",err); return 1; } } logprintfl(EUCAINFO,"doAttachSystemDisk success.\n"); return 0; } else { logprintfl(EUCAINFO, "doAttachSystemDisk(): no connect hypervisior [file:%s---line:%d]\n",__FILE__, __LINE__); return 1; } }
// Semaphore increment (aka lock acquisition) function. // The second parameter tells it not to log the event // (useful for avoiding infinite recursion when locking // from the logging code). int sem_prolaag (sem * s, boolean do_log) { int rc; if (s && do_log) { char addr [24]; snprintf (addr, sizeof (addr), "%lx", (unsigned long)s); logprintfl (EUCAEXTREME, "%s locking\n", (s->name)?(s->name):(addr)); } if (s && s->usemutex) { rc = pthread_mutex_lock(&(s->mutex)); s->mutwaiters++; while(s->mutcount == 0) { pthread_cond_wait(&(s->cond), &(s->mutex)); } s->mutwaiters--; s->mutcount--; rc = pthread_mutex_unlock(&(s->mutex)); return(rc); } if (s && s->posix) { return sem_wait (s->posix); } if (s && s->sysv > 0) { struct sembuf sb = {0, -1, 0}; return semop (s->sysv, &sb, 1); } return -1; }
// checks whether disk state of the item matches the spec (when it does not, function returns 1) int verify_disk_item (const disk_item * di, artifacts_spec * spec) { int ret = ERROR; struct stat mystat; if (stat (di->path, &mystat)<0) return ERROR; if (di->content_size != mystat.st_size) return ERROR; // TODO: check the checksum? char * file_summary = file2str (di->summ); char * spec_summary = gen_summary (spec); if (file_summary==NULL) { logprintfl (EUCAWARN, "warning: failed to read summary file '%s'\n", di->summ); if(spec_summary != NULL) free(spec_summary); ret = OK; } else { if (spec_summary!=NULL) { if (strcmp (file_summary, spec_summary)==0) ret = OK; free (spec_summary); } free (file_summary); } return ret; }
// Semaphore decrement (aka lock release) function. // The second parameter tells it not to log the event // (useful for avoiding infinite recursion when unlocking // from the logging code). int sem_verhogen (sem * s, boolean do_log) { int rc; if (s && do_log) { char addr [24]; snprintf (addr, sizeof (addr), "%lx", (unsigned long)s); logprintfl (EUCAEXTREME, "%s unlocking\n", (s->name)?(s->name):(addr)); } if (s && s->usemutex) { rc = pthread_mutex_lock(&(s->mutex)); if (s->mutwaiters > 0) { rc = pthread_cond_signal(&(s->cond)); } s->mutcount++; rc = pthread_mutex_unlock(&(s->mutex)); return(rc); } if (s && s->posix) { return sem_post (s->posix); } if (s && s->sysv > 0) { struct sembuf sb = {0, 1, 0}; return semop (s->sysv, &sb, 1); } return -1; }
// finds disc item on disk (in work or cache), allocates and fills out memory struct for it disk_item * find_disk_item (const char * id, const boolean cache_item) { char path [EUCA_MAX_PATH]; if (cache_item) { snprintf (path, EUCA_MAX_PATH, "%s/%s/content", get_cache_dir(), id); } else { snprintf (path, EUCA_MAX_PATH, "%s/%s", get_work_dir(), id); } if (cache_item) { scan_cache (); // rebuilds cache state in memory based on disk return find_in_cache (path); } struct stat mystat; if (stat (path, &mystat)<0) { if (errno!=ENOENT) { // file not found logprintfl (EUCAERROR, "error: could not stat '%s'\n", path); } return NULL; } return alloc_disk_item (id, mystat.st_size, mystat.st_size, cache_item); }
/* libcurl read handler */ static size_t read_data (char *buffer, size_t size, size_t nitems, void *params) { assert (params != NULL); FILE * fp = ((struct read_request *)params)->fp; int items_read = 0; do { items_read += fread (buffer, size, nitems-items_read, fp); } while (items_read!=nitems && !feof(fp)); ((struct read_request *)params)->total_read += items_read * size; ((struct read_request *)params)->total_calls++; if (((struct read_request *)params)->total_calls%50==0) { time_t prev = ((struct read_request *)params)->timestamp; time_t now = time(NULL); if ((now-prev)>10) { ((struct read_request *)params)->timestamp = now; long long bytes_read = ((struct read_request *)params)->total_read; long long bytes_file = ((struct read_request *)params)->file_size; int percent = (int)((bytes_read*100)/bytes_file); logprintfl (EUCADEBUG, "http_put(): upload progress %ld/%ld bytes (%d%%)\n", bytes_read, bytes_file, percent); } } return items_read; }
static void add_to_cache (const char * cached_path, const long long file_size_bytes) { long long file_size_mb = file_size_bytes/MEGABYTE; cache_entry * e = malloc (sizeof(cache_entry)); if (e==NULL) { logprintfl (EUCAFATAL, "error: out of memory in add_to_cache()\n"); return; } strncpy (e->path, cached_path, BUFSIZE); e->size_mb = file_size_mb; e->next = NULL; e->prev = NULL; // add at the end cache_entry ** pp; cache_entry * p = NULL; for ( pp = & cache_head; * pp != NULL; pp = & ((* pp)->next)) p = * pp; if ( p ) { e->prev = p; } * pp = e; cache_free_mb -= file_size_mb; }
adb_ncDescribeUtilizationResponse_t* ncDescribeUtilizationMarshal (adb_ncDescribeUtilization_t* ncDescribeUtilization, const axutil_env_t *env) { pthread_mutex_lock(&ncHandlerLock); adb_ncDescribeUtilizationType_t * input = adb_ncDescribeUtilization_get_ncDescribeUtilization(ncDescribeUtilization, env); adb_ncDescribeUtilizationResponse_t * response = adb_ncDescribeUtilizationResponse_create(env); adb_ncDescribeUtilizationResponseType_t * output = adb_ncDescribeUtilizationResponseType_create(env); // get standard fields from input axis2_char_t * correlationId = adb_ncDescribeUtilizationType_get_correlationId(input, env); axis2_char_t * userId = adb_ncDescribeUtilizationType_get_userId(input, env); // get operation-specific fields from input // e.g.: axis2_char_t * instanceId = adb_ncOPERATIONType_get_instanceId(input, env); eventlog("NC", userId, correlationId, "DescribeUtilization", "begin"); { // do it ncMetadata meta = { correlationId, userId }; ncUtilization utilization; int error = doDescribeUtilization (&meta, &utilization); if (error) { logprintfl (EUCAERROR, "ERROR: doDescribeUtilization() failed error=%d\n", error); adb_ncDescribeUtilizationResponseType_set_return(output, env, AXIS2_FALSE); } else { int i; // set standard fields in output adb_ncDescribeUtilizationResponseType_set_return(output, env, AXIS2_TRUE); adb_ncDescribeUtilizationResponseType_set_correlationId(output, env, correlationId); adb_ncDescribeUtilizationResponseType_set_userId(output, env, userId); // set operation-specific fields in output adb_ncDescribeUtilizationResponseType_set_utilization(output, env, utilization.utilization); adb_ncDescribeUtilizationResponseType_set_networkUtilization(output,env, utilization.networkUtilization); adb_ncDescribeUtilizationResponseType_set_powerConsumption(output, env, utilization.powerConsumption); adb_ncDescribeUtilizationResponseType_set_measurementTimepoint(output, env, (long) utilization.timePoint); /*for (i=0; i<utilization.numInstances; i++) { int numVcpus, j; numVcpus = utilization.instances[i].numVcpus; adb_instanceUtilization_t *instance = adb_instanceUtilization_create(env); adb_instanceUtilization_set_instanceId (instance, env, utilization.instances[i].instanceId); for (j=0; j<numVcpus; j++) { adb_instanceUtilization_add_vcpuUtilization (instance, env, utilization.instances[i].vcpuUtilization[j]); adb_instanceUtilization_set_vnetworkUtilization (instance, env, utilization.instances[i].vnetworkUtilization); } adb_ncDescribeUtilizationResponseType_add_instances (output, env, instance); }*/ } } // set response to output adb_ncDescribeUtilizationResponse_set_ncDescribeUtilizationResponse(response, env, output); pthread_mutex_unlock(&ncHandlerLock); eventlog("NC", userId, correlationId, "DescribeUtilization", "end"); return response; }
//! //! downloads a digest of an image and compares it to file at old_digest_path //! //! @param[in] url //! @param[in] old_digest_path //! //! @return 0 if same, -1 if different, EUCA_INVALID_ERROR if error //! int walrus_verify_digest(const char *url, const char *old_digest_path) { int e = EUCA_INVALID_ERROR; char *new_digest; char *old_digest = file2strn(old_digest_path, 2000000); if (old_digest == NULL) { logprintfl(EUCAERROR, "failed to read old digest %s\n", old_digest_path); return e; } if ((new_digest = walrus_get_digest(url)) != NULL) { // compare the two if (strcmp(new_digest, old_digest)) { e = -1; } else { e = EUCA_OK; } EUCA_FREE(new_digest); } EUCA_FREE(old_digest); return e; }