From b6e2973ee66bad2e998cd2acd2c47fecaa1e6942 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 21 Mar 2018 12:59:40 +0100 Subject: MDEV-14533 Provide information_schema tables using which hardware information can be obtained. update README, use maria_declare_plugin(), specify the author. --- plugin/disks/CMakeLists.txt | 5 + plugin/disks/README.txt | 86 ++++++++++++ plugin/disks/information_schema_disks.cc | 155 +++++++++++++++++++++ plugin/information_schema_disks/CMakeLists.txt | 5 - plugin/information_schema_disks/README.txt | 101 -------------- .../information_schema_disks.cc | 154 -------------------- 6 files changed, 246 insertions(+), 260 deletions(-) create mode 100644 plugin/disks/CMakeLists.txt create mode 100644 plugin/disks/README.txt create mode 100644 plugin/disks/information_schema_disks.cc delete mode 100644 plugin/information_schema_disks/CMakeLists.txt delete mode 100644 plugin/information_schema_disks/README.txt delete mode 100644 plugin/information_schema_disks/information_schema_disks.cc diff --git a/plugin/disks/CMakeLists.txt b/plugin/disks/CMakeLists.txt new file mode 100644 index 00000000000..a0ed929c62c --- /dev/null +++ b/plugin/disks/CMakeLists.txt @@ -0,0 +1,5 @@ +IF(NOT WIN32) + INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/sql) + MYSQL_ADD_PLUGIN(DISKS information_schema_disks.cc MODULE_ONLY RECOMPILE_FOR_EMBEDDED) +ENDIF() + diff --git a/plugin/disks/README.txt b/plugin/disks/README.txt new file mode 100644 index 00000000000..b49db3c03b5 --- /dev/null +++ b/plugin/disks/README.txt @@ -0,0 +1,86 @@ +Information Schema Disks +------------------------ +This is a proof-of-concept information schema plugin that allows the +disk space situation to be monitored. When installed, it can be used +as follows: + + > select * from information_schema.disks; + +-----------+-----------------------+-----------+----------+-----------+ + | Disk | Path | Total | Used | Available | + +-----------+-----------------------+-----------+----------+-----------+ + | /dev/sda3 | / | 47929956 | 30666304 | 14805864 | + | /dev/sda1 | /boot/efi | 191551 | 3461 | 188090 | + | /dev/sda4 | /home | 174679768 | 80335392 | 85448120 | + | /dev/sdb1 | /mnt/hdd | 961301832 | 83764 | 912363644 | + | /dev/sdb1 | /home/wikman/Music | 961301832 | 83764 | 912363644 | + | /dev/sdb1 | /home/wikman/Videos | 961301832 | 83764 | 912363644 | + | /dev/sdb1 | /home/wikman/hdd | 961301832 | 83764 | 912363644 | + | /dev/sdb1 | /home/wikman/Pictures | 961301832 | 83764 | 912363644 | + | /dev/sda3 | /var/lib/docker/aufs | 47929956 | 30666304 | 14805864 | + +-----------+-----------------------+-----------+----------+-----------+ + 9 rows in set (0.00 sec) + +- 'Disk' is the name of the disk itself. +- 'Path' is the mount point of the disk. +- 'Total' is the total space in KiB. +- 'Used' is the used amount of space in KiB, and +- 'Available' is the amount of space in KiB available to non-root users. + +Note that as the amount of space available to root may be more that what +is available to non-root users, 'available' + 'used' may be less than 'total'. + +All paths to which a particular disk has been mounted are reported. The +rationale is that someone might want to take different action e.g. depending +on which disk is relevant for a particular path. This leads to the same disk +being reported multiple times. An alternative to this would be to have two +tables; disks and mounts. + + > select * from information_schema.disks; + +-----------+-----------+----------+-----------+ + | Disk | Total | Used | Available | + +-----------+-----------+----------+-----------+ + | /dev/sda3 | 47929956 | 30666304 | 14805864 | + | /dev/sda1 | 191551 | 3461 | 188090 | + | /dev/sda4 | 174679768 | 80335392 | 85448120 | + | /dev/sdb1 | 961301832 | 83764 | 912363644 | + +-----------+-----------+----------+-----------+ + + > select * from information_schema.mounts; + +-----------------------+-----------+ + | Path | Disk | + +-----------------------+-----------+ + | / | /dev/sda3 | + | /boot/efi | /dev/sda1 | + | /home | /dev/sda4 | + | /mnt/hdd | /dev/sdb1 | + | /home/wikman/Music | /dev/sdb1 | + ... + + +Installation +------------ + +- Use "install plugin" or "install soname" command: + + MariaDB [(none)]> install plugin disks soname 'disks.so'; + + or + + MariaDB [(none)]> install soname 'disks.so'; + +Usage +----- +The plugin appears as the table 'disks' in 'information_schema'. + + MariaDB [(none)]> select * from information_schema.disks; + +-----------+-----------------------+-----------+----------+-----------+ + | Disk | Path | Total | Used | Available | + +-----------+-----------------------+-----------+----------+-----------+ + | /dev/sda3 | / | 47929956 | 30666308 | 14805860 | + | /dev/sda1 | /boot/efi | 191551 | 3461 | 188090 | + | /dev/sda4 | /home | 174679768 | 80348148 | 85435364 | + | /dev/sdb1 | /mnt/hdd | 961301832 | 83764 | 912363644 | + | /dev/sdb1 | /home/wikman/Music | 961301832 | 83764 | 912363644 | + | /dev/sdb1 | /home/wikman/Videos | 961301832 | 83764 | 912363644 | + ... + diff --git a/plugin/disks/information_schema_disks.cc b/plugin/disks/information_schema_disks.cc new file mode 100644 index 00000000000..122b3d3f17f --- /dev/null +++ b/plugin/disks/information_schema_disks.cc @@ -0,0 +1,155 @@ +/* + Copyright (c) 2017, MariaDB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ + +#include +#include +#include +#include +#include + +bool schema_table_store_record(THD *thd, TABLE *table); + +namespace +{ + +struct st_mysql_information_schema disks_table_info = { MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION }; + +ST_FIELD_INFO disks_table_fields[]= +{ + { "Disk", PATH_MAX, MYSQL_TYPE_STRING, 0, 0 ,0, 0 }, + { "Path", PATH_MAX, MYSQL_TYPE_STRING, 0, 0 ,0, 0 }, + { "Total", 32, MYSQL_TYPE_LONG, 0, 0 ,0 ,0 }, // Total amount available + { "Used", 32, MYSQL_TYPE_LONG, 0, 0 ,0 ,0 }, // Amount of space used + { "Available", 32, MYSQL_TYPE_LONG, 0, 0 ,0 ,0 }, // Amount available to users other than root. + { 0, 0, MYSQL_TYPE_NULL, 0, 0, 0, 0 } +}; + +int disks_table_add_row(THD* pThd, + TABLE* pTable, + const char* zDisk, + const char* zPath, + const struct statvfs& info) +{ + // From: http://pubs.opengroup.org/onlinepubs/009695399/basedefs/sys/statvfs.h.html + // + // f_frsize Fundamental file system block size. + // f_blocks Total number of blocks on file system in units of f_frsize. + // f_bfree Total number of free blocks. + // f_bavail Number of free blocks available to non-privileged process. + + size_t total = (info.f_frsize * info.f_blocks) / 1024; + size_t used = (info.f_frsize * (info.f_blocks - info.f_bfree)) / 1024; + size_t avail = (info.f_frsize * info.f_bavail) / 1024; + + pTable->field[0]->store(zDisk, strlen(zDisk), system_charset_info); + pTable->field[1]->store(zPath, strlen(zPath), system_charset_info); + pTable->field[2]->store(total); + pTable->field[3]->store(used); + pTable->field[4]->store(avail); + + // 0 means success. + return (schema_table_store_record(pThd, pTable) != 0) ? 1 : 0; +} + +int disks_table_add_row(THD* pThd, TABLE* pTable, const char* zDisk, const char* zPath) +{ + int rv = 0; + + struct statvfs info; + + if (statvfs(zPath, &info) == 0) // We ignore failures. + { + rv = disks_table_add_row(pThd, pTable, zDisk, zPath, info); + } + + return rv; +} + +int disks_fill_table(THD* pThd, TABLE_LIST* pTables, Item* pCond) +{ + int rv = 1; + TABLE* pTable = pTables->table; + + FILE* pFile = setmntent("/etc/mtab", "r"); + + if (pFile) + { + const size_t BUFFER_SIZE = 4096; // 4K should be sufficient. + + char* pBuffer = new (std::nothrow) char [BUFFER_SIZE]; + + if (pBuffer) + { + rv = 0; + + struct mntent ent; + struct mntent* pEnt; + + while ((rv == 0) && (pEnt = getmntent_r(pFile, &ent, pBuffer, BUFFER_SIZE))) + { + // We only report the ones that refer to physical disks. + if (pEnt->mnt_fsname[0] == '/') + { + rv = disks_table_add_row(pThd, pTable, pEnt->mnt_fsname, pEnt->mnt_dir); + } + } + + delete [] pBuffer; + } + else + { + rv = 1; + } + + endmntent(pFile); + } + + return rv; +} + +int disks_table_init(void *ptr) +{ + ST_SCHEMA_TABLE* pSchema_table = (ST_SCHEMA_TABLE*)ptr; + + pSchema_table->fields_info = disks_table_fields; + pSchema_table->fill_table = disks_fill_table; + return 0; +} + +} + +extern "C" +{ + +maria_declare_plugin(disks) +{ + MYSQL_INFORMATION_SCHEMA_PLUGIN, + &disks_table_info, /* type-specific descriptor */ + "DISKS", /* table name */ + "Johan Wikman", /* author */ + "Disk space information", /* description */ + PLUGIN_LICENSE_GPL, /* license type */ + disks_table_init, /* init function */ + NULL, /* deinit function */ + 0x0100, /* version = 1.0 */ + NULL, /* no status variables */ + NULL, /* no system variables */ + "1.0", /* String version representation */ + MariaDB_PLUGIN_MATURITY_BETA /* Maturity (see include/mysql/plugin.h)*/ +} +mysql_declare_plugin_end; + +} diff --git a/plugin/information_schema_disks/CMakeLists.txt b/plugin/information_schema_disks/CMakeLists.txt deleted file mode 100644 index a0ed929c62c..00000000000 --- a/plugin/information_schema_disks/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -IF(NOT WIN32) - INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/sql) - MYSQL_ADD_PLUGIN(DISKS information_schema_disks.cc MODULE_ONLY RECOMPILE_FOR_EMBEDDED) -ENDIF() - diff --git a/plugin/information_schema_disks/README.txt b/plugin/information_schema_disks/README.txt deleted file mode 100644 index 1c9b8fb6283..00000000000 --- a/plugin/information_schema_disks/README.txt +++ /dev/null @@ -1,101 +0,0 @@ -Information Schema Disks ------------------------- -This is a proof-of-concept information schema plugin that allows the -disk space situation to be monitored. When installed, it can be used -as follows: - - > select * from information_schema.disks; - +-----------+-----------------------+-----------+----------+-----------+ - | Disk | Path | Total | Used | Available | - +-----------+-----------------------+-----------+----------+-----------+ - | /dev/sda3 | / | 47929956 | 30666304 | 14805864 | - | /dev/sda1 | /boot/efi | 191551 | 3461 | 188090 | - | /dev/sda4 | /home | 174679768 | 80335392 | 85448120 | - | /dev/sdb1 | /mnt/hdd | 961301832 | 83764 | 912363644 | - | /dev/sdb1 | /home/wikman/Music | 961301832 | 83764 | 912363644 | - | /dev/sdb1 | /home/wikman/Videos | 961301832 | 83764 | 912363644 | - | /dev/sdb1 | /home/wikman/hdd | 961301832 | 83764 | 912363644 | - | /dev/sdb1 | /home/wikman/Pictures | 961301832 | 83764 | 912363644 | - | /dev/sda3 | /var/lib/docker/aufs | 47929956 | 30666304 | 14805864 | - +-----------+-----------------------+-----------+----------+-----------+ - 9 rows in set (0.00 sec) - -- 'Disk' is the name of the disk itself. -- 'Path' is the mount point of the disk. -- 'Total' is the total space in KiB. -- 'Used' is the used amount of space in KiB, and -- 'Available' is the amount of space in KiB available to non-root users. - -Note that as the amount of space available to root may be more that what -is available to non-root users, 'available' + 'used' may be less than 'total'. - -All paths to which a particular disk has been mounted are reported. The -rationale is that someone might want to take different action e.g. depending -on which disk is relevant for a particular path. This leads to the same disk -being reported multiple times. An alternative to this would be to have two -tables; disks and mounts. - - > select * from information_schema.disks; - +-----------+-----------+----------+-----------+ - | Disk | Total | Used | Available | - +-----------+-----------+----------+-----------+ - | /dev/sda3 | 47929956 | 30666304 | 14805864 | - | /dev/sda1 | 191551 | 3461 | 188090 | - | /dev/sda4 | 174679768 | 80335392 | 85448120 | - | /dev/sdb1 | 961301832 | 83764 | 912363644 | - +-----------+-----------+----------+-----------+ - - > select * from information_schema.mounts; - +-----------------------+-----------+ - | Path | Disk | - +-----------------------+-----------+ - | / | /dev/sda3 | - | /boot/efi | /dev/sda1 | - | /home | /dev/sda4 | - | /mnt/hdd | /dev/sdb1 | - | /home/wikman/Music | /dev/sdb1 | - ... - - -Building --------- -- Ensure that the directory information_schema_disks is in the top-level - directory of the server. -- Add - - ADD_SUBDIRECTORY(information_schema_disks) - - to the top-level CMakeLists.txt - -> Invoke make - - $ make - -Installation ------------- -- Copy information_schema_disks/libinformation_schema_disks.so to the plugin - directory of the server: - - $ cd information_schema_disks - $ sudo cp libinformation_schema_disks.so plugin-directory-of-server - -- Using mysql, install the plugin: - - MariaDB [(none)]> install plugin disks soname 'libinformation_schema_disks.so'; - -Usage ------ -The plugin appears as the table 'disks' in 'information_schema'. - - MariaDB [(none)]> select * from information_schema.disks; - +-----------+-----------------------+-----------+----------+-----------+ - | Disk | Path | Total | Used | Available | - +-----------+-----------------------+-----------+----------+-----------+ - | /dev/sda3 | / | 47929956 | 30666308 | 14805860 | - | /dev/sda1 | /boot/efi | 191551 | 3461 | 188090 | - | /dev/sda4 | /home | 174679768 | 80348148 | 85435364 | - | /dev/sdb1 | /mnt/hdd | 961301832 | 83764 | 912363644 | - | /dev/sdb1 | /home/wikman/Music | 961301832 | 83764 | 912363644 | - | /dev/sdb1 | /home/wikman/Videos | 961301832 | 83764 | 912363644 | - ... - diff --git a/plugin/information_schema_disks/information_schema_disks.cc b/plugin/information_schema_disks/information_schema_disks.cc deleted file mode 100644 index b5e3a6dc728..00000000000 --- a/plugin/information_schema_disks/information_schema_disks.cc +++ /dev/null @@ -1,154 +0,0 @@ -/* - Copyright (c) 2017, MariaDB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ - -#include -#include -#include -#include -#include -#include - -namespace -{ - -struct st_mysql_information_schema disks_table_info = { MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION }; - -ST_FIELD_INFO disks_table_fields[]= -{ - { "Disk", PATH_MAX, MYSQL_TYPE_STRING, 0, 0 ,0, 0 }, - { "Path", PATH_MAX, MYSQL_TYPE_STRING, 0, 0 ,0, 0 }, - { "Total", 32, MYSQL_TYPE_LONG, 0, 0 ,0 ,0 }, // Total amount available - { "Used", 32, MYSQL_TYPE_LONG, 0, 0 ,0 ,0 }, // Amount of space used - { "Available", 32, MYSQL_TYPE_LONG, 0, 0 ,0 ,0 }, // Amount available to users other than root. - { 0, 0, MYSQL_TYPE_NULL, 0, 0, 0, 0 } -}; - -int disks_table_add_row(THD* pThd, - TABLE* pTable, - const char* zDisk, - const char* zPath, - const struct statvfs& info) -{ - // From: http://pubs.opengroup.org/onlinepubs/009695399/basedefs/sys/statvfs.h.html - // - // f_frsize Fundamental file system block size. - // f_blocks Total number of blocks on file system in units of f_frsize. - // f_bfree Total number of free blocks. - // f_bavail Number of free blocks available to non-privileged process. - - size_t total = (info.f_frsize * info.f_blocks) / 1024; - size_t used = (info.f_frsize * (info.f_blocks - info.f_bfree)) / 1024; - size_t avail = (info.f_frsize * info.f_bavail) / 1024; - - pTable->field[0]->store(zDisk, strlen(zDisk), system_charset_info); - pTable->field[1]->store(zPath, strlen(zPath), system_charset_info); - pTable->field[2]->store(total); - pTable->field[3]->store(used); - pTable->field[4]->store(avail); - - // 0 means success. - return (schema_table_store_record(pThd, pTable) != 0) ? 1 : 0; -} - -int disks_table_add_row(THD* pThd, TABLE* pTable, const char* zDisk, const char* zPath) -{ - int rv = 0; - - struct statvfs info; - - if (statvfs(zPath, &info) == 0) // We ignore failures. - { - rv = disks_table_add_row(pThd, pTable, zDisk, zPath, info); - } - - return rv; -} - -int disks_fill_table(THD* pThd, TABLE_LIST* pTables, Item* pCond) -{ - int rv = 1; - TABLE* pTable = pTables->table; - - FILE* pFile = setmntent("/etc/mtab", "r"); - - if (pFile) - { - const size_t BUFFER_SIZE = 4096; // 4K should be sufficient. - - char* pBuffer = new (std::nothrow) char [BUFFER_SIZE]; - - if (pBuffer) - { - rv = 0; - - struct mntent ent; - struct mntent* pEnt; - - while ((rv == 0) && (pEnt = getmntent_r(pFile, &ent, pBuffer, BUFFER_SIZE))) - { - // We only report the ones that refer to physical disks. - if (pEnt->mnt_fsname[0] == '/') - { - rv = disks_table_add_row(pThd, pTable, pEnt->mnt_fsname, pEnt->mnt_dir); - } - } - - delete [] pBuffer; - } - else - { - rv = 1; - } - - endmntent(pFile); - } - - return rv; -} - -int disks_table_init(void *ptr) -{ - ST_SCHEMA_TABLE* pSchema_table = (ST_SCHEMA_TABLE*)ptr; - - pSchema_table->fields_info = disks_table_fields; - pSchema_table->fill_table = disks_fill_table; - return 0; -} - -} - -extern "C" -{ - -mysql_declare_plugin(disks_library) -{ - MYSQL_INFORMATION_SCHEMA_PLUGIN, - &disks_table_info, /* type-specific descriptor */ - "DISKS", /* table name */ - "MariaDB", /* author */ - "Disk space information", /* description */ - PLUGIN_LICENSE_GPL, /* license type */ - disks_table_init, /* init function */ - NULL, - 0x0100, /* version = 1.0 */ - NULL, /* no status variables */ - NULL, /* no system variables */ - NULL, /* no reserved information */ - 0 /* no flags */ -} -mysql_declare_plugin_end; - -} -- cgit v1.2.1