// PathExists verifies if a path exists and does not raise an exception if the // path does not exist func PathExists(conn client.Connection, p string) (bool, error) { exists, err := conn.Exists(p) if err == client.ErrNoNode { return false, nil } return exists, err }
func (s *Server) Run(shutdown <-chan interface{}, conn client.Connection) error { node := &Node{ Host: *s.host, ExportPath: fmt.Sprintf("%s:%s", s.host.IPAddr, s.driver.ExportPath()), ExportTime: strconv.FormatInt(time.Now().UnixNano(), 16), } // Create the storage leader and client nodes if exists, _ := conn.Exists("/storage/leader"); !exists { conn.CreateDir("/storage/leader") } storageClientsPath := "/storage/clients" if exists, _ := conn.Exists(storageClientsPath); !exists { conn.CreateDir(storageClientsPath) } leader := conn.NewLeader("/storage/leader", node) leaderW, err := leader.TakeLead() if err != zookeeper.ErrDeadlock && err != nil { glog.Errorf("Could not take storage lead: %s", err) return err } // monitor dfs; log warnings each cycle; restart dfs if needed go s.monitor.MonitorDFSVolume(path.Join("/exports", s.driver.ExportPath()), s.host.IPAddr, node.ExportTime, shutdown, s.monitor.DFSVolumeMonitorPollUpdateFunc) // loop until shutdown event defer leader.ReleaseLead() for { clients, clientW, err := conn.ChildrenW(storageClientsPath) if err != nil { glog.Errorf("Could not set up watch for storage clients: %s", err) return err } s.monitor.SetMonitorStorageClients(conn, storageClientsPath) s.driver.SetClients(clients...) if err := s.driver.Sync(); err != nil { glog.Errorf("Error syncing driver: %s", err) return err } select { case e := <-clientW: glog.Info("storage.server: receieved event: %s", e) case <-leaderW: err := fmt.Errorf("storage.server: lost lead") return err case <-shutdown: return nil } } }
// updateInstance updates the service state and host instances func updateInstance(conn client.Connection, hostID, stateID string, mutate func(*HostState, *ss.ServiceState)) error { glog.V(2).Infof("Updating instance %s", stateID) // do not lock if parent lock does not exist if exists, err := conn.Exists(path.Join(zkInstanceLock, stateID)); err != nil && err != client.ErrNoNode { glog.Errorf("Could not check for lock on instance %s: %s", stateID, err) return err } else if !exists { glog.Errorf("Lock not found for instance %s", stateID) return ErrLockNotFound } lock := newInstanceLock(conn, stateID) if err := lock.Lock(); err != nil { glog.Errorf("Could not set lock for service instance %s on host %s: %s", stateID, hostID, err) return err } defer lock.Unlock() glog.V(2).Infof("Acquired lock for instance %s", stateID) hpath := hostpath(hostID, stateID) var hsdata HostState if err := conn.Get(hpath, &hsdata); err != nil { glog.Errorf("Could not get instance %s for host %s: %s", stateID, hostID, err) return err } serviceID := hsdata.ServiceID spath := servicepath(serviceID, stateID) var ssnode ServiceStateNode if err := conn.Get(spath, &ssnode); err != nil { glog.Errorf("Could not get instance %s for service %s: %s", stateID, serviceID, err) return err } mutate(&hsdata, ssnode.ServiceState) if err := conn.Set(hpath, &hsdata); err != nil { glog.Errorf("Could not update instance %s for host %s: %s", stateID, hostID, err) return err } if err := conn.Set(spath, &ssnode); err != nil { glog.Errorf("Could not update instance %s for service %s: %s", stateID, serviceID, err) return err } glog.V(2).Infof("Releasing lock for instance %s", stateID) return nil }