handlers.c (eucalyptus-4.4.1) | : | handlers.c (eucalyptus-4.4.2) | ||
---|---|---|---|---|
skipping to change at line 142 | skipping to change at line 142 | |||
#include "service_sensor.h" | #include "service_sensor.h" | |||
/*----------------------------------------------------------------------------*\ | /*----------------------------------------------------------------------------*\ | |||
| | | | | | |||
| DEFINES | | | DEFINES | | |||
| | | | | | |||
\*----------------------------------------------------------------------------*/ | \*----------------------------------------------------------------------------*/ | |||
#define MONITORING_PERIOD (5) //!< Instance state tran sition monitoring period in seconds. | #define MONITORING_PERIOD (5) //!< Instance state tran sition monitoring period in seconds. | |||
#define MAX_CREATE_TRYS 5 | #define MAX_CREATE_TRYS 5 | |||
#define CREATE_TIMEOUT_SEC 60 | #define CREATE_TIMEOUT_SEC 300 | |||
#define LIBVIRT_TIMEOUT_SEC 5 | #define LIBVIRT_TIMEOUT_SEC 5 | |||
#define NETWORK_GATE_TIMEOUT_SEC 1200 | #define NETWORK_GATE_TIMEOUT_SEC 1200 | |||
#define PER_INSTANCE_BUFFER_MB 20 //!< by default reserve this much extra room (in MB) per instance (for kernel, ramdisk, and metadata ove rhead) | #define PER_INSTANCE_BUFFER_MB 20 //!< by default reserve this much extra room (in MB) per instance (for kernel, ramdisk, and metadata ove rhead) | |||
#define SEC_PER_MB ((1024 * 1024) / 512) | #define SEC_PER_MB ((1024 * 1024) / 512) | |||
#define MIN_BLOBSTORE_SIZE_MB 10 //!< even with boot-from -EBS one will need work space for kernel and ramdisk | #define MIN_BLOBSTORE_SIZE_MB 10 //!< even with boot-from -EBS one will need work space for kernel and ramdisk | |||
#define FS_BUFFER_PERCENT 0.03 //!< leave 3% extra when deciding on blobstore sizes automatically | #define FS_BUFFER_PERCENT 0.03 //!< leave 3% extra when deciding on blobstore sizes automatically | |||
#define WORK_BS_PERCENT 0.33 //!< give a third of available space to work, the rest to cache | #define WORK_BS_PERCENT 0.33 //!< give a third of available space to work, the rest to cache | |||
#define MAX_CONNECTION_ERRORS 5 | #define MAX_CONNECTION_ERRORS 5 | |||
skipping to change at line 517 | skipping to change at line 517 | |||
if (rc != EUCA_OK) { | if (rc != EUCA_OK) { | |||
LOGERROR("[%s] '%s %s %s %s %s' failed. rc=%d\n", SP(instanceId), euca_r ootwrap, command, "-a", NP(host), NP(credentials), rc); | LOGERROR("[%s] '%s %s %s %s %s' failed. rc=%d\n", SP(instanceId), euca_r ootwrap, command, "-a", NP(host), NP(credentials), rc); | |||
return (EUCA_SYSTEM_ERROR); | return (EUCA_SYSTEM_ERROR); | |||
} else { | } else { | |||
LOGDEBUG("[%s] migration key authorization succeeded\n", SP(instanceId)) ; | LOGDEBUG("[%s] migration key authorization succeeded\n", SP(instanceId)) ; | |||
} | } | |||
return (EUCA_OK); | return (EUCA_OK); | |||
} | } | |||
//! | //! | |||
//! Configure libvirtd to not use polkitd by default. | ||||
//! | ||||
//! Only needs to be run during init() as a one time operation. In most cases | ||||
//! this will check the config and not restart libvirt if everything is ok. | ||||
//! | ||||
//! @param[in] use_polkit set 1, will enable polkit, 0 will disable (default) | ||||
//! @return EUCA_OK, EUCA_INVALID_ERROR, or EUCA_SYSTEM_ERROR | ||||
//! | ||||
int config_polkit(int use_polkit) | ||||
{ | ||||
int rc = 0; | ||||
char euca_rootwrap[EUCA_MAX_PATH] = ""; | ||||
char command[EUCA_MAX_PATH] = ""; | ||||
char *euca_base = getenv(EUCALYPTUS_ENV_VAR_NAME); | ||||
snprintf(command, EUCA_MAX_PATH, EUCALYPTUS_CONFIG_NO_POLKIT, NP(euca_base)) | ||||
; | ||||
snprintf(euca_rootwrap, EUCA_MAX_PATH, EUCALYPTUS_ROOTWRAP, NP(euca_base)); | ||||
LOGDEBUG("config-no-polkit command: '%s %s'\n", euca_rootwrap, command); | ||||
if (use_polkit) | ||||
rc = euca_execlp(NULL, euca_rootwrap, command, "-e", NULL); // enable | ||||
else | ||||
rc = euca_execlp(NULL, euca_rootwrap, command, NULL); // disable - | ||||
default | ||||
if (rc != EUCA_OK) { | ||||
LOGERROR("%s %s' failed. rc=%d\n",euca_rootwrap, command, rc); | ||||
return (EUCA_SYSTEM_ERROR); | ||||
} else { | ||||
LOGDEBUG("Libvirtd polkit configuration succeeded\n"); | ||||
} | ||||
return (EUCA_OK); | ||||
} | ||||
//! | ||||
//! Copies the url string of the ENABLED service of the requested type into dest _buffer. | //! Copies the url string of the ENABLED service of the requested type into dest _buffer. | |||
//! dest_buffer MUST be the same size as the services uri array length, 512. | //! dest_buffer MUST be the same size as the services uri array length, 512. | |||
//! | //! | |||
//! @param[in] service_type | //! @param[in] service_type | |||
//! @param[in] nc | //! @param[in] nc | |||
//! @param[in] dest_buffer | //! @param[in] dest_buffer | |||
//! @return EUCA_OK on success, EUCA_ERROR on failure. | //! @return EUCA_OK on success, EUCA_ERROR on failure. | |||
//! @pre | //! @pre | |||
//! | //! | |||
//! @post | //! @post | |||
skipping to change at line 1810 | skipping to change at line 1844 | |||
//! @param[in] arg a transparent pointer to the instance structure to start | //! @param[in] arg a transparent pointer to the instance structure to start | |||
//! | //! | |||
//! @return Always return NULL | //! @return Always return NULL | |||
//! | //! | |||
void *startup_thread(void *arg) | void *startup_thread(void *arg) | |||
{ | { | |||
int i = 0; | int i = 0; | |||
int error = EUCA_OK; | int error = EUCA_OK; | |||
int status = 0; | int status = 0; | |||
int rc = 0; | int rc = 0; | |||
int create_timedout = 0; | ||||
char *xml = NULL; | char *xml = NULL; | |||
char brname[IF_NAME_LEN] = ""; | char brname[IF_NAME_LEN] = ""; | |||
pid_t cpid = 0; | pid_t cpid = 0; | |||
boolean try_killing = FALSE; | boolean try_killing = FALSE; | |||
boolean created = FALSE; | boolean created = FALSE; | |||
ncInstance *instance = ((ncInstance *) arg); | ncInstance *instance = ((ncInstance *) arg); | |||
virDomainPtr dom = NULL; | virDomainPtr dom = NULL; | |||
LOGDEBUG("[%s] spawning startup thread\n", instance->instanceId); | LOGDEBUG("[%s] spawning startup thread\n", instance->instanceId); | |||
virConnectPtr conn = lock_hypervisor_conn(); | virConnectPtr conn = lock_hypervisor_conn(); | |||
skipping to change at line 1892 | skipping to change at line 1927 | |||
{ // all this is done while holding the hyp ervisor lock, with a valid connection | { // all this is done while holding the hyp ervisor lock, with a valid connection | |||
virConnectPtr conn = lock_hypervisor_conn(); | virConnectPtr conn = lock_hypervisor_conn(); | |||
if (conn == NULL) { // get a new connection for each loop ite ration | if (conn == NULL) { // get a new connection for each loop ite ration | |||
LOGERROR("[%s] could not contact the hypervisor, abandoning the instance\n", instance->instanceId); | LOGERROR("[%s] could not contact the hypervisor, abandoning the instance\n", instance->instanceId); | |||
hypervisor_conn_errors++; | hypervisor_conn_errors++; | |||
goto shutoff; | goto shutoff; | |||
} | } | |||
sem_p(loop_sem); | sem_p(loop_sem); | |||
if (i > 0 && create_timedout == 1) { | ||||
dom = virDomainLookupByName(conn, instance->instanceId); | ||||
if (dom) { | ||||
// a forked process failed to return in a timely manner, yet | ||||
the instance | ||||
// launched. Since we can't verify the validity of the insta | ||||
nce, terminate and | ||||
// let the NC clean up. | ||||
LOGERROR("[%s] failed to launch cleanly after %d seconds, de | ||||
stroying instance\n", instance->instanceId, CREATE_TIMEOUT_SEC); | ||||
error = virDomainDestroy(dom); | ||||
LOGINFO("[%s] instance destroyed - return: %d\n", instance-> | ||||
instanceId, error); | ||||
virDomainFree(dom); | ||||
sem_v(loop_sem); | ||||
unlock_hypervisor_conn(); | ||||
goto shutoff; | ||||
} | ||||
} | ||||
// We have seen virDomainCreateLinux() on occasion block indefinitel y, | // We have seen virDomainCreateLinux() on occasion block indefinitel y, | |||
// which freezes all activity on the NC since hyp_sem and loop_sem a re | // which freezes all activity on the NC since hyp_sem and loop_sem a re | |||
// being held by the thread. (This is on Lucid with AppArmor enabled .) | // being held by the thread. (This is on Lucid with AppArmor enabled .) | |||
// To protect against that, we invoke the function in a process and | // To protect against that, we invoke the function in a process and | |||
// terminate it after CREATE_TIMEOUT_SEC seconds. | // terminate it after CREATE_TIMEOUT_SEC seconds. | |||
// | // | |||
// #0 0x00007f359f0b1f93 in poll () from /lib/libc.so.6 | // #0 0x00007f359f0b1f93 in poll () from /lib/libc.so.6 | |||
// #1 0x00007f359a9a44e2 in ?? () from /usr/lib/libvirt.so.0 | // #1 0x00007f359a9a44e2 in ?? () from /usr/lib/libvirt.so.0 | |||
// #2 0x00007f359a9a5060 in ?? () from /usr/lib/libvirt.so.0 | // #2 0x00007f359a9a5060 in ?? () from /usr/lib/libvirt.so.0 | |||
// #3 0x00007f359a9ac159 in ?? () from /usr/lib/libvirt.so.0 | // #3 0x00007f359a9ac159 in ?? () from /usr/lib/libvirt.so.0 | |||
skipping to change at line 1936 | skipping to change at line 1990 | |||
exit(1); | exit(1); | |||
} | } | |||
} else { | } else { | |||
// parent process - waits for the child, kills it if necessary | // parent process - waits for the child, kills it if necessary | |||
try_killing = FALSE; | try_killing = FALSE; | |||
if ((rc = timewait(cpid, &status, CREATE_TIMEOUT_SEC)) < 0) { | if ((rc = timewait(cpid, &status, CREATE_TIMEOUT_SEC)) < 0) { | |||
LOGERROR("[%s] failed to wait for forked process: %s\n", ins tance->instanceId, strerror(errno)); | LOGERROR("[%s] failed to wait for forked process: %s\n", ins tance->instanceId, strerror(errno)); | |||
try_killing = TRUE; | try_killing = TRUE; | |||
} else if (rc == 0) { | } else if (rc == 0) { | |||
LOGERROR("[%s] timed out waiting for forked process pid=%d\n ", instance->instanceId, cpid); | LOGERROR("[%s] timed out waiting for forked process pid=%d\n ", instance->instanceId, cpid); | |||
create_timedout = 1; // Sometimes a timeout can occur but th e instance is running... | ||||
try_killing = TRUE; | try_killing = TRUE; | |||
} else if (WEXITSTATUS(status) != 0) { | } else if (WEXITSTATUS(status) != 0) { | |||
LOGERROR("[%s] hypervisor failed to create the instance\n", instance->instanceId); | LOGERROR("[%s] hypervisor failed to create the instance\n", instance->instanceId); | |||
} else { | } else { | |||
created = TRUE; | created = TRUE; | |||
} | } | |||
if (try_killing) { | if (try_killing) { | |||
killwait(cpid); | killwait(cpid); | |||
} | } | |||
skipping to change at line 2347 | skipping to change at line 2402 | |||
} | } | |||
{ | { | |||
/* Initialize libvirtd.conf, since some buggy versions of libvirt | /* Initialize libvirtd.conf, since some buggy versions of libvirt | |||
* require it. At least two versions of libvirt have had this issue, | * require it. At least two versions of libvirt have had this issue, | |||
* most recently the version in RHEL 6.1. Note that this happens | * most recently the version in RHEL 6.1. Note that this happens | |||
* at each startup of the NC mainly because the location of the | * at each startup of the NC mainly because the location of the | |||
* required file depends on the process owner's home directory, which | * required file depends on the process owner's home directory, which | |||
* may change after the initial installation. | * may change after the initial installation. | |||
*/ | */ | |||
int use_polkit = 0; | ||||
char libVirtConf[EUCA_MAX_PATH]; | char libVirtConf[EUCA_MAX_PATH]; | |||
uid_t uid = geteuid(); | uid_t uid = geteuid(); | |||
struct passwd *pw; | struct passwd *pw; | |||
FILE *fd; | FILE *fd; | |||
struct stat lvcstat; | struct stat lvcstat; | |||
pw = getpwuid(uid); | pw = getpwuid(uid); | |||
errno = 0; | errno = 0; | |||
if (pw != NULL) { | if (pw != NULL) { | |||
snprintf(libVirtConf, EUCA_MAX_PATH, "%s/.libvirt/libvirtd.conf", pw ->pw_dir); | snprintf(libVirtConf, EUCA_MAX_PATH, "%s/.libvirt/libvirtd.conf", pw ->pw_dir); | |||
if (access(libVirtConf, R_OK) == -1 && errno == ENOENT) { | if (access(libVirtConf, R_OK) == -1 && errno == ENOENT) { | |||
skipping to change at line 2378 | skipping to change at line 2434 | |||
LOGINFO("Failed to open %s, error code %d\n", libVirtConf, e rrno); | LOGINFO("Failed to open %s, error code %d\n", libVirtConf, e rrno); | |||
} else { | } else { | |||
fclose(fd); | fclose(fd); | |||
} | } | |||
} else if (errno) { | } else if (errno) { | |||
LOGINFO("Failed to access libvirtd.conf, error code %d\n", errno ); | LOGINFO("Failed to access libvirtd.conf, error code %d\n", errno ); | |||
} | } | |||
} else { | } else { | |||
LOGINFO("Cannot get EUID, not creating libvirtd.conf\n"); | LOGINFO("Cannot get EUID, not creating libvirtd.conf\n"); | |||
} | } | |||
} | ||||
// | ||||
// Configure libvirtd polkit authentication on the libvirt sockets | ||||
// by default we *disable* polkit authentication due to stability issues | ||||
. | ||||
// If the configuration parameter is set to -1 we won't touch the config | ||||
uration | ||||
// | ||||
GET_VAR_INT(use_polkit, CONFIG_LIBVIRT_USE_POLICY_KIT, 0); | ||||
if (use_polkit >= 0) { | ||||
if (config_polkit(use_polkit) != EUCA_OK) { | ||||
LOGERROR("Unable to %s polkitd for libvirtd.\n", use_polkit ? "e | ||||
nable" : "disable"); | ||||
} else { | ||||
LOGINFO("libvirtd configured to %s polkitd.\n", use_polkit ? "us | ||||
e" : "not use"); | ||||
} | ||||
} else { | ||||
LOGDEBUG("Skipping libvirt policy kit configuration\n"); | ||||
} | ||||
} | ||||
{ // initialize hooks if their directory lo oks ok | { // initialize hooks if their directory lo oks ok | |||
char dir[EUCA_MAX_PATH]; | char dir[EUCA_MAX_PATH]; | |||
snprintf(dir, sizeof(dir), EUCALYPTUS_NC_HOOKS_DIR, nc_state.home); | snprintf(dir, sizeof(dir), EUCALYPTUS_NC_HOOKS_DIR, nc_state.home); | |||
// if 'dir' does not exist, init_hooks() will silently fail, | // if 'dir' does not exist, init_hooks() will silently fail, | |||
// and all future call_hooks() will silently succeed | // and all future call_hooks() will silently succeed | |||
init_hooks(nc_state.home, dir); | init_hooks(nc_state.home, dir); | |||
if (call_hooks(NC_EVENT_PRE_INIT, nc_state.home)) { | if (call_hooks(NC_EVENT_PRE_INIT, nc_state.home)) { | |||
LOGFATAL("hooks prevented initialization\n"); | LOGFATAL("hooks prevented initialization\n"); | |||
return (EUCA_FATAL_ERROR); | return (EUCA_FATAL_ERROR); | |||
End of changes. 8 change blocks. | ||||
2 lines changed or deleted | 83 lines changed or added |