cz_system_info 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.github/workflows/main.yml +18 -0
- data/.gitignore +8 -0
- data/Gemfile +10 -0
- data/LICENSE.txt +21 -0
- data/README.md +39 -0
- data/Rakefile +12 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/cz_system_info.gemspec +36 -0
- data/lib/cz_system_info/cpu.rb +167 -0
- data/lib/cz_system_info/filesystem/constants.rb +72 -0
- data/lib/cz_system_info/filesystem/functions.rb +75 -0
- data/lib/cz_system_info/filesystem/structs.rb +216 -0
- data/lib/cz_system_info/filesystem.rb +450 -0
- data/lib/cz_system_info/memory.rb +66 -0
- data/lib/cz_system_info/uptime.rb +222 -0
- data/lib/cz_system_info/version.rb +5 -0
- data/lib/cz_system_info.rb +12 -0
- metadata +78 -0
@@ -0,0 +1,216 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'ffi'
|
4
|
+
require 'rbconfig'
|
5
|
+
|
6
|
+
module CzSystemInfo
|
7
|
+
class Filesystem
|
8
|
+
module Structs
|
9
|
+
# The Statfs struct is a subclass of FFI::Struct that corresponds to a struct statfs.
|
10
|
+
class Statfs < FFI::Struct
|
11
|
+
# Private method that will determine the layout of the struct on Linux.
|
12
|
+
def self.linux64?
|
13
|
+
if RUBY_PLATFORM == 'java'
|
14
|
+
ENV_JAVA['sun.arch.data.model'].to_i == 64
|
15
|
+
else
|
16
|
+
RbConfig::CONFIG['host_os'] =~ /linux/i &&
|
17
|
+
(RbConfig::CONFIG['arch'] =~ /64/ || RbConfig::CONFIG['DEFS'] =~ /64/)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
private_class_method :linux64?
|
22
|
+
|
23
|
+
# FreeBSD 12.0 MNAMELEN from 88 => 1024.
|
24
|
+
MNAMELEN =
|
25
|
+
if RbConfig::CONFIG['host_os'] =~ /freebsd(.*)/i
|
26
|
+
Regexp.last_match(1).to_f < 12.0 ? 88 : 1024
|
27
|
+
else
|
28
|
+
88
|
29
|
+
end
|
30
|
+
|
31
|
+
case RbConfig::CONFIG['host_os']
|
32
|
+
when /bsd/i
|
33
|
+
layout(
|
34
|
+
:f_version, :uint32,
|
35
|
+
:f_type, :uint32,
|
36
|
+
:f_flags, :uint64,
|
37
|
+
:f_bsize, :uint64,
|
38
|
+
:f_iosize, :int64,
|
39
|
+
:f_blocks, :uint64,
|
40
|
+
:f_bfree, :uint64,
|
41
|
+
:f_bavail, :int64,
|
42
|
+
:f_files, :uint64,
|
43
|
+
:f_ffree, :uint64,
|
44
|
+
:f_syncwrites, :uint64,
|
45
|
+
:f_asyncwrites, :uint64,
|
46
|
+
:f_syncreads, :uint64,
|
47
|
+
:f_asyncreads, :uint64,
|
48
|
+
:f_spare, [:uint64, 10],
|
49
|
+
:f_namemax, :uint32,
|
50
|
+
:f_owner, :int32,
|
51
|
+
:f_fsid, [:int32, 2],
|
52
|
+
:f_charspare, [:char, 80],
|
53
|
+
:f_fstypename, [:char, 16],
|
54
|
+
:f_mntfromname, [:char, MNAMELEN],
|
55
|
+
:f_mntonname, [:char, MNAMELEN]
|
56
|
+
)
|
57
|
+
when /linux/i
|
58
|
+
if linux64?
|
59
|
+
layout(
|
60
|
+
:f_type, :ulong,
|
61
|
+
:f_bsize, :ulong,
|
62
|
+
:f_blocks, :uint64,
|
63
|
+
:f_bfree, :uint64,
|
64
|
+
:f_bavail, :uint64,
|
65
|
+
:f_files, :uint64,
|
66
|
+
:f_ffree, :uint64,
|
67
|
+
:f_fsid, [:int, 2],
|
68
|
+
:f_namelen, :ulong,
|
69
|
+
:f_frsize, :ulong,
|
70
|
+
:f_flags, :ulong,
|
71
|
+
:f_spare, [:ulong, 4]
|
72
|
+
)
|
73
|
+
else
|
74
|
+
layout(
|
75
|
+
:f_type, :ulong,
|
76
|
+
:f_bsize, :ulong,
|
77
|
+
:f_blocks, :uint32,
|
78
|
+
:f_bfree, :uint32,
|
79
|
+
:f_bavail, :uint32,
|
80
|
+
:f_files, :uint32,
|
81
|
+
:f_ffree, :uint32,
|
82
|
+
:f_fsid, [:int, 2],
|
83
|
+
:f_namelen, :ulong,
|
84
|
+
:f_frsize, :ulong,
|
85
|
+
:f_flags, :ulong,
|
86
|
+
:f_spare, [:ulong, 4]
|
87
|
+
)
|
88
|
+
end
|
89
|
+
else
|
90
|
+
layout(
|
91
|
+
:f_bsize, :uint32,
|
92
|
+
:f_iosize, :int32,
|
93
|
+
:f_blocks, :uint64,
|
94
|
+
:f_bfree, :uint64,
|
95
|
+
:f_bavail, :uint64,
|
96
|
+
:f_files, :uint64,
|
97
|
+
:f_ffree, :uint64,
|
98
|
+
:f_fsid, [:int32, 2],
|
99
|
+
:f_owner, :int32,
|
100
|
+
:f_type, :uint32,
|
101
|
+
:f_flags, :uint32,
|
102
|
+
:f_fssubtype, :uint32,
|
103
|
+
:f_fstypename, [:char, 16],
|
104
|
+
:f_mntonname, [:char, 1024],
|
105
|
+
:f_mntfromname, [:char, 1024],
|
106
|
+
:f_reserved, [:uint32, 8]
|
107
|
+
)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
# The Statvfs struct represents struct statvfs from CzSystemInfo/statvfs.h.
|
112
|
+
class Statvfs < FFI::Struct
|
113
|
+
if RbConfig::CONFIG['host_os'] =~ /darwin|osx|mach/i
|
114
|
+
layout(
|
115
|
+
:f_bsize, :ulong,
|
116
|
+
:f_frsize, :ulong,
|
117
|
+
:f_blocks, :uint,
|
118
|
+
:f_bfree, :uint,
|
119
|
+
:f_bavail, :uint,
|
120
|
+
:f_files, :uint,
|
121
|
+
:f_ffree, :uint,
|
122
|
+
:f_favail, :uint,
|
123
|
+
:f_fsid, :ulong,
|
124
|
+
:f_flag, :ulong,
|
125
|
+
:f_namemax, :ulong
|
126
|
+
)
|
127
|
+
elsif RbConfig::CONFIG['host'] =~ /bsd/i
|
128
|
+
layout(
|
129
|
+
:f_bavail, :uint64,
|
130
|
+
:f_bfree, :uint64,
|
131
|
+
:f_blocks, :uint64,
|
132
|
+
:f_favail, :uint64,
|
133
|
+
:f_ffree, :uint64,
|
134
|
+
:f_files, :uint64,
|
135
|
+
:f_bsize, :ulong,
|
136
|
+
:f_flag, :ulong,
|
137
|
+
:f_frsize, :ulong,
|
138
|
+
:f_fsid, :ulong,
|
139
|
+
:f_namemax, :ulong
|
140
|
+
)
|
141
|
+
elsif RbConfig::CONFIG['host'] =~ /sunos|solaris/i
|
142
|
+
layout(
|
143
|
+
:f_bsize, :ulong,
|
144
|
+
:f_frsize, :ulong,
|
145
|
+
:f_blocks, :uint64_t,
|
146
|
+
:f_bfree, :uint64_t,
|
147
|
+
:f_bavail, :uint64_t,
|
148
|
+
:f_files, :uint64_t,
|
149
|
+
:f_ffree, :uint64_t,
|
150
|
+
:f_favail, :uint64_t,
|
151
|
+
:f_fsid, :ulong,
|
152
|
+
:f_basetype, [:char, 16],
|
153
|
+
:f_flag, :ulong,
|
154
|
+
:f_namemax, :ulong,
|
155
|
+
:f_fstr, [:char, 32],
|
156
|
+
:f_filler, [:ulong, 16]
|
157
|
+
)
|
158
|
+
elsif RbConfig::CONFIG['host'] =~ /i686/i
|
159
|
+
layout(
|
160
|
+
:f_bsize, :ulong,
|
161
|
+
:f_frsize, :ulong,
|
162
|
+
:f_blocks, :uint,
|
163
|
+
:f_bfree, :uint,
|
164
|
+
:f_bavail, :uint,
|
165
|
+
:f_files, :uint,
|
166
|
+
:f_ffree, :uint,
|
167
|
+
:f_favail, :uint,
|
168
|
+
:f_fsid, :ulong,
|
169
|
+
:f_unused, :int,
|
170
|
+
:f_flag, :ulong,
|
171
|
+
:f_namemax, :ulong,
|
172
|
+
:f_spare, [:int, 6]
|
173
|
+
)
|
174
|
+
else
|
175
|
+
layout(
|
176
|
+
:f_bsize, :ulong,
|
177
|
+
:f_frsize, :ulong,
|
178
|
+
:f_blocks, :uint64,
|
179
|
+
:f_bfree, :uint64,
|
180
|
+
:f_bavail, :uint64,
|
181
|
+
:f_files, :uint64,
|
182
|
+
:f_ffree, :uint64,
|
183
|
+
:f_favail, :uint64,
|
184
|
+
:f_fsid, :ulong,
|
185
|
+
:f_flag, :ulong,
|
186
|
+
:f_namemax, :ulong,
|
187
|
+
:f_spare, [:int, 6]
|
188
|
+
)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
# The Mnttab struct represents struct mnnttab from CzSystemInfo/mnttab.h on Solaris.
|
193
|
+
class Mnttab < FFI::Struct
|
194
|
+
layout(
|
195
|
+
:mnt_special, :string,
|
196
|
+
:mnt_mountp, :string,
|
197
|
+
:mnt_fstype, :string,
|
198
|
+
:mnt_mntopts, :string,
|
199
|
+
:mnt_time, :string
|
200
|
+
)
|
201
|
+
end
|
202
|
+
|
203
|
+
# The Mntent struct represents struct mntent from CzSystemInfo/mount.h on Unix.
|
204
|
+
class Mntent < FFI::Struct
|
205
|
+
layout(
|
206
|
+
:mnt_fsname, :string,
|
207
|
+
:mnt_dir, :string,
|
208
|
+
:mnt_type, :string,
|
209
|
+
:mnt_opts, :string,
|
210
|
+
:mnt_freq, :int,
|
211
|
+
:mnt_passno, :int
|
212
|
+
)
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
@@ -0,0 +1,450 @@
|
|
1
|
+
require_relative 'filesystem/constants'
|
2
|
+
require_relative 'filesystem/structs'
|
3
|
+
require_relative 'filesystem/functions'
|
4
|
+
|
5
|
+
# The CzSystemInfo module serves as a namespace only.
|
6
|
+
module CzSystemInfo
|
7
|
+
# The Filesystem class serves as an abstract base class. Its methods
|
8
|
+
# return objects of other types. Do not instantiate.
|
9
|
+
class Filesystem
|
10
|
+
include CzSystemInfo::Filesystem::Constants
|
11
|
+
include CzSystemInfo::Filesystem::Structs
|
12
|
+
extend CzSystemInfo::Filesystem::Functions
|
13
|
+
|
14
|
+
private_class_method :new
|
15
|
+
|
16
|
+
# Readable versions of constant names
|
17
|
+
OPT_NAMES = {
|
18
|
+
MNT_RDONLY => 'read-only',
|
19
|
+
MNT_SYNCHRONOUS => 'synchronous',
|
20
|
+
MNT_NOEXEC => 'noexec',
|
21
|
+
MNT_NOSUID => 'nosuid',
|
22
|
+
MNT_NODEV => 'nodev',
|
23
|
+
MNT_UNION => 'union',
|
24
|
+
MNT_ASYNC => 'asynchronous',
|
25
|
+
MNT_CPROTECT => 'content-protection',
|
26
|
+
MNT_EXPORTED => 'exported',
|
27
|
+
MNT_QUARANTINE => 'quarantined',
|
28
|
+
MNT_LOCAL => 'local',
|
29
|
+
MNT_QUOTA => 'quotas',
|
30
|
+
MNT_ROOTFS => 'rootfs',
|
31
|
+
MNT_DONTBROWSE => 'nobrowse',
|
32
|
+
MNT_IGNORE_OWNERSHIP => 'noowners',
|
33
|
+
MNT_AUTOMOUNTED => 'automounted',
|
34
|
+
MNT_JOURNALED => 'journaled',
|
35
|
+
MNT_NOUSERXATTR => 'nouserxattr',
|
36
|
+
MNT_DEFWRITE => 'defwrite',
|
37
|
+
MNT_NOATIME => 'noatime'
|
38
|
+
}.freeze
|
39
|
+
|
40
|
+
private_constant :OPT_NAMES
|
41
|
+
|
42
|
+
# File used to read mount informtion from.
|
43
|
+
if File.exist?('/etc/mtab')
|
44
|
+
MOUNT_FILE = '/etc/mtab'.freeze
|
45
|
+
elsif File.exist?('/etc/mnttab')
|
46
|
+
MOUNT_FILE = '/etc/mnttab'.freeze
|
47
|
+
elsif File.exist?('/proc/mounts')
|
48
|
+
MOUNT_FILE = '/proc/mounts'.freeze
|
49
|
+
else
|
50
|
+
MOUNT_FILE = 'getmntinfo'.freeze
|
51
|
+
end
|
52
|
+
|
53
|
+
private_constant :MOUNT_FILE
|
54
|
+
|
55
|
+
# The error raised if any of the Filesystem methods fail.
|
56
|
+
class Error < StandardError; end
|
57
|
+
|
58
|
+
# Stat objects are returned by the CzSystemInfo::Filesystem.stat method.
|
59
|
+
class Stat
|
60
|
+
# Read-only filesystem
|
61
|
+
RDONLY = 1
|
62
|
+
|
63
|
+
# Filesystem does not support suid or sgid semantics.
|
64
|
+
NOSUID = 2
|
65
|
+
|
66
|
+
# Filesystem does not truncate file names longer than +name_max+.
|
67
|
+
NOTRUNC = 3
|
68
|
+
|
69
|
+
# The path of the filesystem.
|
70
|
+
attr_accessor :path
|
71
|
+
|
72
|
+
# The preferred system block size.
|
73
|
+
attr_accessor :block_size
|
74
|
+
|
75
|
+
# The fragment size, i.e. fundamental filesystem block size.
|
76
|
+
attr_accessor :fragment_size
|
77
|
+
|
78
|
+
# The total number of +fragment_size+ blocks in the filesystem.
|
79
|
+
attr_accessor :blocks
|
80
|
+
|
81
|
+
# The total number of free blocks in the filesystem.
|
82
|
+
attr_accessor :blocks_free
|
83
|
+
|
84
|
+
# The number of free blocks available to unprivileged processes.
|
85
|
+
attr_accessor :blocks_available
|
86
|
+
|
87
|
+
# The total number of files/inodes that can be created.
|
88
|
+
attr_accessor :files
|
89
|
+
|
90
|
+
# The total number of files/inodes on the filesystem.
|
91
|
+
attr_accessor :files_free
|
92
|
+
|
93
|
+
# The number of free files/inodes available to unprivileged processes.
|
94
|
+
attr_accessor :files_available
|
95
|
+
|
96
|
+
# The filesystem identifier.
|
97
|
+
attr_accessor :filesystem_id
|
98
|
+
|
99
|
+
# A bit mask of flags.
|
100
|
+
attr_accessor :flags
|
101
|
+
|
102
|
+
# The maximum length of a file name permitted on the filesystem.
|
103
|
+
attr_accessor :name_max
|
104
|
+
|
105
|
+
# The filesystem type, e.g. UFS.
|
106
|
+
attr_accessor :base_type
|
107
|
+
|
108
|
+
alias inodes files
|
109
|
+
alias inodes_free files_free
|
110
|
+
alias inodes_available files_available
|
111
|
+
|
112
|
+
# Creates a new CzSystemInfo::Filesystem::Stat object. This is meant for
|
113
|
+
# internal use only. Do not instantiate directly.
|
114
|
+
#
|
115
|
+
def initialize
|
116
|
+
@path = nil
|
117
|
+
@block_size = nil
|
118
|
+
@fragment_size = nil
|
119
|
+
@blocks = nil
|
120
|
+
@blocks_free = nil
|
121
|
+
@blocks_available = nil
|
122
|
+
@files = nil
|
123
|
+
@files_free = nil
|
124
|
+
@files_available = nil
|
125
|
+
@filesystem_id = nil
|
126
|
+
@flags = nil
|
127
|
+
@name_max = nil
|
128
|
+
@base_type = nil
|
129
|
+
end
|
130
|
+
|
131
|
+
# Returns the total space on the partition.
|
132
|
+
def bytes_total
|
133
|
+
blocks * fragment_size
|
134
|
+
end
|
135
|
+
|
136
|
+
# Returns the total amount of free space on the partition.
|
137
|
+
def bytes_free
|
138
|
+
blocks_free * fragment_size
|
139
|
+
end
|
140
|
+
|
141
|
+
# Returns the amount of free space available to unprivileged processes.
|
142
|
+
def bytes_available
|
143
|
+
blocks_available * fragment_size
|
144
|
+
end
|
145
|
+
|
146
|
+
# Returns the total amount of used space on the partition.
|
147
|
+
def bytes_used
|
148
|
+
bytes_total - bytes_free
|
149
|
+
end
|
150
|
+
|
151
|
+
# Returns the percentage of the partition that has been used.
|
152
|
+
def percent_used
|
153
|
+
100 - (100.0 * bytes_free.to_f / bytes_total.to_f)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
# Mount objects are returned by the CzSystemInfo::Filesystem.mounts method.
|
158
|
+
class Mount
|
159
|
+
# The name of the mounted resource.
|
160
|
+
attr_accessor :name
|
161
|
+
|
162
|
+
# The mount point/directory.
|
163
|
+
attr_accessor :mount_point
|
164
|
+
|
165
|
+
# The type of filesystem mount, e.g. ufs, nfs, etc.
|
166
|
+
attr_accessor :mount_type
|
167
|
+
|
168
|
+
# A list of comma separated options for the mount, e.g. nosuid, etc.
|
169
|
+
attr_accessor :options
|
170
|
+
|
171
|
+
# The time the filesystem was mounted. May be nil.
|
172
|
+
attr_accessor :mount_time
|
173
|
+
|
174
|
+
# The dump frequency in days. May be nil.
|
175
|
+
attr_accessor :dump_frequency
|
176
|
+
|
177
|
+
# The pass number of the filessytem check. May be nil.
|
178
|
+
attr_accessor :pass_number
|
179
|
+
|
180
|
+
alias fsname name
|
181
|
+
alias dir mount_point
|
182
|
+
alias opts options
|
183
|
+
alias passno pass_number
|
184
|
+
alias freq dump_frequency
|
185
|
+
|
186
|
+
# Creates a CzSystemInfo::Filesystem::Mount object. This is meant for internal
|
187
|
+
# use only. Do no instantiate directly.
|
188
|
+
#
|
189
|
+
def initialize
|
190
|
+
@name = nil
|
191
|
+
@mount_point = nil
|
192
|
+
@mount_type = nil
|
193
|
+
@options = nil
|
194
|
+
@mount_time = nil
|
195
|
+
@dump_frequency = nil
|
196
|
+
@pass_number = nil
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
# Returns a CzSystemInfo::Filesystem::Stat object containing information about the
|
201
|
+
# +path+ on the filesystem.
|
202
|
+
#
|
203
|
+
# Examples:
|
204
|
+
#
|
205
|
+
# # path
|
206
|
+
# CzSystemInfo::Filesystem.stat("path")
|
207
|
+
#
|
208
|
+
# # Pathname
|
209
|
+
# pathname = Pathname.new("path")
|
210
|
+
# CzSystemInfo::Filesystem.stat(pathname)
|
211
|
+
#
|
212
|
+
# # File
|
213
|
+
# file = File.open("file", "r")
|
214
|
+
# CzSystemInfo::Filesystem.stat(file)
|
215
|
+
#
|
216
|
+
# # Dir
|
217
|
+
# dir = Dir.open("/")
|
218
|
+
# CzSystemInfo::Filesystem.stat(dir)
|
219
|
+
#
|
220
|
+
def self.stat(path)
|
221
|
+
path = path.path if path.respond_to?(:path) # File, Dir
|
222
|
+
path = path.to_s if path.respond_to?(:to_s) # Pathname
|
223
|
+
|
224
|
+
fs = Statvfs.new
|
225
|
+
|
226
|
+
if statvfs(path, fs) < 0
|
227
|
+
raise Error, "statvfs() function failed: #{strerror(FFI.errno)}"
|
228
|
+
end
|
229
|
+
|
230
|
+
obj = CzSystemInfo::Filesystem::Stat.new
|
231
|
+
obj.path = path
|
232
|
+
obj.block_size = fs[:f_bsize]
|
233
|
+
obj.fragment_size = fs[:f_frsize]
|
234
|
+
obj.blocks = fs[:f_blocks]
|
235
|
+
obj.blocks_free = fs[:f_bfree]
|
236
|
+
obj.blocks_available = fs[:f_bavail]
|
237
|
+
obj.files = fs[:f_files]
|
238
|
+
obj.files_free = fs[:f_ffree]
|
239
|
+
obj.files_available = fs[:f_favail]
|
240
|
+
obj.filesystem_id = fs[:f_fsid]
|
241
|
+
obj.flags = fs[:f_flag]
|
242
|
+
obj.name_max = fs[:f_namemax]
|
243
|
+
|
244
|
+
# OSX does things a little differently
|
245
|
+
if RbConfig::CONFIG['host_os'] =~ /darwin|osx|mach/i
|
246
|
+
obj.block_size /= 256
|
247
|
+
end
|
248
|
+
|
249
|
+
if fs.members.include?(:f_basetype)
|
250
|
+
obj.base_type = fs[:f_basetype].to_s
|
251
|
+
end
|
252
|
+
|
253
|
+
obj.freeze
|
254
|
+
end
|
255
|
+
|
256
|
+
# In block form, yields a CzSystemInfo::Filesystem::Mount object for each mounted
|
257
|
+
# filesytem on the host. Otherwise it returns an array of Mount objects.
|
258
|
+
#
|
259
|
+
# Example:
|
260
|
+
#
|
261
|
+
# CzSystemInfo::Filesystem.mounts{ |fs|
|
262
|
+
# p fs.name # => '/dev/dsk/c0t0d0s0'
|
263
|
+
# p fs.mount_time # => Thu Dec 11 15:07:23 -0700 2008
|
264
|
+
# p fs.mount_type # => 'ufs'
|
265
|
+
# p fs.mount_point # => '/'
|
266
|
+
# p fs.options # => local, noowner, nosuid
|
267
|
+
# }
|
268
|
+
#
|
269
|
+
def self.mounts
|
270
|
+
array = block_given? ? nil : []
|
271
|
+
|
272
|
+
if respond_to?(:getmntinfo, true)
|
273
|
+
buf = FFI::MemoryPointer.new(:pointer)
|
274
|
+
|
275
|
+
num = getmntinfo(buf, 2)
|
276
|
+
|
277
|
+
if num == 0
|
278
|
+
raise Error, "getmntinfo() function failed: #{strerror(FFI.errno)}"
|
279
|
+
end
|
280
|
+
|
281
|
+
ptr = buf.get_pointer(0)
|
282
|
+
|
283
|
+
num.times do
|
284
|
+
mnt = Statfs.new(ptr)
|
285
|
+
obj = CzSystemInfo::Filesystem::Mount.new
|
286
|
+
obj.name = mnt[:f_mntfromname].to_s
|
287
|
+
obj.mount_point = mnt[:f_mntonname].to_s
|
288
|
+
obj.mount_type = mnt[:f_fstypename].to_s
|
289
|
+
|
290
|
+
string = ''
|
291
|
+
flags = mnt[:f_flags] & MNT_VISFLAGMASK
|
292
|
+
|
293
|
+
OPT_NAMES.each do |key, val|
|
294
|
+
if flags & key > 0
|
295
|
+
if string.empty?
|
296
|
+
string << val
|
297
|
+
else
|
298
|
+
string << ", #{val}"
|
299
|
+
end
|
300
|
+
end
|
301
|
+
flags &= ~key
|
302
|
+
end
|
303
|
+
|
304
|
+
obj.options = string
|
305
|
+
|
306
|
+
if block_given?
|
307
|
+
yield obj.freeze
|
308
|
+
else
|
309
|
+
array << obj.freeze
|
310
|
+
end
|
311
|
+
|
312
|
+
ptr += Statfs.size
|
313
|
+
end
|
314
|
+
else
|
315
|
+
begin
|
316
|
+
if respond_to?(:setmntent, true)
|
317
|
+
method_name = 'setmntent'
|
318
|
+
fp = setmntent(MOUNT_FILE, 'r')
|
319
|
+
else
|
320
|
+
method_name = 'fopen'
|
321
|
+
fp = fopen(MOUNT_FILE, 'r')
|
322
|
+
end
|
323
|
+
|
324
|
+
if fp.null?
|
325
|
+
raise SystemCallError.new(method_name, FFI.errno)
|
326
|
+
end
|
327
|
+
|
328
|
+
if RbConfig::CONFIG['host_os'] =~ /sunos|solaris/i
|
329
|
+
mt = Mnttab.new
|
330
|
+
while getmntent(fp, mt) == 0
|
331
|
+
obj = CzSystemInfo::Filesystem::Mount.new
|
332
|
+
obj.name = mt[:mnt_special].to_s
|
333
|
+
obj.mount_point = mt[:mnt_mountp].to_s
|
334
|
+
obj.mount_type = mt[:mnt_fstype].to_s
|
335
|
+
obj.options = mt[:mnt_mntopts].to_s
|
336
|
+
obj.mount_time = Time.at(Integer(mt[:mnt_time]))
|
337
|
+
|
338
|
+
if block_given?
|
339
|
+
yield obj.freeze
|
340
|
+
else
|
341
|
+
array << obj.freeze
|
342
|
+
end
|
343
|
+
end
|
344
|
+
else
|
345
|
+
while ptr = getmntent(fp)
|
346
|
+
break if ptr.null?
|
347
|
+
mt = Mntent.new(ptr)
|
348
|
+
|
349
|
+
obj = CzSystemInfo::Filesystem::Mount.new
|
350
|
+
obj.name = mt[:mnt_fsname]
|
351
|
+
obj.mount_point = mt[:mnt_dir]
|
352
|
+
obj.mount_type = mt[:mnt_type]
|
353
|
+
obj.options = mt[:mnt_opts]
|
354
|
+
obj.mount_time = nil
|
355
|
+
obj.dump_frequency = mt[:mnt_freq]
|
356
|
+
obj.pass_number = mt[:mnt_passno]
|
357
|
+
|
358
|
+
if block_given?
|
359
|
+
yield obj.freeze
|
360
|
+
else
|
361
|
+
array << obj.freeze
|
362
|
+
end
|
363
|
+
end
|
364
|
+
end
|
365
|
+
ensure
|
366
|
+
if fp && !fp.null?
|
367
|
+
if respond_to?(:endmntent, true)
|
368
|
+
endmntent(fp)
|
369
|
+
else
|
370
|
+
fclose(fp)
|
371
|
+
end
|
372
|
+
end
|
373
|
+
end
|
374
|
+
end
|
375
|
+
|
376
|
+
array
|
377
|
+
end
|
378
|
+
|
379
|
+
# Returns the mount point of the given +file+, or itself if it cannot
|
380
|
+
# be found.
|
381
|
+
#
|
382
|
+
# Example:
|
383
|
+
#
|
384
|
+
# CzSystemInfo::Filesystem.mount_point('/home/some_user') # => /home
|
385
|
+
#
|
386
|
+
def self.mount_point(file)
|
387
|
+
dev = File.stat(file).dev
|
388
|
+
val = file
|
389
|
+
|
390
|
+
mounts.each do |mnt|
|
391
|
+
mp = mnt.mount_point
|
392
|
+
begin
|
393
|
+
if File.stat(mp).dev == dev
|
394
|
+
val = mp
|
395
|
+
break
|
396
|
+
end
|
397
|
+
rescue Errno::EACCES
|
398
|
+
next
|
399
|
+
end
|
400
|
+
end
|
401
|
+
|
402
|
+
val
|
403
|
+
end
|
404
|
+
|
405
|
+
# Attach the filesystem specified by +source+ to the location (a directory
|
406
|
+
# or file) specified by the pathname in +target+.
|
407
|
+
#
|
408
|
+
# Note that the +source+ is often a pathname referring to a device, but
|
409
|
+
# can also be the pathname of a directory or file, or a dummy string.
|
410
|
+
#
|
411
|
+
# By default this method will assume 'ext2' as the filesystem type, but
|
412
|
+
# you should update this as needed.
|
413
|
+
#
|
414
|
+
# Typically requires admin privileges.
|
415
|
+
#
|
416
|
+
# Example:
|
417
|
+
#
|
418
|
+
# CzSystemInfo::Filesystem.mount('/dev/loop0', '/home/you/tmp', 'ext4', CzSystemInfo::Filesystem::MNT_RDONLY)
|
419
|
+
#
|
420
|
+
def self.mount(source, target, fstype = 'ext2', flags = 0, data = nil)
|
421
|
+
if mount_c(source, target, fstype, flags, data) != 0
|
422
|
+
raise Error, "mount() function failed: #{strerror(FFI.errno)}"
|
423
|
+
end
|
424
|
+
|
425
|
+
self
|
426
|
+
end
|
427
|
+
|
428
|
+
# Removes the attachment of the (topmost) filesystem mounted on target.
|
429
|
+
# Additional flags may be provided for operating systems that support
|
430
|
+
# the umount2 function. Otherwise this argument is ignored.
|
431
|
+
#
|
432
|
+
# Typically requires admin privileges.
|
433
|
+
#
|
434
|
+
def self.umount(target, flags = nil)
|
435
|
+
if flags && respond_to?(:umount2)
|
436
|
+
function = 'umount2'
|
437
|
+
rv = umount2_c(target, flags)
|
438
|
+
else
|
439
|
+
function = 'umount'
|
440
|
+
rv = umount_c(target)
|
441
|
+
end
|
442
|
+
|
443
|
+
if rv != 0
|
444
|
+
raise Error, "#{function} function failed: " + strerror(FFI.errno)
|
445
|
+
end
|
446
|
+
|
447
|
+
self
|
448
|
+
end
|
449
|
+
end
|
450
|
+
end
|