static int init (void) { static int initialized = 0; int do_warn = 0, i; char configFiles[2][MAX_PATH], log[MAX_PATH], *bridge, *hypervisor, *s, *tmp; struct stat mystat; struct statfs fs; struct handlers ** h; long long fs_free_blocks = 0; long long fs_block_size = 0; long long instances_bytes = 0; pthread_t tcb; if (initialized>0) /* 0 => hasn't run, -1 => failed, 1 => ok */ return 0; else if (initialized<0) return 1; bzero (&nc_state, sizeof(struct nc_state_t)); // ensure that MAXes are zeroed out /* from now on we have unrecoverable failure, so no point in * retrying to re-init */ initialized = -1; /* read in configuration - this should be first! */ tmp = getenv(EUCALYPTUS_ENV_VAR_NAME); if (!tmp) { nc_state.home[0] = '\0'; do_warn = 1; } else strncpy(nc_state.home, tmp, MAX_PATH); /* set the minimum log for now */ snprintf(log, MAX_PATH, "%s/var/log/eucalyptus/nc.log", nc_state.home); logfile(log, EUCADEBUG); if (do_warn) logprintfl (EUCAWARN, "env variable %s not set, using /\n", EUCALYPTUS_ENV_VAR_NAME); /* search for the config file */ snprintf(configFiles[1], MAX_PATH, EUCALYPTUS_CONF_LOCATION, nc_state.home); if (stat(configFiles[1], &mystat)) { logprintfl (EUCAFATAL, "could not open configuration file %s\n", configFiles[1]); return 1; } snprintf(configFiles[0], MAX_PATH, EUCALYPTUS_CONF_OVERRIDE_LOCATION, nc_state.home); logprintfl (EUCAINFO, "NC is looking for configuration in %s,%s\n", configFiles[1], configFiles[0]); /* reset the log to the right value */ tmp = getConfString(configFiles, 2, "LOGLEVEL"); i = EUCADEBUG; if (tmp) { if (!strcmp(tmp,"INFO")) {i=EUCAINFO;} else if (!strcmp(tmp,"WARN")) {i=EUCAWARN;} else if (!strcmp(tmp,"ERROR")) {i=EUCAERROR;} else if (!strcmp(tmp,"FATAL")) {i=EUCAFATAL;} free(tmp); } logfile(log, i); #define GET_VAR_INT(var,name) \ s = getConfString(configFiles, 2, name); \ if (s){ \ var = atoi(s);\ free (s);\ } GET_VAR_INT(nc_state.config_max_mem, CONFIG_MAX_MEM); GET_VAR_INT(nc_state.config_max_disk, CONFIG_MAX_DISK); GET_VAR_INT(nc_state.config_max_cores, CONFIG_MAX_CORES); GET_VAR_INT(nc_state.save_instance_files, CONFIG_SAVE_INSTANCES); nc_state.config_network_port = NC_NET_PORT_DEFAULT; strcpy(nc_state.admin_user_id, EUCALYPTUS_ADMIN); hyp_sem = sem_alloc (1, "mutex"); inst_sem = sem_alloc (1, "mutex"); addkey_sem = sem_alloc (1, "mutex"); if (!hyp_sem || !inst_sem) { logprintfl (EUCAFATAL, "failed to create and initialize a semaphore\n"); return ERROR_FATAL; } /* set default in the paths. the driver will override */ nc_state.config_network_path[0] = '\0'; nc_state.gen_libvirt_cmd_path[0] = '\0'; nc_state.xm_cmd_path[0] = '\0'; nc_state.virsh_cmd_path[0] = '\0'; nc_state.get_info_cmd_path[0] = '\0'; snprintf (nc_state.rootwrap_cmd_path, MAX_PATH, EUCALYPTUS_ROOTWRAP, nc_state.home); /* prompt the SC to read the configuration too */ if (scInitConfig()) { logprintfl (EUCAFATAL, "ERROR: scInitConfig() failed\n"); return ERROR_FATAL; } /* determine the hypervisor to use */ //if (get_conf_var(config, CONFIG_HYPERVISOR, &hypervisor)<1) { hypervisor = getConfString(configFiles, 2, CONFIG_HYPERVISOR); if (!hypervisor) { logprintfl (EUCAFATAL, "value %s is not set in the config file\n", CONFIG_HYPERVISOR); return ERROR_FATAL; } /* let's look for the right hypervisor driver */ for (h = available_handlers; *h; h++ ) { if (!strncmp ((*h)->name, "default", CHAR_BUFFER_SIZE)) nc_state.D = *h; if (!strncmp ((*h)->name, hypervisor, CHAR_BUFFER_SIZE)) nc_state.H = *h; } if (nc_state.H == NULL) { logprintfl (EUCAFATAL, "requested hypervisor type (%s) is not available\n", hypervisor); free (hypervisor); return ERROR_FATAL; } /* only load virtio config for kvm */ if (!strncmp("kvm", hypervisor, CHAR_BUFFER_SIZE) || !strncmp("KVM", hypervisor, CHAR_BUFFER_SIZE)) { GET_VAR_INT(nc_state.config_use_virtio_net, CONFIG_USE_VIRTIO_NET); GET_VAR_INT(nc_state.config_use_virtio_disk, CONFIG_USE_VIRTIO_DISK); GET_VAR_INT(nc_state.config_use_virtio_root, CONFIG_USE_VIRTIO_ROOT); } free (hypervisor); /* NOTE: this is the only call which needs to be called on both * the default and the specific handler! All the others will be * either or */ i = nc_state.D->doInitialize(&nc_state); if (nc_state.H->doInitialize) i += nc_state.H->doInitialize(&nc_state); if (i) { logprintfl(EUCAFATAL, "ERROR: failed to initialized hypervisor driver!\n"); return ERROR_FATAL; } /* adopt running instances */ adopt_instances(); /* setup the network */ nc_state.vnetconfig = malloc(sizeof(vnetConfig)); if (!nc_state.vnetconfig) { logprintfl (EUCAFATAL, "Cannot allocate vnetconfig!\n"); return 1; } snprintf (nc_state.config_network_path, MAX_PATH, NC_NET_PATH_DEFAULT, nc_state.home); hypervisor = getConfString(configFiles, 2, "VNET_PUBINTERFACE"); if (!hypervisor) hypervisor = getConfString(configFiles, 2, "VNET_INTERFACE"); bridge = getConfString(configFiles, 2, "VNET_BRIDGE"); tmp = getConfString(configFiles, 2, "VNET_MODE"); vnetInit(nc_state.vnetconfig, tmp, nc_state.home, nc_state.config_network_path, NC, hypervisor, hypervisor, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, bridge, NULL, NULL); if (hypervisor) free(hypervisor); if (bridge) free(bridge); if (tmp) free(tmp); /* cleanup from previous runs and verify integrity of * instances directory */ sem_p (inst_sem); instances_bytes = scFSCK (&global_instances); sem_v (inst_sem); if (instances_bytes < 0) { logprintfl (EUCAFATAL, "instances store failed integrity check (error=%lld)\n", instances_bytes); return ERROR_FATAL; } /* get disk max */ strncpy(log, scGetInstancePath(), MAX_PATH); if (statfs(log, &fs) == -1) { logprintfl(EUCAWARN, "Failed to stat %s\n", log); } else { nc_state.disk_max = (long long)fs.f_bsize * (long long)fs.f_bavail + instances_bytes; /* max for Euca, not total */ nc_state.disk_max /= BYTES_PER_DISK_UNIT; if (nc_state.config_max_disk && nc_state.config_max_disk < nc_state.disk_max) nc_state.disk_max = nc_state.config_max_disk; logprintfl (EUCAINFO, "Maximum disk available: %lld (under %s)\n", nc_state.disk_max, log); } /* start the monitoring thread */ if (pthread_create(&tcb, NULL, monitoring_thread, &nc_state)) { logprintfl (EUCAFATAL, "failed to spawn a monitoring thread\n"); return ERROR_FATAL; } if (pthread_detach(tcb)) { logprintfl(EUCAFATAL, "failed to detach the monitoring thread\n"); return ERROR_FATAL; } initialized = 1; return OK; }
static int doAdoptInstances(struct nc_state_t *nc, ncMetadata *meta) { adopt_instances(); return OK; }