2 * Copyright 2005, Axel Dörfler, axeld@pinc-software.de
3 * All rights reserved. Distributed under the terms of the MIT License.
5 * Copyright 2010-2012 Haiku, Inc. All rights reserved.
6 * Distributed under the terms of the MIT License.
9 * Hamish Morrison, hamish@lavabit.com
10 * Alexander von Gluck, kallisti5@unixzen.com
20 #include <AutoDeleter.h>
22 #include <FindDirectory.h>
24 #include <VolumeRoster.h>
26 #include <driver_settings.h>
29 static const char* const kWindowSettingsFile
= "virtualmemory_preferences";
30 static const char* const kVirtualMemorySettings
= "virtual_memory";
31 static const off_t kMegaByte
= 1024 * 1024;
32 static const off_t kGigaByte
= kMegaByte
* 1024;
37 fDefaultSettings
.enabled
= true;
38 fDefaultSettings
.automatic
= true;
41 get_system_info(&sysInfo
);
43 fDefaultSettings
.size
= (off_t
)sysInfo
.max_pages
* B_PAGE_SIZE
;
44 if (fDefaultSettings
.size
<= kGigaByte
) {
45 // Memory under 1GB? double the swap
46 // This matches the behaviour of the kernel
47 fDefaultSettings
.size
*= 2;
50 fDefaultSettings
.volume
= dev_for_path("/boot");
55 Settings::SetSwapEnabled(bool enabled
, bool revertable
)
57 fCurrentSettings
.enabled
= enabled
;
59 fInitialSettings
.enabled
= enabled
;
64 Settings::SetSwapAutomatic(bool automatic
, bool revertable
)
66 fCurrentSettings
.automatic
= automatic
;
68 fInitialSettings
.automatic
= automatic
;
73 Settings::SetSwapSize(off_t size
, bool revertable
)
75 fCurrentSettings
.size
= size
;
77 fInitialSettings
.size
= size
;
82 Settings::SetSwapVolume(dev_t volume
, bool revertable
)
84 fCurrentSettings
.volume
= volume
;
86 fInitialSettings
.volume
= volume
;
92 Settings::SetWindowPosition(BPoint position
)
94 fWindowPosition
= position
;
99 Settings::ReadWindowSettings()
102 if (find_directory(B_USER_SETTINGS_DIRECTORY
, &path
) != B_OK
)
105 path
.Append(kWindowSettingsFile
);
107 if (file
.SetTo(path
.Path(), B_READ_ONLY
) != B_OK
)
110 if (file
.Read(&fWindowPosition
, sizeof(BPoint
)) == sizeof(BPoint
))
118 Settings::WriteWindowSettings()
121 if (find_directory(B_USER_SETTINGS_DIRECTORY
, &path
) < B_OK
)
124 path
.Append(kWindowSettingsFile
);
127 if (file
.SetTo(path
.Path(), B_WRITE_ONLY
| B_CREATE_FILE
| B_ERASE_FILE
)
131 file
.Write(&fWindowPosition
, sizeof(BPoint
));
137 Settings::ReadSwapSettings()
139 void* settings
= load_driver_settings(kVirtualMemorySettings
);
140 if (settings
== NULL
)
141 return kErrorSettingsNotFound
;
142 CObjectDeleter
<void, status_t
> settingDeleter(settings
,
143 &unload_driver_settings
);
145 const char* enabled
= get_driver_parameter(settings
, "vm", NULL
, NULL
);
146 const char* automatic
= get_driver_parameter(settings
, "swap_auto",
148 const char* size
= get_driver_parameter(settings
, "swap_size", NULL
, NULL
);
149 const char* volume
= get_driver_parameter(settings
, "swap_volume_name",
151 const char* device
= get_driver_parameter(settings
,
152 "swap_volume_device", NULL
, NULL
);
153 const char* filesystem
= get_driver_parameter(settings
,
154 "swap_volume_filesystem", NULL
, NULL
);
155 const char* capacity
= get_driver_parameter(settings
,
156 "swap_volume_capacity", NULL
, NULL
);
158 if (enabled
== NULL
|| automatic
== NULL
|| size
== NULL
|| device
== NULL
159 || volume
== NULL
|| capacity
== NULL
|| filesystem
== NULL
)
160 return kErrorSettingsInvalid
;
162 off_t volCapacity
= atoll(capacity
);
164 SetSwapEnabled(get_driver_boolean_parameter(settings
,
166 SetSwapAutomatic(get_driver_boolean_parameter(settings
,
167 "swap_auto", true, false));
168 SetSwapSize(atoll(size
));
170 int32 bestScore
= -1;
175 BVolumeRoster roster
;
176 while (roster
.GetNextVolume(&vol
) == B_OK
) {
177 if (!vol
.IsPersistent() || vol
.IsReadOnly() || vol
.IsRemovable()
180 if (fs_stat_dev(vol
.Device(), &volStat
) == 0) {
182 if (strcmp(volume
, volStat
.volume_name
) == 0)
184 if (strcmp(device
, volStat
.device_name
) == 0)
186 if (volCapacity
== volStat
.total_blocks
* volStat
.block_size
)
188 if (strcmp(filesystem
, volStat
.fsh_name
) == 0)
190 if (score
>= 4 && score
> bestScore
) {
191 bestVol
= vol
.Device();
197 SetSwapVolume(bestVol
);
198 fInitialSettings
= fCurrentSettings
;
201 return kErrorVolumeNotFound
;
208 Settings::WriteSwapSettings()
211 if (find_directory(B_USER_SETTINGS_DIRECTORY
, &path
) != B_OK
)
214 path
.Append("kernel/drivers");
215 path
.Append(kVirtualMemorySettings
);
218 if (file
.SetTo(path
.Path(), B_WRITE_ONLY
| B_CREATE_FILE
| B_ERASE_FILE
)
223 if (fs_stat_dev(SwapVolume(), &info
) != 0)
227 snprintf(buffer
, sizeof(buffer
), "vm %s\nswap_auto %s\nswap_size %"
228 B_PRIdOFF
"\nswap_volume_name %s\nswap_volume_device %s\n"
229 "swap_volume_filesystem %s\nswap_volume_capacity %" B_PRIdOFF
"\n",
230 SwapEnabled() ? "on" : "off", SwapAutomatic() ? "yes" : "no",
231 SwapSize(), info
.volume_name
, info
.device_name
, info
.fsh_name
,
232 info
.total_blocks
* info
.block_size
);
234 file
.Write(buffer
, strlen(buffer
));
240 Settings::IsRevertable()
242 return SwapEnabled() != fInitialSettings
.enabled
243 || SwapAutomatic() != fInitialSettings
.automatic
244 || SwapSize() != fInitialSettings
.size
245 || SwapVolume() != fInitialSettings
.volume
;
250 Settings::RevertSwapSettings()
252 SetSwapEnabled(fInitialSettings
.enabled
);
253 SetSwapAutomatic(fInitialSettings
.automatic
);
254 SetSwapSize(fInitialSettings
.size
);
255 SetSwapVolume(fInitialSettings
.volume
);
260 Settings::IsDefaultable()
262 return SwapEnabled() != fDefaultSettings
.enabled
263 || SwapAutomatic() != fDefaultSettings
.automatic
264 || SwapSize() != fDefaultSettings
.size
265 || SwapVolume() != fDefaultSettings
.volume
;
270 Settings::DefaultSwapSettings(bool revertable
)
272 SetSwapEnabled(fDefaultSettings
.enabled
);
273 SetSwapAutomatic(fDefaultSettings
.automatic
);
274 SetSwapSize(fDefaultSettings
.size
);
275 SetSwapVolume(fDefaultSettings
.volume
);
277 fInitialSettings
= fDefaultSettings
;