Module: Suzuna

Defined in:
lib/suzuna.rb

Defined Under Namespace

Modules: Exceptions, IOCTL, Template Classes: DestroyedGate

Constant Summary collapse

Suzuna =
self
VERSION =
Gem::Version.new "0.0.1"
G_GATE_CTL_NAME =
"/dev/ggctl"
G_GATE_TIMEOUT =
0
G_GATE_UNIT_AUTO =
-1
G_GATE_PROVIDER_NAME =
"ggate"
G_GATE_FLAG_READWRITE =
0x0000
G_GATE_FLAG_READONLY =
0x0001
G_GATE_FLAG_WRITEONLY =
0x0002
G_GATE_FLAG_DESTROY =
0x1000
G_GATE_USERFLAGS =
G_GATE_FLAG_READONLY | G_GATE_FLAG_WRITEONLY
G_GATE_VERSION =
3
BIO_READ =
0x01
BIO_WRITE =
0x02
BIO_DELETE =
0x04

Class Method Summary collapse

Class Method Details

.err2code(err) ⇒ Object



242
243
244
245
246
247
248
249
250
251
252
253
# File 'lib/suzuna.rb', line 242

def self.err2code(err)
  case err
  when nil
    Errno::NOERROR::Errno
  when Class
    err::Errno
  when Integer
    err.to_i
  else
    err.errno
  end
end

.join(unitobj) ⇒ Object



156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/suzuna.rb', line 156

def self.join(unitobj)
  unit = IOCTL::Create.post(unitobj.mediasize, unitobj.flags,
                            sectorsize: unitobj.sectorsize, info: unitobj.info,
                            timeout: unitobj.timeout, unit: unitobj.unit)

  begin
    mainloop(unitobj, unit)
  ensure
    IOCTL::Destroy.post(unit, true) rescue nil unless $!.kind_of?(DestroyedGate)
    unitobj.cleanup
  end
end

.mainloop(unitobj, unit) ⇒ Object

Raises:

  • (Exception)


169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
# File 'lib/suzuna.rb', line 169

def self.mainloop(unitobj, unit)
  ioc = IOCTL::IOReq.new
  ioc.start.version = G_GATE_VERSION
  ioc.start.unit = unit
  bufsize = unitobj.sectorsize
  buf = String.alloc(bufsize)
  ioc.start.data = buf.to_ptr

  while true
    while true
      ioc.start.data = buf.to_ptr
      ioc.start.length = buf.bytesize
      ioc.start.error = 0
      begin
        ioc.start.post
      rescue Errno::ENXIO
        raise DestroyedGate, "/dev/ggate#{unit}"
      end

      case ioc.start.error
      when Errno::NOERROR::Errno
        # nothing to do here
      when Errno::ECANCELED::Errno, Errno::ENXIO::Errno
        raise DestroyedGate, "/dev/ggate#{unit}"
      when Errno::ENOMEM::Errno
        buf.resize(bufsize = ioc.start.length)
        unless buf.bytesize == bufsize
          raise Errno::ENOMEM, <<-EOM.chomp
#{G_GATE_CTL_NAME} (require size = #{bufsize}, but allocated size = #{buf.bytesize})
          EOM
        end
        break
      else
        raise SystemCallError.new("#{G_GATE_CTL_NAME} (ioctl)", ioc.start.error)
      end

      catch(:break) do
        begin
          case ioc.start.cmd
          when BIO_READ
            if ioc.start.length > bufsize
              buf.resize(bufsize = ioc.start.length)
              unless buf.bytesize == bufsize
                ioc.done.error = Errno::ENOMEM::Errno
                throw :break
              end
            end
            ioc.done.error = err2code(unitobj.read(ioc.start.offset, ioc.start.length, buf))
            ioc.done.data = buf.to_ptr
          when BIO_DELETE
            ioc.done.error = err2code(unitobj.delete(ioc.start.offset, ioc.start.length))
          when BIO_WRITE
            buf.resize(ioc.start.length)
            ioc.done.error = err2code(unitobj.write(ioc.start.offset, buf))
            buf.resize(bufsize)
            ioc.done.data = buf.to_ptr
          else
            ioc.done.error = Errno::EOPNOTSUPP::Errno
          end
        rescue BasicObject
          ioc.done.error = Errno::EFAULT::Errno
          raise
        ensure
          #p err: SystemCallError.new(ioc.done.error)
          ioc.done.post
        end
      end
    end
  end

  raise Exception, "!!BUG!! - SHALL NOT REACHED HERE!"
end