Class: CzSystemInfo::Filesystem

Inherits:
Object
  • Object
show all
Extended by:
Functions
Includes:
Constants, Structs
Defined in:
lib/cz_system_info/filesystem.rb,
lib/cz_system_info/filesystem/structs.rb,
lib/cz_system_info/filesystem/constants.rb,
lib/cz_system_info/filesystem/functions.rb

Overview

The Filesystem class serves as an abstract base class. Its methods return objects of other types. Do not instantiate.

Defined Under Namespace

Modules: Constants, Functions, Structs Classes: Error, Mount, Stat

Constant Summary

Constants included from Constants

Constants::MNT_ASYNC, Constants::MNT_AUTOMOUNTED, Constants::MNT_CPROTECT, Constants::MNT_DEFWRITE, Constants::MNT_DETACH, Constants::MNT_DONTBROWSE, Constants::MNT_DOVOLFS, Constants::MNT_EXPIRE, Constants::MNT_EXPORTED, Constants::MNT_FORCE, Constants::MNT_IGNORE_OWNERSHIP, Constants::MNT_JOURNALED, Constants::MNT_LOCAL, Constants::MNT_MULTILABEL, Constants::MNT_NOATIME, Constants::MNT_NODEV, Constants::MNT_NOEXEC, Constants::MNT_NOSUID, Constants::MNT_NOUSERXATTR, Constants::MNT_QUARANTINE, Constants::MNT_QUOTA, Constants::MNT_RDONLY, Constants::MNT_ROOTFS, Constants::MNT_SYNCHRONOUS, Constants::MNT_UNION, Constants::MNT_VISFLAGMASK, Constants::MS_ACTIVE, Constants::MS_BIND, Constants::MS_DIRSYNC, Constants::MS_I_VERSION, Constants::MS_KERNMOUNT, Constants::MS_MANDLOCK, Constants::MS_MOVE, Constants::MS_NOATIME, Constants::MS_NODEV, Constants::MS_NODIRATIME, Constants::MS_NOEXEC, Constants::MS_NOSUID, Constants::MS_NOUSER, Constants::MS_POSIXACL, Constants::MS_PRIVATE, Constants::MS_RDONLY, Constants::MS_REC, Constants::MS_RELATIME, Constants::MS_REMOUNT, Constants::MS_SHARED, Constants::MS_SILENT, Constants::MS_SLAVE, Constants::MS_STRICTATIME, Constants::MS_SYNCHRONOUS, Constants::MS_UNBINDABLE, Constants::UMOUNT_NOFOLLOW

Class Method Summary collapse

Methods included from Functions

solaris?

Class Method Details

.mount(source, target, fstype = 'ext2', flags = 0, data = nil) ⇒ Object

Attach the filesystem specified by source to the location (a directory or file) specified by the pathname in target.

Note that the source is often a pathname referring to a device, but can also be the pathname of a directory or file, or a dummy string.

By default this method will assume ‘ext2’ as the filesystem type, but you should update this as needed.

Typically requires admin privileges.

Example:

CzSystemInfo::Filesystem.mount('/dev/loop0', '/home/you/tmp', 'ext4', CzSystemInfo::Filesystem::MNT_RDONLY)


420
421
422
423
424
425
426
# File 'lib/cz_system_info/filesystem.rb', line 420

def self.mount(source, target, fstype = 'ext2', flags = 0, data = nil)
  if mount_c(source, target, fstype, flags, data) != 0
    raise Error, "mount() function failed: #{strerror(FFI.errno)}"
  end

  self
end

.mount_point(file) ⇒ Object

Returns the mount point of the given file, or itself if it cannot be found.

Example:

CzSystemInfo::Filesystem.mount_point('/home/some_user') # => /home


386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
# File 'lib/cz_system_info/filesystem.rb', line 386

def self.mount_point(file)
  dev = File.stat(file).dev
  val = file

  mounts.each do |mnt|
    mp = mnt.mount_point
    begin
      if File.stat(mp).dev == dev
        val = mp
        break
      end
    rescue Errno::EACCES
      next
    end
  end

  val
end

.mountsObject

In block form, yields a CzSystemInfo::Filesystem::Mount object for each mounted filesytem on the host. Otherwise it returns an array of Mount objects.

Example:

CzSystemInfo::Filesystem.mounts{ |fs|

p fs.name        # => '/dev/dsk/c0t0d0s0'
p fs.mount_time  # => Thu Dec 11 15:07:23 -0700 2008
p fs.mount_type  # => 'ufs'
p fs.mount_point # => '/'
p fs.options     # => local, noowner, nosuid

}



269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
# File 'lib/cz_system_info/filesystem.rb', line 269

