mirror of https://github.com/apache/cassandra
Merge branch 'cassandra-3.11' into trunk
This commit is contained in:
commit
91c5f4c28d
|
|
@ -65,6 +65,7 @@
|
|||
* NoReplicationTokenAllocator should work with zero replication factor (CASSANDRA-12983)
|
||||
* Address message coalescing regression (CASSANDRA-12676)
|
||||
Merged from 3.0:
|
||||
* Use the Kernel32 library to retrieve the PID on Windows and fix startup checks (CASSANDRA-13333)
|
||||
* Fix code to not exchange schema across major versions (CASSANDRA-13274)
|
||||
* Dropping column results in "corrupt" SSTable (CASSANDRA-13337)
|
||||
* Bugs handling range tombstones in the sstable iterators (CASSANDRA-13340)
|
||||
|
|
|
|||
3
NEWS.txt
3
NEWS.txt
|
|
@ -54,6 +54,9 @@ Upgrading
|
|||
|
||||
Upgrading
|
||||
---------
|
||||
- The NativeAccessMBean isAvailable method will only return true if the
|
||||
native library has been successfully linked. Previously it was returning
|
||||
true if JNA could be found but was not taking into account link failures.
|
||||
- Primary ranges in the system.size_estimates table are now based on the keyspace
|
||||
replication settings and adjacent ranges are no longer merged (CASSANDRA-9639).
|
||||
- In 2.1, the default for otc_coalescing_strategy was 'DISABLED'.
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ import org.apache.cassandra.io.util.FileUtils;
|
|||
import org.apache.cassandra.schema.Schema;
|
||||
import org.apache.cassandra.schema.TableId;
|
||||
import org.apache.cassandra.schema.TableMetadata;
|
||||
import org.apache.cassandra.utils.CLibrary;
|
||||
import org.apache.cassandra.utils.NativeLibrary;
|
||||
import org.apache.cassandra.utils.IntegerInterval;
|
||||
import org.apache.cassandra.utils.concurrent.OpOrder;
|
||||
import org.apache.cassandra.utils.concurrent.WaitQueue;
|
||||
|
|
@ -164,7 +164,7 @@ public abstract class CommitLogSegment
|
|||
try
|
||||
{
|
||||
channel = FileChannel.open(logFile.toPath(), StandardOpenOption.WRITE, StandardOpenOption.READ, StandardOpenOption.CREATE);
|
||||
fd = CLibrary.getfd(channel);
|
||||
fd = NativeLibrary.getfd(channel);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ import java.nio.channels.FileChannel;
|
|||
import org.apache.cassandra.config.DatabaseDescriptor;
|
||||
import org.apache.cassandra.io.FSWriteError;
|
||||
import org.apache.cassandra.io.util.FileUtils;
|
||||
import org.apache.cassandra.utils.CLibrary;
|
||||
import org.apache.cassandra.utils.NativeLibrary;
|
||||
import org.apache.cassandra.utils.SyncUtil;
|
||||
|
||||
/*
|
||||
|
|
@ -86,7 +86,7 @@ public class MemoryMappedSegment extends CommitLogSegment
|
|||
{
|
||||
throw new FSWriteError(e, getPath());
|
||||
}
|
||||
CLibrary.trySkipCache(fd, startMarker, nextMarker, logFile.getAbsolutePath());
|
||||
NativeLibrary.trySkipCache(fd, startMarker, nextMarker, logFile.getAbsolutePath());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
|
||||
import org.apache.cassandra.io.util.FileUtils;
|
||||
import org.apache.cassandra.utils.CLibrary;
|
||||
import org.apache.cassandra.utils.NativeLibrary;
|
||||
|
||||
/**
|
||||
* Because a column family may have sstables on different disks and disks can
|
||||
|
|
@ -45,12 +45,12 @@ final class LogReplica implements AutoCloseable
|
|||
|
||||
static LogReplica create(File directory, String fileName)
|
||||
{
|
||||
return new LogReplica(new File(fileName), CLibrary.tryOpenDirectory(directory.getPath()));
|
||||
return new LogReplica(new File(fileName), NativeLibrary.tryOpenDirectory(directory.getPath()));
|
||||
}
|
||||
|
||||
static LogReplica open(File file)
|
||||
{
|
||||
return new LogReplica(file, CLibrary.tryOpenDirectory(file.getParentFile().getPath()));
|
||||
return new LogReplica(file, NativeLibrary.tryOpenDirectory(file.getParentFile().getPath()));
|
||||
}
|
||||
|
||||
LogReplica(File file, int directoryDescriptor)
|
||||
|
|
@ -93,7 +93,7 @@ final class LogReplica implements AutoCloseable
|
|||
void syncDirectory()
|
||||
{
|
||||
if (directoryDescriptor >= 0)
|
||||
CLibrary.trySync(directoryDescriptor);
|
||||
NativeLibrary.trySync(directoryDescriptor);
|
||||
}
|
||||
|
||||
void delete()
|
||||
|
|
@ -111,7 +111,7 @@ final class LogReplica implements AutoCloseable
|
|||
{
|
||||
if (directoryDescriptor >= 0)
|
||||
{
|
||||
CLibrary.tryCloseFD(directoryDescriptor);
|
||||
NativeLibrary.tryCloseFD(directoryDescriptor);
|
||||
directoryDescriptor = -1;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ import com.google.common.base.Preconditions;
|
|||
|
||||
import org.apache.cassandra.io.compress.BufferType;
|
||||
import org.apache.cassandra.io.util.*;
|
||||
import org.apache.cassandra.utils.CLibrary;
|
||||
import org.apache.cassandra.utils.NativeLibrary;
|
||||
import org.apache.cassandra.utils.memory.BufferPool;
|
||||
|
||||
/**
|
||||
|
|
@ -215,7 +215,7 @@ public class ChecksummedDataInput extends RebufferingInputStream
|
|||
|
||||
public void tryUncacheRead()
|
||||
{
|
||||
CLibrary.trySkipCache(getChannel().getFileDescriptor(), 0, getSourcePosition(), getPath());
|
||||
NativeLibrary.trySkipCache(getChannel().getFileDescriptor(), 0, getSourcePosition(), getPath());
|
||||
}
|
||||
|
||||
private void updateCrc()
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ import java.util.stream.Stream;
|
|||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
import org.apache.cassandra.io.FSReadError;
|
||||
import org.apache.cassandra.utils.CLibrary;
|
||||
import org.apache.cassandra.utils.NativeLibrary;
|
||||
import org.apache.cassandra.utils.SyncUtil;
|
||||
|
||||
import static java.util.stream.Collectors.groupingBy;
|
||||
|
|
@ -130,11 +130,11 @@ final class HintsCatalog
|
|||
|
||||
void fsyncDirectory()
|
||||
{
|
||||
int fd = CLibrary.tryOpenDirectory(hintsDirectory.getAbsolutePath());
|
||||
int fd = NativeLibrary.tryOpenDirectory(hintsDirectory.getAbsolutePath());
|
||||
if (fd != -1)
|
||||
{
|
||||
SyncUtil.trySync(fd);
|
||||
CLibrary.tryCloseFD(fd);
|
||||
NativeLibrary.tryCloseFD(fd);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ import org.apache.cassandra.config.DatabaseDescriptor;
|
|||
import org.apache.cassandra.io.FSWriteError;
|
||||
import org.apache.cassandra.io.util.DataOutputBuffer;
|
||||
import org.apache.cassandra.io.util.DataOutputBufferFixed;
|
||||
import org.apache.cassandra.utils.CLibrary;
|
||||
import org.apache.cassandra.utils.NativeLibrary;
|
||||
import org.apache.cassandra.utils.SyncUtil;
|
||||
import org.apache.cassandra.utils.Throwables;
|
||||
|
||||
|
|
@ -70,7 +70,7 @@ class HintsWriter implements AutoCloseable
|
|||
File file = new File(directory, descriptor.fileName());
|
||||
|
||||
FileChannel channel = FileChannel.open(file.toPath(), StandardOpenOption.WRITE, StandardOpenOption.CREATE_NEW);
|
||||
int fd = CLibrary.getfd(channel);
|
||||
int fd = NativeLibrary.getfd(channel);
|
||||
|
||||
CRC32 crc = new CRC32();
|
||||
|
||||
|
|
@ -289,7 +289,7 @@ class HintsWriter implements AutoCloseable
|
|||
// don't skip page cache for tiny files, on the assumption that if they are tiny, the target node is probably
|
||||
// alive, and if so, the file will be closed and dispatched shortly (within a minute), and the file will be dropped.
|
||||
if (position >= DatabaseDescriptor.getTrickleFsyncIntervalInKb() * 1024L)
|
||||
CLibrary.trySkipCache(fd, 0, position - (position % PAGE_SIZE), file.getPath());
|
||||
NativeLibrary.trySkipCache(fd, 0, position - (position % PAGE_SIZE), file.getPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ import org.apache.cassandra.db.rows.UnfilteredRowIterator;
|
|||
import org.apache.cassandra.io.sstable.format.SSTableReader;
|
||||
import org.apache.cassandra.io.sstable.format.SSTableWriter;
|
||||
import org.apache.cassandra.db.lifecycle.LifecycleTransaction;
|
||||
import org.apache.cassandra.utils.CLibrary;
|
||||
import org.apache.cassandra.utils.NativeLibrary;
|
||||
import org.apache.cassandra.utils.concurrent.Transactional;
|
||||
|
||||
/**
|
||||
|
|
@ -171,7 +171,7 @@ public class SSTableRewriter extends Transactional.AbstractTransactional impleme
|
|||
for (SSTableReader reader : transaction.originals())
|
||||
{
|
||||
RowIndexEntry index = reader.getPosition(key, SSTableReader.Operator.GE);
|
||||
CLibrary.trySkipCache(reader.getFilename(), 0, index == null ? 0 : index.position);
|
||||
NativeLibrary.trySkipCache(reader.getFilename(), 0, index == null ? 0 : index.position);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -2243,8 +2243,8 @@ public abstract class SSTableReader extends SSTable implements SelfRefCounted<SS
|
|||
obsoletion.run();
|
||||
|
||||
// don't ideally want to dropPageCache for the file until all instances have been released
|
||||
CLibrary.trySkipCache(desc.filenameFor(Component.DATA), 0, 0);
|
||||
CLibrary.trySkipCache(desc.filenameFor(Component.PRIMARY_INDEX), 0, 0);
|
||||
NativeLibrary.trySkipCache(desc.filenameFor(Component.DATA), 0, 0);
|
||||
NativeLibrary.trySkipCache(desc.filenameFor(Component.PRIMARY_INDEX), 0, 0);
|
||||
}
|
||||
|
||||
public String name()
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ import java.nio.channels.WritableByteChannel;
|
|||
import java.nio.file.StandardOpenOption;
|
||||
|
||||
import org.apache.cassandra.io.FSReadError;
|
||||
import org.apache.cassandra.utils.CLibrary;
|
||||
import org.apache.cassandra.utils.NativeLibrary;
|
||||
import org.apache.cassandra.utils.concurrent.RefCounted;
|
||||
import org.apache.cassandra.utils.concurrent.SharedCloseableImpl;
|
||||
|
||||
|
|
@ -172,7 +172,7 @@ public final class ChannelProxy extends SharedCloseableImpl
|
|||
|
||||
public int getFileDescriptor()
|
||||
{
|
||||
return CLibrary.getfd(channel);
|
||||
return NativeLibrary.getfd(channel);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ import org.slf4j.LoggerFactory;
|
|||
import org.apache.cassandra.cache.ChunkCache;
|
||||
import org.apache.cassandra.io.compress.BufferType;
|
||||
import org.apache.cassandra.io.compress.CompressionMetadata;
|
||||
import org.apache.cassandra.utils.CLibrary;
|
||||
import org.apache.cassandra.utils.NativeLibrary;
|
||||
import org.apache.cassandra.utils.concurrent.Ref;
|
||||
import org.apache.cassandra.utils.concurrent.RefCounted;
|
||||
import org.apache.cassandra.utils.concurrent.SharedCloseableImpl;
|
||||
|
|
@ -164,7 +164,7 @@ public class FileHandle extends SharedCloseableImpl
|
|||
else
|
||||
return metadata.chunkFor(before).offset;
|
||||
}).orElse(before);
|
||||
CLibrary.trySkipCache(channel.getFileDescriptor(), 0, position, path());
|
||||
NativeLibrary.trySkipCache(channel.getFileDescriptor(), 0, position, path());
|
||||
}
|
||||
|
||||
private Rebufferer instantiateRebufferer(RateLimiter limiter)
|
||||
|
|
|
|||
|
|
@ -188,7 +188,7 @@ public class CassandraDaemon
|
|||
|
||||
logSystemInfo();
|
||||
|
||||
CLibrary.tryMlockall();
|
||||
NativeLibrary.tryMlockall();
|
||||
|
||||
try
|
||||
{
|
||||
|
|
@ -669,12 +669,12 @@ public class CassandraDaemon
|
|||
{
|
||||
public boolean isAvailable()
|
||||
{
|
||||
return CLibrary.jnaAvailable();
|
||||
return NativeLibrary.isAvailable();
|
||||
}
|
||||
|
||||
public boolean isMemoryLockable()
|
||||
{
|
||||
return CLibrary.jnaMemoryLockable();
|
||||
return NativeLibrary.jnaMemoryLockable();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ import org.apache.cassandra.exceptions.ConfigurationException;
|
|||
import org.apache.cassandra.exceptions.StartupException;
|
||||
import org.apache.cassandra.io.sstable.Descriptor;
|
||||
import org.apache.cassandra.io.util.FileUtils;
|
||||
import org.apache.cassandra.utils.CLibrary;
|
||||
import org.apache.cassandra.utils.NativeLibrary;
|
||||
import org.apache.cassandra.utils.FBUtilities;
|
||||
import org.apache.cassandra.utils.SigarLibrary;
|
||||
|
||||
|
|
@ -80,7 +80,7 @@ public class StartupChecks
|
|||
checkJMXPorts,
|
||||
checkJMXProperties,
|
||||
inspectJvmOptions,
|
||||
checkJnaInitialization,
|
||||
checkNativeLibraryInitialization,
|
||||
initSigarLibrary,
|
||||
checkMaxMapCount,
|
||||
checkDataDirs,
|
||||
|
|
@ -203,13 +203,13 @@ public class StartupChecks
|
|||
}
|
||||
};
|
||||
|
||||
public static final StartupCheck checkJnaInitialization = new StartupCheck()
|
||||
public static final StartupCheck checkNativeLibraryInitialization = new StartupCheck()
|
||||
{
|
||||
public void execute() throws StartupException
|
||||
{
|
||||
// Fail-fast if JNA is not available or failing to initialize properly
|
||||
if (!CLibrary.jnaAvailable())
|
||||
throw new StartupException(StartupException.ERR_WRONG_MACHINE_STATE, "JNA failing to initialize properly. ");
|
||||
// Fail-fast if the native library could not be linked.
|
||||
if (!NativeLibrary.isAvailable())
|
||||
throw new StartupException(StartupException.ERR_WRONG_MACHINE_STATE, "The native library could not be initialized properly. ");
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -169,7 +169,7 @@ public final class HeapUtils
|
|||
*/
|
||||
private static Long getProcessId()
|
||||
{
|
||||
long pid = CLibrary.getProcessID();
|
||||
long pid = NativeLibrary.getProcessID();
|
||||
if (pid >= 0)
|
||||
return pid;
|
||||
|
||||
|
|
|
|||
|
|
@ -31,14 +31,14 @@ import org.slf4j.LoggerFactory;
|
|||
import com.sun.jna.LastErrorException;
|
||||
import sun.nio.ch.FileChannelImpl;
|
||||
|
||||
import static org.apache.cassandra.utils.CLibrary.OSType.LINUX;
|
||||
import static org.apache.cassandra.utils.CLibrary.OSType.MAC;
|
||||
import static org.apache.cassandra.utils.CLibrary.OSType.WINDOWS;
|
||||
import static org.apache.cassandra.utils.CLibrary.OSType.AIX;
|
||||
import static org.apache.cassandra.utils.NativeLibrary.OSType.LINUX;
|
||||
import static org.apache.cassandra.utils.NativeLibrary.OSType.MAC;
|
||||
import static org.apache.cassandra.utils.NativeLibrary.OSType.WINDOWS;
|
||||
import static org.apache.cassandra.utils.NativeLibrary.OSType.AIX;
|
||||
|
||||
public final class CLibrary
|
||||
public final class NativeLibrary
|
||||
{
|
||||
private static final Logger logger = LoggerFactory.getLogger(CLibrary.class);
|
||||
private static final Logger logger = LoggerFactory.getLogger(NativeLibrary.class);
|
||||
|
||||
public enum OSType
|
||||
{
|
||||
|
|
@ -69,7 +69,7 @@ public final class CLibrary
|
|||
private static final int POSIX_FADV_DONTNEED = 4; /* fadvise.h */
|
||||
private static final int POSIX_FADV_NOREUSE = 5; /* fadvise.h */
|
||||
|
||||
private static final CLibraryWrapper wrappedCLibrary;
|
||||
private static final NativeLibraryWrapper wrappedLibrary;
|
||||
private static boolean jnaLockable = false;
|
||||
|
||||
private static final Field FILE_DESCRIPTOR_FD_FIELD;
|
||||
|
|
@ -85,12 +85,12 @@ public final class CLibrary
|
|||
osType = getOsType();
|
||||
switch (osType)
|
||||
{
|
||||
case MAC: wrappedCLibrary = new CLibraryDarwin(); break;
|
||||
case WINDOWS: wrappedCLibrary = new CLibraryWindows(); break;
|
||||
case MAC: wrappedLibrary = new NativeLibraryDarwin(); break;
|
||||
case WINDOWS: wrappedLibrary = new NativeLibraryWindows(); break;
|
||||
case LINUX:
|
||||
case AIX:
|
||||
case OTHER:
|
||||
default: wrappedCLibrary = new CLibraryLinux();
|
||||
default: wrappedLibrary = new NativeLibraryLinux();
|
||||
}
|
||||
|
||||
if (System.getProperty("os.arch").toLowerCase().contains("ppc"))
|
||||
|
|
@ -118,7 +118,7 @@ public final class CLibrary
|
|||
}
|
||||
}
|
||||
|
||||
private CLibrary() {}
|
||||
private NativeLibrary() {}
|
||||
|
||||
/**
|
||||
* @return the detected OSType of the Operating System running the JVM using crude string matching
|
||||
|
|
@ -155,9 +155,13 @@ public final class CLibrary
|
|||
}
|
||||
}
|
||||
|
||||
public static boolean jnaAvailable()
|
||||
/**
|
||||
* Checks if the library has been successfully linked.
|
||||
* @return {@code true} if the library has been successfully linked, {@code false} otherwise.
|
||||
*/
|
||||
public static boolean isAvailable()
|
||||
{
|
||||
return wrappedCLibrary.jnaAvailable();
|
||||
return wrappedLibrary.isAvailable();
|
||||
}
|
||||
|
||||
public static boolean jnaMemoryLockable()
|
||||
|
|
@ -169,7 +173,7 @@ public final class CLibrary
|
|||
{
|
||||
try
|
||||
{
|
||||
wrappedCLibrary.callMlockall(MCL_CURRENT);
|
||||
wrappedLibrary.callMlockall(MCL_CURRENT);
|
||||
jnaLockable = true;
|
||||
logger.info("JNA mlockall successful");
|
||||
}
|
||||
|
|
@ -235,14 +239,14 @@ public final class CLibrary
|
|||
{
|
||||
if (osType == LINUX)
|
||||
{
|
||||
int result = wrappedCLibrary.callPosixFadvise(fd, offset, len, POSIX_FADV_DONTNEED);
|
||||
int result = wrappedLibrary.callPosixFadvise(fd, offset, len, POSIX_FADV_DONTNEED);
|
||||
if (result != 0)
|
||||
NoSpamLogger.log(
|
||||
logger,
|
||||
NoSpamLogger.Level.WARN,
|
||||
10,
|
||||
TimeUnit.MINUTES,
|
||||
"Failed trySkipCache on file: {} Error: " + wrappedCLibrary.callStrerror(result).getString(0),
|
||||
"Failed trySkipCache on file: {} Error: " + wrappedLibrary.callStrerror(result).getString(0),
|
||||
path);
|
||||
}
|
||||
}
|
||||
|
|
@ -267,7 +271,7 @@ public final class CLibrary
|
|||
|
||||
try
|
||||
{
|
||||
result = wrappedCLibrary.callFcntl(fd, command, flags);
|
||||
result = wrappedLibrary.callFcntl(fd, command, flags);
|
||||
}
|
||||
catch (UnsatisfiedLinkError e)
|
||||
{
|
||||
|
|
@ -290,7 +294,7 @@ public final class CLibrary
|
|||
|
||||
try
|
||||
{
|
||||
return wrappedCLibrary.callOpen(path, O_RDONLY);
|
||||
return wrappedLibrary.callOpen(path, O_RDONLY);
|
||||
}
|
||||
catch (UnsatisfiedLinkError e)
|
||||
{
|
||||
|
|
@ -314,7 +318,7 @@ public final class CLibrary
|
|||
|
||||
try
|
||||
{
|
||||
wrappedCLibrary.callFsync(fd);
|
||||
wrappedLibrary.callFsync(fd);
|
||||
}
|
||||
catch (UnsatisfiedLinkError e)
|
||||
{
|
||||
|
|
@ -336,7 +340,7 @@ public final class CLibrary
|
|||
|
||||
try
|
||||
{
|
||||
wrappedCLibrary.callClose(fd);
|
||||
wrappedLibrary.callClose(fd);
|
||||
}
|
||||
catch (UnsatisfiedLinkError e)
|
||||
{
|
||||
|
|
@ -391,7 +395,7 @@ public final class CLibrary
|
|||
{
|
||||
try
|
||||
{
|
||||
return wrappedCLibrary.callGetpid();
|
||||
return wrappedLibrary.callGetpid();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
|
@ -26,7 +26,7 @@ import com.sun.jna.Native;
|
|||
import com.sun.jna.Pointer;
|
||||
|
||||
/**
|
||||
* A CLibraryWrapper implementation for Darwin/Mac.
|
||||
* A {@code NativeLibraryWrapper} implementation for Darwin/Mac.
|
||||
* <p>
|
||||
* When JNA is initialized, all methods that have the 'native' keyword
|
||||
* will be attmpted to be linked against. As Java doesn't have the equivalent
|
||||
|
|
@ -37,35 +37,33 @@ import com.sun.jna.Pointer;
|
|||
* native calls that are supported on that target operating system will be
|
||||
* unavailable simply because of one native defined method not supported
|
||||
* on the runtime operating system.
|
||||
* @see org.apache.cassandra.utils.CLibraryWrapper
|
||||
* @see CLibrary
|
||||
* @see org.apache.cassandra.utils.NativeLibraryWrapper
|
||||
* @see NativeLibrary
|
||||
*/
|
||||
public class CLibraryDarwin implements CLibraryWrapper
|
||||
public class NativeLibraryDarwin implements NativeLibraryWrapper
|
||||
{
|
||||
private static final Logger logger = LoggerFactory.getLogger(CLibraryDarwin.class);
|
||||
private static final Logger logger = LoggerFactory.getLogger(NativeLibraryDarwin.class);
|
||||
|
||||
private static boolean jnaAvailable = true;
|
||||
private static boolean available;
|
||||
|
||||
static
|
||||
{
|
||||
try
|
||||
{
|
||||
Native.register("c");
|
||||
available = true;
|
||||
}
|
||||
catch (NoClassDefFoundError e)
|
||||
{
|
||||
logger.warn("JNA not found. Native methods will be disabled.");
|
||||
jnaAvailable = false;
|
||||
}
|
||||
catch (UnsatisfiedLinkError e)
|
||||
{
|
||||
logger.warn("JNA link failure, one or more native method will be unavailable.");
|
||||
logger.error("JNA link failure details: {}", e.getMessage());
|
||||
logger.error("Failed to link the C library against JNA. Native methods will be unavailable.", e);
|
||||
}
|
||||
catch (NoSuchMethodError e)
|
||||
{
|
||||
logger.warn("Obsolete version of JNA present; unable to register C library. Upgrade to JNA 3.2.7 or later");
|
||||
jnaAvailable = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -124,8 +122,8 @@ public class CLibraryDarwin implements CLibraryWrapper
|
|||
return getpid();
|
||||
}
|
||||
|
||||
public boolean jnaAvailable()
|
||||
public boolean isAvailable()
|
||||
{
|
||||
return jnaAvailable;
|
||||
return available;
|
||||
}
|
||||
}
|
||||
|
|
@ -26,7 +26,7 @@ import com.sun.jna.Native;
|
|||
import com.sun.jna.Pointer;
|
||||
|
||||
/**
|
||||
* A CLibraryWrapper implementation for Linux.
|
||||
* A {@code NativeLibraryWrapper} implementation for Linux.
|
||||
* <p>
|
||||
* When JNA is initialized, all methods that have the 'native' keyword
|
||||
* will be attmpted to be linked against. As Java doesn't have the equivalent
|
||||
|
|
@ -37,35 +37,33 @@ import com.sun.jna.Pointer;
|
|||
* native calls that are supported on that target operating system will be
|
||||
* unavailable simply because of one native defined method not supported
|
||||
* on the runtime operating system.
|
||||
* @see org.apache.cassandra.utils.CLibraryWrapper
|
||||
* @see CLibrary
|
||||
* @see org.apache.cassandra.utils.NativeLibraryWrapper
|
||||
* @see NativeLibrary
|
||||
*/
|
||||
public class CLibraryLinux implements CLibraryWrapper
|
||||
public class NativeLibraryLinux implements NativeLibraryWrapper
|
||||
{
|
||||
private static boolean jnaAvailable = true;
|
||||
private static boolean available;
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(CLibraryLinux.class);
|
||||
private static final Logger logger = LoggerFactory.getLogger(NativeLibraryLinux.class);
|
||||
|
||||
static
|
||||
{
|
||||
try
|
||||
{
|
||||
Native.register("c");
|
||||
available = true;
|
||||
}
|
||||
catch (NoClassDefFoundError e)
|
||||
{
|
||||
logger.warn("JNA not found. Native methods will be disabled.");
|
||||
jnaAvailable = false;
|
||||
}
|
||||
catch (UnsatisfiedLinkError e)
|
||||
{
|
||||
logger.warn("JNA link failure, one or more native method will be unavailable.");
|
||||
logger.error("JNA link failure details: {}", e.getMessage());
|
||||
logger.error("Failed to link the C library against JNA. Native methods will be unavailable.", e);
|
||||
}
|
||||
catch (NoSuchMethodError e)
|
||||
{
|
||||
logger.warn("Obsolete version of JNA present; unable to register C library. Upgrade to JNA 3.2.7 or later");
|
||||
jnaAvailable = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -124,8 +122,8 @@ public class CLibraryLinux implements CLibraryWrapper
|
|||
return getpid();
|
||||
}
|
||||
|
||||
public boolean jnaAvailable()
|
||||
public boolean isAvailable()
|
||||
{
|
||||
return jnaAvailable;
|
||||
return available;
|
||||
}
|
||||
}
|
||||
|
|
@ -21,21 +21,51 @@ package org.apache.cassandra.utils;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.sun.jna.LastErrorException;
|
||||
import com.sun.jna.Native;
|
||||
import com.sun.jna.Pointer;
|
||||
|
||||
/**
|
||||
* A CLibraryWrapper implementation for Windows.
|
||||
* <p>
|
||||
* As libc isn't available on Windows these implementations
|
||||
* will obviously be a no-op, however when possible implementations
|
||||
* are used that are Windows friendly that will return the same
|
||||
* return value.
|
||||
* @see org.apache.cassandra.utils.CLibraryWrapper
|
||||
* @see CLibrary
|
||||
* A {@code NativeLibraryWrapper} implementation for Windows.
|
||||
* <p> This implementation only offers support for the {@code callGetpid} method
|
||||
* using the Windows/Kernel32 library.</p>
|
||||
*
|
||||
* @see org.apache.cassandra.utils.NativeLibraryWrapper
|
||||
* @see NativeLibrary
|
||||
*/
|
||||
public class CLibraryWindows implements CLibraryWrapper
|
||||
public class NativeLibraryWindows implements NativeLibraryWrapper
|
||||
{
|
||||
private static final Logger logger = LoggerFactory.getLogger(CLibraryWindows.class);
|
||||
private static final Logger logger = LoggerFactory.getLogger(NativeLibraryWindows.class);
|
||||
|
||||
private static boolean available;
|
||||
|
||||
static
|
||||
{
|
||||
try
|
||||
{
|
||||
Native.register("kernel32");
|
||||
available = true;
|
||||
}
|
||||
catch (NoClassDefFoundError e)
|
||||
{
|
||||
logger.warn("JNA not found. Native methods will be disabled.");
|
||||
}
|
||||
catch (UnsatisfiedLinkError e)
|
||||
{
|
||||
logger.error("Failed to link the Windows/Kernel32 library against JNA. Native methods will be unavailable.", e);
|
||||
}
|
||||
catch (NoSuchMethodError e)
|
||||
{
|
||||
logger.warn("Obsolete version of JNA present; unable to register Windows/Kernel32 library. Upgrade to JNA 3.2.7 or later");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the process identifier of the calling process (<a href='https://msdn.microsoft.com/en-us/library/windows/desktop/ms683180(v=vs.85).aspx'>GetCurrentProcessId function</a>).
|
||||
*
|
||||
* @return the process identifier of the calling process
|
||||
*/
|
||||
private static native long GetCurrentProcessId() throws LastErrorException;
|
||||
|
||||
public int callMlockall(int flags) throws UnsatisfiedLinkError, RuntimeException
|
||||
{
|
||||
|
|
@ -84,20 +114,11 @@ public class CLibraryWindows implements CLibraryWrapper
|
|||
*/
|
||||
public long callGetpid() throws UnsatisfiedLinkError, RuntimeException
|
||||
{
|
||||
try
|
||||
{
|
||||
return SigarLibrary.instance.getPid();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.error("Failed to initialize or use Sigar Library", e);
|
||||
}
|
||||
|
||||
return -1;
|
||||
return GetCurrentProcessId();
|
||||
}
|
||||
|
||||
public boolean jnaAvailable()
|
||||
public boolean isAvailable()
|
||||
{
|
||||
return false;
|
||||
return available;
|
||||
}
|
||||
}
|
||||
|
|
@ -22,11 +22,15 @@ import com.sun.jna.Pointer;
|
|||
|
||||
/**
|
||||
* An interface to implement for using OS specific native methods.
|
||||
* @see CLibrary
|
||||
* @see NativeLibrary
|
||||
*/
|
||||
interface CLibraryWrapper
|
||||
interface NativeLibraryWrapper
|
||||
{
|
||||
boolean jnaAvailable();
|
||||
/**
|
||||
* Checks if the library has been successfully linked.
|
||||
* @return {@code true} if the library has been successfully linked, {@code false} otherwise.
|
||||
*/
|
||||
boolean isAvailable();
|
||||
|
||||
int callMlockall(int flags) throws UnsatisfiedLinkError, RuntimeException;
|
||||
int callMunlockall() throws UnsatisfiedLinkError, RuntimeException;
|
||||
|
|
@ -176,7 +176,7 @@ public class SyncUtil
|
|||
if (SKIP_SYNC)
|
||||
return;
|
||||
else
|
||||
CLibrary.trySync(fd);
|
||||
NativeLibrary.trySync(fd);
|
||||
}
|
||||
|
||||
public static void trySyncDir(File dir)
|
||||
|
|
@ -184,14 +184,14 @@ public class SyncUtil
|
|||
if (SKIP_SYNC)
|
||||
return;
|
||||
|
||||
int directoryFD = CLibrary.tryOpenDirectory(dir.getPath());
|
||||
int directoryFD = NativeLibrary.tryOpenDirectory(dir.getPath());
|
||||
try
|
||||
{
|
||||
trySync(directoryFD);
|
||||
}
|
||||
finally
|
||||
{
|
||||
CLibrary.tryCloseFD(directoryFD);
|
||||
NativeLibrary.tryCloseFD(directoryFD);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -385,7 +385,7 @@ public class UUIDGen
|
|||
messageDigest.update(addr.getAddress());
|
||||
|
||||
// Identify the process on the load: we use both the PID and class loader hash.
|
||||
long pid = CLibrary.getProcessID();
|
||||
long pid = NativeLibrary.getProcessID();
|
||||
if (pid < 0)
|
||||
pid = new Random(System.currentTimeMillis()).nextLong();
|
||||
FBUtilities.updateWithLong(messageDigest, pid);
|
||||
|
|
|
|||
|
|
@ -34,6 +34,10 @@ public final class WindowsTimer
|
|||
{
|
||||
Native.register("winmm");
|
||||
}
|
||||
catch (NoClassDefFoundError e)
|
||||
{
|
||||
logger.warn("JNA not found. winmm.dll cannot be registered. Performance will be negatively impacted on this node.");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.error("Failed to register winmm.dll. Performance will be negatively impacted on this node.");
|
||||
|
|
|
|||
|
|
@ -25,20 +25,20 @@ import org.junit.Test;
|
|||
|
||||
import org.apache.cassandra.io.util.FileUtils;
|
||||
|
||||
public class CLibraryTest
|
||||
public class NativeLibraryTest
|
||||
{
|
||||
@Test
|
||||
public void testSkipCache()
|
||||
{
|
||||
File file = FileUtils.createTempFile("testSkipCache", "1");
|
||||
|
||||
CLibrary.trySkipCache(file.getPath(), 0, 0);
|
||||
NativeLibrary.trySkipCache(file.getPath(), 0, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getPid()
|
||||
{
|
||||
long pid = CLibrary.getProcessID();
|
||||
long pid = NativeLibrary.getProcessID();
|
||||
Assert.assertTrue(pid > 0);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue