smartmontools SVN Rev 3317
Utility to control and monitor storage systems with "S.M.A.R.T."
os_generic.cpp
Go to the documentation of this file.
00001 /*
00002  * os_generic.cpp
00003  *
00004  * Home page of code is: http://smartmontools.sourceforge.net
00005  *
00006  * Copyright (C) YEAR YOUR_NAME <smartmontools-support@lists.sourceforge.net>
00007  * Copyright (C) 2003-8 Bruce Allen <smartmontools-support@lists.sourceforge.net>
00008  * Copyright (C) 2008 Christian Franke <smartmontools-support@lists.sourceforge.net>
00009  *
00010  * This program is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2, or (at your option)
00013  * any later version.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * (for example COPYING); If not, see <http://www.gnu.org/licenses/>.
00017  *
00018  */
00019 
00020 
00021 /*
00022     NOTE: The code in this file is only called when smartmontools has
00023     been compiled on an unrecognized/unsupported platform.  This file
00024     can then serve as a "template" to make os_myOS.cpp if you wish to
00025     build support for that platform.
00026 
00027 
00028  PORTING NOTES AND COMMENTS
00029  --------------------------
00030 
00031  To port smartmontools to the OS of your choice, please:
00032 
00033  [0] Contact smartmontools-support@lists.sourceforge.net to check
00034      that it's not already been done.
00035 
00036  [1] Make copies of os_generic.h and os_generic.cpp called os_myOS.h
00037      and os_myOS.cpp .
00038 
00039  [2] Modify configure.in so that case "${host}" includes myOS.
00040 
00041  [3] Verify that ./autogen.sh && ./configure && make compiles the
00042      code.  If not, fix any compilation problems.  If your OS lacks
00043      some function that is used elsewhere in the code, then add a
00044      AC_CHECK_FUNCS([missingfunction]) line to configure.in, and
00045      surround uses of the function with:
00046      #ifdef HAVE_MISSINGFUNCTION
00047      ... 
00048      #endif
00049      where the macro HAVE_MISSINGFUNCTION is (or is not) defined in
00050      config.h.
00051 
00052  [4] Now that you have a working build environment, you have to
00053      replace the 'stub' function calls provided in this file.
00054 
00055      Provide the functions defined in this file by fleshing out the
00056      skeletons below.  You can entirely eliminate the function
00057      'unsupported()'.
00058 
00059  [5] Contact smartmontools-support@lists.sourceforge.net to see
00060      about checking your code into the smartmontools CVS archive.
00061 */
00062 
00063 /*
00064  Developer's note: for testing this file, use an unsupported system,
00065  for example: ./configure --build=rs6000-ibm-aix && make
00066 */
00067 
00068 
00069 // This is needed for the various HAVE_* macros and PROJECT_* macros.
00070 #include "config.h"
00071 
00072 // These are needed to define prototypes and structures for the
00073 // functions defined below
00074 #include "int64.h"
00075 #include "atacmds.h"
00076 #include "utility.h"
00077 
00078 // This is to include whatever structures and prototypes you define in
00079 // os_generic.h
00080 #include "os_generic.h"
00081 
00082 // Needed by '-V' option (CVS versioning) of smartd/smartctl.  You
00083 // should have one *_H_CVSID macro appearing below for each file
00084 // appearing with #include "*.h" above.  Please list these (below) in
00085 // alphabetic/dictionary order.
00086 const char * os_XXXX_cpp_cvsid="$Id: os_generic.cpp 3579 2012-07-20 17:50:12Z chrfranke $"
00087   ATACMDS_H_CVSID CONFIG_H_CVSID INT64_H_CVSID OS_GENERIC_H_CVSID UTILITY_H_CVSID;
00088 
00089 // This is here to prevent compiler warnings for unused arguments of
00090 // functions.
00091 #define ARGUSED(x) ((void)(x))
00092 
00093 // Please eliminate the following block: both the #include and
00094 // the 'unsupported()' function.  They are only here to warn
00095 // unsuspecting users that their Operating System is not supported! If
00096 // you wish, you can use a similar warning mechanism for any of the
00097 // functions in this file that you can not (or choose not to)
00098 // implement.
00099 
00100 
00101 #ifdef HAVE_UNAME
00102 #include <sys/utsname.h>
00103 #endif
00104 
00105 static void unsupported(){
00106   static int warninggiven;
00107 
00108   if (!warninggiven) {
00109     char *osname;
00110     
00111 #ifdef HAVE_UNAME
00112     struct utsname ostype;
00113     uname(&ostype);
00114     osname=ostype.sysname;
00115 #else
00116     osname="host's";
00117 #endif
00118 
00119     pout("\n"
00120          "############################################################################\n"
00121          "WARNING: smartmontools has not been ported to the %s Operating System.\n"
00122          "Please see the files os_generic.cpp and os_generic.h for porting instructions.\n"
00123          "############################################################################\n\n",
00124          osname);
00125     warninggiven=1;
00126   }
00127   
00128   return;
00129 }
00130 // End of the 'unsupported()' block that you should eliminate.
00131 
00132 
00133 // print examples for smartctl.  You should modify this function so
00134 // that the device paths are sensible for your OS, and to eliminate
00135 // unsupported commands (eg, 3ware controllers).
00136 static void print_smartctl_examples(){
00137   printf("=================================================== SMARTCTL EXAMPLES =====\n\n");
00138 #ifdef HAVE_GETOPT_LONG
00139   printf(
00140          "  smartctl -a /dev/hda                       (Prints all SMART information)\n\n"
00141          "  smartctl --smart=on --offlineauto=on --saveauto=on /dev/hda\n"
00142          "                                              (Enables SMART on first disk)\n\n"
00143          "  smartctl -t long /dev/hda              (Executes extended disk self-test)\n\n"
00144          "  smartctl --attributes --log=selftest --quietmode=errorsonly /dev/hda\n"
00145          "                                      (Prints Self-Test & Attribute errors)\n"
00146          "  smartctl -a --device=3ware,2 /dev/sda\n"
00147          "          (Prints all SMART info for 3rd ATA disk on 3ware RAID controller)\n"
00148          );
00149 #else
00150   printf(
00151          "  smartctl -a /dev/hda                       (Prints all SMART information)\n"
00152          "  smartctl -s on -o on -S on /dev/hda         (Enables SMART on first disk)\n"
00153          "  smartctl -t long /dev/hda              (Executes extended disk self-test)\n"
00154          "  smartctl -A -l selftest -q errorsonly /dev/hda\n"
00155          "                                      (Prints Self-Test & Attribute errors)\n"
00156          "  smartctl -a -d 3ware,2 /dev/sda\n"
00157          "          (Prints all SMART info for 3rd ATA disk on 3ware RAID controller)\n"
00158          );
00159 #endif
00160   return;
00161 }
00162 
00163 /////////////////////////////////////////////////////////////////////////////
00164 
00165 namespace generic { // No need to publish anything, name provided for Doxygen
00166 
00167 class generic_smart_interface
00168 : public /*implements*/ smart_interface
00169 {
00170 public:
00171 #ifdef HAVE_GET_OS_VERSION_STR
00172   virtual const char * get_os_version_str();
00173 #endif
00174 
00175   virtual std::string get_app_examples(const char * appname);
00176 
00177   virtual bool scan_smart_devices(smart_device_list & devlist, const char * type,
00178     const char * pattern = 0);
00179 
00180 protected:
00181   virtual ata_device * get_ata_device(const char * name, const char * type);
00182 
00183   virtual scsi_device * get_scsi_device(const char * name, const char * type);
00184 
00185   virtual smart_device * autodetect_smart_device(const char * name);
00186 
00187   virtual smart_device * get_custom_smart_device(const char * name, const char * type);
00188 
00189   virtual std::string get_valid_custom_dev_types_str();
00190 };
00191 
00192 
00193 //////////////////////////////////////////////////////////////////////
00194 
00195 #ifdef HAVE_GET_OS_VERSION_STR
00196 /// Return build host and OS version as static string
00197 const char * generic_smart_interface::get_os_version_str()
00198 {
00199   return ::get_os_version_str();
00200 }
00201 #endif
00202 
00203 std::string generic_smart_interface::get_app_examples(const char * appname)
00204 {
00205   if (!strcmp(appname, "smartctl"))
00206     ::print_smartctl_examples(); // this prints to stdout ...
00207   return ""; // ... so don't print again.
00208 }
00209 
00210 // Return ATA device object for the given device name or NULL
00211 // the type is always set to "ata"
00212 ata_device * generic_smart_interface::get_ata_device(const char * name, const char * type)
00213 {
00214   ARGUSED(name);
00215   ARGUSED(type);
00216 
00217   unsupported();
00218   return NULL;
00219 }
00220 
00221 // Return SCSI device object for the given device name or NULL
00222 // the type is always set to "scsi"
00223 scsi_device * generic_smart_interface::get_scsi_device(const char * name, const char * type)
00224 {
00225   ARGUSED(name);
00226   ARGUSED(type);
00227 
00228   unsupported();
00229   return NULL;
00230 }
00231 
00232 
00233 // Return device object for the given device name (autodetect the device type)
00234 smart_device * generic_smart_interface::autodetect_smart_device(const char * name)
00235 {
00236   ARGUSED(name);
00237 
00238   // for the given name return the apropriate device type 
00239   unsupported();
00240   return NULL;
00241 }
00242 
00243 
00244 // Fill devlist with all OS's disk devices of given type that match the pattern
00245 bool generic_smart_interface::scan_smart_devices(smart_device_list & devlist,
00246   const char * type, const char * pattern /*= 0*/)
00247 {
00248   ARGUSED(devlist);
00249   ARGUSED(type);
00250   ARGUSED(pattern);
00251 
00252   unsupported();
00253   return false;
00254 }
00255 
00256 
00257 // Return device object of the given type with specified name or NULL
00258 smart_device * generic_smart_interface::get_custom_smart_device(const char * name, const char * type)
00259 {
00260   ARGUSED(name);
00261   ARGUSED(type);
00262 
00263   unsupported();
00264   return NULL;
00265 }
00266 
00267 std::string generic_smart_interface::get_valid_custom_dev_types_str()
00268 {
00269   return "";
00270 }
00271 
00272 } // namespace
00273 
00274 
00275 /////////////////////////////////////////////////////////////////////////////
00276 /// Initialize platform interface and register with smi()
00277 
00278 void smart_interface::init()
00279 {
00280   static generic::generic_smart_interface the_interface;
00281   smart_interface::set(&the_interface);
00282 }