def self.mounts
  array = block_given? ? nil : []

  if respond_to?(:getmntinfo, true)
    buf = FFI::MemoryPointer.new(:pointer)

    num = getmntinfo(buf, 2)

    if num == 0
      raise Error, "getmntinfo() function failed: #{strerror(FFI.errno)}"
    end

    ptr = buf.get_pointer(0)

    num.times do
      mnt = Statfs.new(ptr)
      obj = CzSystemInfo::Filesystem::Mount.new
      obj.name = mnt[:f_mntfromname].to_s
      obj.mount_point = mnt[:f_mntonname].to_s
      obj.mount_type = mnt[:f_fstypename].to_s

      string = ''
      flags = mnt[:f_flags] & MNT_VISFLAGMASK

      OPT_NAMES.each do |key, val|
        if flags & key > 0
          if string.empty?
            string << val
          else
            string << ", #{val}"
          end
        end
        flags &= ~key
      end

      obj.options = string

      if block_given?
        yield obj.freeze
      else
        array << obj.freeze
      end

      ptr += Statfs.size
    end
  else
    begin
      if respond_to?(:setmntent, true)
        method_name = 'setmntent'
        fp = setmntent(MOUNT_FILE, 'r')
      else
        method_name = 'fopen'
        fp = fopen(MOUNT_FILE, 'r')
      end

      if fp.null?
        raise SystemCallError.new(method_name, FFI.errno)
      end

      if RbConfig::CONFIG['host_os'] =~ /sunos|solaris/i
        mt = Mnttab.new
        while getmntent(fp, mt) == 0
          obj = CzSystemInfo::Filesystem::Mount.new
          obj.name = mt[:mnt_special].to_s
          obj.mount_point = mt[:mnt_mountp].to_s
          obj.mount_type = mt[:mnt_fstype].to_s
          obj.options = mt[:mnt_mntopts].to_s
          obj.mount_time = Time.at(Integer(mt[:mnt_time]))

          if block_given?
            yield obj.freeze
          else
            array << obj.freeze
          end
        end
      else
        while ptr = getmntent(fp)
          break if ptr.null?
          mt = Mntent.new(ptr)

          obj = CzSystemInfo::Filesystem::Mount.new
          obj.name = mt[:mnt_fsname]
          obj.mount_point = mt[:mnt_dir]
          obj.mount_type = mt[:mnt_type]
          obj.options = mt[:mnt_opts]
          obj.mount_time = nil
          obj.dump_frequency = mt[:mnt_freq]
          obj.pass_number = mt[:mnt_passno]

          if block_given?
            yield obj.freeze
          else
            array << obj.freeze
          end
        end
      end
    ensure
      if fp && !fp.null?
        if respond_to?(:endmntent, true)
          endmntent(fp)
        else
          fclose(fp)
        end
      end
    end
  end

  array
end

.stat(path) ⇒ Object

Returns a CzSystemInfo::Filesystem::Stat object containing information about the path on the filesystem.

Examples:

# path
CzSystemInfo::Filesystem.stat("path")

# Pathname
pathname = Pathname.new("path")
CzSystemInfo::Filesystem.stat(pathname)

# File
file = File.open("file", "r")
CzSystemInfo::Filesystem.stat(file)

# Dir
dir = Dir.open("/")
CzSystemInfo::Filesystem.stat(dir)


220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
# File 'lib/cz_system_info/filesystem.rb', line 220

def self.stat(path)
  path = path.path if path.respond_to?(:path) # File, Dir
  path = path.to_s if path.respond_to?(:to_s) # Pathname

  fs = Statvfs.new

  if statvfs(path, fs) < 0
    raise Error, "statvfs() function failed: #{strerror(FFI.errno)}"
  end

  obj = CzSystemInfo::Filesystem::Stat.new
  obj.path = path
  obj.block_size = fs[:f_bsize]
  obj.fragment_size = fs[:f_frsize]
  obj.blocks = fs[:f_blocks]
  obj.blocks_free = fs[:f_bfree]
  obj.blocks_available = fs[:f_bavail]
  obj.files = fs[:f_files]
  obj.files_free = fs[:f_ffree]
  obj.files_available = fs[:f_favail]
  obj.filesystem_id = fs[:f_fsid]
  obj.flags = fs[:f_flag]
  obj.name_max = fs[:f_namemax]

  # OSX does things a little differently
  if RbConfig::CONFIG['host_os'] =~ /darwin|osx|mach/i
    obj.block_size /= 256
  end

  if fs.members.include?(:f_basetype)
    obj.base_type = fs[:f_basetype].to_s
  end

  obj.freeze
end

.umount(target, flags = nil) ⇒ Object

Removes the attachment of the (topmost) filesystem mounted on target. Additional flags may be provided for operating systems that support the umount2 function. Otherwise this argument is ignored.

Typically requires admin privileges.



434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
# File 'lib/cz_system_info/filesystem.rb', line 434

def self.umount(target, flags = nil)
  if flags && respond_to?(:umount2)
    function = 'umount2'
    rv = umount2_c(target, flags)
  else
    function = 'umount'
    rv = umount_c(target)
  end

  if rv != 0
    raise Error, "#{function} function failed: " + strerror(FFI.errno)
  end

  self
end