Skip to content

Commit

Permalink
pool: allow max disksize to be specified as percent of filesystem
Browse files Browse the repository at this point in the history
Motivation:
To avoid disk dise miscalculations, it will be useful if pool is
configured not with an absolute pool size, but with a percentage of
available space.

Modification:
Update `set max diskspace` to accept percentage. Update space
calculation to use percentage of filesystems total size, if configured.

Result:
simplified pool configuration

```
set max diskspace 94%
...
Limits for maximum disk space
    File system (limit)  : 547735052288 (94%)
    Statically configured: -
    Runtime configured   : -
```

Acked-by: Dmitry Litvintsev
Target: master
Require-book: no
Require-notes: yes
  • Loading branch information
kofemann committed Dec 4, 2024
1 parent 103bfeb commit 8c71927
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ public class RepositoryData implements Serializable {
private Long fileSystemMaxSpace;
private Long staticallyConfiguredMax;
private Long runtimeConfiguredMax;
private Integer percentage;
private Long gap;
private Long lru;

Expand Down Expand Up @@ -176,6 +177,14 @@ public Double getUsedDiskSpaceRatio() {
return usedDiskSpaceRatio;
}

public Integer getPercentage() {
return percentage;
}

public void setPercentage(Integer percentage) {
this.percentage = percentage;
}

public void print(PrintWriter pw) {
pw.append("State : ").append(String.valueOf(state));
if (initializationProgress != null) {
Expand Down Expand Up @@ -205,7 +214,8 @@ public void print(PrintWriter pw) {
pw.println(" Free : " + fileSystemFree +
" [" + fileSystemRatioFreeToTotal + "]");
pw.println("Limits for maximum disk space");
pw.println(" File system : " + fileSystemMaxSpace);
pw.println(" File system (limit) : " + fileSystemMaxSpace + " ("
+ (percentage == null ? "100" : percentage.toString())+"%)");
pw.println(" Statically configured: " + (staticallyConfiguredMax == null ? "-"
: staticallyConfiguredMax.toString()));
pw.println(" Runtime configured : " + (runtimeConfiguredMax == null ? "-"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.OptionalInt;
import java.util.OptionalLong;
import java.util.Set;
import java.util.concurrent.ArrayBlockingQueue;
Expand Down Expand Up @@ -223,6 +224,11 @@ enum State {
@GuardedBy("_stateLock")
private DiskSpace _runtimeMaxSize = DiskSpace.UNSPECIFIED;

/**
* Whatever the pool size is a factor of the total disk space.
*/
private OptionalInt _diskPercentage = OptionalInt.empty();

/**
* Pool size configured in the configuration files.
*/
Expand Down Expand Up @@ -1005,6 +1011,7 @@ public synchronized RepositoryData getDataObject() {
info.setFileSystemFree(fsFree);
info.setFileSystemRatioFreeToTotal(((double) fsFree) / fsTotal);
info.setFileSystemMaxSpace(fsFree + used);
_diskPercentage.ifPresent(p -> info.setPercentage(p));
info.setStaticallyConfiguredMax(
_staticMaxSize.isSpecified() ? _staticMaxSize.longValue() : null);
info.setRuntimeConfiguredMax(
Expand Down Expand Up @@ -1174,16 +1181,30 @@ public void run() {
"executed.")
class SetMaxDiskspaceCommand implements Callable<String> {

@Argument(valueSpec = "-|BYTES[k|m|g|t]",
usage = "Disk space in bytes, kibibytes, mebibytes, gibibytes, or tebibytes. If " +
"- is specified, then the pool will return to the size configured in " +
@Argument(valueSpec = "-|BYTES[k|m|g|t|%]",
usage = "Disk space in bytes, kibibytes, mebibytes, gibibytes, tebibytes or percentage of physical partition." +
"If - is specified, then the pool will return to the size configured in " +
"the configuration file, or no maximum if such a size is not defined.")
DiskSpace size;
String sizeStr;

@Override
public String call() throws IllegalArgumentException {
_stateLock.writeLock().lock();
try {

DiskSpace size;
if (sizeStr.charAt(sizeStr.length() -1) == '%') {
int percent = Integer.parseInt(sizeStr.substring(0, sizeStr.length() - 1));
if (percent < 1 || percent > 100) {
throw new IllegalArgumentException("Percentage must be between 1 and 100");
}
_diskPercentage = OptionalInt.of(percent);
size = DiskSpace.UNSPECIFIED;
} else {
_diskPercentage = OptionalInt.empty();
size = new DiskSpace(sizeStr);
}

_runtimeMaxSize = size;
if (_state == State.OPEN) {
updateAccountSize();
Expand Down Expand Up @@ -1245,7 +1266,11 @@ public void printSetup(PrintWriter pw) {
}

if (runtimeMaxSize.isSpecified()) {
pw.println("set max diskspace " + runtimeMaxSize);
if (_diskPercentage.isPresent()) {
pw.println("set max diskspace " + _diskPercentage.getAsInt() + "%");
} else {
pw.println("set max diskspace " + runtimeMaxSize);
}
}
if (gap.isSpecified()) {
pw.println("set gap " + gap);
Expand All @@ -1255,6 +1280,13 @@ public void printSetup(PrintWriter pw) {
private DiskSpace getConfiguredMaxSize() {
_stateLock.readLock().lock();
try {

if (_diskPercentage.isPresent()) {
long total = _store.getTotalSpace();
double percentFactor = _diskPercentage.getAsInt()*0.01;
return new DiskSpace((long) (total * percentFactor));
}

return _runtimeMaxSize.orElse(_staticMaxSize);
} finally {
_stateLock.readLock().unlock();
Expand Down

0 comments on commit 8c71927

Please sign in to comment.