rswap 1.0.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/bin/rswap +8 -0
- data/ext/rswap/Makefile +273 -0
- data/ext/rswap/extconf.rb +15 -0
- data/ext/rswap/mkmf.log +20 -0
- data/ext/rswap/native.cpp +134 -0
- data/ext/rswap/native.o +0 -0
- data/ext/rswap/rswap_native.so +0 -0
- data/lib/rswap/cli.rb +175 -0
- data/lib/rswap/native.rb +53 -0
- data/lib/rswap/version.rb +4 -0
- data/lib/rswap.rb +11 -0
- metadata +95 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: c78cb324adbac507c04b943c46b09237530558ed55cda541c634ee87270e68ed
|
|
4
|
+
data.tar.gz: d3f9fe2c1c2e8ffe2ec1c23956ca4ef4b56a23883299f6ae3c38927d48f259b9
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 2e59db26877c8d3a54e802dbea279e21335fd154c49aadf539dca130a6171a4483da2fe0b5e19b78f95101785cff8ef64b502d2f88a7ab2800ad71a0cb504062
|
|
7
|
+
data.tar.gz: b84789bbd7c4c62fa9d25272a447f900f50787daf699345742e585cdcb39a425ea64c1525152bf0387f6697c52a0bfec4e1ca45e884343347e426a26d9468606
|
data/bin/rswap
ADDED
data/ext/rswap/Makefile
ADDED
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
|
|
2
|
+
SHELL = /bin/sh
|
|
3
|
+
|
|
4
|
+
# V=0 quiet, V=1 verbose. other values don't work.
|
|
5
|
+
V = 0
|
|
6
|
+
V0 = $(V:0=)
|
|
7
|
+
Q1 = $(V:1=)
|
|
8
|
+
Q = $(Q1:0=@)
|
|
9
|
+
ECHO1 = $(V:1=@ :)
|
|
10
|
+
ECHO = $(ECHO1:0=@ echo)
|
|
11
|
+
NULLCMD = :
|
|
12
|
+
|
|
13
|
+
#### Start of system configuration section. ####
|
|
14
|
+
|
|
15
|
+
srcdir = .
|
|
16
|
+
topdir = /usr/include/ruby-3.4.0
|
|
17
|
+
hdrdir = $(topdir)
|
|
18
|
+
arch_hdrdir = /usr/include/ruby-3.4.0/x86_64-linux
|
|
19
|
+
PATH_SEPARATOR = :
|
|
20
|
+
VPATH = $(srcdir):$(arch_hdrdir)/ruby:$(hdrdir)/ruby
|
|
21
|
+
prefix = $(DESTDIR)/usr
|
|
22
|
+
rubysitearchprefix = $(rubylibprefix)/$(sitearch)
|
|
23
|
+
rubyarchprefix = $(rubylibprefix)/$(arch)
|
|
24
|
+
rubylibprefix = $(libdir)/$(RUBY_BASE_NAME)
|
|
25
|
+
exec_prefix = $(prefix)
|
|
26
|
+
vendorarchhdrdir = $(vendorhdrdir)/$(sitearch)
|
|
27
|
+
sitearchhdrdir = $(sitehdrdir)/$(sitearch)
|
|
28
|
+
rubyarchhdrdir = $(rubyhdrdir)/$(arch)
|
|
29
|
+
vendorhdrdir = $(rubyhdrdir)/vendor_ruby
|
|
30
|
+
sitehdrdir = $(rubyhdrdir)/site_ruby
|
|
31
|
+
rubyhdrdir = $(includedir)/$(RUBY_VERSION_NAME)
|
|
32
|
+
vendorarchdir = $(vendorlibdir)/$(sitearch)
|
|
33
|
+
vendorlibdir = $(vendordir)/$(ruby_version)
|
|
34
|
+
vendordir = $(rubylibprefix)/vendor_ruby
|
|
35
|
+
sitearchdir = $(sitelibdir)/$(sitearch)
|
|
36
|
+
sitelibdir = $(sitedir)/$(ruby_version)
|
|
37
|
+
sitedir = $(rubylibprefix)/site_ruby
|
|
38
|
+
rubyarchdir = $(rubylibdir)/$(arch)
|
|
39
|
+
rubylibdir = $(rubylibprefix)/$(ruby_version)
|
|
40
|
+
sitearchincludedir = $(includedir)/$(sitearch)
|
|
41
|
+
archincludedir = $(includedir)/$(arch)
|
|
42
|
+
sitearchlibdir = $(libdir)/$(sitearch)
|
|
43
|
+
archlibdir = $(libdir)/$(arch)
|
|
44
|
+
ridir = $(datarootdir)/$(RI_BASE_NAME)
|
|
45
|
+
modular_gc_dir = $(DESTDIR)
|
|
46
|
+
mandir = $(DESTDIR)/usr/share/man
|
|
47
|
+
localedir = $(datarootdir)/locale
|
|
48
|
+
libdir = $(exec_prefix)/lib64
|
|
49
|
+
psdir = $(docdir)
|
|
50
|
+
pdfdir = $(docdir)
|
|
51
|
+
dvidir = $(docdir)
|
|
52
|
+
htmldir = $(docdir)
|
|
53
|
+
infodir = $(DESTDIR)/usr/share/info
|
|
54
|
+
docdir = $(datarootdir)/doc/$(PACKAGE)
|
|
55
|
+
oldincludedir = $(DESTDIR)/usr/include
|
|
56
|
+
includedir = $(prefix)/include
|
|
57
|
+
runstatedir = $(localstatedir)/run
|
|
58
|
+
localstatedir = $(DESTDIR)/var
|
|
59
|
+
sharedstatedir = $(prefix)/com
|
|
60
|
+
sysconfdir = $(DESTDIR)/etc
|
|
61
|
+
datadir = $(datarootdir)
|
|
62
|
+
datarootdir = $(prefix)/share
|
|
63
|
+
libexecdir = $(exec_prefix)/libexec
|
|
64
|
+
sbindir = $(DESTDIR)/usr/bin
|
|
65
|
+
bindir = $(exec_prefix)/bin
|
|
66
|
+
archdir = $(rubyarchdir)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
CC_WRAPPER =
|
|
70
|
+
CC = cc
|
|
71
|
+
CXX = g++
|
|
72
|
+
LIBRUBY = $(LIBRUBY_SO)
|
|
73
|
+
LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a
|
|
74
|
+
LIBRUBYARG_SHARED = -l$(RUBY_SO_NAME)
|
|
75
|
+
LIBRUBYARG_STATIC = -l$(RUBY_SO_NAME)-static $(MAINLIBS)
|
|
76
|
+
empty =
|
|
77
|
+
OUTFLAG = -o $(empty)
|
|
78
|
+
COUTFLAG = -o $(empty)
|
|
79
|
+
CSRCFLAG = $(empty)
|
|
80
|
+
|
|
81
|
+
RUBY_EXTCONF_H =
|
|
82
|
+
cflags = $(hardenflags) $(optflags) $(debugflags) $(warnflags)
|
|
83
|
+
cxxflags =
|
|
84
|
+
optflags = -O3 -fno-fast-math
|
|
85
|
+
debugflags = -ggdb3
|
|
86
|
+
warnflags = -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef
|
|
87
|
+
cppflags =
|
|
88
|
+
CCDLFLAGS = -fPIC
|
|
89
|
+
CFLAGS = $(CCDLFLAGS) -fstack-clash-protection -D_FORTIFY_SOURCE=2 -mtune=generic -O2 -pipe -g -ffile-prefix-map=/builddir/ruby-3.4.10=. -fPIC $(ARCH_FLAG)
|
|
90
|
+
INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir)/ruby/backward -I$(hdrdir) -I$(srcdir)
|
|
91
|
+
DEFS =
|
|
92
|
+
CPPFLAGS = $(DEFS) $(cppflags)
|
|
93
|
+
CXXFLAGS = $(CCDLFLAGS) -fstack-clash-protection -D_FORTIFY_SOURCE=2 -mtune=generic -O2 -pipe -g -ffile-prefix-map=/builddir/ruby-3.4.10=. -std=c++23 -fPIC $(ARCH_FLAG)
|
|
94
|
+
ldflags = -L. -Wl,-z,relro -Wl,-z,now -Wl,--as-needed -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -shared
|
|
95
|
+
dldflags = -Wl,-z,relro -Wl,-z,now -Wl,--as-needed -Wl,--compress-debug-sections=zlib
|
|
96
|
+
ARCH_FLAG =
|
|
97
|
+
DLDFLAGS = $(ldflags) $(dldflags) $(ARCH_FLAG)
|
|
98
|
+
LDSHARED = $(CC) -shared
|
|
99
|
+
LDSHAREDXX = $(CXX) -shared
|
|
100
|
+
POSTLINK = :
|
|
101
|
+
AR = ar
|
|
102
|
+
LD = ld
|
|
103
|
+
EXEEXT =
|
|
104
|
+
|
|
105
|
+
RUBY_INSTALL_NAME = $(RUBY_BASE_NAME)
|
|
106
|
+
RUBY_SO_NAME = ruby
|
|
107
|
+
RUBYW_INSTALL_NAME =
|
|
108
|
+
RUBY_VERSION_NAME = $(RUBY_BASE_NAME)-$(ruby_version)
|
|
109
|
+
RUBYW_BASE_NAME = rubyw
|
|
110
|
+
RUBY_BASE_NAME = ruby
|
|
111
|
+
|
|
112
|
+
arch = x86_64-linux
|
|
113
|
+
sitearch = $(arch)
|
|
114
|
+
ruby_version = 3.4.0
|
|
115
|
+
ruby = $(bindir)/$(RUBY_BASE_NAME)
|
|
116
|
+
RUBY = $(ruby)
|
|
117
|
+
BUILTRUBY = $(bindir)/$(RUBY_BASE_NAME)
|
|
118
|
+
ruby_headers = $(hdrdir)/ruby.h $(hdrdir)/ruby/backward.h $(hdrdir)/ruby/ruby.h $(hdrdir)/ruby/defines.h $(hdrdir)/ruby/missing.h $(hdrdir)/ruby/intern.h $(hdrdir)/ruby/st.h $(hdrdir)/ruby/subst.h $(arch_hdrdir)/ruby/config.h
|
|
119
|
+
|
|
120
|
+
RM = rm -f
|
|
121
|
+
RM_RF = rm -fr
|
|
122
|
+
RMDIRS = rmdir --ignore-fail-on-non-empty -p
|
|
123
|
+
MAKEDIRS = /usr/bin/mkdir -p
|
|
124
|
+
INSTALL = /usr/bin/install -c
|
|
125
|
+
INSTALL_PROG = $(INSTALL) -m 0755
|
|
126
|
+
INSTALL_DATA = $(INSTALL) -m 644
|
|
127
|
+
COPY = cp
|
|
128
|
+
TOUCH = exit >
|
|
129
|
+
|
|
130
|
+
#### End of system configuration section. ####
|
|
131
|
+
|
|
132
|
+
preload =
|
|
133
|
+
libpath = . $(libdir)
|
|
134
|
+
LIBPATH = -L. -L$(libdir)
|
|
135
|
+
DEFFILE =
|
|
136
|
+
|
|
137
|
+
CLEANFILES = mkmf.log
|
|
138
|
+
DISTCLEANFILES =
|
|
139
|
+
DISTCLEANDIRS =
|
|
140
|
+
|
|
141
|
+
extout =
|
|
142
|
+
extout_prefix =
|
|
143
|
+
target_prefix =
|
|
144
|
+
LOCAL_LIBS =
|
|
145
|
+
LIBS = $(LIBRUBYARG_SHARED) -lm -lpthread -lc
|
|
146
|
+
ORIG_SRCS = native.cpp
|
|
147
|
+
SRCS = $(ORIG_SRCS)
|
|
148
|
+
OBJS = native.o
|
|
149
|
+
HDRS =
|
|
150
|
+
LOCAL_HDRS =
|
|
151
|
+
TARGET = rswap_native
|
|
152
|
+
TARGET_NAME = rswap_native
|
|
153
|
+
TARGET_ENTRY = Init_$(TARGET_NAME)
|
|
154
|
+
DLLIB = $(TARGET).so
|
|
155
|
+
EXTSTATIC =
|
|
156
|
+
STATIC_LIB =
|
|
157
|
+
|
|
158
|
+
TIMESTAMP_DIR = .
|
|
159
|
+
BINDIR = $(bindir)
|
|
160
|
+
RUBYCOMMONDIR = $(sitedir)$(target_prefix)
|
|
161
|
+
RUBYLIBDIR = $(sitelibdir)$(target_prefix)
|
|
162
|
+
RUBYARCHDIR = $(sitearchdir)$(target_prefix)
|
|
163
|
+
HDRDIR = $(sitehdrdir)$(target_prefix)
|
|
164
|
+
ARCHHDRDIR = $(sitearchhdrdir)$(target_prefix)
|
|
165
|
+
TARGET_SO_DIR =
|
|
166
|
+
TARGET_SO = $(TARGET_SO_DIR)$(DLLIB)
|
|
167
|
+
CLEANLIBS = $(TARGET_SO) false
|
|
168
|
+
CLEANOBJS = $(OBJS) *.bak
|
|
169
|
+
TARGET_SO_DIR_TIMESTAMP = $(TIMESTAMP_DIR)/.sitearchdir.time
|
|
170
|
+
|
|
171
|
+
all: $(DLLIB)
|
|
172
|
+
static: $(STATIC_LIB)
|
|
173
|
+
.PHONY: all install static install-so install-rb
|
|
174
|
+
.PHONY: clean clean-so clean-static clean-rb
|
|
175
|
+
|
|
176
|
+
clean-static::
|
|
177
|
+
clean-rb-default::
|
|
178
|
+
clean-rb::
|
|
179
|
+
clean-so::
|
|
180
|
+
clean: clean-so clean-static clean-rb-default clean-rb
|
|
181
|
+
-$(Q)$(RM_RF) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES) .*.time
|
|
182
|
+
|
|
183
|
+
distclean-rb-default::
|
|
184
|
+
distclean-rb::
|
|
185
|
+
distclean-so::
|
|
186
|
+
distclean-static::
|
|
187
|
+
distclean: clean distclean-so distclean-static distclean-rb-default distclean-rb
|
|
188
|
+
-$(Q)$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log
|
|
189
|
+
-$(Q)$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES)
|
|
190
|
+
-$(Q)$(RMDIRS) $(DISTCLEANDIRS) 2> /dev/null || true
|
|
191
|
+
|
|
192
|
+
realclean: distclean
|
|
193
|
+
install: install-so install-rb
|
|
194
|
+
|
|
195
|
+
install-so: $(DLLIB) $(TARGET_SO_DIR_TIMESTAMP)
|
|
196
|
+
$(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR)
|
|
197
|
+
clean-static::
|
|
198
|
+
-$(Q)$(RM) $(STATIC_LIB)
|
|
199
|
+
install-rb: pre-install-rb do-install-rb install-rb-default
|
|
200
|
+
install-rb-default: pre-install-rb-default do-install-rb-default
|
|
201
|
+
pre-install-rb: Makefile
|
|
202
|
+
pre-install-rb-default: Makefile
|
|
203
|
+
do-install-rb:
|
|
204
|
+
do-install-rb-default:
|
|
205
|
+
pre-install-rb-default:
|
|
206
|
+
@$(NULLCMD)
|
|
207
|
+
$(TARGET_SO_DIR_TIMESTAMP):
|
|
208
|
+
$(Q) $(MAKEDIRS) $(@D) $(RUBYARCHDIR)
|
|
209
|
+
$(Q) $(TOUCH) $@
|
|
210
|
+
|
|
211
|
+
site-install: site-install-so site-install-rb
|
|
212
|
+
site-install-so: install-so
|
|
213
|
+
site-install-rb: install-rb
|
|
214
|
+
|
|
215
|
+
.SUFFIXES: .c .m .cc .mm .cxx .cpp .o .S
|
|
216
|
+
|
|
217
|
+
.cc.o:
|
|
218
|
+
$(ECHO) compiling $(<)
|
|
219
|
+
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$<
|
|
220
|
+
|
|
221
|
+
.cc.S:
|
|
222
|
+
$(ECHO) translating $(<)
|
|
223
|
+
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$<
|
|
224
|
+
|
|
225
|
+
.mm.o:
|
|
226
|
+
$(ECHO) compiling $(<)
|
|
227
|
+
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$<
|
|
228
|
+
|
|
229
|
+
.mm.S:
|
|
230
|
+
$(ECHO) translating $(<)
|
|
231
|
+
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$<
|
|
232
|
+
|
|
233
|
+
.cxx.o:
|
|
234
|
+
$(ECHO) compiling $(<)
|
|
235
|
+
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$<
|
|
236
|
+
|
|
237
|
+
.cxx.S:
|
|
238
|
+
$(ECHO) translating $(<)
|
|
239
|
+
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$<
|
|
240
|
+
|
|
241
|
+
.cpp.o:
|
|
242
|
+
$(ECHO) compiling $(<)
|
|
243
|
+
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$<
|
|
244
|
+
|
|
245
|
+
.cpp.S:
|
|
246
|
+
$(ECHO) translating $(<)
|
|
247
|
+
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$<
|
|
248
|
+
|
|
249
|
+
.c.o:
|
|
250
|
+
$(ECHO) compiling $(<)
|
|
251
|
+
$(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$<
|
|
252
|
+
|
|
253
|
+
.c.S:
|
|
254
|
+
$(ECHO) translating $(<)
|
|
255
|
+
$(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$<
|
|
256
|
+
|
|
257
|
+
.m.o:
|
|
258
|
+
$(ECHO) compiling $(<)
|
|
259
|
+
$(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$<
|
|
260
|
+
|
|
261
|
+
.m.S:
|
|
262
|
+
$(ECHO) translating $(<)
|
|
263
|
+
$(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$<
|
|
264
|
+
|
|
265
|
+
$(TARGET_SO): $(OBJS) Makefile
|
|
266
|
+
$(ECHO) linking shared-object $(DLLIB)
|
|
267
|
+
-$(Q)$(RM) $(@)
|
|
268
|
+
$(Q) $(LDSHAREDXX) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS)
|
|
269
|
+
$(Q) $(POSTLINK)
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
$(OBJS): $(HDRS) $(ruby_headers)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# ext/rswap/extconf.rb
|
|
3
|
+
require 'mkmf'
|
|
4
|
+
|
|
5
|
+
if try_compile('int main(){ return 0; }', '-std=c++23')
|
|
6
|
+
$CXXFLAGS << ' -std=c++23'
|
|
7
|
+
else
|
|
8
|
+
abort 'C++23 compiler required'
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# Position independent code for shared library
|
|
12
|
+
$CXXFLAGS << ' -fPIC'
|
|
13
|
+
$LDFLAGS << ' -shared'
|
|
14
|
+
|
|
15
|
+
create_makefile('rswap_native')
|
data/ext/rswap/mkmf.log
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
LD_LIBRARY_PATH=.:/usr/lib64 ASAN_OPTIONS=detect_leaks=0 "cc -o conftest -I/usr/include/ruby-3.4.0/x86_64-linux -I/usr/include/ruby-3.4.0/ruby/backward -I/usr/include/ruby-3.4.0 -I. -fstack-clash-protection -D_FORTIFY_SOURCE=2 -mtune=generic -O2 -pipe -g -ffile-prefix-map=/builddir/ruby-3.4.10=. -fPIC conftest.c -L. -L/usr/lib64 -L. -Wl,-z,relro -Wl,-z,now -Wl,--as-needed -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lruby -lm -lpthread -lc"
|
|
2
|
+
checked program was:
|
|
3
|
+
/* begin */
|
|
4
|
+
1: #include "ruby.h"
|
|
5
|
+
2:
|
|
6
|
+
3: int main(int argc, char **argv)
|
|
7
|
+
4: {
|
|
8
|
+
5: return !!argv[argc];
|
|
9
|
+
6: }
|
|
10
|
+
/* end */
|
|
11
|
+
|
|
12
|
+
LD_LIBRARY_PATH=.:/usr/lib64 ASAN_OPTIONS=detect_leaks=0 "cc -I/usr/include/ruby-3.4.0/x86_64-linux -I/usr/include/ruby-3.4.0/ruby/backward -I/usr/include/ruby-3.4.0 -I. -fstack-clash-protection -D_FORTIFY_SOURCE=2 -mtune=generic -O2 -pipe -g -ffile-prefix-map=/builddir/ruby-3.4.10=. -fPIC -std=c++23 -c conftest.c"
|
|
13
|
+
cc1: warning: command-line option '-std=c++23' is valid for C++/ObjC++ but not for C
|
|
14
|
+
checked program was:
|
|
15
|
+
/* begin */
|
|
16
|
+
1: #include "ruby.h"
|
|
17
|
+
2:
|
|
18
|
+
3: int main(){ return 0; }
|
|
19
|
+
/* end */
|
|
20
|
+
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
// ext/rswap/native.cpp
|
|
2
|
+
// C++ Backend - 8 exported functions
|
|
3
|
+
#include <cstdlib>
|
|
4
|
+
#include <cstring>
|
|
5
|
+
#include <filesystem>
|
|
6
|
+
#include <fstream>
|
|
7
|
+
#include <memory>
|
|
8
|
+
#include <sstream>
|
|
9
|
+
|
|
10
|
+
namespace fs = std::filesystem;
|
|
11
|
+
|
|
12
|
+
constexpr ssize_t SIZE = 1024 * 1024;
|
|
13
|
+
|
|
14
|
+
struct Ctrl {
|
|
15
|
+
std::string path;
|
|
16
|
+
explicit Ctrl(const char* p) : path(p ? p : "") {}
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
struct SwapInfo {
|
|
20
|
+
bool active = false;
|
|
21
|
+
long long used = 0;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
// Helper: Parse /proc/swaps for swap status and memory usage
|
|
25
|
+
SwapInfo get_swap_info(const std::string& path) {
|
|
26
|
+
SwapInfo info;
|
|
27
|
+
std::ifstream p("/proc/swaps");
|
|
28
|
+
if (!p.is_open()) return info;
|
|
29
|
+
|
|
30
|
+
std::string line;
|
|
31
|
+
while (std::getline(p, line)) {
|
|
32
|
+
if (line.find(path) != std::string::npos) {
|
|
33
|
+
std::istringstream s(line);
|
|
34
|
+
std::string f, t;
|
|
35
|
+
ssize_t sz, used;
|
|
36
|
+
int pri;
|
|
37
|
+
if (s >> f >> t >> sz >> used >> pri) {
|
|
38
|
+
info.active = true;
|
|
39
|
+
info.used = static_cast<long long>(used) * 1024;
|
|
40
|
+
}
|
|
41
|
+
break;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return info;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Helper: System command execution
|
|
48
|
+
int exec_cmd(const std::string& cmd) {
|
|
49
|
+
return std::system(cmd.c_str()) == 0 ? 0 : 2;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
extern "C" {
|
|
53
|
+
|
|
54
|
+
Ctrl* swap_new(const char* path) {
|
|
55
|
+
if (!path) return nullptr;
|
|
56
|
+
try {
|
|
57
|
+
auto ctrl = std::make_unique<Ctrl>(path);
|
|
58
|
+
return ctrl.release();
|
|
59
|
+
} catch (...) {
|
|
60
|
+
return nullptr;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
void swap_free(const Ctrl* c) {
|
|
65
|
+
delete c;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
int swap_create(Ctrl* c, ssize_t bytes) {
|
|
69
|
+
if (!c || c->path.empty()) return 1;
|
|
70
|
+
if (fs::exists(c->path)) return 5;
|
|
71
|
+
|
|
72
|
+
std::string bytes_str = std::to_string(bytes);
|
|
73
|
+
std::string mb_str = std::to_string(bytes / SIZE);
|
|
74
|
+
|
|
75
|
+
// 1. Create empty file (touch)
|
|
76
|
+
// 2. Set NOCOW (+C) for Btrfs filesystems before writing data
|
|
77
|
+
// 3. Allocate file space via fallocate (fallback to dd)
|
|
78
|
+
// 4. Restrict permissions (chmod 600)
|
|
79
|
+
// 5. Format as swap space (mkswap)
|
|
80
|
+
std::string cmd =
|
|
81
|
+
"touch '" + c->path + "' && "
|
|
82
|
+
"chattr +C '" + c->path + "' 2>/dev/null; "
|
|
83
|
+
"(fallocate -l " + bytes_str + " '" + c->path + "' 2>/dev/null || "
|
|
84
|
+
"dd if=/dev/zero of='" + c->path + "' bs=1M count=" + mb_str + " status=none) && "
|
|
85
|
+
"chmod 600 '" + c->path + "' && "
|
|
86
|
+
"mkswap '" + c->path + "'";
|
|
87
|
+
|
|
88
|
+
return exec_cmd(cmd);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
int swap_enable(Ctrl* c) {
|
|
92
|
+
if (!c || c->path.empty()) return 1;
|
|
93
|
+
return exec_cmd("swapon '" + c->path + "' 2>/dev/null");
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
int swap_disable(Ctrl* c) {
|
|
97
|
+
if (!c || c->path.empty()) return 1;
|
|
98
|
+
|
|
99
|
+
auto info = get_swap_info(c->path);
|
|
100
|
+
if (!info.active) return 4;
|
|
101
|
+
|
|
102
|
+
return exec_cmd("swapoff '" + c->path + "' 2>/dev/null");
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
int swap_remove(Ctrl* c) {
|
|
106
|
+
if (!c || c->path.empty()) return 1;
|
|
107
|
+
std::error_code ec;
|
|
108
|
+
return fs::remove(c->path, ec) ? 0 : 6;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
char* swap_status(Ctrl* c) {
|
|
112
|
+
if (!c || c->path.empty()) return strdup("{}");
|
|
113
|
+
|
|
114
|
+
auto info = get_swap_info(c->path);
|
|
115
|
+
bool exists = fs::exists(c->path);
|
|
116
|
+
std::uintmax_t file_sz = exists ? fs::file_size(c->path) : 0;
|
|
117
|
+
|
|
118
|
+
std::ostringstream j;
|
|
119
|
+
j << "{"
|
|
120
|
+
<< "\"p\":\"" << c->path << "\","
|
|
121
|
+
<< "\"x\":" << (exists ? "true" : "false") << ","
|
|
122
|
+
<< "\"s\":" << (exists ? static_cast<long long>(file_sz) : -1) << ","
|
|
123
|
+
<< "\"a\":" << (info.active ? "true" : "false") << ","
|
|
124
|
+
<< "\"u\":" << info.used
|
|
125
|
+
<< "}";
|
|
126
|
+
|
|
127
|
+
return strdup(j.str().c_str());
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
void swap_free_str(char* s) {
|
|
131
|
+
free(s);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
} // extern "C"
|
data/ext/rswap/native.o
ADDED
|
Binary file
|
|
Binary file
|
data/lib/rswap/cli.rb
ADDED
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'rainbow'
|
|
4
|
+
require 'optparse'
|
|
5
|
+
require_relative 'native'
|
|
6
|
+
|
|
7
|
+
module Rswap
|
|
8
|
+
class CLI
|
|
9
|
+
HELP = <<~USAGE
|
|
10
|
+
Usage: rswap <command> [options]
|
|
11
|
+
|
|
12
|
+
Commands:
|
|
13
|
+
add [SIZE] Create and enable swap (default: 8GB)
|
|
14
|
+
on Enable existing swap
|
|
15
|
+
off Disable existing swap
|
|
16
|
+
status Show current state
|
|
17
|
+
|
|
18
|
+
Options:
|
|
19
|
+
--swapfile PATH Path to swap file (default: /swapfile)
|
|
20
|
+
USAGE
|
|
21
|
+
|
|
22
|
+
ERR = {
|
|
23
|
+
0 => 'OK',
|
|
24
|
+
1 => 'internal error',
|
|
25
|
+
2 => 'command failed',
|
|
26
|
+
3 => 'cannot read /proc/swaps',
|
|
27
|
+
4 => 'already disabled',
|
|
28
|
+
5 => 'file exists',
|
|
29
|
+
6 => 'remove failed'
|
|
30
|
+
}.freeze
|
|
31
|
+
|
|
32
|
+
def self.run(argv)
|
|
33
|
+
sf = '/swapfile'
|
|
34
|
+
|
|
35
|
+
parser = OptionParser.new do |opts|
|
|
36
|
+
opts.on('--swapfile PATH') { |path| sf = path }
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
begin
|
|
40
|
+
parser.order!(argv)
|
|
41
|
+
rescue OptionParser::InvalidOption => e
|
|
42
|
+
puts Rainbow("ERR: #{e.message}").red
|
|
43
|
+
exit 1
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
cmd = argv.shift
|
|
47
|
+
if cmd.nil?
|
|
48
|
+
puts HELP
|
|
49
|
+
exit 1
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
c = Rswap::Native::Ctrl.new(sf)
|
|
53
|
+
|
|
54
|
+
case cmd
|
|
55
|
+
when 'add' then add(c, argv[0] || '8GB')
|
|
56
|
+
when 'on' then on(c)
|
|
57
|
+
when 'off' then off(c)
|
|
58
|
+
when 'status' then status(c)
|
|
59
|
+
else
|
|
60
|
+
puts Rainbow("ERR: unknown '#{cmd}'").red
|
|
61
|
+
puts 'Valid: add, on, off, status'
|
|
62
|
+
exit 1
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def self.add(c, sz)
|
|
67
|
+
bytes = parse(sz)
|
|
68
|
+
st = c.status
|
|
69
|
+
size_h = human(bytes)
|
|
70
|
+
|
|
71
|
+
case st
|
|
72
|
+
in { x: true, s: ^bytes }
|
|
73
|
+
puts Rainbow("OK: exists (#{size_h})").green
|
|
74
|
+
return
|
|
75
|
+
in { x: true, s: cur } if cur != bytes
|
|
76
|
+
puts Rainbow("WARN: size mismatch (#{human(cur)} vs #{size_h})").yellow
|
|
77
|
+
print 'Remove and recreate? [y/N]: '
|
|
78
|
+
return unless $stdin.gets.chomp.downcase == 'y'
|
|
79
|
+
|
|
80
|
+
# if active -> disable and remove
|
|
81
|
+
c.disable if st[:a]
|
|
82
|
+
|
|
83
|
+
if c.remove != 0
|
|
84
|
+
puts Rainbow('ERR: failed to remove existing swapfile').red
|
|
85
|
+
return
|
|
86
|
+
end
|
|
87
|
+
else
|
|
88
|
+
# Hey
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
case [c.create(bytes), c.enable]
|
|
92
|
+
in [0, 0]
|
|
93
|
+
puts Rainbow("OK: created + enabled (#{size_h})").green
|
|
94
|
+
in [0, e]
|
|
95
|
+
puts Rainbow("ERR: created but enable failed: #{ERR[e]}").red
|
|
96
|
+
in [cr, _]
|
|
97
|
+
puts Rainbow("ERR: create failed: #{ERR[cr]}").red
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def self.on(c)
|
|
102
|
+
st = c.status
|
|
103
|
+
|
|
104
|
+
case st
|
|
105
|
+
in { x: false }
|
|
106
|
+
puts Rainbow('ERR: file not found').red
|
|
107
|
+
in { a: true }
|
|
108
|
+
puts Rainbow('OK: already active').green
|
|
109
|
+
else
|
|
110
|
+
case c.enable
|
|
111
|
+
in 0 then puts Rainbow('OK: enabled').green
|
|
112
|
+
in e then puts Rainbow("ERR: #{ERR[e]}").red
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def self.off(c)
|
|
118
|
+
st = c.status
|
|
119
|
+
|
|
120
|
+
case st
|
|
121
|
+
in { x: false }
|
|
122
|
+
puts Rainbow('ERR: file not found').red
|
|
123
|
+
in { a: false }
|
|
124
|
+
puts Rainbow('OK: already off').green
|
|
125
|
+
in { a: true, u: usage } if usage && usage > 0
|
|
126
|
+
puts Rainbow("WARN: #{human(usage)} in use").yellow
|
|
127
|
+
case c.disable
|
|
128
|
+
in 0 then puts Rainbow('OK: off').green
|
|
129
|
+
in e then puts Rainbow("ERR: #{ERR[e]} (tty: sudo swapoff -a)").red
|
|
130
|
+
end
|
|
131
|
+
in { a: true }
|
|
132
|
+
case c.disable
|
|
133
|
+
in 0 then puts Rainbow('OK: off').green
|
|
134
|
+
in e then puts Rainbow("ERR: #{ERR[e]} (tty: sudo swapoff -a)").red
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def self.status(c)
|
|
140
|
+
st = c.status
|
|
141
|
+
|
|
142
|
+
puts Rainbow('--- Swap ---').bright
|
|
143
|
+
puts "Path: #{st[:p]}"
|
|
144
|
+
puts "Exists: #{st[:x] ? 'yes' : 'no'}"
|
|
145
|
+
puts "Size: #{human(st[:s])}" if st[:s] && st[:s] > 0
|
|
146
|
+
|
|
147
|
+
case st[:a]
|
|
148
|
+
in true then puts "Active: #{Rainbow('yes').green}"
|
|
149
|
+
in false then puts "Active: #{Rainbow('no').red}"
|
|
150
|
+
else puts "Active: #{Rainbow('no').red}"
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
puts "Usage: #{human(st[:u])}" if st[:u] && st[:u] >= 0
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def self.human(b)
|
|
157
|
+
case b
|
|
158
|
+
when nil, 0 then '0B'
|
|
159
|
+
when (1024**3..) then sprintf('%.2fGB', b.to_f / 1024**3)
|
|
160
|
+
when (1024**2..) then sprintf('%.2fMB', b.to_f / 1024**2)
|
|
161
|
+
when (1024..) then sprintf('%.2fKB', b.to_f / 1024)
|
|
162
|
+
else "#{b}B"
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def self.parse(s)
|
|
167
|
+
case s.to_s.upcase
|
|
168
|
+
when /^([\d.]+)GB?$/ then ($1.to_f * 1024**3).to_i
|
|
169
|
+
when /^([\d.]+)MB?$/ then ($1.to_f * 1024**2).to_i
|
|
170
|
+
when /^([\d.]+)KB?$/ then ($1.to_f * 1024).to_i
|
|
171
|
+
else s.to_i
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
end
|
data/lib/rswap/native.rb
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'ffi'
|
|
4
|
+
require 'json'
|
|
5
|
+
|
|
6
|
+
module Rswap
|
|
7
|
+
module Native
|
|
8
|
+
extend FFI::Library
|
|
9
|
+
|
|
10
|
+
lib_dir = File.expand_path('../../ext/rswap', __dir__)
|
|
11
|
+
ffi_lib File.join(lib_dir, 'rswap_native.so')
|
|
12
|
+
|
|
13
|
+
attach_function :swap_new, [:string], :pointer
|
|
14
|
+
attach_function :swap_free, [:pointer], :void
|
|
15
|
+
attach_function :swap_create, [:pointer, :ssize_t], :int
|
|
16
|
+
attach_function :swap_enable, [:pointer], :int
|
|
17
|
+
attach_function :swap_disable, [:pointer], :int
|
|
18
|
+
attach_function :swap_remove, [:pointer], :int
|
|
19
|
+
attach_function :swap_status, [:pointer], :pointer
|
|
20
|
+
attach_function :swap_free_str, [:pointer], :void
|
|
21
|
+
|
|
22
|
+
class Ctrl
|
|
23
|
+
def initialize(path)
|
|
24
|
+
@p = Native.swap_new(path)
|
|
25
|
+
raise 'init failed' if @p.null?
|
|
26
|
+
|
|
27
|
+
ObjectSpace.define_finalizer(self, self.class.finalizer(@p))
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def self.finalizer(p)
|
|
31
|
+
proc { Native.swap_free(p) }
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def create(sz) = Native.swap_create(@p, sz)
|
|
35
|
+
def enable = Native.swap_enable(@p)
|
|
36
|
+
def disable = Native.swap_disable(@p)
|
|
37
|
+
def remove = Native.swap_remove(@p)
|
|
38
|
+
|
|
39
|
+
def status
|
|
40
|
+
ptr = Native.swap_status(@p)
|
|
41
|
+
return {} if ptr.null?
|
|
42
|
+
|
|
43
|
+
begin
|
|
44
|
+
json_str = ptr.read_string
|
|
45
|
+
JSON.parse(json_str, symbolize_names: true)
|
|
46
|
+
ensure
|
|
47
|
+
Native.swap_free_str(ptr)
|
|
48
|
+
# The C++ side frees up the memory that was accessed via strdup to prevent memory leaks.
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
data/lib/rswap.rb
ADDED
metadata
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: rswap
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- KennedySilverDollar
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: ffi
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '1.17'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '1.17'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: rainbow
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - "~>"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '3.1'
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '3.1'
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: rake
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - "~>"
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '13.0'
|
|
47
|
+
type: :development
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - "~>"
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '13.0'
|
|
54
|
+
description: Create/enable/disable rswap files with extreme efficiency
|
|
55
|
+
email:
|
|
56
|
+
- kenshinlights@tutamail.com
|
|
57
|
+
executables:
|
|
58
|
+
- rswap
|
|
59
|
+
extensions:
|
|
60
|
+
- ext/rswap/extconf.rb
|
|
61
|
+
extra_rdoc_files: []
|
|
62
|
+
files:
|
|
63
|
+
- bin/rswap
|
|
64
|
+
- ext/rswap/Makefile
|
|
65
|
+
- ext/rswap/extconf.rb
|
|
66
|
+
- ext/rswap/mkmf.log
|
|
67
|
+
- ext/rswap/native.cpp
|
|
68
|
+
- ext/rswap/native.o
|
|
69
|
+
- ext/rswap/rswap_native.so
|
|
70
|
+
- lib/rswap.rb
|
|
71
|
+
- lib/rswap/cli.rb
|
|
72
|
+
- lib/rswap/native.rb
|
|
73
|
+
- lib/rswap/version.rb
|
|
74
|
+
homepage: https://github.com/KennedySilverDollar/rswap-tool
|
|
75
|
+
licenses:
|
|
76
|
+
- MIT
|
|
77
|
+
metadata: {}
|
|
78
|
+
rdoc_options: []
|
|
79
|
+
require_paths:
|
|
80
|
+
- lib
|
|
81
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
82
|
+
requirements:
|
|
83
|
+
- - ">="
|
|
84
|
+
- !ruby/object:Gem::Version
|
|
85
|
+
version: 3.0.0
|
|
86
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
87
|
+
requirements:
|
|
88
|
+
- - ">="
|
|
89
|
+
- !ruby/object:Gem::Version
|
|
90
|
+
version: '0'
|
|
91
|
+
requirements: []
|
|
92
|
+
rubygems_version: 3.6.9
|
|
93
|
+
specification_version: 4
|
|
94
|
+
summary: Minimal rswap manager with C++23 backend
|
|
95
|
+
test_files: []
|