Class: VixDiskLib

Inherits:
Object
  • Object
show all
Includes:
VMwareWebService::Logging
Defined in:
lib/VMwareWebService/VixDiskLib/VixDiskLib.rb

Constant Summary collapse

VIXDISKLIB_FLAG_OPEN_READ_ONLY =
FFI::VixDiskLib::API::VIXDISKLIB_FLAG_OPEN_READ_ONLY

Class Method Summary collapse

Methods included from VMwareWebService::Logging

#logger

Class Method Details

.connect(connect_parms) ⇒ Object



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/VMwareWebService/VixDiskLib/VixDiskLib.rb', line 39

def self.connect(connect_parms)
  @connection_lock.synchronize(:EX) do
    raise VixDiskLibError, "VixDiskLib.connect() failed: VixDiskLib not initialized" if @initialized.nil?
    raise VixDiskLibError, "VixDiskLib.connect() aborting: VixDiskLib shutting down" if @shutting_down
    vix_disk_lib_service = start_service
    @drb_services << vix_disk_lib_service
    #
    # Let the DRb service start before attempting to use it.
    # I can find no examples suggesting that this is required, but on my test machine it is indeed.
    #
    retry_limit = 5
    begin
      sleep 1
      vix_disk_lib_service.init
    rescue DRb::DRbConnError => e
      if retry_limit > 0
        sleep 1
        retry_limit -= 1
        retry
      else
        raise VixDiskLibError, "VixDiskLib.connect() failed: #{e} on VixDiskLib.init()"
      end
    end
    vix_disk_lib_service.connect(connect_parms)
  end
end

.exitObject



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/VMwareWebService/VixDiskLib/VixDiskLib.rb', line 66

def self.exit
  @connection_lock.synchronize(:EX) do
    @shutting_down = true
    DRb.stop_service
    i = 0
    @drb_services.each do |vdl_service|
      i += 1
      logger.info "VixDiskLib.exit: shutting down service #{i} of #{@drb_services.size}"
      unless vdl_service.nil?
        begin
          vdl_service.shutdown = true
        rescue DRb::DRbConnError
          logger.info "VixDiskLib.exit: DRb connection closed due to service shutdown.  Continuing"
        end
      end
    end
    # Now clear data so we can start over if needed
    @initialized = nil
    num_services = @drb_services.size
    @drb_services.pop(num_services)
  end
end

.get_uri(reader) ⇒ Object



143
144
145
146
147
148
149
150
151
# File 'lib/VMwareWebService/VixDiskLib/VixDiskLib.rb', line 143

def self.get_uri(reader)
  if reader.eof
    #
    # Error - unable to read the URI with port number written into the pipe by the child (Server).
    #
    raise VixDiskLibError, "ERROR: VixDiskLib.connect() Unable to determine port used by VixDiskLib Server."
  end
  reader.gets
end

.init(_info_logger = nil, _warn_logger = nil, _error_logger = nil, _lib_dir = nil) ⇒ Object

Just stash the init arguments into a hash for now. We will call init on the server every time a connect request is made.



34
35
36
37
# File 'lib/VMwareWebService/VixDiskLib/VixDiskLib.rb', line 34

def self.init(_info_logger = nil, _warn_logger = nil, _error_logger = nil, _lib_dir = nil)
  @initialized = true
  nil
end

.setup_envObject

Remove the Rails Environment Variables set in the Current Environment so that the SSL Libraries don’t get loaded.

Raises:



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/VMwareWebService/VixDiskLib/VixDiskLib.rb', line 92

def self.setup_env
  vars_to_clear = %w(BUNDLE_BIN BUNDLE_BIN_PATH BUNDLE_GEMFILE
                     BUNDLE_ORIG_MANPATH EVMSERVER MIQ_GUID
                     RAILS_ENV RUBYOPT ORIGINAL_GEM_PATH)
  my_env = ENV.to_hash
  vars_to_clear.each do |key|
    my_env.delete(key)
  end

  my_env["LD_LIBRARY_PATH"] = (my_env["LD_LIBRARY_PATH"].to_s.split(':') << VIXDISKLIB_PATH).compact.join(":")
  raise VixDiskLibError, "VixDiskLib.connect() failed: No logger defined" unless logger
  my_env["LOG_FILE"] = logger.logdev.filename.to_s if logger.try(:logdev).kind_of?(Logger::LogDevice)

  my_env
end

.start_serviceObject



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/VMwareWebService/VixDiskLib/VixDiskLib.rb', line 108

def self.start_service
  #
  # TODO: Get the path to the server programatically - this server should probably live elsewhere.
  #
  my_env                    = setup_env
  uri_reader, uri_writer    = IO.pipe
  proc_reader, @proc_writer = IO.pipe

  server_cmd = "ruby #{SERVER_PATH}/VixDiskLibServer.rb"
  log_target = my_env["LOG_FILE"] ? [my_env["LOG_FILE"], "a"] : $stdout

  logger.info "VixDiskLib.start_service: running command = #{server_cmd}"

  pid = Kernel.spawn(my_env, server_cmd,
                     [:out, :err]     => log_target,
                     :unsetenv_others => true,
                     3                => uri_writer,
                     4                => proc_reader)
  uri_writer.close
  proc_reader.close
  Process.detach(pid)
  logger.info "VixDiskLibServer Process #{pid} started"
  DRb.start_service
  retry_num = 5
  uri       = get_uri(uri_reader)
  begin
    vix_disk_lib_service = DRbObject.new(nil, uri)
  rescue DRb::DRbConnError => e
    raise VixDiskLibError, "ERROR: VixDiskLib.connect() got #{e} on DRbObject.new_with_uri()" if retry_num == 0
    sleep 1
    retry_num -= 1 && retry
  end
  vix_disk_lib_service
end