// This test ensures that when explicit acknowledgements are enabled, // acknowledgements for master-generated updates are dropped by the // driver. We test this by creating an invalid task that uses no // resources. TEST_F(MesosSchedulerDriverTest, ExplicitAcknowledgementsMasterGeneratedUpdate) { Try<Owned<cluster::Master>> master = StartMaster(); ASSERT_SOME(master); Owned<MasterDetector> detector = master.get()->createDetector(); Try<Owned<cluster::Slave>> slave = StartSlave(detector.get()); ASSERT_SOME(slave); MockScheduler sched; MesosSchedulerDriver driver( &sched, DEFAULT_FRAMEWORK_INFO, master.get()->pid, false, DEFAULT_CREDENTIAL); EXPECT_CALL(sched, registered(&driver, _, _)); Future<vector<Offer>> offers; EXPECT_CALL(sched, resourceOffers(&driver, _)) .WillOnce(FutureArg<1>(&offers)) .WillRepeatedly(Return()); // Ignore subsequent offers. // Ensure no status update acknowledgements are sent to the master. EXPECT_NO_FUTURE_CALLS( mesos::scheduler::Call(), mesos::scheduler::Call::ACKNOWLEDGE, _ , master.get()->pid); driver.start(); AWAIT_READY(offers); EXPECT_NE(0u, offers->size()); // Launch a task using no resources. TaskInfo task; task.set_name(""); task.mutable_task_id()->set_value("1"); task.mutable_slave_id()->MergeFrom(offers.get()[0].slave_id()); task.mutable_executor()->MergeFrom(DEFAULT_EXECUTOR_INFO); vector<TaskInfo> tasks; tasks.push_back(task); Future<TaskStatus> status; EXPECT_CALL(sched, statusUpdate(&driver, _)) .WillOnce(FutureArg<1>(&status)); driver.launchTasks(offers.get()[0].id(), tasks); AWAIT_READY(status); ASSERT_EQ(TASK_ERROR, status->state()); ASSERT_EQ(TaskStatus::SOURCE_MASTER, status->source()); ASSERT_EQ(TaskStatus::REASON_TASK_INVALID, status->reason()); // Now send the acknowledgement. driver.acknowledgeStatusUpdate(status.get()); // Settle the clock to ensure driver processes the acknowledgement, // which should get dropped due to having come from the master. Clock::pause(); Clock::settle(); driver.stop(); driver.join(); }
fsal_status_t POSIXFSAL_close_by_fileid(posixfsal_file_t * file_descriptor /* IN */ , fsal_u64_t fileid) { Return(ERR_FSAL_NOTSUPP, 0, INDEX_FSAL_open_by_fileid); }
/** * FSAL_getattrs: * Get attributes for the object specified by its filehandle. * * \param filehandle (input): * The handle of the object to get parameters. * \param p_context (input): * Authentication context for the operation (user, export...). * \param object_attributes (mandatory input/output): * The retrieved attributes for the object. * As input, it defines the attributes that the caller * wants to retrieve (by positioning flags into this structure) * and the output is built considering this input * (it fills the structure according to the flags it contains). * * \return Major error codes : * - ERR_FSAL_NO_ERROR (no error) * - ERR_FSAL_STALE (object_handle does not address an existing object) * - ERR_FSAL_FAULT (a NULL pointer was passed as mandatory argument) * - Another error code if an error occured. */ fsal_status_t SNMPFSAL_getattrs(fsal_handle_t * file_hdl, /* IN */ fsal_op_context_t * context, /* IN */ fsal_attrib_list_t * object_attributes /* IN/OUT */ ) { int rc; fsal_status_t status; fsal_request_desc_t query_desc; struct tree *mib_node; netsnmp_variable_list *p_convert_var = NULL; snmpfsal_handle_t * filehandle = (snmpfsal_handle_t *)file_hdl; snmpfsal_op_context_t * p_context = (snmpfsal_op_context_t *)context; /* sanity checks. * note : object_attributes is mandatory in FSAL_getattrs. */ if(!filehandle || !p_context || !object_attributes) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_getattrs); /* don't call GET request on directory */ if(filehandle->data.object_type_reminder == FSAL_NODETYPE_LEAF && filehandle->data.oid_len != 0) { query_desc.request_type = SNMP_MSG_GET; TakeTokenFSCall(); /* call to snmpget */ rc = IssueSNMPQuery(p_context, filehandle->data.oid_tab, filehandle->data.oid_len, &query_desc); ReleaseTokenFSCall(); /* convert error code in case of error */ if(rc != SNMPERR_SUCCESS && snmp2fsal_error(rc) != ERR_FSAL_NOENT) Return(snmp2fsal_error(rc), rc, INDEX_FSAL_getattrs); if(snmp2fsal_error(rc) == ERR_FSAL_NOENT) Return(ERR_FSAL_STALE, rc, INDEX_FSAL_getattrs); p_convert_var = p_context->snmp_response->variables; /* check no such object, etc... */ if(p_convert_var->type == SNMP_NOSUCHOBJECT || p_convert_var->type == SNMP_NOSUCHINSTANCE || p_convert_var->type == SNMP_ENDOFMIBVIEW) Return(ERR_FSAL_STALE, p_convert_var->type, INDEX_FSAL_getattrs); /* retrieve the associated MIB node (can be null) */ mib_node = GetMIBNode(p_context, filehandle, TRUE); } /* endif not root */ else if(filehandle->data.object_type_reminder != FSAL_NODETYPE_ROOT && filehandle->data.oid_len != 0) { /* retrieve the associated MIB node (can be null) */ mib_node = GetMIBNode(p_context, filehandle, TRUE); } else /* root */ mib_node = NULL; /* @todo check no such object, etc... */ /* convert SNMP attributes to FSAL attributes */ rc = snmp2fsal_attributes(filehandle, p_convert_var, mib_node, object_attributes); Return(rc, 0, INDEX_FSAL_getattrs); }
/** * FSAL_open: * Open a regular file for reading/writing its data content. * * \param filehandle (input): * Handle of the file to be read/modified. * \param cred (input): * Authentication context for the operation (user,...). * \param openflags (input): * Flags that indicates behavior for file opening and access. * This is an inclusive OR of the following values * ( such of them are not compatible) : * - FSAL_O_RDONLY: opening file for reading only. * - FSAL_O_RDWR: opening file for reading and writing. * - FSAL_O_WRONLY: opening file for writting only. * - FSAL_O_APPEND: always write at the end of the file. * - FSAL_O_TRUNC: truncate the file to 0 on opening. * \param file_descriptor (output): * The file descriptor to be used for FSAL_read/write operations. * \param file_attributes (optionnal input/output): * Post operation attributes. * As input, it defines the attributes that the caller * wants to retrieve (by positioning flags into this structure) * and the output is built considering this input * (it fills the structure according to the flags it contains). * * \return Major error codes: * - ERR_FSAL_NO_ERROR: no error. * - Another error code if an error occured during this call. */ fsal_status_t POSIXFSAL_open(posixfsal_handle_t * p_filehandle, /* IN */ posixfsal_op_context_t * p_context, /* IN */ fsal_openflags_t openflags, /* IN */ posixfsal_file_t * p_file_descriptor, /* OUT */ fsal_attrib_list_t * p_file_attributes /* [ IN/OUT ] */ ) { int rc, errsv; fsal_status_t status; fsal_path_t fsalpath; struct stat buffstat; #ifdef _FSAL_POSIX_USE_STREAM char posix_flags[4]; /* stores r, r+, w, w+, a, or a+ */ #else int posix_flags; #endif /* sanity checks. * note : file_attributes is optional. */ if(!p_filehandle || !p_context || !p_file_descriptor) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_open); status = fsal_internal_getPathFromHandle(p_context, p_filehandle, 0, &fsalpath, &buffstat); if(FSAL_IS_ERROR(status)) Return(status.major, status.minor, INDEX_FSAL_open); status = fsal_internal_testAccess(p_context, (openflags & FSAL_O_RDONLY ? FSAL_R_OK : FSAL_W_OK) | FSAL_OWNER_OK, &buffstat, NULL); if(FSAL_IS_ERROR(status)) Return(status.major, status.minor, INDEX_FSAL_open); /* convert fsal open flags to posix open flags */ rc = fsal2posix_openflags(openflags, &posix_flags); /* flags conflicts. */ if(rc) { LogEvent(COMPONENT_FSAL, "Invalid/conflicting flags : %#X", openflags); Return(rc, 0, INDEX_FSAL_open); } TakeTokenFSCall(); #ifdef _FSAL_POSIX_USE_STREAM p_file_descriptor->p_file = fopen(fsalpath.path, posix_flags); errsv = errno; ReleaseTokenFSCall(); if(!(p_file_descriptor->p_file)) Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_open); #else p_file_descriptor->filefd = open(fsalpath.path, posix_flags); errsv = errno; ReleaseTokenFSCall(); #endif /* set the read-only flag of the file descriptor */ p_file_descriptor->ro = openflags & FSAL_O_RDONLY; /* output attributes */ if(p_file_attributes) { status = posix2fsal_attributes(&buffstat, p_file_attributes); if(FSAL_IS_ERROR(status)) { FSAL_CLEAR_MASK(p_file_attributes->asked_attributes); FSAL_SET_MASK(p_file_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR); } } Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_open); }
fsal_status_t POSIXFSAL_write(posixfsal_file_t * p_file_descriptor, /* IN */ fsal_seek_t * p_seek_descriptor, /* IN */ fsal_size_t buffer_size, /* IN */ caddr_t buffer, /* IN */ fsal_size_t * p_write_amount /* OUT */ ) { size_t nb_written; size_t i_size; int rc, errsv; /* sanity checks. */ if(!p_file_descriptor || !buffer || !p_write_amount) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_write); if(p_file_descriptor->ro) Return(ERR_FSAL_PERM, 0, INDEX_FSAL_write); /** @todo: manage fsal_size_t to size_t convertion */ i_size = (size_t) buffer_size; /* positioning */ if(p_seek_descriptor) { switch (p_seek_descriptor->whence) { case FSAL_SEEK_CUR: /* set position plus offset */ TakeTokenFSCall(); rc = fseek(p_file_descriptor->p_file, p_seek_descriptor->offset, SEEK_CUR); errsv = errno; ReleaseTokenFSCall(); break; case FSAL_SEEK_SET: /* set absolute position to offset */ TakeTokenFSCall(); rc = fseek(p_file_descriptor->p_file, p_seek_descriptor->offset, SEEK_SET); errsv = errno; ReleaseTokenFSCall(); break; case FSAL_SEEK_END: /* set end of file plus offset */ TakeTokenFSCall(); rc = fseek(p_file_descriptor->p_file, p_seek_descriptor->offset, SEEK_END); errsv = errno; ReleaseTokenFSCall(); break; } if(rc) { LogEvent(COMPONENT_FSAL, "Error in posix fseek operation (whence=%s, offset=%lld)", (p_seek_descriptor->whence == FSAL_SEEK_CUR ? "SEEK_CUR" : (p_seek_descriptor->whence == FSAL_SEEK_SET ? "SEEK_SET" : (p_seek_descriptor->whence == FSAL_SEEK_END ? "SEEK_END" : "ERROR"))), p_seek_descriptor->offset); Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_write); } LogFullDebug(COMPONENT_FSAL, "Write operation (whence=%s, offset=%lld, size=%lld)", (p_seek_descriptor->whence == FSAL_SEEK_CUR ? "SEEK_CUR" : (p_seek_descriptor->whence == FSAL_SEEK_SET ? "SEEK_SET" : (p_seek_descriptor->whence == FSAL_SEEK_END ? "SEEK_END" : "ERROR"))), p_seek_descriptor->offset, buffer_size); } /* write operation */ TakeTokenFSCall(); nb_written = fwrite(buffer, 1, i_size, p_file_descriptor->p_file); /* With no flush, uncommited write may occur on 64 bits platforms */ (void)fflush(p_file_descriptor->p_file); ReleaseTokenFSCall(); /** @todo: manage ssize_t to fsal_size_t convertion */ if(nb_written <= 0 && ferror(p_file_descriptor->p_file)) { Return(posix2fsal_error(EBADF), EBADF, INDEX_FSAL_write); } /* set output vars */ *p_write_amount = (fsal_size_t) nb_written; Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_write); }
// This test verifies that a re-registering slave sends the terminal // unacknowledged tasks for a terminal executor. This is required // for the master to correctly reconcile its view with the slave's // view of tasks. This test drops a terminal update to the master // and then forces the slave to re-register. TEST_F(MasterSlaveReconciliationTest, SlaveReregisterTerminatedExecutor) { Try<Owned<cluster::Master>> master = StartMaster(); ASSERT_SOME(master); MockExecutor exec(DEFAULT_EXECUTOR_ID); TestContainerizer containerizer(&exec); StandaloneMasterDetector detector(master.get()->pid); Try<Owned<cluster::Slave>> slave = StartSlave(&detector, &containerizer); ASSERT_SOME(slave); MockScheduler sched; MesosSchedulerDriver driver( &sched, DEFAULT_FRAMEWORK_INFO, master.get()->pid, DEFAULT_CREDENTIAL); Future<FrameworkID> frameworkId; EXPECT_CALL(sched, registered(&driver, _, _)) .WillOnce(FutureArg<1>(&frameworkId)); EXPECT_CALL(sched, resourceOffers(&driver, _)) .WillOnce(LaunchTasks(DEFAULT_EXECUTOR_INFO, 1, 1, 512, "*")) .WillRepeatedly(Return()); // Ignore subsequent offers. ExecutorDriver* execDriver; EXPECT_CALL(exec, registered(_, _, _, _)) .WillOnce(SaveArg<0>(&execDriver)); EXPECT_CALL(exec, launchTask(_, _)) .WillOnce(SendStatusUpdateFromTask(TASK_RUNNING)); Future<TaskStatus> status; EXPECT_CALL(sched, statusUpdate(&driver, _)) .WillOnce(FutureArg<1>(&status)); Future<StatusUpdateAcknowledgementMessage> statusUpdateAcknowledgementMessage = FUTURE_PROTOBUF( StatusUpdateAcknowledgementMessage(), master.get()->pid, slave.get()->pid); driver.start(); AWAIT_READY(status); EXPECT_EQ(TASK_RUNNING, status.get().state()); // Make sure the acknowledgement reaches the slave. AWAIT_READY(statusUpdateAcknowledgementMessage); // Drop the TASK_FINISHED status update sent to the master. Future<StatusUpdateMessage> statusUpdateMessage = DROP_PROTOBUF(StatusUpdateMessage(), _, master.get()->pid); Future<ExitedExecutorMessage> executorExitedMessage = FUTURE_PROTOBUF(ExitedExecutorMessage(), _, _); TaskStatus finishedStatus; finishedStatus = status.get(); finishedStatus.set_state(TASK_FINISHED); execDriver->sendStatusUpdate(finishedStatus); // Ensure the update was sent. AWAIT_READY(statusUpdateMessage); EXPECT_CALL(sched, executorLost(&driver, DEFAULT_EXECUTOR_ID, _, _)); // Now kill the executor. containerizer.destroy(frameworkId.get(), DEFAULT_EXECUTOR_ID); Future<TaskStatus> status2; EXPECT_CALL(sched, statusUpdate(&driver, _)) .WillOnce(FutureArg<1>(&status2)); // We drop the 'UpdateFrameworkMessage' from the master to slave to // stop the status update manager from retrying the update that was // already sent due to the new master detection. DROP_PROTOBUFS(UpdateFrameworkMessage(), _, _); detector.appoint(master.get()->pid); AWAIT_READY(status2); EXPECT_EQ(TASK_FINISHED, status2.get().state()); driver.stop(); driver.join(); }
/** * FSAL_readdir : * Read the entries of an opened directory. * * \param dir_descriptor (input): * Pointer to the directory descriptor filled by FSAL_opendir. * \param start_position (input): * Cookie that indicates the first object to be read during * this readdir operation. * This should be : * - FSAL_READDIR_FROM_BEGINNING for reading the content * of the directory from the beginning. * - The end_position parameter returned by the previous * call to FSAL_readdir. * \param get_attr_mask (input) * Specify the set of attributes to be retrieved for directory entries. * \param buffersize (input) * The size (in bytes) of the buffer where * the direntries are to be stored. * \param pdirent (output) * Adresse of the buffer where the direntries are to be stored. * \param end_position (output) * Cookie that indicates the current position in the directory. * \param nb_entries (output) * Pointer to the number of entries read during the call. * \param end_of_dir (output) * Pointer to a boolean that indicates if the end of dir * has been reached during the call. * * \return Major error codes : * - ERR_FSAL_NO_ERROR (no error) * - Another error code if an error occured. */ fsal_status_t LUSTREFSAL_readdir(fsal_dir_t *dir_desc, /* IN */ fsal_cookie_t start_pos, /* IN */ fsal_attrib_mask_t get_attr_mask, /* IN */ fsal_mdsize_t buffersize, /* IN */ fsal_dirent_t * p_pdirent, /* OUT */ fsal_cookie_t * p_end_position, /* OUT */ fsal_count_t * p_nb_entries, /* OUT */ fsal_boolean_t * p_end_of_dir /* OUT */ ) { fsal_status_t st; fsal_count_t max_dir_entries; struct dirent *dp; struct dirent dpe; fsal_path_t fsalpath; int rc; lustrefsal_dir_t * p_dir_descriptor = (lustrefsal_dir_t *)dir_desc; lustrefsal_cookie_t start_position; /*****************/ /* sanity checks */ /*****************/ if(!p_dir_descriptor || !p_pdirent || !p_end_position || !p_nb_entries || !p_end_of_dir) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_readdir); max_dir_entries = (buffersize / sizeof(fsal_dirent_t)); start_position.data.cookie = (off_t)start_pos.data; /***************************/ /* seek into the directory */ /***************************/ errno = 0; if(start_position.data.cookie == 0) { rewinddir(p_dir_descriptor->p_dir); rc = errno; } else { seekdir(p_dir_descriptor->p_dir, start_position.data.cookie); rc = errno; } if(rc) Return(posix2fsal_error(rc), rc, INDEX_FSAL_readdir); /************************/ /* browse the directory */ /************************/ *p_nb_entries = 0; while(*p_nb_entries < max_dir_entries) { /***********************/ /* read the next entry */ /***********************/ TakeTokenFSCall(); rc = readdir_r(p_dir_descriptor->p_dir, &dpe, &dp); ReleaseTokenFSCall(); if(rc) { rc = errno; Return(posix2fsal_error(rc), rc, INDEX_FSAL_readdir); } /* End of directory */ if(!dp) { *p_end_of_dir = 1; break; } /***********************************/ /* Get information about the entry */ /***********************************/ /* skip . and .. */ if(!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) continue; /* build the full path of the file into "fsalpath */ if(FSAL_IS_ERROR (st = FSAL_str2name(dp->d_name, FSAL_MAX_NAME_LEN, &(p_pdirent[*p_nb_entries].name)))) ReturnStatus(st, INDEX_FSAL_readdir); memcpy(&fsalpath, &(p_dir_descriptor->path), sizeof(fsal_path_t)); st = fsal_internal_appendNameToPath(&fsalpath, &(p_pdirent[*p_nb_entries].name)); if(FSAL_IS_ERROR(st)) ReturnStatus(st, INDEX_FSAL_readdir); /* get object handle */ TakeTokenFSCall(); st = fsal_internal_Path2Handle((fsal_op_context_t *) &p_dir_descriptor->context, &fsalpath, &(p_pdirent[*p_nb_entries].handle)); ReleaseTokenFSCall(); if(FSAL_IS_ERROR(st)) ReturnStatus(st, INDEX_FSAL_readdir); /************************ * Fills the attributes * ************************/ p_pdirent[*p_nb_entries].attributes.asked_attributes = get_attr_mask; st = LUSTREFSAL_getattrs(&(p_pdirent[*p_nb_entries].handle), (fsal_op_context_t *) &p_dir_descriptor->context, &p_pdirent[*p_nb_entries].attributes); if(FSAL_IS_ERROR(st)) { FSAL_CLEAR_MASK(p_pdirent[*p_nb_entries].attributes.asked_attributes); FSAL_SET_MASK(p_pdirent[*p_nb_entries].attributes.asked_attributes, FSAL_ATTR_RDATTR_ERR); } ((lustrefsal_cookie_t *) (&p_pdirent[*p_nb_entries].cookie))->data.cookie = telldir(p_dir_descriptor->p_dir); p_pdirent[*p_nb_entries].nextentry = NULL; if(*p_nb_entries) p_pdirent[*p_nb_entries - 1].nextentry = &(p_pdirent[*p_nb_entries]); memcpy((char *)p_end_position, (char *)&p_pdirent[*p_nb_entries].cookie, sizeof(lustrefsal_cookie_t)); (*p_nb_entries)++; } Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_readdir); }
// The purpose of this test is to ensure that when slaves are removed // from the master, and then attempt to re-register, we deny the // re-registration by sending a ShutdownMessage to the slave. // Why? Because during a network partition, the master will remove a // partitioned slave, thus sending its tasks to LOST. At this point, // when the partition is removed, the slave will attempt to // re-register with its running tasks. We've already notified // frameworks that these tasks were LOST, so we have to have the slave // slave shut down. TEST_F(PartitionTest, PartitionedSlaveReregistration) { Try<PID<Master> > master = StartMaster(); ASSERT_SOME(master); // Allow the master to PING the slave, but drop all PONG messages // from the slave. Note that we don't match on the master / slave // PIDs because it's actually the SlaveObserver Process that sends // the pings. Future<Message> ping = FUTURE_MESSAGE(Eq("PING"), _, _); DROP_MESSAGES(Eq("PONG"), _, _); MockExecutor exec(DEFAULT_EXECUTOR_ID); StandaloneMasterDetector detector(master.get()); Try<PID<Slave> > slave = StartSlave(&exec, &detector); ASSERT_SOME(slave); MockScheduler sched; MesosSchedulerDriver driver( &sched, DEFAULT_FRAMEWORK_INFO, master.get(), DEFAULT_CREDENTIAL); EXPECT_CALL(sched, registered(&driver, _, _)); Future<vector<Offer> > offers; EXPECT_CALL(sched, resourceOffers(&driver, _)) .WillOnce(FutureArg<1>(&offers)) .WillRepeatedly(Return()); driver.start(); AWAIT_READY(offers); ASSERT_NE(0u, offers.get().size()); // Launch a task. This is to ensure the task is killed by the slave, // during shutdown. TaskID taskId; taskId.set_value("1"); TaskInfo task; task.set_name(""); task.mutable_task_id()->MergeFrom(taskId); task.mutable_slave_id()->MergeFrom(offers.get()[0].slave_id()); task.mutable_resources()->MergeFrom(offers.get()[0].resources()); task.mutable_executor()->MergeFrom(DEFAULT_EXECUTOR_INFO); task.mutable_executor()->mutable_command()->set_value("sleep 60"); vector<TaskInfo> tasks; tasks.push_back(task); // Set up the expectations for launching the task. EXPECT_CALL(exec, registered(_, _, _, _)); EXPECT_CALL(exec, launchTask(_, _)) .WillOnce(SendStatusUpdateFromTask(TASK_RUNNING)); Future<TaskStatus> runningStatus; EXPECT_CALL(sched, statusUpdate(&driver, _)) .WillOnce(FutureArg<1>(&runningStatus)); Future<Nothing> statusUpdateAck = FUTURE_DISPATCH( slave.get(), &Slave::_statusUpdateAcknowledgement); driver.launchTasks(offers.get()[0].id(), tasks); AWAIT_READY(runningStatus); EXPECT_EQ(TASK_RUNNING, runningStatus.get().state()); // Wait for the slave to have handled the acknowledgment prior // to pausing the clock. AWAIT_READY(statusUpdateAck); // Drop the first shutdown message from the master (simulated // partition), allow the second shutdown message to pass when // the slave re-registers. Future<ShutdownMessage> shutdownMessage = DROP_PROTOBUF(ShutdownMessage(), _, slave.get()); Future<TaskStatus> lostStatus; EXPECT_CALL(sched, statusUpdate(&driver, _)) .WillOnce(FutureArg<1>(&lostStatus)); Future<Nothing> slaveLost; EXPECT_CALL(sched, slaveLost(&driver, _)) .WillOnce(FutureSatisfy(&slaveLost)); Clock::pause(); // Now, induce a partition of the slave by having the master // timeout the slave. uint32_t pings = 0; while (true) { AWAIT_READY(ping); pings++; if (pings == master::MAX_SLAVE_PING_TIMEOUTS) { break; } ping = FUTURE_MESSAGE(Eq("PING"), _, _); Clock::advance(master::SLAVE_PING_TIMEOUT); Clock::settle(); } Clock::advance(master::SLAVE_PING_TIMEOUT); Clock::settle(); // The master will have notified the framework of the lost task. AWAIT_READY(lostStatus); EXPECT_EQ(TASK_LOST, lostStatus.get().state()); // Wait for the master to attempt to shut down the slave. AWAIT_READY(shutdownMessage); // The master will notify the framework that the slave was lost. AWAIT_READY(slaveLost); Clock::resume(); // We now complete the partition on the slave side as well. This // is done by simulating a master loss event which would normally // occur during a network partition. detector.appoint(None()); Future<Nothing> shutdown; EXPECT_CALL(exec, shutdown(_)) .WillOnce(FutureSatisfy(&shutdown)); shutdownMessage = FUTURE_PROTOBUF(ShutdownMessage(), _, slave.get()); // Have the slave re-register with the master. detector.appoint(master.get()); // Upon re-registration, the master will shutdown the slave. // The slave will then shut down the executor. AWAIT_READY(shutdownMessage); AWAIT_READY(shutdown); driver.stop(); driver.join(); Shutdown(); }
// The purpose of this test is to ensure that when slaves are removed // from the master, and then attempt to send status updates, we send // a ShutdownMessage to the slave. Why? Because during a network // partition, the master will remove a partitioned slave, thus sending // its tasks to LOST. At this point, when the partition is removed, // the slave may attempt to send updates if it was unaware that the // master removed it. We've already notified frameworks that these // tasks were LOST, so we have to have the slave shut down. TEST_F(PartitionTest, PartitionedSlaveStatusUpdates) { Try<PID<Master> > master = StartMaster(); ASSERT_SOME(master); // Allow the master to PING the slave, but drop all PONG messages // from the slave. Note that we don't match on the master / slave // PIDs because it's actually the SlaveObserver Process that sends // the pings. Future<Message> ping = FUTURE_MESSAGE(Eq("PING"), _, _); DROP_MESSAGES(Eq("PONG"), _, _); Future<SlaveRegisteredMessage> slaveRegisteredMessage = FUTURE_PROTOBUF(SlaveRegisteredMessage(), _, _); MockExecutor exec(DEFAULT_EXECUTOR_ID); Try<PID<Slave> > slave = StartSlave(&exec); ASSERT_SOME(slave); AWAIT_READY(slaveRegisteredMessage); SlaveID slaveId = slaveRegisteredMessage.get().slave_id(); MockScheduler sched; MesosSchedulerDriver driver( &sched, DEFAULT_FRAMEWORK_INFO, master.get(), DEFAULT_CREDENTIAL); Future<FrameworkID> frameworkId; EXPECT_CALL(sched, registered(&driver, _, _)) .WillOnce(FutureArg<1>(&frameworkId)); EXPECT_CALL(sched, resourceOffers(&driver, _)) .WillRepeatedly(Return()); driver.start(); AWAIT_READY(frameworkId); // Drop the first shutdown message from the master (simulated // partition), allow the second shutdown message to pass when // the slave sends an update. Future<ShutdownMessage> shutdownMessage = DROP_PROTOBUF(ShutdownMessage(), _, slave.get()); EXPECT_CALL(sched, offerRescinded(&driver, _)) .WillRepeatedly(Return()); Future<Nothing> slaveLost; EXPECT_CALL(sched, slaveLost(&driver, _)) .WillOnce(FutureSatisfy(&slaveLost)); Clock::pause(); // Now, induce a partition of the slave by having the master // timeout the slave. uint32_t pings = 0; while (true) { AWAIT_READY(ping); pings++; if (pings == master::MAX_SLAVE_PING_TIMEOUTS) { break; } ping = FUTURE_MESSAGE(Eq("PING"), _, _); Clock::advance(master::SLAVE_PING_TIMEOUT); Clock::settle(); } Clock::advance(master::SLAVE_PING_TIMEOUT); Clock::settle(); // Wait for the master to attempt to shut down the slave. AWAIT_READY(shutdownMessage); // The master will notify the framework that the slave was lost. AWAIT_READY(slaveLost); shutdownMessage = FUTURE_PROTOBUF(ShutdownMessage(), _, slave.get()); // At this point, the slave still thinks it's registered, so we // simulate a status update coming from the slave. TaskID taskId; taskId.set_value("task_id"); const StatusUpdate& update = protobuf::createStatusUpdate( frameworkId.get(), slaveId, taskId, TASK_RUNNING, TaskStatus::SOURCE_SLAVE); StatusUpdateMessage message; message.mutable_update()->CopyFrom(update); message.set_pid(stringify(slave.get())); process::post(master.get(), message); // The master should shutdown the slave upon receiving the update. AWAIT_READY(shutdownMessage); Clock::resume(); driver.stop(); driver.join(); Shutdown(); }
TEST_P(MemoryIsolatorTest, ROOT_MemUsage) { Try<Owned<cluster::Master>> master = StartMaster(); ASSERT_SOME(master); slave::Flags flags = CreateSlaveFlags(); flags.isolation = GetParam(); Fetcher fetcher(flags); Try<MesosContainerizer*> _containerizer = MesosContainerizer::create(flags, true, &fetcher); ASSERT_SOME(_containerizer); Owned<MesosContainerizer> containerizer(_containerizer.get()); Owned<MasterDetector> detector = master.get()->createDetector(); Try<Owned<cluster::Slave>> slave = StartSlave( detector.get(), containerizer.get()); ASSERT_SOME(slave); MockScheduler sched; MesosSchedulerDriver driver( &sched, DEFAULT_FRAMEWORK_INFO, master.get()->pid, DEFAULT_CREDENTIAL); EXPECT_CALL(sched, registered(&driver, _, _)); Future<vector<Offer>> offers; EXPECT_CALL(sched, resourceOffers(&driver, _)) .WillOnce(FutureArg<1>(&offers)) .WillRepeatedly(Return()); // Ignore subsequent offers. driver.start(); AWAIT_READY(offers); ASSERT_FALSE(offers->empty()); TaskInfo task = createTask(offers.get()[0], "sleep 120"); Future<TaskStatus> statusRunning; EXPECT_CALL(sched, statusUpdate(&driver, _)) .WillOnce(FutureArg<1>(&statusRunning)); driver.launchTasks(offers.get()[0].id(), {task}); AWAIT_READY(statusRunning); EXPECT_EQ(TASK_RUNNING, statusRunning->state()); Future<hashset<ContainerID>> containers = containerizer->containers(); AWAIT_READY(containers); ASSERT_EQ(1u, containers->size()); ContainerID containerId = *(containers->begin()); Future<ResourceStatistics> usage = containerizer->usage(containerId); AWAIT_READY(usage); // TODO(jieyu): Consider using a program that predictably increases // RSS so that we can set more meaningful expectation here. EXPECT_LT(0u, usage->mem_rss_bytes()); driver.stop(); driver.join(); }
fsal_status_t VFSFSAL_truncate(vfsfsal_handle_t * p_filehandle, /* IN */ vfsfsal_op_context_t * p_context, /* IN */ fsal_size_t length, /* IN */ vfsfsal_file_t * file_descriptor, /* Unused in this FSAL */ fsal_attrib_list_t * p_object_attributes /* [ IN/OUT ] */ ) { int rc, errsv; int fd; fsal_status_t st; /* sanity checks. * note : object_attributes is optional. */ if(!p_filehandle || !p_context) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_truncate); /* get the path of the file and its handle */ TakeTokenFSCall(); st = fsal_internal_handle2fd(p_context, p_filehandle, &fd, O_RDWR); ReleaseTokenFSCall(); if(FSAL_IS_ERROR(st)) ReturnStatus(st, INDEX_FSAL_truncate); /* Executes the POSIX truncate operation */ TakeTokenFSCall(); rc = ftruncate(fd, length); errsv = errno; ReleaseTokenFSCall(); close(fd); /* convert return code */ if(rc) { if(errsv == ENOENT) Return(ERR_FSAL_STALE, errsv, INDEX_FSAL_truncate); else Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_truncate); } /* Optionally retrieve attributes */ if(p_object_attributes) { fsal_status_t st; st = VFSFSAL_getattrs(p_filehandle, p_context, p_object_attributes); if(FSAL_IS_ERROR(st)) { FSAL_CLEAR_MASK(p_object_attributes->asked_attributes); FSAL_SET_MASK(p_object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR); } } /* No error occurred */ Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_truncate); }
TEST(AggregateTests, PlainSumCountDistinctTest) { /* * SELECT SUM(a), COUNT(b), COUNT(DISTINCT b) from table */ const int tuple_count = TESTS_TUPLES_PER_TILEGROUP; // Create a table and wrap it in logical tiles auto &txn_manager = concurrency::TransactionManager::GetInstance(); auto txn = txn_manager.BeginTransaction(); auto txn_id = txn->GetTransactionId(); std::unique_ptr<storage::DataTable> data_table( ExecutorTestsUtil::CreateTable(tuple_count, false)); ExecutorTestsUtil::PopulateTable(txn, data_table.get(), 2 * tuple_count, false, true, true); txn_manager.CommitTransaction(); std::unique_ptr<executor::LogicalTile> source_logical_tile1( executor::LogicalTileFactory::WrapTileGroup(data_table->GetTileGroup(0), txn_id)); std::unique_ptr<executor::LogicalTile> source_logical_tile2( executor::LogicalTileFactory::WrapTileGroup(data_table->GetTileGroup(1), txn_id)); // (1-5) Setup plan node // 1) Set up group-by columns std::vector<oid_t> group_by_columns; // 2) Set up project info planner::ProjectInfo::DirectMapList direct_map_list = { {0, {1, 0}}, {1, {1, 1}}, {2, {1, 2}}}; auto proj_info = new planner::ProjectInfo(planner::ProjectInfo::TargetList(), std::move(direct_map_list)); // 3) Set up unique aggregates std::vector<planner::AggregatePlan::AggTerm> agg_terms; planner::AggregatePlan::AggTerm sumA(EXPRESSION_TYPE_AGGREGATE_SUM, expression::TupleValueFactory(0, 0), false); planner::AggregatePlan::AggTerm countB(EXPRESSION_TYPE_AGGREGATE_COUNT, expression::TupleValueFactory(0, 1), false); // Flag distinct planner::AggregatePlan::AggTerm countDistinctB( EXPRESSION_TYPE_AGGREGATE_COUNT, expression::TupleValueFactory(0, 1), true); // Flag distinct agg_terms.push_back(sumA); agg_terms.push_back(countB); agg_terms.push_back(countDistinctB); // 4) Set up predicate (empty) expression::AbstractExpression* predicate = nullptr; // 5) Create output table schema auto data_table_schema = data_table.get()->GetSchema(); std::vector<oid_t> set = {0, 1, 1}; std::vector<catalog::Column> columns; for (auto column_index : set) { columns.push_back(data_table_schema->GetColumn(column_index)); } auto output_table_schema = new catalog::Schema(columns); // OK) Create the plan node planner::AggregatePlan node(proj_info, predicate, std::move(agg_terms), std::move(group_by_columns), output_table_schema, AGGREGATE_TYPE_PLAIN); // Create and set up executor auto txn2 = txn_manager.BeginTransaction(); std::unique_ptr<executor::ExecutorContext> context( new executor::ExecutorContext(txn2)); executor::AggregateExecutor executor(&node, context.get()); MockExecutor child_executor; executor.AddChild(&child_executor); EXPECT_CALL(child_executor, DInit()).WillOnce(Return(true)); EXPECT_CALL(child_executor, DExecute()) .WillOnce(Return(true)) .WillOnce(Return(true)) .WillOnce(Return(false)); EXPECT_CALL(child_executor, GetOutput()) .WillOnce(Return(source_logical_tile1.release())) .WillOnce(Return(source_logical_tile2.release())); EXPECT_TRUE(executor.Init()); EXPECT_TRUE(executor.Execute()); txn_manager.CommitTransaction(); /* Verify result */ std::unique_ptr<executor::LogicalTile> result_tile(executor.GetOutput()); EXPECT_TRUE(result_tile.get() != nullptr); EXPECT_TRUE(result_tile->GetValue(0, 0) .OpEquals(ValueFactory::GetIntegerValue(50)) .IsTrue()); EXPECT_TRUE(result_tile->GetValue(0, 1) .OpEquals(ValueFactory::GetIntegerValue(10)) .IsTrue()); EXPECT_TRUE(result_tile->GetValue(0, 2) .OpLessThanOrEqual(ValueFactory::GetIntegerValue(3)) .IsTrue()); }
TEST(AggregateTests, HashDistinctTest) { /* * SELECT d, a, b, c FROM table GROUP BY a, b, c, d; */ const int tuple_count = TESTS_TUPLES_PER_TILEGROUP; // Create a table and wrap it in logical tiles auto &txn_manager = concurrency::TransactionManager::GetInstance(); auto txn = txn_manager.BeginTransaction(); auto txn_id = txn->GetTransactionId(); std::unique_ptr<storage::DataTable> data_table( ExecutorTestsUtil::CreateTable(tuple_count, false)); ExecutorTestsUtil::PopulateTable(txn, data_table.get(), 2 * tuple_count, false, true, true); // let it be random txn_manager.CommitTransaction(); std::unique_ptr<executor::LogicalTile> source_logical_tile1( executor::LogicalTileFactory::WrapTileGroup(data_table->GetTileGroup(0), txn_id)); std::unique_ptr<executor::LogicalTile> source_logical_tile2( executor::LogicalTileFactory::WrapTileGroup(data_table->GetTileGroup(1), txn_id)); // (1-5) Setup plan node // 1) Set up group-by columns std::vector<oid_t> group_by_columns = {0, 1, 2, 3}; // 2) Set up project info planner::ProjectInfo::DirectMapList direct_map_list = { {0, {0, 3}}, {1, {0, 0}}, {2, {0, 1}}, {3, {0, 2}}}; auto proj_info = new planner::ProjectInfo(planner::ProjectInfo::TargetList(), std::move(direct_map_list)); // 3) Set up unique aggregates (empty) std::vector<planner::AggregatePlan::AggTerm> agg_terms; // 4) Set up predicate (empty) expression::AbstractExpression* predicate = nullptr; // 5) Create output table schema auto data_table_schema = data_table.get()->GetSchema(); std::vector<oid_t> set = {3, 0, 1, 2}; std::vector<catalog::Column> columns; for (auto column_index : set) { columns.push_back(data_table_schema->GetColumn(column_index)); } auto output_table_schema = new catalog::Schema(columns); // OK) Create the plan node planner::AggregatePlan node(proj_info, predicate, std::move(agg_terms), std::move(group_by_columns), output_table_schema, AGGREGATE_TYPE_HASH); // Create and set up executor auto txn2 = txn_manager.BeginTransaction(); std::unique_ptr<executor::ExecutorContext> context( new executor::ExecutorContext(txn2)); executor::AggregateExecutor executor(&node, context.get()); MockExecutor child_executor; executor.AddChild(&child_executor); EXPECT_CALL(child_executor, DInit()).WillOnce(Return(true)); EXPECT_CALL(child_executor, DExecute()) .WillOnce(Return(true)) .WillOnce(Return(true)) .WillOnce(Return(false)); EXPECT_CALL(child_executor, GetOutput()) .WillOnce(Return(source_logical_tile1.release())) .WillOnce(Return(source_logical_tile2.release())); EXPECT_TRUE(executor.Init()); EXPECT_TRUE(executor.Execute()); txn_manager.CommitTransaction(); /* Verify result */ std::unique_ptr<executor::LogicalTile> result_tile(executor.GetOutput()); EXPECT_TRUE(result_tile.get() != nullptr); for (auto tuple_id : *result_tile) { int colA = ValuePeeker::PeekAsInteger(result_tile->GetValue(tuple_id, 1)); (void)colA; } }
fsal_status_t CEPHFSAL_rename(fsal_handle_t * extold_parent, fsal_name_t * old_name, fsal_handle_t * extnew_parent, fsal_name_t * new_name, fsal_op_context_t * extcontext, fsal_attrib_list_t * src_dir_attributes, fsal_attrib_list_t * tgt_dir_attributes) { int rc; cephfsal_handle_t* old_parent = (cephfsal_handle_t*) extold_parent; cephfsal_handle_t* new_parent = (cephfsal_handle_t*) extnew_parent; cephfsal_op_context_t* context = (cephfsal_op_context_t*) extcontext; char oldstr[FSAL_MAX_NAME_LEN+1]; char newstr[FSAL_MAX_NAME_LEN+1]; int uid = FSAL_OP_CONTEXT_TO_UID(context); int gid = FSAL_OP_CONTEXT_TO_GID(context); /* sanity checks. * note : src/tgt_dir_attributes are optional. */ if(!old_parent || !new_parent || !old_name || !new_name || !context) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_rename); if(src_dir_attributes) { fsal_status_t status = CEPHFSAL_getattrs(extold_parent, extcontext, src_dir_attributes); if(FSAL_IS_ERROR(status)) { FSAL_CLEAR_MASK(src_dir_attributes->asked_attributes); FSAL_SET_MASK(src_dir_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR); } } if(tgt_dir_attributes) { fsal_status_t status; /* optimization when src=tgt : */ if(!CEPHFSAL_handlecmp(extold_parent, extnew_parent, &status) && src_dir_attributes) { /* If source dir = target dir, we just copy the attributes. * to avoid doing another getattr. */ (*tgt_dir_attributes) = (*src_dir_attributes); } else { status = CEPHFSAL_getattrs(extnew_parent, extcontext, tgt_dir_attributes); if(FSAL_IS_ERROR(status)) { FSAL_CLEAR_MASK(tgt_dir_attributes->asked_attributes); FSAL_SET_MASK(tgt_dir_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR); } } } FSAL_name2str(old_name, oldstr, FSAL_MAX_NAME_LEN); FSAL_name2str(new_name, newstr, FSAL_MAX_NAME_LEN); rc = ceph_ll_rename(context->export_context->cmount, VINODE(old_parent), oldstr, VINODE(new_parent), newstr, uid, gid); if (rc < 0) Return(posix2fsal_error(rc), 0, INDEX_FSAL_rename); /* OK */ Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_rename); }
// This test verifies that when the slave re-registers, the master // does not send TASK_LOST update for a task that has reached terminal // state but is waiting for an acknowledgement. TEST_F(MasterSlaveReconciliationTest, SlaveReregisterTerminalTask) { Try<Owned<cluster::Master>> master = StartMaster(); ASSERT_SOME(master); MockExecutor exec(DEFAULT_EXECUTOR_ID); TestContainerizer containerizer(&exec); StandaloneMasterDetector detector(master.get()->pid); Try<Owned<cluster::Slave>> slave = StartSlave(&detector, &containerizer); ASSERT_SOME(slave); MockScheduler sched; MesosSchedulerDriver driver( &sched, DEFAULT_FRAMEWORK_INFO, master.get()->pid, DEFAULT_CREDENTIAL); EXPECT_CALL(sched, registered(&driver, _, _)); Future<vector<Offer> > offers; EXPECT_CALL(sched, resourceOffers(&driver, _)) .WillOnce(FutureArg<1>(&offers)) .WillRepeatedly(Return()); // Ignore subsequent offers. driver.start(); AWAIT_READY(offers); EXPECT_NE(0u, offers.get().size()); TaskInfo task; task.set_name("test task"); task.mutable_task_id()->set_value("1"); task.mutable_slave_id()->MergeFrom(offers.get()[0].slave_id()); task.mutable_resources()->MergeFrom(offers.get()[0].resources()); task.mutable_executor()->MergeFrom(DEFAULT_EXECUTOR_INFO); EXPECT_CALL(exec, registered(_, _, _, _)); // Send a terminal update right away. EXPECT_CALL(exec, launchTask(_, _)) .WillOnce(SendStatusUpdateFromTask(TASK_FINISHED)); // Drop the status update from slave to the master, so that // the slave has a pending terminal update when it re-registers. DROP_PROTOBUF(StatusUpdateMessage(), _, master.get()->pid); Future<Nothing> _statusUpdate = FUTURE_DISPATCH(_, &Slave::_statusUpdate); Future<TaskStatus> status; EXPECT_CALL(sched, statusUpdate(&driver, _)) .WillOnce(FutureArg<1>(&status)) .WillRepeatedly(Return()); // Ignore retried update due to update framework. driver.launchTasks(offers.get()[0].id(), {task}); AWAIT_READY(_statusUpdate); Future<SlaveReregisteredMessage> slaveReregisteredMessage = FUTURE_PROTOBUF(SlaveReregisteredMessage(), _, _); // Simulate a spurious master change event (e.g., due to ZooKeeper // expiration) at the slave to force re-registration. detector.appoint(master.get()->pid); AWAIT_READY(slaveReregisteredMessage); // The master should not send a TASK_LOST after the slave // re-registers. We check this by calling Clock::settle() so that // the only update the scheduler receives is the retried // TASK_FINISHED update. // NOTE: The status update manager resends the status update when // it detects a new master. Clock::pause(); Clock::settle(); AWAIT_READY(status); ASSERT_EQ(TASK_FINISHED, status.get().state()); EXPECT_CALL(exec, shutdown(_)) .Times(AtMost(1)); driver.stop(); driver.join(); }
// The purpose of this test is to ensure that when slaves are removed // from the master, and then attempt to send exited executor messages, // we send a ShutdownMessage to the slave. Why? Because during a // network partition, the master will remove a partitioned slave, thus // sending its tasks to LOST. At this point, when the partition is // removed, the slave may attempt to send exited executor messages if // it was unaware that the master removed it. We've already // notified frameworks that the tasks under the executors were LOST, // so we have to have the slave shut down. TEST_F(PartitionTest, PartitionedSlaveExitedExecutor) { Try<PID<Master> > master = StartMaster(); ASSERT_SOME(master); // Allow the master to PING the slave, but drop all PONG messages // from the slave. Note that we don't match on the master / slave // PIDs because it's actually the SlaveObserver Process that sends // the pings. Future<Message> ping = FUTURE_MESSAGE(Eq("PING"), _, _); DROP_MESSAGES(Eq("PONG"), _, _); MockExecutor exec(DEFAULT_EXECUTOR_ID); TestContainerizer containerizer(&exec); Try<PID<Slave> > slave = StartSlave(&containerizer); ASSERT_SOME(slave); MockScheduler sched; MesosSchedulerDriver driver( &sched, DEFAULT_FRAMEWORK_INFO, master.get(), DEFAULT_CREDENTIAL); Future<FrameworkID> frameworkId; EXPECT_CALL(sched, registered(&driver, _, _)) .WillOnce(FutureArg<1>(&frameworkId));\ Future<vector<Offer> > offers; EXPECT_CALL(sched, resourceOffers(&driver, _)) .WillOnce(FutureArg<1>(&offers)) .WillRepeatedly(Return()); driver.start(); AWAIT_READY(frameworkId); AWAIT_READY(offers); ASSERT_NE(0u, offers.get().size()); // Launch a task. This allows us to have the slave send an // ExitedExecutorMessage. TaskID taskId; taskId.set_value("1"); TaskInfo task; task.set_name(""); task.mutable_task_id()->MergeFrom(taskId); task.mutable_slave_id()->MergeFrom(offers.get()[0].slave_id()); task.mutable_resources()->MergeFrom(offers.get()[0].resources()); task.mutable_executor()->MergeFrom(DEFAULT_EXECUTOR_INFO); task.mutable_executor()->mutable_command()->set_value("sleep 60"); vector<TaskInfo> tasks; tasks.push_back(task); // Set up the expectations for launching the task. EXPECT_CALL(exec, registered(_, _, _, _)); EXPECT_CALL(exec, launchTask(_, _)) .WillOnce(SendStatusUpdateFromTask(TASK_RUNNING)); // Drop all the status updates from the slave, so that we can // ensure the ExitedExecutorMessage is what triggers the slave // shutdown. DROP_PROTOBUFS(StatusUpdateMessage(), _, master.get()); driver.launchTasks(offers.get()[0].id(), tasks); // Drop the first shutdown message from the master (simulated // partition) and allow the second shutdown message to pass when // triggered by the ExitedExecutorMessage. Future<ShutdownMessage> shutdownMessage = DROP_PROTOBUF(ShutdownMessage(), _, slave.get()); Future<TaskStatus> lostStatus; EXPECT_CALL(sched, statusUpdate(&driver, _)) .WillOnce(FutureArg<1>(&lostStatus)); Future<Nothing> slaveLost; EXPECT_CALL(sched, slaveLost(&driver, _)) .WillOnce(FutureSatisfy(&slaveLost)); Clock::pause(); // Now, induce a partition of the slave by having the master // timeout the slave. uint32_t pings = 0; while (true) { AWAIT_READY(ping); pings++; if (pings == master::MAX_SLAVE_PING_TIMEOUTS) { break; } ping = FUTURE_MESSAGE(Eq("PING"), _, _); Clock::advance(master::SLAVE_PING_TIMEOUT); Clock::settle(); } Clock::advance(master::SLAVE_PING_TIMEOUT); Clock::settle(); // The master will have notified the framework of the lost task. AWAIT_READY(lostStatus); EXPECT_EQ(TASK_LOST, lostStatus.get().state()); // Wait for the master to attempt to shut down the slave. AWAIT_READY(shutdownMessage); // The master will notify the framework that the slave was lost. AWAIT_READY(slaveLost); shutdownMessage = FUTURE_PROTOBUF(ShutdownMessage(), _, slave.get()); // Induce an ExitedExecutorMessage from the slave. containerizer.destroy( frameworkId.get(), DEFAULT_EXECUTOR_INFO.executor_id()); // Upon receiving the message, the master will shutdown the slave. AWAIT_READY(shutdownMessage); Clock::resume(); driver.stop(); driver.join(); Shutdown(); }
// This test verifies that when the slave re-registers, we correctly // send the information about actively running frameworks. TEST_F(MasterSlaveReconciliationTest, SlaveReregisterFrameworks) { Try<Owned<cluster::Master>> master = StartMaster(); ASSERT_SOME(master); MockExecutor exec(DEFAULT_EXECUTOR_ID); TestContainerizer containerizer(&exec); StandaloneMasterDetector detector(master.get()->pid); Try<Owned<cluster::Slave>> slave = StartSlave(&detector, &containerizer); ASSERT_SOME(slave); MockScheduler sched; MesosSchedulerDriver driver( &sched, DEFAULT_FRAMEWORK_INFO, master.get()->pid, DEFAULT_CREDENTIAL); EXPECT_CALL(sched, registered(&driver, _, _)); Future<vector<Offer> > offers; EXPECT_CALL(sched, resourceOffers(&driver, _)) .WillOnce(FutureArg<1>(&offers)) .WillRepeatedly(Return()); // Ignore subsequent offers. driver.start(); AWAIT_READY(offers); EXPECT_NE(0u, offers.get().size()); TaskInfo task; task.set_name("test task"); task.mutable_task_id()->set_value("1"); task.mutable_slave_id()->MergeFrom(offers.get()[0].slave_id()); task.mutable_resources()->MergeFrom(offers.get()[0].resources()); task.mutable_executor()->MergeFrom(DEFAULT_EXECUTOR_INFO); EXPECT_CALL(exec, registered(_, _, _, _)); // Send an update right away. EXPECT_CALL(exec, launchTask(_, _)) .WillOnce(SendStatusUpdateFromTask(TASK_RUNNING)); Future<Nothing> _statusUpdate = FUTURE_DISPATCH(_, &Slave::_statusUpdate); Future<TaskStatus> status; EXPECT_CALL(sched, statusUpdate(&driver, _)) .WillOnce(FutureArg<1>(&status)) .WillRepeatedly(Return()); // Ignore retried update due to update framework. driver.launchTasks(offers.get()[0].id(), {task}); AWAIT_READY(_statusUpdate); Future<ReregisterSlaveMessage> reregisterSlave = FUTURE_PROTOBUF(ReregisterSlaveMessage(), _, _); // Simulate a spurious master change event (e.g., due to ZooKeeper // expiration) at the slave to force re-registration. detector.appoint(master.get()->pid); // Expect to receive the 'ReregisterSlaveMessage' containing the // active frameworks. AWAIT_READY(reregisterSlave); EXPECT_EQ(1u, reregisterSlave.get().frameworks().size()); Clock::pause(); Clock::settle(); AWAIT_READY(status); EXPECT_CALL(exec, shutdown(_)) .Times(AtMost(1)); driver.stop(); driver.join(); }
// This test checks that a scheduler gets a slave lost // message for a partitioned slave. TEST_F(PartitionTest, PartitionedSlave) { Try<PID<Master> > master = StartMaster(); ASSERT_SOME(master); // Set these expectations up before we spawn the slave so that we // don't miss the first PING. Future<Message> ping = FUTURE_MESSAGE(Eq("PING"), _, _); // Drop all the PONGs to simulate slave partition. DROP_MESSAGES(Eq("PONG"), _, _); Try<PID<Slave> > slave = StartSlave(); ASSERT_SOME(slave); MockScheduler sched; MesosSchedulerDriver driver( &sched, DEFAULT_FRAMEWORK_INFO, master.get(), DEFAULT_CREDENTIAL); EXPECT_CALL(sched, registered(&driver, _, _)); Future<Nothing> resourceOffers; EXPECT_CALL(sched, resourceOffers(&driver, _)) .WillOnce(FutureSatisfy(&resourceOffers)) .WillRepeatedly(Return()); // Ignore subsequent offers. driver.start(); // Need to make sure the framework AND slave have registered with // master. Waiting for resource offers should accomplish both. AWAIT_READY(resourceOffers); Clock::pause(); EXPECT_CALL(sched, offerRescinded(&driver, _)) .Times(AtMost(1)); Future<Nothing> slaveLost; EXPECT_CALL(sched, slaveLost(&driver, _)) .WillOnce(FutureSatisfy(&slaveLost)); // Now advance through the PINGs. uint32_t pings = 0; while (true) { AWAIT_READY(ping); pings++; if (pings == master::MAX_SLAVE_PING_TIMEOUTS) { break; } ping = FUTURE_MESSAGE(Eq("PING"), _, _); Clock::advance(master::SLAVE_PING_TIMEOUT); } Clock::advance(master::SLAVE_PING_TIMEOUT); AWAIT_READY(slaveLost); this->Stop(slave.get()); JSON::Object stats = Metrics(); EXPECT_EQ(1, stats.values["master/slave_removals"]); EXPECT_EQ(1, stats.values["master/slave_removals/reason_unhealthy"]); driver.stop(); driver.join(); Shutdown(); Clock::resume(); }
/// Processes the data using contractors and bissections. Classifies the boxes in outside (grey), back_in(yellow) and unsafe (red) void Sivia::do_Sivia(Ctc& tubeConstraints, Data &data, Function gdot, bool calcInner) { QTime tSivia; tSivia.start(); if (calcInner) //inner approximation calculation { int count=0; while (!data.boxes.empty()) { IntervalVector currentBox = data.boxes.front(); //start from the first one data.boxes.pop_front(); //once it has been copied remove the first box IntervalVector auxBox=currentBox; //store it in aux variable to compare later tubeConstraints.contract(currentBox); //contract the current box using the previously calculated constraints if (currentBox!=auxBox){ //if the box has been contracted IntervalVector* removedByContractorInner; int setDiff=auxBox.diff(currentBox, removedByContractorInner); //set difference between the contracted box and the original box for (int i = 0; i < setDiff; ++i) { //data.boxesOutside.push_back(removedByContractor[i]); //add the areas removed by the contractor to the outside set bool testInside=true; IntervalVector gg=data.g->eval_vector(removedByContractorInner[i]); for(int j = 0; j<gg.size(); j++){ testInside = testInside && (gg[j].ub()<=0); } if (testInside) { data.boxesInside.append(removedByContractorInner[i]); } } delete[] removedByContractorInner; } if(data.realTimeDraw){ //draw the boxes processing in real time draw_update(data, auxBox, currentBox); } bool allBoxesLessEpsilon=true; //check if all the boxes are smaler than epsilon for (int i=0;(i<(currentBox.size()-1));i++){ allBoxesLessEpsilon = (allBoxesLessEpsilon && ((currentBox.diam()[i])<=data.epsilons[i])); } allBoxesLessEpsilon = (allBoxesLessEpsilon && ((currentBox[currentBox.size()-1].diam())<=data.dt)); //check the time box also bool boxesLessEpsilon=false; //check if at least one box is smaller than epsilon for (int i=0;(i<(currentBox.size()-1));i++){ boxesLessEpsilon = boxesLessEpsilon||((currentBox[i].diam())<=data.epsilons[i]); } boxesLessEpsilon = boxesLessEpsilon&&((currentBox[currentBox.size()-1].diam())<=data.dt); //check time box if (boxesLessEpsilon && !allBoxesLessEpsilon){ IntervalVector xnext = currentBox.subvector(0, data.numVarF-1).mid(); //using the middle point of the box calculate the future positions using euler method IntervalVector x = currentBox.mid(); bool testBackIn; for (int i = 0;i<data.numFuturePos;i++){ // Euler method: x(n+1)=x(n)+dt*fx x[data.numVarF]= x[data.numVarF].mid(); testBackIn = true; xnext=xnext+(data.dt)*data.f->eval_vector(x); x.put(0, xnext); x[data.numVarF] = x[data.numVarF]+(data.dt); IntervalVector gg=data.g->eval_vector(x); for(int j = 0; j<gg.size(); j++){ testBackIn = testBackIn && (gg[j].ub()<0); //test if it comes back to the bubble } if(testBackIn == true){ //If so we calculate the max deviation break; } } if(testBackIn == true){ //If my box was back in the bubble after integration, I store it in boxesbackin (data.boxesInsideBackIn).append(currentBox); continue; } } if (allBoxesLessEpsilon) { //if allBoxesLessEpsilon = true the box is unsafe and I continue my loop (data.boxesInsideUnsafe).push_back(currentBox); count++; if (count >=data.maxNumUnsafeBoxes && data.maxNumUnsafeBoxesActivated){ //If I have more boxes than nbPerhaps I stop the loop and I display the results break; } } else { //Otherwise we bissect following the widest diameter double l = 0; double l_temp = 0; int v = -1; for(int i = 0; i<currentBox.size()-1; i++){ //test that the diameter of the boxes doesnt depend on time if(currentBox[i].is_bisectable()||!(currentBox[i].is_degenerated())){ l_temp = currentBox[i].diam(); if(l_temp>=data.epsilons[i] && l_temp/(data.epsilons[i]) > l){ l = l_temp/(data.epsilons[i]); v = i; } } } l_temp = currentBox[currentBox.size()-1].diam(); //test the time interval if(l_temp>=data.dt && l_temp/(data.dt) > l){ v = currentBox.size()-1; } if(v != -1 && currentBox[v].is_bisectable()){ // then the test interval of the state variables, and then it bisects the interval which has the largest diameter pair<IntervalVector,IntervalVector> boxes=currentBox.bisect(v, 0.5); (data.boxes).push_back(boxes.first); (data.boxes).push_back(boxes.second); } else{ if (data.myDebug){ std::cout<<"Cannot be bisected \n"; } } } } } else //outer approximation { int count=0; //SIVIA //process all the boxes in data while (!data.boxes.empty()) { IntervalVector currentBox = data.boxes.front(); //start from the first one data.boxes.pop_front(); //once it has been copied remove the first box IntervalVector auxBox=currentBox; //store it in aux variable to compare later tubeConstraints.contract(currentBox); //contract the current box using the previously calculated constraints if (currentBox!=auxBox){ //if the box has been contracted IntervalVector* removedByContractor; int setDiff=auxBox.diff(currentBox, removedByContractor); //set difference between the contracted box and the original box for (int i = 0; i < setDiff; ++i) { data.boxesOutside.push_back(removedByContractor[i]); //add the areas removed by the contractor to the outside set } delete[] removedByContractor; } if(data.realTimeDraw){ //draw the boxes processing in real time draw_update(data, auxBox, currentBox); } bool allBoxesLessEpsilon=true; //check if all the boxes are smaler than epsilon for (int i=0;(i<(currentBox.size()-1));i++){ allBoxesLessEpsilon = (allBoxesLessEpsilon && ((currentBox.diam()[i])<=data.epsilons[i])); } allBoxesLessEpsilon = (allBoxesLessEpsilon && ((currentBox[currentBox.size()-1].diam())<=data.dt)); //check the time box also bool boxesLessEpsilon=false; //check if at least one box is smaller than epsilon for (int i=0;(i<(currentBox.size()-1));i++){ boxesLessEpsilon = boxesLessEpsilon||((currentBox[i].diam())<=data.epsilons[i]); } boxesLessEpsilon = boxesLessEpsilon&&((currentBox[currentBox.size()-1].diam())<=data.dt); //check time box if (boxesLessEpsilon && !allBoxesLessEpsilon){ IntervalVector xnext = currentBox.subvector(0, data.numVarF-1).mid(); //using the middle point of the box calculate the future positions using euler method IntervalVector x = currentBox.mid(); bool testBackIn; for (int i = 0;i<data.numFuturePos;i++){ // Euler method: x(n+1)=x(n)+dt*fx x[data.numVarF]= x[data.numVarF].mid(); testBackIn = true; xnext=xnext+(data.dt)*data.f->eval_vector(x); x.put(0, xnext); x[data.numVarF] = x[data.numVarF]+(data.dt); IntervalVector gg=data.g->eval_vector(x); for(int j = 0; j<gg.size(); j++){ testBackIn = testBackIn && (gg[j].ub()<0); //test if it comes back to the bubble } if(testBackIn == true){ //If so we calculate the max deviation break; } } // if(testBackIn == true){ //If my box was back in the bubble after integration, I store it in boxesbackin // (data.boxesBackIn).append(currentBox); // continue; // } } if (allBoxesLessEpsilon) { //if allBoxesLessEpsilon = true the box is unsafe and I continue my loop (data.boxesUnsafe).push_back(currentBox); count++; if (count >=data.maxNumUnsafeBoxes && data.maxNumUnsafeBoxesActivated){ //If I have more boxes than nbPerhaps I stop the loop and I display the results break; } } else { //Otherwise we bissect following the widest diameter double l = 0; double l_temp = 0; int v = -1; for(int i = 0; i<currentBox.size()-1; i++){ //test that the diameter of the boxes doesnt depend on time if(currentBox[i].is_bisectable()||!(currentBox[i].is_degenerated())){ l_temp = currentBox[i].diam(); if(l_temp>=data.epsilons[i] && l_temp/(data.epsilons[i]) > l){ l = l_temp/(data.epsilons[i]); v = i; } } } l_temp = currentBox[currentBox.size()-1].diam(); //test the time interval if(l_temp>=data.dt && l_temp/(data.dt) > l){ v = currentBox.size()-1; } if(v != -1 && currentBox[v].is_bisectable()){ // then the test interval of the state variables, and then it bisects the interval which has the largest diameter pair<IntervalVector,IntervalVector> boxes=currentBox.bisect(v, 0.5); (data.boxes).push_back(boxes.first); (data.boxes).push_back(boxes.second); } else{ if (data.myDebug){ std::cout<<"Cannot be bisected \n"; } } } } for(int i=0; i<data.boxesUnsafe.size();i++) { //process unsafe boxes IntervalVector currentBox=data.boxesUnsafe.at(i); IntervalVector nextBox = currentBox.subvector(0, data.numVarF-1); if (data.intMethod==0){ //Guaranteed integration // State variables Variable y(data.numVarF); // Initial conditions IntervalVector yinit(data.numVarF); for (int i = 0; i < data.numVarF; ++i) { yinit[i] = currentBox[i]; cout<<currentBox[i]<<endl; } Interval t = currentBox[data.numVarF]; Interval xd = 7*t; Interval xdd = 7; Interval yd = sin(0.1*t); Interval ydd = 0.1*cos(0.1*t); // Interval xdiff = (xd-y[0]+xdd); // Interval ydiff = (yd-y[1]+ydd); // Interval norm = (sqrt((xdiff)^2 +(ydiff)^2)); // system fn has to be re entered here, cannot be loaded directly from text file //pendulum Function ydot = Function (y,Return (y[1],-1*sin(y[0])-0.15*y[1])); // Ivp contruction (initial time is 0.0) //non holonomic // Function ydot = Function (y, Return ((sqrt(((xd-y[0]+xdd)*(xd-y[0]+xdd)) +((yd-y[1]+ydd)*(yd-y[1]+ydd))))*cos(y[2]), (sqrt(((xd-y[0]+xdd)*(xd-y[0]+xdd)) +((yd-y[1]+ydd)*(yd-y[1]+ydd))))*sin(y[2]),10*(cos(y[2])*((yd-y[1]+ydd))-sin(y[2])*((xd-y[0]+xdd)))/(sqrt(((xd-y[0]+xdd)*(xd-y[0]+xdd)) +((yd-y[1]+ydd)*(yd-y[1]+ydd)))))); // Ivp contruction (initial time is 0.0) QTime t1; t1.start(); ivp_ode problem = ivp_ode (ydot,0.0 , yinit); // Simulation construction and run simulation simu = simulation (&problem,data.dt*data.numFuturePos, __METH__, __PREC__); //uses Runge-kutta4 method data.boxesUnsafeFuture.append(simu.run_simulation()); //modified ibex_simulation.h to make it return a list with all the solutions, not just the last one double timeSiviaCalculations1=t1.elapsed()/1000.0; double timeSiviaCalculationsTotal=tSivia.elapsed()/1000.0; cout<<endl<<"Unsafe # "<<i<<" , Box time = "<<timeSiviaCalculations1<<" , Total elapsed time = "<<timeSiviaCalculationsTotal<<endl; } if (data.intMethod==1){ //euler method for (int i = 0;i<data.numFuturePos;i++){ IntervalVector gdotValue=gdot.eval_vector(currentBox); //evaluate the g and gdot functions to inspect the constraints IntervalVector gValue=data.g->eval_vector(currentBox); if (data.myDebug){ cout<<"box = "<<currentBox<<endl; for(int j = 0; j<gValue.size(); j++){ cout<<"gdot"<<j<<" = "<<gdotValue<<" / "<<(gdotValue[j].lb()>0) <<endl; //gdot i values } } nextBox=nextBox+(data.dt)*data.f->eval_vector(currentBox); //euler method data.boxesUnsafeFuture.append(nextBox); currentBox.put(0, nextBox); currentBox[data.numVarF] = currentBox[data.numVarF]+(data.dt); //increase time for the next step } } if (data.intMethod==2){ //vertex unsafe //check derivative of the unsafe boxes of outer g wrt the inner g // Function g_inner("g_inner.txt"); // Function dg_inner(g_inner, Function::DIFF); // d/dx(gi)(x,t) // Variable x(data.numVarF),t; //we have x[] and t as variables for our fns // // initialize auxMat and auxVector to the correct sizes and fill with zeros // IntervalMatrix auxMat(data.numVarF+1, data.numVarF,Interval::ZERO); // IntervalVector auxVector(data.numVarF+1,Interval::ZERO); // //put 1 in the diagonal of auxMat // for (int i=0; i<data.numVarF; i++){ // auxMat[i][i]=1;} // auxVector[data.numVarF]=1; // Function f=("f.txt"); // Function gdot_inner(x,t,dg_inner(x,t)*(auxMat*transpose(f(x,t))+auxVector)); // cout<<"gdot: "<<gdot_inner<<endl; // IntervalVector gdot_inner_Result=gdot_inner.eval_vector(currentBox); // bool testNegative=true; // for(int j = 0; j<gdot_inner_Result.size(); j++){ // testNegative = testNegative && (gdot_inner_Result[j].ub()<0); // } // if (testNegative) { // data.boxesOuterGSafeForInnerG.append(currentBox); // cout<<"Safe for inner G: "<<currentBox<<" result: "<<gdot_inner_Result<<endl; // } // else{ // data.boxesOuterGUnsafeForInnerG.append(currentBox); // cout<<"Unsafe for inner G: "<<currentBox<<" result: "<<gdot_inner_Result<<endl; // } //system double x_k_lb[currentBox.size()], x_k_ub[currentBox.size()]; for (int j = 0; j < currentBox.size(); ++j) { x_k_ub[j]=currentBox[j].ub(); x_k_lb[j]=currentBox[j].lb(); } int numVar=currentBox.size()-1; int numSamples=data.dt*data.numFuturePos*1000; double x_k_uu[numVar][numSamples]; double x_k_ul[numVar][numSamples]; double x_k_lu[numVar][numSamples]; double x_k_ll[numVar][numSamples]; x_k_uu[0][0]=x_k_ub[0]; x_k_ll[0][0]=x_k_lb[0]; x_k_lu[0][0]=x_k_lb[0]; x_k_ul[0][0]=x_k_ub[0]; x_k_uu[1][0]=x_k_ub[1]; x_k_ll[1][0]=x_k_lb[1]; x_k_lu[1][0]=x_k_ub[1]; x_k_ul[1][0]=x_k_lb[1]; double g_outer_uu, g_outer_lu, g_outer_ul, g_outer_ll, g_inner_uu, g_inner_lu, g_inner_ul, g_inner_ll; bool unsafeBox=false; bool safeBox=false; //pendulum system for (int j = 1; j < data.dt*data.numFuturePos*1000; ++j) { x_k_uu[1][j]=data.dt/10.0*(-sin(x_k_uu[0][j-1])-0.15*x_k_uu[1][j-1])+x_k_uu[1][j-1]; x_k_ll[1][j]=data.dt/10.0*(-sin(x_k_ll[0][j-1])-0.15*x_k_ll[1][j-1])+x_k_ll[1][j-1]; x_k_lu[1][j]=data.dt/10.0*(-sin(x_k_lu[0][j-1])-0.15*x_k_lu[1][j-1])+x_k_lu[1][j-1]; x_k_ul[1][j]=data.dt/10.0*(-sin(x_k_ul[0][j-1])-0.15*x_k_ul[1][j-1])+x_k_ul[1][j-1]; x_k_uu[0][j]=(x_k_uu[1][j-1])*(data.dt/10.0)+x_k_uu[0][j-1]; x_k_ll[0][j]=(x_k_ll[1][j-1])*(data.dt/10.0)+x_k_uu[0][j-1]; x_k_lu[0][j]=(x_k_lu[1][j-1])*(data.dt/10.0)+x_k_uu[0][j-1]; x_k_ul[0][j]=(x_k_ul[1][j-1])*(data.dt/10.0)+x_k_uu[0][j-1]; //add discretized sys //check if they leave the outer g g_outer_uu= (x_k_uu[0][j]*x_k_uu[0][j])+(x_k_uu[1][j]*x_k_uu[1][j])-1; g_outer_lu= (x_k_lu[0][j]*x_k_lu[0][j])+(x_k_lu[1][j]*x_k_lu[1][j])-1; g_outer_ul= (x_k_ul[0][j]*x_k_ul[0][j])+(x_k_ul[1][j]*x_k_ul[1][j])-1; g_outer_ll= (x_k_ll[0][j]*x_k_ll[0][j])+(x_k_ll[1][j]*x_k_ll[1][j])-1; //check if the trajectories reenter the inner g if (data.ellipseInner) { g_inner_uu= (x_k_uu[0][j]*x_k_uu[0][j])/0.81+(x_k_uu[1][j]*x_k_uu[1][j])/(0.4*0.4)-1; g_inner_lu= (x_k_lu[0][j]*x_k_lu[0][j])/0.81+(x_k_lu[1][j]*x_k_lu[1][j])/(0.4*0.4)-1; g_inner_ul= (x_k_ul[0][j]*x_k_ul[0][j])/0.81+(x_k_ul[1][j]*x_k_ul[1][j])/(0.4*0.4)-1; g_inner_ll= (x_k_ll[0][j]*x_k_ll[0][j])/0.81+(x_k_ll[1][j]*x_k_ll[1][j])/(0.4*0.4)-1; } else{ g_inner_uu= (x_k_uu[0][j]*x_k_uu[0][j])/(0.99*0.99)+(x_k_uu[1][j]*x_k_uu[1][j])/(0.96*0.96)-1; g_inner_lu= (x_k_lu[0][j]*x_k_lu[0][j])/(0.99*0.99)+(x_k_lu[1][j]*x_k_lu[1][j])/(0.96*0.96)-1; g_inner_ul= (x_k_ul[0][j]*x_k_ul[0][j])/(0.99*0.99)+(x_k_ul[1][j]*x_k_ul[1][j])/(0.96*0.96)-1; g_inner_ll= (x_k_ll[0][j]*x_k_ll[0][j])/(0.99*0.99)+(x_k_ll[1][j]*x_k_ll[1][j])/(0.96*0.96)-1; } double myFutureBox[j][2][2]; double myMaxPos= qMax(qMax(qMax(x_k_uu[0][j],x_k_ll[0][j]),x_k_lu[0][j]),x_k_ul[0][j]); double myMinPos= qMin(qMin(qMin(x_k_uu[0][j],x_k_ll[0][j]),x_k_lu[0][j]),x_k_ul[0][j]); double myMaxVel= qMax(qMax(qMax(x_k_uu[1][j],x_k_ll[1][j]),x_k_lu[1][j]),x_k_ul[1][j]); double myMinVel= qMin(qMin(qMin(x_k_uu[1][j],x_k_ll[1][j]),x_k_lu[1][j]),x_k_ul[1][j]); myFutureBox[j][0][0]=myMinPos; myFutureBox[j][0][1]=myMaxPos; myFutureBox[j][1][0]=myMinVel; myFutureBox[j][1][1]=myMaxVel; IntervalVector BoxFuture(data.numVarG, myFutureBox[j]); data.boxesVertexFuture.append(BoxFuture); if (true &&(g_outer_uu>=0 || g_outer_lu>=0 || g_outer_ul>=0 || g_outer_ll>=0)){ unsafeBox=true; data.boxesUnsafeOuterG.append(currentBox); double myUnsafeFutureBox[j][2][2]; for (int k = 0; k < j; ++k) { myMaxPos= qMax(qMax(qMax(x_k_uu[0][j],x_k_ll[0][j]),x_k_lu[0][j]),x_k_ul[0][j]); myMinPos= qMin(qMin(qMin(x_k_uu[0][j],x_k_ll[0][j]),x_k_lu[0][j]),x_k_ul[0][j]); myMaxVel= qMax(qMax(qMax(x_k_uu[1][j],x_k_ll[1][j]),x_k_lu[1][j]),x_k_ul[1][j]); myMinVel= qMin(qMin(qMin(x_k_uu[1][j],x_k_ll[1][j]),x_k_lu[1][j]),x_k_ul[1][j]); myUnsafeFutureBox[j][0][0]=myMinPos; myUnsafeFutureBox[j][0][1]=myMaxPos; myUnsafeFutureBox[j][1][0]=myMinVel; myUnsafeFutureBox[j][1][1]=myMaxVel; IntervalVector BoxUnsafeFuture(data.numVarG, myUnsafeFutureBox[k]); data.boxesUnsafeOuterGFuture.append(BoxUnsafeFuture); // cout<<"Unsafe vertex box "<<BoxUnsafeFuture<<endl; } break; } if (j>20 && g_inner_uu<0 && g_inner_lu<0 && g_inner_ul<0 && g_inner_ll<0){ safeBox=true; //data.boxesUnsafeOuterG.append(currentBox); double mySafeFutureBox[j][2][2]; for (int k = 0; k < j; ++k) { myMaxPos= qMax(qMax(qMax(x_k_uu[0][j],x_k_ll[0][j]),x_k_lu[0][j]),x_k_ul[0][j]); myMinPos= qMin(qMin(qMin(x_k_uu[0][j],x_k_ll[0][j]),x_k_lu[0][j]),x_k_ul[0][j]); myMaxVel= qMax(qMax(qMax(x_k_uu[1][j],x_k_ll[1][j]),x_k_lu[1][j]),x_k_ul[1][j]); myMinVel= qMin(qMin(qMin(x_k_uu[1][j],x_k_ll[1][j]),x_k_lu[1][j]),x_k_ul[1][j]); mySafeFutureBox[j][0][0]=myMinPos; mySafeFutureBox[j][0][1]=myMaxPos; mySafeFutureBox[j][1][0]=myMinVel; mySafeFutureBox[j][1][1]=myMaxVel; IntervalVector BoxSafeFuture(data.numVarG, mySafeFutureBox[k]); data.boxesGuaranteedIntegrationUnsafe.append(BoxSafeFuture); // cout<<"Safe vertex box "<<BoxSafeFuture<<endl; } break; } } if (unsafeBox==false && safeBox==true){ data.boxesUncertain.append(currentBox); } } } for (int i = 0; i < data.boxesUncertain.size(); ++i) { //process uncertain boxes IntervalVector uncertainBox=data.boxesUncertain.at(i); Variable y(data.numVarF); // Initial conditions IntervalVector yinit(data.numVarF); for (int j = 0; j < data.numVarF; ++j) { yinit[j] = uncertainBox[j]; cout<<uncertainBox[j]<<endl; } Function ydot = Function (y,Return (y[1],-1*sin(y[0])-0.15*y[1])); // Ivp contruction (initial time is 0.0) QTime t1; t1.start(); ivp_ode problem = ivp_ode (ydot, 0.0 , yinit); // Simulation construction and run int prevSize=data.boxesUncertainFuture.size(); simulation simu = simulation (&problem,data.dt*data.numFuturePos, __METH__, __PREC__); //uses Runge-kutta4 method data.boxesUncertainFuture.append(simu.run_simulation()); //modified ibex_simulation.h to make it return a list with all the solutions, not just the last one int afterSize=data.boxesUncertainFuture.size(); for (int k = 0; k < (afterSize-prevSize); ++k) { data.boxesUncertainFutureIndex.append(i); } double timeSiviaCalculations1=t1.elapsed()/1000.0; double timeSiviaCalculationsTotal=tSivia.elapsed()/1000.0; cout<<endl<<"Unsafe # "<<i<<" , Box time = "<<timeSiviaCalculations1<<" , Total elapsed time = "<<timeSiviaCalculationsTotal<<endl; } for (int j = 0; j < data.boxesUncertainFuture.size(); ++j) { IntervalVector myBox=data.boxesUncertainFuture.at(j); bool testInsideOuterG = true; Function g_outer("g_outer.txt"); IntervalVector gg=g_outer.eval_vector(myBox); for(int j = 0; j<gg.size(); j++){ testInsideOuterG = (testInsideOuterG && (gg[j].ub()<0)); } if (testInsideOuterG==false){ data.boxesUnsafeOuterGFuture.append(myBox); data.boxesUnsafeOuterG.append(data.boxesUncertain.at(data.boxesUncertainFutureIndex.at(j))); } else{ data.boxesSafeOuterGFuture.append(myBox); } } } }
fsal_status_t VFSFSAL_rcp(fsal_handle_t * filehandle, /* IN */ fsal_op_context_t * p_context, /* IN */ fsal_path_t * p_local_path, /* IN */ fsal_rcpflag_t transfer_opt /* IN */ ) { int local_fd; int local_flags; int errsv; fsal_file_t fs_fd; fsal_openflags_t fs_flags; fsal_status_t st = FSAL_STATUS_NO_ERROR; /* default buffer size for RCP: 10MB */ #define RCP_BUFFER_SIZE 10485760 caddr_t IObuffer; int to_local = FALSE; int to_fs = FALSE; int eof = FALSE; ssize_t local_size; fsal_size_t fs_size; /* sanity checks. */ if(!filehandle || !p_context || !p_local_path) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_rcp); to_local = ((transfer_opt & FSAL_RCP_FS_TO_LOCAL) == FSAL_RCP_FS_TO_LOCAL); to_fs = ((transfer_opt & FSAL_RCP_LOCAL_TO_FS) == FSAL_RCP_LOCAL_TO_FS); if(to_local) LogFullDebug(COMPONENT_FSAL, "FSAL_rcp: FSAL -> local file (%s)", p_local_path->path); if(to_fs) LogFullDebug(COMPONENT_FSAL, "FSAL_rcp: local file -> FSAL (%s)", p_local_path->path); /* must give the sens of transfert (exactly one) */ if((!to_local && !to_fs) || (to_local && to_fs)) Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_rcp); /* first, open local file with the correct flags */ if(to_fs) { local_flags = O_RDONLY; } else { local_flags = O_WRONLY | O_TRUNC; if((transfer_opt & FSAL_RCP_LOCAL_CREAT) == FSAL_RCP_LOCAL_CREAT) local_flags |= O_CREAT; if((transfer_opt & FSAL_RCP_LOCAL_EXCL) == FSAL_RCP_LOCAL_EXCL) local_flags |= O_EXCL; } if(isFullDebug(COMPONENT_FSAL)) { char msg[1024]; msg[0] = '\0'; if((local_flags & O_RDONLY) == O_RDONLY) strcat(msg, "O_RDONLY "); if((local_flags & O_WRONLY) == O_WRONLY) strcat(msg, "O_WRONLY "); if((local_flags & O_TRUNC) == O_TRUNC) strcat(msg, "O_TRUNC "); if((local_flags & O_CREAT) == O_CREAT) strcat(msg, "O_CREAT "); if((local_flags & O_EXCL) == O_EXCL) strcat(msg, "O_EXCL "); LogFullDebug(COMPONENT_FSAL, "Openning local file %s with flags: %s", p_local_path->path, msg); } local_fd = open(p_local_path->path, local_flags); errsv = errno; if(local_fd == -1) { Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_rcp); } /* call FSAL_open with the correct flags */ if(to_fs) { fs_flags = FSAL_O_WRONLY | FSAL_O_TRUNC; /* invalid flags for local to filesystem */ if(((transfer_opt & FSAL_RCP_LOCAL_CREAT) == FSAL_RCP_LOCAL_CREAT) || ((transfer_opt & FSAL_RCP_LOCAL_EXCL) == FSAL_RCP_LOCAL_EXCL)) { /* clean & return */ close(local_fd); Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_rcp); } } else { fs_flags = FSAL_O_RDONLY; } if(isFullDebug(COMPONENT_FSAL)) { char msg[1024]; msg[0] = '\0'; if((fs_flags & FSAL_O_RDONLY) == FSAL_O_RDONLY) strcat(msg, "FSAL_O_RDONLY "); if((fs_flags & FSAL_O_WRONLY) == FSAL_O_WRONLY) strcat(msg, "FSAL_O_WRONLY "); if((fs_flags & FSAL_O_TRUNC) == FSAL_O_TRUNC) strcat(msg, "FSAL_O_TRUNC "); LogFullDebug(COMPONENT_FSAL, "Openning FSAL file with flags: %s", msg); } st = FSAL_open(filehandle, p_context, fs_flags, &fs_fd, NULL); if(FSAL_IS_ERROR(st)) { /* clean & return */ close(local_fd); Return(st.major, st.minor, INDEX_FSAL_rcp); } LogFullDebug(COMPONENT_FSAL, "Allocating IO buffer of size %llu", (unsigned long long)RCP_BUFFER_SIZE); /* Allocates buffer */ IObuffer = (caddr_t) Mem_Alloc_Label(RCP_BUFFER_SIZE, "IO Buffer"); if(IObuffer == NULL) { /* clean & return */ close(local_fd); FSAL_close(&fs_fd); Return(ERR_FSAL_NOMEM, Mem_Errno, INDEX_FSAL_rcp); } /* read/write loop */ while(!eof) { /* initialize error code */ st = FSAL_STATUS_NO_ERROR; LogFullDebug(COMPONENT_FSAL, "Read a block from source"); /* read */ if(to_fs) /* from local filesystem */ { LogFullDebug(COMPONENT_FSAL, "Read a block from local file system"); local_size = read(local_fd, IObuffer, RCP_BUFFER_SIZE); if(local_size == -1) { st.major = ERR_FSAL_IO; st.minor = errno; break; /* exit loop */ } eof = (local_size == 0); if(!eof) { LogFullDebug(COMPONENT_FSAL, "Write a block (%llu bytes) to FSAL", (unsigned long long)local_size); st = FSAL_write(&fs_fd, NULL, local_size, IObuffer, &fs_size); if(FSAL_IS_ERROR(st)) { LogFullDebug(COMPONENT_FSAL, "Error writing to FSAL"); break; /* exit loop */ } } else { LogFullDebug(COMPONENT_FSAL, "End of file on local file system"); } } else /* from FSAL filesystem */ { LogFullDebug(COMPONENT_FSAL, "Read a block from FSAL"); fs_size = 0; st = FSAL_read(&fs_fd, NULL, RCP_BUFFER_SIZE, IObuffer, &fs_size, &eof); if(FSAL_IS_ERROR(st)) break; /* exit loop */ if(fs_size > 0) { LogFullDebug(COMPONENT_FSAL, "Write a block (%llu bytes) to local file system", (unsigned long long)fs_size); local_size = write(local_fd, IObuffer, fs_size); if(local_size == -1) { st.major = ERR_FSAL_IO; st.minor = errno; break; /* exit loop */ } } else { LogFullDebug(COMPONENT_FSAL, "End of file on FSAL"); break; } LogFullDebug(COMPONENT_FSAL, "Size read from source: %llu", (unsigned long long)fs_size); } } /* while !eof */ /* Clean */ Mem_Free(IObuffer); close(local_fd); FSAL_close(&fs_fd); /* return status. */ Return(st.major, st.minor, INDEX_FSAL_rcp); }
/** * FSAL_opendir : * Opens a directory for reading its content. * * \param dir_handle (input) * the handle of the directory to be opened. * \param cred (input) * Permission context for the operation (user,...). * \param dir_descriptor (output) * pointer to an allocated structure that will receive * directory stream informations, on successfull completion. * \param dir_attributes (optional output) * On successfull completion,the structure pointed * by dir_attributes receives the new directory attributes. * May be NULL. * * \return Major error codes : * - ERR_FSAL_NO_ERROR (no error) * - Another error code if an error occured. */ fsal_status_t LUSTREFSAL_opendir(fsal_handle_t * p_dir_handle, /* IN */ fsal_op_context_t * p_context, /* IN */ fsal_dir_t *dir_desc, /* OUT */ fsal_attrib_list_t * p_dir_attributes /* [ IN/OUT ] */ ) { int rc; fsal_status_t status; fsal_path_t fsalpath; struct stat buffstat; lustrefsal_dir_t *p_dir_descriptor = (lustrefsal_dir_t *)dir_desc; /* sanity checks * note : dir_attributes is optionnal. */ if(!p_dir_handle || !p_context || !p_dir_descriptor) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_opendir); /* get the path of the directory */ status = fsal_internal_Handle2FidPath(p_context, p_dir_handle, &fsalpath); if(FSAL_IS_ERROR(status)) ReturnStatus(status, INDEX_FSAL_opendir); /* get directory metadata */ TakeTokenFSCall(); rc = lstat(fsalpath.path, &buffstat); ReleaseTokenFSCall(); if(rc != 0) { rc = errno; if(rc == ENOENT) Return(ERR_FSAL_STALE, rc, INDEX_FSAL_opendir); else Return(posix2fsal_error(rc), rc, INDEX_FSAL_opendir); } /* Test access rights for this directory */ status = fsal_internal_testAccess(p_context, FSAL_R_OK, &buffstat, NULL); if(FSAL_IS_ERROR(status)) ReturnStatus(status, INDEX_FSAL_opendir); /* if everything is OK, fills the dir_desc structure : */ TakeTokenFSCall(); p_dir_descriptor->p_dir = opendir(fsalpath.path); ReleaseTokenFSCall(); if(!p_dir_descriptor->p_dir) Return(posix2fsal_error(errno), errno, INDEX_FSAL_opendir); memcpy(&(p_dir_descriptor->context), p_context, sizeof(lustrefsal_op_context_t)); memcpy(&(p_dir_descriptor->path), &fsalpath, sizeof(fsal_path_t)); memcpy(&(p_dir_descriptor->handle), p_dir_handle, sizeof(lustrefsal_handle_t)); if(p_dir_attributes) { status = posix2fsal_attributes(&buffstat, p_dir_attributes); if(FSAL_IS_ERROR(status)) { FSAL_CLEAR_MASK(p_dir_attributes->asked_attributes); FSAL_SET_MASK(p_dir_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR); } } Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_opendir); }
/** * build the export entry */ fsal_status_t GPFSFSAL_BuildExportContext(fsal_export_context_t *export_context, /* OUT */ fsal_path_t * p_export_path, /* IN */ char *fs_specific_options /* IN */ ) { int rc, fd, mntexists; FILE * fp; struct mntent * p_mnt; char * mnt_dir = NULL; struct statfs stat_buf; gpfs_fsal_up_ctx_t * gpfs_fsal_up_ctx; bool_t start_fsal_up_thread = FALSE; fsal_status_t status; fsal_op_context_t op_context; gpfsfsal_export_context_t *p_export_context = (gpfsfsal_export_context_t *)export_context; /* Make sure the FSAL UP context list is initialized */ if(glist_null(&gpfs_fsal_up_ctx_list)) init_glist(&gpfs_fsal_up_ctx_list); /* sanity check */ if((p_export_context == NULL) || (p_export_path == NULL)) { LogCrit(COMPONENT_FSAL, "NULL mandatory argument passed to %s()", __FUNCTION__); Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_BuildExportContext); } /* open mnt file */ fp = setmntent(MOUNTED, "r"); if(fp == NULL) { rc = errno; LogCrit(COMPONENT_FSAL, "Error %d in setmntent(%s): %s", rc, MOUNTED, strerror(rc)); Return(posix2fsal_error(rc), rc, INDEX_FSAL_BuildExportContext); } /* Check if mount point is really a gpfs share. If not, we can't continue.*/ mntexists = 0; while((p_mnt = getmntent(fp)) != NULL) if(p_mnt->mnt_dir != NULL && p_mnt->mnt_type != NULL) /* There is probably a macro for "gpfs" type ... not sure where it is. */ if (strncmp(p_mnt->mnt_type, "gpfs", 4) == 0) { LogFullDebug(COMPONENT_FSAL, "Checking Export Path %s against GPFS fs %s", p_export_path->path, p_mnt->mnt_dir); /* If export path is shorter than fs path, then this isn't a match */ if(strlen(p_export_path->path) < strlen(p_mnt->mnt_dir)) continue; /* If export path doesn't have a path separator after mnt_dir, then it * isn't a proper sub-directory of mnt_dir. */ if((p_export_path->path[strlen(p_mnt->mnt_dir)] != '/') && (p_export_path->path[strlen(p_mnt->mnt_dir)] != '\0')) continue; if (strncmp(p_mnt->mnt_dir, p_export_path->path, strlen(p_mnt->mnt_dir)) == 0) { mnt_dir = gsh_strdup(p_mnt->mnt_dir); mntexists = 1; break; } } endmntent(fp); if (mntexists == 0) { LogMajor(COMPONENT_FSAL, "GPFS mount point %s does not exist.", p_export_path->path); gsh_free(mnt_dir); ReturnCode(ERR_FSAL_INVAL, 0); } /* save file descriptor to root of GPFS share */ fd = open(p_export_path->path, O_RDONLY | O_DIRECTORY); if(fd < 0) { if(errno == ENOENT) LogMajor(COMPONENT_FSAL, "GPFS export path %s does not exist.", p_export_path->path); else if (errno == ENOTDIR) LogMajor(COMPONENT_FSAL, "GPFS export path %s is not a directory.", p_export_path->path); else LogMajor(COMPONENT_FSAL, "Could not open GPFS export path %s: rc = %d(%s)", p_export_path->path, errno, strerror(errno)); if(mnt_dir != NULL) gsh_free(mnt_dir); ReturnCode(ERR_FSAL_INVAL, 0); } p_export_context->mount_root_fd = fd; LogFullDebug(COMPONENT_FSAL, "GPFSFSAL_BuildExportContext: %d", p_export_context->mount_root_fd); /* Save pointer to fsal_staticfsinfo_t in export context */ p_export_context->fe_static_fs_info = &global_fs_info; /* save filesystem ID */ rc = statfs(p_export_path->path, &stat_buf); if(rc) { close(fd); LogMajor(COMPONENT_FSAL, "statfs call failed on file %s: %d(%s)", p_export_path->path, errno, strerror(errno)); if(mnt_dir != NULL) gsh_free(mnt_dir); ReturnCode(ERR_FSAL_INVAL, 0); } p_export_context->fsid[0] = stat_buf.f_fsid.__val[0]; p_export_context->fsid[1] = stat_buf.f_fsid.__val[1]; /* save file handle to root of GPFS share */ op_context.export_context = export_context; // op_context.credential = ??? status = fsal_internal_get_handle(&op_context, p_export_path, (fsal_handle_t *)(&(p_export_context->mount_root_handle))); if(FSAL_IS_ERROR(status)) { close(p_export_context->mount_root_fd); LogMajor(COMPONENT_FSAL, "FSAL BUILD EXPORT CONTEXT: ERROR: Conversion from gpfs filesystem root path to handle failed : %d", status.minor); if(mnt_dir != NULL) gsh_free(mnt_dir); ReturnCode(ERR_FSAL_INVAL, 0); } gpfs_fsal_up_ctx = gpfsfsal_find_fsal_up_context(p_export_context); if(gpfs_fsal_up_ctx == NULL) { gpfs_fsal_up_ctx = gsh_calloc(1, sizeof(gpfs_fsal_up_ctx_t)); if(gpfs_fsal_up_ctx == NULL || mnt_dir == NULL) { LogFatal(COMPONENT_FSAL, "Out of memory can not continue."); } /* Initialize the gpfs_fsal_up_ctx */ init_glist(&gpfs_fsal_up_ctx->gf_exports); gpfs_fsal_up_ctx->gf_fs = mnt_dir; gpfs_fsal_up_ctx->gf_fsid[0] = p_export_context->fsid[0]; gpfs_fsal_up_ctx->gf_fsid[1] = p_export_context->fsid[1]; /* Add it to the list of contexts */ glist_add_tail(&gpfs_fsal_up_ctx_list, &gpfs_fsal_up_ctx->gf_list); start_fsal_up_thread = TRUE; } else { if(mnt_dir != NULL) gsh_free(mnt_dir); } /* Add this export context to the list for it's gpfs_fsal_up_ctx */ glist_add_tail(&gpfs_fsal_up_ctx->gf_exports, &p_export_context->fe_list); p_export_context->fe_fsal_up_ctx = gpfs_fsal_up_ctx; if(start_fsal_up_thread) { pthread_attr_t attr_thr; memset(&attr_thr, 0, sizeof(attr_thr)); /* Initialization of thread attributes borrowed from nfs_init.c */ if(pthread_attr_init(&attr_thr) != 0) LogCrit(COMPONENT_THREAD, "can't init pthread's attributes"); if(pthread_attr_setscope(&attr_thr, PTHREAD_SCOPE_SYSTEM) != 0) LogCrit(COMPONENT_THREAD, "can't set pthread's scope"); if(pthread_attr_setdetachstate(&attr_thr, PTHREAD_CREATE_JOINABLE) != 0) LogCrit(COMPONENT_THREAD, "can't set pthread's join state"); if(pthread_attr_setstacksize(&attr_thr, 2116488) != 0) LogCrit(COMPONENT_THREAD, "can't set pthread's stack size"); rc = pthread_create(&gpfs_fsal_up_ctx->gf_thread, &attr_thr, GPFSFSAL_UP_Thread, gpfs_fsal_up_ctx); if(rc != 0) { LogFatal(COMPONENT_THREAD, "Could not create GPFSFSAL_UP_Thread, error = %d (%s)", errno, strerror(errno)); } } Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_BuildExportContext); }
fsal_status_t POSIXFSAL_read(posixfsal_file_t * p_file_descriptor, /* IN */ fsal_seek_t * p_seek_descriptor, /* [IN] */ fsal_size_t buffer_size, /* IN */ caddr_t buffer, /* OUT */ fsal_size_t * p_read_amount, /* OUT */ fsal_boolean_t * p_end_of_file /* OUT */ ) { size_t i_size; size_t nb_read; int rc, errsv; /* sanity checks. */ if(!p_file_descriptor || !buffer || !p_read_amount || !p_end_of_file) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_read); /** @todo: manage fsal_size_t to size_t convertion */ i_size = (size_t) buffer_size; /* positioning */ if(p_seek_descriptor) { switch (p_seek_descriptor->whence) { case FSAL_SEEK_CUR: /* set position plus offset */ TakeTokenFSCall(); rc = fseek(p_file_descriptor->p_file, p_seek_descriptor->offset, SEEK_CUR); errsv = errno; ReleaseTokenFSCall(); break; case FSAL_SEEK_SET: /* set absolute position to offset */ TakeTokenFSCall(); rc = fseek(p_file_descriptor->p_file, p_seek_descriptor->offset, SEEK_SET); errsv = errno; ReleaseTokenFSCall(); break; case FSAL_SEEK_END: /* set end of file plus offset */ TakeTokenFSCall(); rc = fseek(p_file_descriptor->p_file, p_seek_descriptor->offset, SEEK_END); errsv = errno; ReleaseTokenFSCall(); break; } if(rc) { LogEvent(COMPONENT_FSAL, "Error in posix fseek operation (whence=%s, offset=%lld)", (p_seek_descriptor->whence == FSAL_SEEK_CUR ? "SEEK_CUR" : (p_seek_descriptor->whence == FSAL_SEEK_SET ? "SEEK_SET" : (p_seek_descriptor->whence == FSAL_SEEK_END ? "SEEK_END" : "ERROR"))), p_seek_descriptor->offset); Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_read); } } /* read operation */ TakeTokenFSCall(); nb_read = fread(buffer, 1, i_size, p_file_descriptor->p_file); ReleaseTokenFSCall(); /** @todo: manage ssize_t to fsal_size_t convertion */ if(feof(p_file_descriptor->p_file)) *p_end_of_file = 1; if(nb_read == 0 && ferror(p_file_descriptor->p_file)) { Return(posix2fsal_error(EBADF), EBADF, INDEX_FSAL_read); } *p_read_amount = nb_read; Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_read); }
// This test verifies that the master reconciles tasks that are // missing from a re-registering slave. In this case, we drop the // RunTaskMessage so the slave should send TASK_LOST. TEST_F(MasterSlaveReconciliationTest, ReconcileLostTask) { Try<Owned<cluster::Master>> master = StartMaster(); ASSERT_SOME(master); StandaloneMasterDetector detector(master.get()->pid); Try<Owned<cluster::Slave>> slave = StartSlave(&detector); ASSERT_SOME(slave); MockScheduler sched; MesosSchedulerDriver driver( &sched, DEFAULT_FRAMEWORK_INFO, master.get()->pid, DEFAULT_CREDENTIAL); EXPECT_CALL(sched, registered(&driver, _, _)); Future<vector<Offer> > offers; EXPECT_CALL(sched, resourceOffers(&driver, _)) .WillOnce(FutureArg<1>(&offers)) .WillRepeatedly(Return()); // Ignore subsequent offers. driver.start(); AWAIT_READY(offers); EXPECT_NE(0u, offers.get().size()); TaskInfo task; task.set_name("test task"); task.mutable_task_id()->set_value("1"); task.mutable_slave_id()->MergeFrom(offers.get()[0].slave_id()); task.mutable_resources()->MergeFrom(offers.get()[0].resources()); task.mutable_executor()->MergeFrom(DEFAULT_EXECUTOR_INFO); // We now launch a task and drop the corresponding RunTaskMessage on // the slave, to ensure that only the master knows about this task. Future<RunTaskMessage> runTaskMessage = DROP_PROTOBUF(RunTaskMessage(), _, _); driver.launchTasks(offers.get()[0].id(), {task}); AWAIT_READY(runTaskMessage); Future<SlaveReregisteredMessage> slaveReregisteredMessage = FUTURE_PROTOBUF(SlaveReregisteredMessage(), _, _); Future<StatusUpdateMessage> statusUpdateMessage = FUTURE_PROTOBUF(StatusUpdateMessage(), _, master.get()->pid); Future<TaskStatus> status; EXPECT_CALL(sched, statusUpdate(&driver, _)) .WillOnce(FutureArg<1>(&status)); // Simulate a spurious master change event (e.g., due to ZooKeeper // expiration) at the slave to force re-registration. detector.appoint(master.get()->pid); AWAIT_READY(slaveReregisteredMessage); // Make sure the slave generated the TASK_LOST. AWAIT_READY(statusUpdateMessage); AWAIT_READY(status); ASSERT_EQ(task.task_id(), status.get().task_id()); ASSERT_EQ(TASK_LOST, status.get().state()); // Before we obtain the metrics, ensure that the master has finished // processing the status update so metrics have been updated. Clock::pause(); Clock::settle(); Clock::resume(); // Check metrics. JSON::Object stats = Metrics(); EXPECT_EQ(1u, stats.values.count("master/tasks_lost")); EXPECT_EQ(1u, stats.values["master/tasks_lost"]); EXPECT_EQ( 1u, stats.values.count( "master/task_lost/source_slave/reason_reconciliation")); EXPECT_EQ( 1u, stats.values["master/task_lost/source_slave/reason_reconciliation"]); driver.stop(); driver.join(); }
fsal_status_t POSIXFSAL_write(posixfsal_file_t * p_file_descriptor, /* IN */ fsal_seek_t * p_seek_descriptor, /* IN */ fsal_size_t buffer_size, /* IN */ caddr_t buffer, /* IN */ fsal_size_t * p_write_amount /* OUT */ ) { size_t i_size; size_t nb_written; int rc, errsv; /* sanity checks. */ if(!p_file_descriptor || !buffer || !p_write_amount) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_read); /** @todo: manage fsal_size_t to size_t convertion */ i_size = (size_t) buffer_size; /* positioning */ if(p_seek_descriptor) { switch (p_seek_descriptor->whence) { case FSAL_SEEK_CUR: case FSAL_SEEK_END: /* set position plus offset */ TakeTokenFSCall(); rc = lseek(p_file_descriptor->filefd, p_seek_descriptor->offset, p_seek_descriptor->whence); errsv = errno; if(rc) { LogEvent(COMPONENT_FSAL, "Error in posix fseek operation (whence=%s, offset=%lld)", (p_seek_descriptor->whence == FSAL_SEEK_CUR ? "SEEK_CUR" : (p_seek_descriptor->whence == FSAL_SEEK_SET ? "SEEK_SET" : (p_seek_descriptor->whence == FSAL_SEEK_END ? "SEEK_END" : "ERROR"))), p_seek_descriptor->offset); ReleaseTokenFSCall(); Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_write); } nb_written = write(p_file_descriptor->filefd, buffer, i_size); ReleaseTokenFSCall(); break; case FSAL_SEEK_SET: /* set absolute position to offset */ TakeTokenFSCall(); nb_written = pwrite(p_file_descriptor->filefd, buffer, i_size, p_seek_descriptor->offset); errsv = errno; ReleaseTokenFSCall(); break; } } else { TakeTokenFSCall(); nb_written = write(p_file_descriptor->filefd, buffer, i_size); ReleaseTokenFSCall(); } /** @todo: manage ssize_t to fsal_size_t convertion */ if(nb_written == -1) Return(posix2fsal_error(EBADF), EBADF, INDEX_FSAL_write); *p_write_amount = nb_written; Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_write); }
// This test verifies that the master reconciles tasks that are // missing from a re-registering slave. In this case, we trigger // a race between the slave re-registration message and the launch // message. There should be no TASK_LOST. // This was motivated by MESOS-1696. TEST_F(MasterSlaveReconciliationTest, ReconcileRace) { Try<Owned<cluster::Master>> master = StartMaster(); ASSERT_SOME(master); MockExecutor exec(DEFAULT_EXECUTOR_ID); TestContainerizer containerizer(&exec); StandaloneMasterDetector detector(master.get()->pid); Future<SlaveRegisteredMessage> slaveRegisteredMessage = FUTURE_PROTOBUF(SlaveRegisteredMessage(), master.get()->pid, _); Try<Owned<cluster::Slave>> slave = StartSlave(&detector, &containerizer); ASSERT_SOME(slave); AWAIT_READY(slaveRegisteredMessage); MockScheduler sched; MesosSchedulerDriver driver( &sched, DEFAULT_FRAMEWORK_INFO, master.get()->pid, DEFAULT_CREDENTIAL); EXPECT_CALL(sched, registered(&driver, _, _)); Future<vector<Offer> > offers; EXPECT_CALL(sched, resourceOffers(&driver, _)) .WillOnce(FutureArg<1>(&offers)) .WillRepeatedly(Return()); // Ignore subsequent offers. driver.start(); // Since the agent may have retried registration, we want to // ensure that any duplicate registrations are flushed before // we appoint the master again. Otherwise, the agent may // receive a stale registration message. Clock::pause(); Clock::settle(); Clock::resume(); // Trigger a re-registration of the slave and capture the message // so that we can spoof a race with a launch task message. DROP_PROTOBUFS(ReregisterSlaveMessage(), slave.get()->pid, master.get()->pid); Future<ReregisterSlaveMessage> reregisterSlaveMessage = DROP_PROTOBUF( ReregisterSlaveMessage(), slave.get()->pid, master.get()->pid); detector.appoint(master.get()->pid); AWAIT_READY(reregisterSlaveMessage); AWAIT_READY(offers); EXPECT_NE(0u, offers.get().size()); TaskInfo task; task.set_name("test task"); task.mutable_task_id()->set_value("1"); task.mutable_slave_id()->MergeFrom(offers.get()[0].slave_id()); task.mutable_resources()->MergeFrom(offers.get()[0].resources()); task.mutable_executor()->MergeFrom(DEFAULT_EXECUTOR_INFO); ExecutorDriver* executorDriver; EXPECT_CALL(exec, registered(_, _, _, _)) .WillOnce(SaveArg<0>(&executorDriver)); // Leave the task in TASK_STAGING. Future<Nothing> launchTask; EXPECT_CALL(exec, launchTask(_, _)) .WillOnce(FutureSatisfy(&launchTask)); EXPECT_CALL(sched, statusUpdate(&driver, _)) .Times(0); driver.launchTasks(offers.get()[0].id(), {task}); AWAIT_READY(launchTask); // Send the stale re-registration message, which does not contain // the task we just launched. This will trigger a reconciliation // by the master. Future<SlaveReregisteredMessage> slaveReregisteredMessage = FUTURE_PROTOBUF(SlaveReregisteredMessage(), _, _); // Prevent this from being dropped per the DROP_PROTOBUFS above. FUTURE_PROTOBUF( ReregisterSlaveMessage(), slave.get()->pid, master.get()->pid); process::post( slave.get()->pid, master.get()->pid, reregisterSlaveMessage.get()); AWAIT_READY(slaveReregisteredMessage); // Neither the master nor the slave should send a TASK_LOST // as part of the reconciliation. We check this by calling // Clock::settle() to flush all pending events. Clock::pause(); Clock::settle(); Clock::resume(); // Now send TASK_FINISHED and make sure it's the only message // received by the scheduler. Future<TaskStatus> status; EXPECT_CALL(sched, statusUpdate(&driver, _)) .WillOnce(FutureArg<1>(&status)); TaskStatus taskStatus; taskStatus.mutable_task_id()->CopyFrom(task.task_id()); taskStatus.set_state(TASK_FINISHED); executorDriver->sendStatusUpdate(taskStatus); AWAIT_READY(status); ASSERT_EQ(TASK_FINISHED, status.get().state()); EXPECT_CALL(exec, shutdown(_)) .Times(AtMost(1)); driver.stop(); driver.join(); }
void CCaptureObject::RealReSpawn( void ) { Return(NULL); }
// This test verifies that the slave reports pending tasks when // re-registering, otherwise the master will report them as being // lost. TEST_F(MasterSlaveReconciliationTest, SlaveReregisterPendingTask) { Try<Owned<cluster::Master>> master = StartMaster(); ASSERT_SOME(master); StandaloneMasterDetector detector(master.get()->pid); Try<Owned<cluster::Slave>> slave = StartSlave(&detector); ASSERT_SOME(slave); MockScheduler sched; MesosSchedulerDriver driver( &sched, DEFAULT_FRAMEWORK_INFO, master.get()->pid, DEFAULT_CREDENTIAL); EXPECT_CALL(sched, registered(&driver, _, _)); Future<vector<Offer> > offers; EXPECT_CALL(sched, resourceOffers(&driver, _)) .WillOnce(FutureArg<1>(&offers)) .WillRepeatedly(Return()); // Ignore subsequent offers. driver.start(); AWAIT_READY(offers); EXPECT_NE(0u, offers.get().size()); // No TASK_LOST updates should occur! EXPECT_CALL(sched, statusUpdate(&driver, _)) .Times(0); // We drop the _runTask dispatch to ensure the task remains // pending in the slave. Future<Nothing> _runTask = DROP_DISPATCH(slave.get()->pid, &Slave::_runTask); TaskInfo task1; task1.set_name("test task"); task1.mutable_task_id()->set_value("1"); task1.mutable_slave_id()->MergeFrom(offers.get()[0].slave_id()); task1.mutable_resources()->MergeFrom(offers.get()[0].resources()); task1.mutable_executor()->MergeFrom(DEFAULT_EXECUTOR_INFO); driver.launchTasks(offers.get()[0].id(), {task1}); AWAIT_READY(_runTask); Future<SlaveReregisteredMessage> slaveReregisteredMessage = FUTURE_PROTOBUF(SlaveReregisteredMessage(), _, _); // Simulate a spurious master change event (e.g., due to ZooKeeper // expiration) at the slave to force re-registration. detector.appoint(master.get()->pid); AWAIT_READY(slaveReregisteredMessage); Clock::pause(); Clock::settle(); Clock::resume(); driver.stop(); driver.join(); }
void expectGetRangeForStmtNoAndReturn(int index, LocationRange range) { auto& sourceManager = parsedFunctionDecl->getASTContext().getSourceManager(); EXPECT_CALL(*this, getStmtRange(Ref(sourceManager), Ref(*stmtNo(index)))) .WillRepeatedly(Return(range)); }
// Ensures that when a scheduler enables explicit acknowledgements // on the driver, there are no implicit acknowledgements sent, and // the call to 'acknowledgeStatusUpdate' sends the ack to the master. TEST_F(MesosSchedulerDriverTest, ExplicitAcknowledgements) { Try<Owned<cluster::Master>> master = StartMaster(); ASSERT_SOME(master); MockExecutor exec(DEFAULT_EXECUTOR_ID); TestContainerizer containerizer(&exec); Owned<MasterDetector> detector = master.get()->createDetector(); Try<Owned<cluster::Slave>> slave = StartSlave(detector.get(), &containerizer); ASSERT_SOME(slave); MockScheduler sched; MesosSchedulerDriver driver( &sched, DEFAULT_FRAMEWORK_INFO, master.get()->pid, false, DEFAULT_CREDENTIAL); EXPECT_CALL(sched, registered(&driver, _, _)); EXPECT_CALL(sched, resourceOffers(&driver, _)) .WillOnce(LaunchTasks(DEFAULT_EXECUTOR_INFO, 1, 1, 16, "*")) .WillRepeatedly(Return()); // Ignore subsequent offers. Future<TaskStatus> status; EXPECT_CALL(sched, statusUpdate(&driver, _)) .WillOnce(FutureArg<1>(&status)); // Ensure no status update acknowledgements are sent from the driver // to the master until the explicit acknowledgement is sent. EXPECT_NO_FUTURE_CALLS( mesos::scheduler::Call(), mesos::scheduler::Call::ACKNOWLEDGE, _ , master.get()->pid); EXPECT_CALL(exec, registered(_, _, _, _)); EXPECT_CALL(exec, launchTask(_, _)) .WillOnce(SendStatusUpdateFromTask(TASK_RUNNING)); EXPECT_CALL(exec, shutdown(_)) .Times(AtMost(1)); driver.start(); AWAIT_READY(status); // Settle the clock to ensure driver finishes processing the status // update, we want to ensure that no implicit acknowledgement gets // sent. Clock::pause(); Clock::settle(); // Now send the acknowledgement. Future<mesos::scheduler::Call> acknowledgement = FUTURE_CALL( mesos::scheduler::Call(), mesos::scheduler::Call::ACKNOWLEDGE, _, master.get()->pid); driver.acknowledgeStatusUpdate(status.get()); AWAIT_READY(acknowledgement); driver.stop(); driver.join(); }