// Regenerate forces the regeneration of endpoint programs & policy
// Should only be called with e.state == StateWaitingToRegenerate or with
// e.state == StateWaitingForIdentity
3492
func (e *Endpoint) Regenerate(owner Owner, regenMetadata *ExternalRegenerationMetadata) <-chan bool {
	done := make(chan bool, 1)

	var (
		ctx   context.Context
		cFunc context.CancelFunc
	)

	if regenMetadata.ParentContext != nil {
		ctx, cFunc = context.WithCancel(regenMetadata.ParentContext)
	} else {
		ctx, cFunc = context.WithCancel(context.Background())
	}

	regenContext := regenMetadata.toRegenerationContext(ctx, cFunc)

	epEvent := eventqueue.NewEvent(&EndpointRegenerationEvent{
		owner:        owner,
		regenContext: regenContext,
		ep:           e,
	})

	// This may block if the Endpoint's EventQueue is full. This has to be done
	// synchronously as some callers depend on the fact that the event is
	// synchronously enqueued.
	resChan := e.EventQueue.Enqueue(epEvent)

	go func() {

		// Free up resources with context.
		defer cFunc()

		var buildSuccess bool
		var regenError error

		select {
		case result, ok := <-resChan:
			if ok {
				regenResult := result.(*EndpointRegenerationResult)
				regenError = regenResult.err
				buildSuccess = regenError == nil
			} else {
				// This may be unnecessary(?) since 'closing' of the results
				// channel means that event has been cancelled?
				e.getLogger().Debug("regeneration was cancelled")
			}
		}

		done <- buildSuccess
		close(done)
	}()

	return done
}
8132
func (s *regenerationStatistics) SendMetrics() {
	endpointPolicyStatus.Update(s.endpointID, s.policyStatus)
	metrics.EndpointCountRegenerating.Dec()

	if !s.success {
		// Endpoint regeneration failed, increase on failed metrics
		metrics.EndpointRegenerationCount.WithLabelValues(metrics.LabelValueOutcomeFail).Inc()
		return
	}

	metrics.EndpointRegenerationCount.WithLabelValues(metrics.LabelValueOutcomeSuccess).Inc()

	sendMetrics(s, metrics.EndpointRegenerationTimeStats)
}
1286299
func (p *parser) restoreState(state storeDict) {
	if p.debug {
		defer p.out(p.in("restoreState"))
	}
	p.cur.state = state
}
737137
func (m *Manager) RegenerateId(ctx *macaron.Context) (sess RawStore, err error) {
	sid := m.sessionID()
	oldsid := ctx.GetCookie(m.opt.CookieName)
	_, err = m.validSessionID(oldsid)
	if err != nil {
		return nil, err
	}
	sess, err = m.provider.Regenerate(oldsid, sid)
	if err != nil {
		return nil, err
	}
	cookie := &http.Cookie{
		Name:     m.opt.CookieName,
		Value:    sid,
		Path:     m.opt.CookiePath,
		HttpOnly: true,
		Secure:   m.opt.Secure,
		Domain:   m.opt.Domain,
	}
	if m.opt.CookieLifeTime >= 0 {
		cookie.MaxAge = m.opt.CookieLifeTime
	}
	http.SetCookie(ctx.Resp, cookie)
	ctx.Req.AddCookie(cookie)
	return sess, nil
}
397860
func (ac *APIController) EndpointGroupCreate(endpointGroup *contivModel.EndpointGroup) error {
	log.Infof("Received EndpointGroupCreate: %+v", endpointGroup)

	// Find the tenant
	tenant := contivModel.FindTenant(endpointGroup.TenantName)
	if tenant == nil {
		return core.Errorf("Tenant not found")
	}
	// Find the network
	nwObjKey := endpointGroup.TenantName + ":" + endpointGroup.NetworkName
	network := contivModel.FindNetwork(nwObjKey)
	if network == nil {
		return core.Errorf("Network %s not found", endpointGroup.NetworkName)
	}
	// If there is a Network with the same name as this endpointGroup, reject.
	nameClash := contivModel.FindNetwork(endpointGroup.Key)
	if nameClash != nil {
		return core.Errorf("Network %s conflicts with the endpointGroup name",
			nameClash.NetworkName)
	}
	// create the endpoint group state
	err := master.CreateEndpointGroup(endpointGroup.TenantName, endpointGroup.NetworkName,
		endpointGroup.GroupName, endpointGroup.IpPool, endpointGroup.CfgdTag)
	if err != nil {
		log.Errorf("Error creating endpoint group %+v. Err: %v", endpointGroup, err)
		return err
	}
	// for each policy create an epg policy Instance
	for _, policyName := range endpointGroup.Policies {
		policyKey := GetpolicyKey(endpointGroup.TenantName, policyName)
		// find the policy
		policy := contivModel.FindPolicy(policyKey)
		if policy == nil {
			log.Errorf("Could not find policy %s", policyName)
			endpointGroupCleanup(endpointGroup)
			return core.Errorf("Policy not found")
		}

		// attach policy to epg
		err = master.PolicyAttach(endpointGroup, policy)
		if err != nil {
			log.Errorf("Error attaching policy %s to epg %s", policyName, endpointGroup.Key)
			endpointGroupCleanup(endpointGroup)
			return err
		}

		// establish Links
		modeldb.AddLinkSet(&policy.LinkSets.EndpointGroups, endpointGroup)
		modeldb.AddLinkSet(&endpointGroup.LinkSets.Policies, policy)

		// Write the policy
		err = policy.Write()
		if err != nil {
			endpointGroupCleanup(endpointGroup)
			return err
		}
	}

	// If endpoint group is to be attached to any netprofile, then attach the netprofile and create links and linksets.
	if endpointGroup.NetProfile != "" {
		profileKey := GetNetprofileKey(endpointGroup.TenantName, endpointGroup.NetProfile)
		netprofile := contivModel.FindNetprofile(profileKey)
		if netprofile == nil {
			log.Errorf("Error finding netprofile: %s", profileKey)
			return errors.New("netprofile not found")
		}

		// attach NetProfile to epg
		err = master.UpdateEndpointGroup(netprofile.Bandwidth, endpointGroup.GroupName, endpointGroup.TenantName, netprofile.DSCP, netprofile.Burst)
		if err != nil {
			log.Errorf("Error attaching NetProfile %s to epg %s", endpointGroup.NetProfile, endpointGroup.Key)
			endpointGroupCleanup(endpointGroup)
			return err
		}

		//establish links (epg - netprofile)
		modeldb.AddLink(&endpointGroup.Links.NetProfile, netprofile)
		//establish linksets (Netprofile - epg)
		modeldb.AddLinkSet(&netprofile.LinkSets.EndpointGroups, endpointGroup)

		//Write the attached Netprofile to modeldb
		err = netprofile.Write()
		if err != nil {
			endpointGroupCleanup(endpointGroup)
			return err
		}
	}

	// Setup external contracts this EPG might have.
	err = setupExternalContracts(endpointGroup, endpointGroup.ExtContractsGrps)
	if err != nil {
		log.Errorf("Error setting up external contracts for epg %s", endpointGroup.Key)
		endpointGroupCleanup(endpointGroup)
		return err
	}

	// Setup links
	modeldb.AddLink(&endpointGroup.Links.Network, network)
	modeldb.AddLink(&endpointGroup.Links.Tenant, tenant)
	modeldb.AddLinkSet(&network.LinkSets.EndpointGroups, endpointGroup)
	modeldb.AddLinkSet(&tenant.LinkSets.EndpointGroups, endpointGroup)

	// Save the tenant and network since we added the links
	err = network.Write()
	if err != nil {
		endpointGroupCleanup(endpointGroup)
		return err
	}

	err = tenant.Write()
	if err != nil {
		endpointGroupCleanup(endpointGroup)
		return err
	}

	return nil
}
1336121
func (p *ProgressBar) Reset() {
	p.lock.Lock()
	defer p.lock.Unlock()

	p.state = getBlankState()
}
1278007
func (s ClusterRoleBindingGeneratorV1) Generate(genericParams map[string]interface{}) (runtime.Object, error) {
	err := generate.ValidateParams(s.ParamNames(), genericParams)
	if err != nil {
		return nil, err
	}
	delegate := &ClusterRoleBindingGeneratorV1{}
	userStrings, found := genericParams["user"]
	if found {
		fromFileArray, isArray := userStrings.([]string)
		if !isArray {
			return nil, fmt.Errorf("expected []string, found :%v", userStrings)
		}
		delegate.Users = fromFileArray
		delete(genericParams, "user")
	}
	groupStrings, found := genericParams["group"]
	if found {
		fromLiteralArray, isArray := groupStrings.([]string)
		if !isArray {
			return nil, fmt.Errorf("expected []string, found :%v", groupStrings)
		}
		delegate.Groups = fromLiteralArray
		delete(genericParams, "group")
	}
	saStrings, found := genericParams["serviceaccount"]
	if found {
		fromLiteralArray, isArray := saStrings.([]string)
		if !isArray {
			return nil, fmt.Errorf("expected []string, found :%v", saStrings)
		}
		delegate.ServiceAccounts = fromLiteralArray
		delete(genericParams, "serviceaccount")
	}
	params := map[string]string{}
	for key, value := range genericParams {
		strVal, isString := value.(string)
		if !isString {
			return nil, fmt.Errorf("expected string, saw %v for '%s'", value, key)
		}
		params[key] = strVal
	}
	delegate.Name = params["name"]
	delegate.ClusterRole = params["clusterrole"]
	return delegate.StructuredGenerate()
}
666625
func (s *State) RefreshState() error {
	s.mu.Lock()
	defer s.mu.Unlock()
	return s.refreshState()
}
968480
func (pder *CookieProvider) SessionRegenerate(oldsid, sid string) (Store, error) {
	return nil, nil
}
20488
func (p CassandraPlugin) Restore(endpoint plugin.ShieldEndpoint) error {
	cassandra, err := cassandraInfo(endpoint)
	if err != nil {
		return err
	}

	plugin.DEBUG("Creating directory '%s' with 0755 permissions", "/var/vcap/store/shield/cassandra")
	err = os.MkdirAll("/var/vcap/store/shield/cassandra", 0755)
	if err != nil {
		fmt.Fprintf(os.Stderr, "@R{\u2717 Create base temporary directory}\n")
		return err
	}
	fmt.Fprintf(os.Stderr, "@G{\u2713 Create base temporary directory}\n")

	keyspaceDirPath := filepath.Join("/var/vcap/store/shield/cassandra", cassandra.Keyspace)

	// Recursively remove /var/vcap/store/shield/cassandra/{cassandra.Keyspace}, if any
	cmd := fmt.Sprintf("rm -rf \"%s\"", keyspaceDirPath)
	plugin.DEBUG("Executing `%s`", cmd)
	err = plugin.Exec(cmd, plugin.STDOUT)
	if err != nil {
		fmt.Fprintf(os.Stderr, "@R{\u2717 Clear base temporary directory}\n")
		return err
	}
	fmt.Fprintf(os.Stderr, "@G{\u2713 Clear base temporary directory}\n")

	defer func() {
		// plugin.DEBUG("Skipping recursive deletion of directory '%s'", keyspaceDirPath)

		// Recursively remove /var/vcap/store/shield/cassandra/{cassandra.Keyspace}, if any
		cmd := fmt.Sprintf("rm -rf \"%s\"", keyspaceDirPath)
		plugin.DEBUG("Executing `%s`", cmd)
		err := plugin.Exec(cmd, plugin.STDOUT)
		if err != nil {
			fmt.Fprintf(os.Stderr, "@R{\u2717 Clean base temporary directory}\n")
			return
		}
		fmt.Fprintf(os.Stderr, "@G{\u2713 Clean base temporary directory}\n")
	}()

	cmd = fmt.Sprintf("tar -x -C /var/vcap/store/shield/cassandra -f -")
	plugin.DEBUG("Executing `%s`", cmd)
	err = plugin.Exec(cmd, plugin.STDIN)
	if err != nil {
		fmt.Fprintf(os.Stderr, "@R{\u2717 Extract tar to temporary directory}\n")
		return err
	}
	fmt.Fprintf(os.Stderr, "@G{\u2713 Extract tar to temporary directory}\n")

	// Iterate through all table directories /var/vcap/store/shield/cassandra/{cassandra.Keyspace}/{tablename}
	dir, err := os.Open(keyspaceDirPath)
	if err != nil {
		fmt.Fprintf(os.Stderr, "@R{\u2717 Load all tables data}\n")
		return err
	}
	defer dir.Close()

	entries, err := dir.Readdir(-1)
	if err != nil {
		fmt.Fprintf(os.Stderr, "@R{\u2717 Load all tables data}\n")
		return err
	}
	for _, tableDirInfo := range entries {
		if !tableDirInfo.IsDir() {
			continue
		}
		// Run sstableloader on each sub-directory found, assuming it is a table backup
		tableDirPath := filepath.Join(keyspaceDirPath, tableDirInfo.Name())
		cmd := fmt.Sprintf("sstableloader -u \"%s\" -pw \"%s\" -d \"%s\" \"%s\"", cassandra.User, cassandra.Password, cassandra.Host, tableDirPath)
		plugin.DEBUG("Executing: `%s`", cmd)
		err = plugin.Exec(cmd, plugin.STDIN)
		if err != nil {
			fmt.Fprintf(os.Stderr, "@R{\u2717 Load all tables data}\n")
			return err
		}
	}
	fmt.Fprintf(os.Stderr, "@G{\u2713 Load all tables data}\n")

	return nil
}
537945
func (r *StateRestore) AllocRestore(alloc *structs.Allocation) error {
	if err := r.txn.Insert("allocs", alloc); err != nil {
		return fmt.Errorf("alloc insert failed: %v", err)
	}
	return nil
}
201583
func (p MySQLPlugin) Restore(endpoint plugin.ShieldEndpoint) error {
	mysql, err := mysqlConnectionInfo(endpoint)
	if err != nil {
		return err
	}
	cmd := fmt.Sprintf("%s/mysql %s", mysql.Bin, connectionString(mysql, false))
	dbname, err := endpoint.StringValueDefault("mysql_database", "")
	if err != nil {
		return err
	} else if dbname == "" {
		fmt.Fprintf(os.Stderr, "Restore Full Database \n")
		return mysqlrestorefull(mysql, cmd)
	} else {
		fmt.Fprintf(os.Stderr, "Restore Database %s \n", dbname)
		plugin.DEBUG("Exec: %s", cmd)
		return plugin.Exec(cmd, plugin.STDIN)
	}
}
778245
func (e *Endpoint) BuilderSetStateLocked(toState, reason string) bool {
	// Validate the state transition.
	fromState := e.state
	switch fromState { // From state
	case StateCreating, StateWaitingForIdentity, StateReady, StateDisconnecting, StateDisconnected:
		// No valid transitions for the builder
	case StateWaitingToRegenerate:
		switch toState {
		// Builder transitions the endpoint from
		// waiting-to-regenerate state to regenerating state
		// right after acquiring the endpoint lock, and while
		// endpoint's build mutex is held. All changes to
		// cilium and endpoint configuration, policy as well
		// as the existing set of security identities will be
		// reconsidered after this point, i.e., even if some
		// of them are changed regeneration need not be queued
		// if the endpoint is already in waiting-to-regenerate
		// state.
		case StateRegenerating:
			goto OKState
		// Transition to ReadyState is not supported, but is
		// attempted when a regeneration is competed, and another
		// regeneration has been queued in the meanwhile. So this
		// is expected and will not be logged as an error or warning.
		case StateReady:
			return false
		}
	case StateRegenerating:
		switch toState {
		// While still holding the build mutex, the builder
		// tries to transition the endpoint to ready
		// state. But since the endpoint mutex was released
		// for the duration of the bpf generation, it is
		// possible that another build request has been
		// queued. In this case the endpoint has been
		// transitioned to waiting-to-regenerate state
		// already, and the transition to ready state is
		// skipped (but not worth logging for, as this is
		// normal, see above).
		case StateReady:
			goto OKState
		}
	}
	e.logStatusLocked(Other, Warning, fmt.Sprintf("Skipped invalid state transition to %s due to: %s", toState, reason))
	return false

OKState:
	e.state = toState
	e.logStatusLocked(Other, OK, reason)

	if fromState != "" {
		metrics.EndpointStateCount.
			WithLabelValues(fromState).Dec()
	}

	// Since StateDisconnected is the final state, after which the
	// endpoint is gone, we should not increment metrics for this state.
	if toState != "" && toState != StateDisconnected {
		metrics.EndpointStateCount.
			WithLabelValues(toState).Inc()
	}
	return true
}
533804
func (p CassandraPlugin) Backup(endpoint plugin.ShieldEndpoint) error {
	cassandra, err := cassandraInfo(endpoint)
	if err != nil {
		return err
	}

	plugin.DEBUG("Cleaning any stale '%s' snapshot", SnapshotName)
	cmd := fmt.Sprintf("nodetool clearsnapshot -t %s \"%s\"", SnapshotName, cassandra.Keyspace)
	plugin.DEBUG("Executing: `%s`", cmd)
	err = plugin.Exec(cmd, plugin.STDIN)
	if err != nil {
		fmt.Fprintf(os.Stderr, "@R{\u2717 Clean any stale snapshot}\n")
		return err
	}
	fmt.Fprintf(os.Stderr, "@G{\u2713 Clean any stale snapshot}\n")

	defer func() {
		plugin.DEBUG("Clearing snapshot '%s'", SnapshotName)
		cmd := fmt.Sprintf("nodetool clearsnapshot -t %s \"%s\"", SnapshotName, cassandra.Keyspace)
		plugin.DEBUG("Executing: `%s`", cmd)
		err := plugin.Exec(cmd, plugin.STDIN)
		if err != nil {
			fmt.Fprintf(os.Stderr, "@R{\u2717 Clean snapshot}\n")
			return
		}
		fmt.Fprintf(os.Stderr, "@G{\u2713 Clean snapshot}\n")
	}()

	plugin.DEBUG("Creating a new '%s' snapshot", SnapshotName)
	cmd = fmt.Sprintf("nodetool snapshot -t %s \"%s\"", SnapshotName, cassandra.Keyspace)
	plugin.DEBUG("Executing: `%s`", cmd)
	err = plugin.Exec(cmd, plugin.STDIN)
	if err != nil {
		fmt.Fprintf(os.Stderr, "@R{\u2717 Create new snapshot}\n")
		return err
	}
	fmt.Fprintf(os.Stderr, "@G{\u2713 Create new snapshot}\n")

	// Here we need to hard-link the snapshots/shield-backup directories into
	// a {keyspace}/{tablename} structure that we'll temporarily put in
	// /var/vcap/store/shield/cassandra. Then we can tar it all and stream
	// that to stdout.

	baseDir := "/var/vcap/store/shield/cassandra"
	plugin.DEBUG("Creating any missing directories for '%s', with 0755 permissions", baseDir)
	err = os.MkdirAll(baseDir, 0755)
	if err != nil {
		fmt.Fprintf(os.Stderr, "@R{\u2717 Create base temporary directory}\n")
		return err
	}
	fmt.Fprintf(os.Stderr, "@G{\u2713 Create base temporary directory}\n")

	// Recursively remove /var/vcap/store/shield/cassandra/{keyspace}, if any
	tmpKeyspaceDir := filepath.Join(baseDir, cassandra.Keyspace)
	plugin.DEBUG("Removing any stale '%s' directory", tmpKeyspaceDir)
	cmd = fmt.Sprintf("rm -rf \"%s\"", tmpKeyspaceDir)
	plugin.DEBUG("Executing `%s`", cmd)
	err = plugin.Exec(cmd, plugin.STDOUT)
	if err != nil {
		fmt.Fprintf(os.Stderr, "@R{\u2717 Clear base temporary directory}\n")
		return err
	}
	fmt.Fprintf(os.Stderr, "@G{\u2713 Clear base temporary directory}\n")

	defer func() {
		// Recursively remove /var/vcap/store/shield/cassandra/{keyspace}, if any
		plugin.DEBUG("Cleaning the '%s' directory up", tmpKeyspaceDir)
		cmd := fmt.Sprintf("rm -rf \"%s\"", tmpKeyspaceDir)
		plugin.DEBUG("Executing `%s`", cmd)
		err := plugin.Exec(cmd, plugin.STDOUT)
		if err != nil {
			fmt.Fprintf(os.Stderr, "@R{\u2717 Clean base temporary directory}\n")
			return
		}
		fmt.Fprintf(os.Stderr, "@G{\u2713 Clean base temporary directory}\n")
	}()

	plugin.DEBUG("Creating directory '%s' with 0700 permissions", tmpKeyspaceDir)
	err = os.Mkdir(tmpKeyspaceDir, 0700)
	if err != nil {
		fmt.Fprintf(os.Stderr, "@R{\u2717 Create temporary directory}\n")
		return err
	}
	fmt.Fprintf(os.Stderr, "@G{\u2713 Create temporary directory}\n")

	// Iterate through {dataDir}/{keyspace}/{tablename}/snapshots/shield-backup/*
	// and for all the immutable files we find here, we hard-link them
	// to /var/vcap/store/shield/cassandra/{keyspace}/{tablename}
	//
	// We chose to hard-link because copying those immutable files is
	// unnecessary anyway. It could lead to performance issues and would
	// consume twice the disk space it should.

	info, err := os.Lstat(cassandra.DataDir)
	if err != nil {
		fmt.Fprintf(os.Stderr, "@R{\u2717 Recursive hard-link snapshot files}\n")
		return err
	}
	if !info.IsDir() {
		fmt.Fprintf(os.Stderr, "@R{\u2717 Recursive hard-link snapshot files}\n")
		return fmt.Errorf("cassandra DataDir is not a directory")
	}

	srcKeyspaceDir := filepath.Join(cassandra.DataDir, cassandra.Keyspace)
	dir, err := os.Open(srcKeyspaceDir)
	if err != nil {
		fmt.Fprintf(os.Stderr, "@R{\u2717 Recursive hard-link snapshot files}\n")
		return err
	}
	defer dir.Close()

	entries, err := dir.Readdir(-1)
	if err != nil {
		fmt.Fprintf(os.Stderr, "@R{\u2717 Recursive hard-link snapshot files}\n")
		return err
	}
	for _, tableDirInfo := range entries {
		if !tableDirInfo.IsDir() {
			continue
		}

		src_dir := filepath.Join(srcKeyspaceDir, tableDirInfo.Name(), "snapshots", SnapshotName)

		tableName := tableDirInfo.Name()
		if idx := strings.LastIndex(tableName, "-"); idx >= 0 {
			tableName = tableName[:idx]
		}

		dst_dir := filepath.Join(tmpKeyspaceDir, tableName)
		plugin.DEBUG("Creating destination directory '%s'", dst_dir)
		err = os.MkdirAll(dst_dir, 0755)
		if err != nil {
			fmt.Fprintf(os.Stderr, "@R{\u2717 Recursive hard-link snapshot files}\n")
			return err
		}

		plugin.DEBUG("Hard-linking all '%s/*' files to '%s/'", src_dir, dst_dir)
		err = hardLinkAll(src_dir, dst_dir)
		if err != nil {
			fmt.Fprintf(os.Stderr, "@R{\u2717 Recursive hard-link snapshot files in temp dir}\n")
			return err
		}
	}
	fmt.Fprintf(os.Stderr, "@G{\u2713 Recursive hard-link snapshot files in temp dir}\n")

	plugin.DEBUG("Setting ownership of all backup files to '%s'", VcapOwnership)
	cmd = fmt.Sprintf("chown -R vcap:vcap \"%s\"", tmpKeyspaceDir)
	plugin.DEBUG("Executing `%s`", cmd)
	err = plugin.Exec(cmd, plugin.STDOUT)
	if err != nil {
		fmt.Fprintf(os.Stderr, "@R{\u2717 Set ownership of snapshot hard-links}\n")
		return err
	}
	fmt.Fprintf(os.Stderr, "@G{\u2713 Set ownership of snapshot hard-links}\n")

	plugin.DEBUG("Streaming output tar file")
	cmd = fmt.Sprintf("tar -c -C /var/vcap/store/shield/cassandra -f - \"%s\"", cassandra.Keyspace)
	plugin.DEBUG("Executing `%s`", cmd)
	err = plugin.Exec(cmd, plugin.STDOUT)
	if err != nil {
		fmt.Fprintf(os.Stderr, "@R{\u2717 Stream tar of snapshots files}\n")
		return err
	}
	fmt.Fprintf(os.Stderr, "@G{\u2713 Stream tar of snapshots files}\n")

	return nil
}
1063753
func RegenerateEndpointSetSignalWhenEnqueued(owner endpoint.Owner, regenMetadata *endpoint.ExternalRegenerationMetadata, endpointIDs map[uint16]struct{}, wg *sync.WaitGroup) {
	wg.Add(len(endpointIDs))

	for endpointID := range endpointIDs {
		ep := endpoints[endpointID]
		go func() {
			regenerateEndpointNonBlocking(owner, ep, regenMetadata)
			wg.Done()
		}()
	}
}
777142
func (sys *PolicySys) Init(objAPI ObjectLayer) error {
	if objAPI == nil {
		return errInvalidArgument
	}

	defer func() {
		// Refresh PolicySys in background.
		go func() {
			ticker := time.NewTicker(globalRefreshBucketPolicyInterval)
			defer ticker.Stop()
			for {
				select {
				case <-GlobalServiceDoneCh:
					return
				case <-ticker.C:
					sys.refresh(objAPI)
				}
			}
		}()
	}()

	doneCh := make(chan struct{})
	defer close(doneCh)

	// Initializing policy needs a retry mechanism for
	// the following reasons:
	//  - Read quorum is lost just after the initialization
	//    of the object layer.
	for range newRetryTimerSimple(doneCh) {
		// Load PolicySys once during boot.
		if err := sys.refresh(objAPI); err != nil {
			if err == errDiskNotFound ||
				strings.Contains(err.Error(), InsufficientReadQuorum{}.Error()) ||
				strings.Contains(err.Error(), InsufficientWriteQuorum{}.Error()) {
				logger.Info("Waiting for policy subsystem to be initialized..")
				continue
			}
			return err
		}
		break
	}
	return nil
}
1095070
func (lt *LifeTime) Revive(onExpire func()) {
	if lt.Time.IsZero() {
		return
	}

	now := time.Now()
	if lt.Time.After(now) {
		d := lt.Time.Sub(now)
		lt.timer = time.AfterFunc(d, onExpire)
	}
}