nfs-ganesha 1.4

fsal_posixdb_tool.c

Go to the documentation of this file.
00001 /*
00002  * vim:expandtab:shiftwidth=8:tabstop=8:
00003  */
00004 #ifdef HAVE_CONFIG_H
00005 #include "config.h"
00006 #endif
00007 
00008 #include "fsal.h"
00009 #include "fsal_internal.h"
00010 #include "abstract_mem.h"
00011 #include <string.h>
00012 #include <unistd.h>
00013 #include <libgen.h>             /* basename */
00014 #include <sys/types.h>
00015 #include <sys/stat.h>
00016 
00017 #define OP_TESTCONN   1
00018 #define OP_EMPTYDB    2
00019 #define OP_FIND       3
00020 #define OP_POPULATE   4
00021 
00022 /* functions related to OP_FIND */
00023 void find(fsal_posixdb_conn * p_conn);
00024 void display_directory(fsal_posixdb_conn * p_conn, posixfsal_handle_t * p_handle_parent,
00025                        char *basedir);
00026 
00027 /* functions related to OP_EMPTYDB */
00028 void emptydb(fsal_posixdb_conn * p_conn);
00029 
00030 /* functions related to OP_POPULATE */
00031 void populatedb(fsal_posixdb_conn * p_conn, char *path);
00032 void add_dir(fsal_posixdb_conn * p_conn, char *path, posixfsal_handle_t * dir_handle);
00033 
00034 /* ---------------------------------------------- */
00035 
00036 void populatedb(fsal_posixdb_conn * p_conn, char *path)
00037 {
00038   int rc;
00039   fsal_posixdb_fileinfo_t info;
00040   fsal_name_t fsalname;
00041   posixfsal_handle_t handle, handle_parent;
00042   struct stat buffstat;
00043   char *begin, *end, backup;
00044 
00045   if(path[0] != '/')
00046     {
00047       fputs("Error : you should provide a complete path", stderr);
00048       return;
00049     }
00050 
00051   if(path[strlen(path) - 1] != '/')
00052     strcat(path, "/");
00053 
00054   /* add the path (given in arguments) to the database */
00055   rc = lstat("/", &buffstat);
00056   fsal_internal_posix2posixdb_fileinfo(&buffstat, &info);
00057   fsal_internal_posixdb_add_entry(p_conn, NULL, &info, NULL, &handle_parent);
00058 
00059   begin = end = path;
00060   while(*end != '\0')
00061     {
00062       while(*begin == '/')
00063         begin++;
00064       if(*begin == '\0')
00065         break;
00066       end = begin + 1;
00067       while(*end != '/' && *end != '\0')
00068         end++;
00069       backup = *end;
00070       *end = '\0';
00071 
00072       rc = lstat(path, &buffstat);
00073       fsal_internal_posix2posixdb_fileinfo(&buffstat, &info);
00074       FSAL_str2name(begin, FSAL_MAX_NAME_LEN, &fsalname);
00075       fsal_internal_posixdb_add_entry(p_conn, &fsalname, &info, &handle_parent, &handle);
00076       memcpy(&handle_parent, &handle, sizeof(posixfsal_handle_t));
00077 
00078       *end = backup;
00079       begin = end;
00080     }
00081 
00082   /* add files */
00083   printf("Adding entries in %s... rc=%d ", path, rc);
00084   fflush(stdout);
00085   add_dir(p_conn, path, &handle_parent);
00086   puts("done");
00087 }
00088 
00089 void add_dir(fsal_posixdb_conn * p_conn, char *path, posixfsal_handle_t * p_dir_handle)
00090 {
00091   DIR *dirp;
00092   struct dirent *dp;
00093   struct dirent dpe;
00094   posixfsal_handle_t new_handle;
00095   struct stat buffstat;
00096   char path_temp[FSAL_MAX_PATH_LEN];
00097   fsal_status_t st;
00098   fsal_posixdb_fileinfo_t info;
00099   fsal_name_t fsalname;
00100 
00101   if((dirp = opendir(path)))
00102     {
00103       while(!readdir_r(dirp, &dpe, &dp) && dp)
00104         {
00105           if(!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
00106             continue;
00107           if(!strcmp(dp->d_name, ".snapshot"))
00108             {
00109               fputs("(ignoring .snapshot)", stderr);
00110               continue;
00111             }
00112           strcpy(path_temp, path);
00113           strcat(path_temp, dp->d_name);
00114           lstat(path_temp, &buffstat);
00115 
00116           fsal_internal_posix2posixdb_fileinfo(&buffstat, &info);
00117           FSAL_str2name(dp->d_name, FSAL_MAX_NAME_LEN, &fsalname);
00118           st = fsal_internal_posixdb_add_entry(p_conn, &fsalname, &info, p_dir_handle,
00119                                                &new_handle);
00120           if(FSAL_IS_ERROR(st))
00121             {
00122               fprintf(stderr, "[Error %i/%i]\n", st.major, st.minor);
00123               return;
00124             }
00125           if(S_ISDIR(buffstat.st_mode))
00126             {
00127               strcat(path_temp, "/");
00128               add_dir(p_conn, path_temp, &new_handle);
00129             }
00130         };
00131       closedir(dirp);
00132     }
00133 }
00134 
00135 void emptydb(fsal_posixdb_conn * p_conn)
00136 {
00137   fsal_posixdb_status_t st;
00138 
00139   st = fsal_posixdb_flush(p_conn);
00140   if(FSAL_POSIXDB_IS_ERROR(st))
00141     {
00142       fprintf(stderr, "Error (%i/%i) while emptying the database\n", st.major, st.minor);
00143     }
00144   else
00145     {
00146       printf("Database entries have been successfully deleted\n");
00147     }
00148 
00149   return;
00150 }
00151 
00152 void find(fsal_posixdb_conn * p_conn)
00153 {
00154   posixfsal_handle_t handle_root;
00155   fsal_posixdb_status_t st;
00156 
00157   st = fsal_posixdb_getInfoFromName(p_conn, NULL,       /* parent handle */
00158                                     NULL,       /* filename */
00159                                     NULL,       /* path */
00160                                     &handle_root);
00161   if(FSAL_POSIXDB_IS_NOENT(st))
00162     {
00163       fputs("Error : Root handle not found. Is the database empty ?", stderr);
00164       return;
00165     }
00166   else if(FSAL_POSIXDB_IS_ERROR(st))
00167     {
00168       fprintf(stderr, "Error (%i/%i) while getting root handle\n", st.major, st.minor);
00169       return;
00170     }
00171 
00172   display_directory(p_conn, &handle_root, "");
00173   return;
00174 }
00175 
00176 void display_directory(fsal_posixdb_conn * p_conn, posixfsal_handle_t * p_handle_parent,
00177                        char *basedir)
00178 {
00179   fsal_posixdb_child *p_children;
00180   fsal_posixdb_status_t st;
00181   unsigned int count, i;
00182 
00183   st = fsal_posixdb_getChildren(p_conn, p_handle_parent, 0, &p_children, &count);
00184   if(FSAL_POSIXDB_IS_ERROR(st))
00185     {
00186       fprintf(stderr, "Error (%i/%i) while getting children of %s\n", st.major, st.minor,
00187               basedir);
00188       return;
00189     }
00190   for(i = 0; i < count; i++)
00191     {
00192       printf("%llu %s/%s\n", (unsigned long long int)p_children[i].handle.data.info.inode,
00193              basedir, p_children[i].name.name);
00194       if(p_children[i].handle.data.info.ftype == FSAL_TYPE_DIR)
00195         {
00196           char basedir_new[FSAL_MAX_PATH_LEN];
00197 
00198           memset( basedir_new, 0, FSAL_MAX_PATH_LEN ) ;
00199           strncpy(basedir_new, basedir, FSAL_MAX_PATH_LEN);
00200           strncat(basedir_new, "/", FSAL_MAX_PATH_LEN);
00201           strncat(basedir_new, p_children[i].name.name, FSAL_MAX_PATH_LEN);
00202           display_directory(p_conn, &(p_children[i].handle), basedir_new);
00203         }
00204     }
00205   gsh_free(p_children);
00206 }
00207 
00208 int main(int argc, char **argv)
00209 {
00210   fsal_posixdb_conn_params_t dbparams;
00211   char exec_name[MAXPATHLEN];
00212   char c, op = 0;
00213   fsal_posixdb_conn *p_conn;
00214   fsal_posixdb_status_t statusdb;
00215   char path[MAXPATHLEN];
00216   int rc;
00217 
00218   char options[] = "h@H:P:L:D:K:";
00219   char usage[] =
00220       "Usage: %s [-h][-H <host>][-P <port>][-L <login>][-D <dbname>][-K <passwd file>] operation operation_parameters\n"
00221       "\t[-h]               display this help\n"
00222       "\t[-H <host>]        Database host\n"
00223       "\t[-P <port>]        Database port\n"
00224       "\t[-L <login>]       Database login\n"
00225       "\t[-D <dbname>]      Name of the database\n"
00226       "\t[-K <passwd file>] Path of the file where is stored the password\n"
00227       "------------- Default Values -------------\n"
00228       "host        : localhost\n"
00229       "port        : default DB port\n"
00230       "dbname      : posixdb\n"
00231       "login       : current unix user\n"
00232       "passwd file : default path ($PGPASSFILE)\n"
00233       "------------- Operations -----------------\n"
00234       "test_connection       : try to connect to the database\n"
00235       "empty_database        : Delete all entries in the database\n"
00236       "find                  : Print the entries of the database (as 'find' would do it)\n"
00237       "populate <path>       : Add (recursively) the object in <path> into the database\n\n";
00238 
00239   memset(&dbparams, 0, sizeof(fsal_posixdb_conn_params_t));
00240   strcpy(dbparams.host, "localhost");
00241   strcpy(dbparams.dbname, "posixdb");
00242 
00243   /* What is the executable file's name */
00244   if(*exec_name == '\0')
00245     strcpy((char *)exec_name, basename(argv[0]));
00246 
00247   /* now parsing options with getopt */
00248   while((c = getopt(argc, argv, options)) != EOF)
00249     {
00250       switch (c)
00251         {
00252         case '@':
00253           /* A litlle backdoor to keep track of binary versions */
00254           printf("%s compiled on %s at %s\n", exec_name, __DATE__, __TIME__);
00255           exit(0);
00256           break;
00257         case 'H':
00258           strncpy(dbparams.host, optarg, FSAL_MAX_DBHOST_NAME_LEN);
00259           break;
00260         case 'P':
00261           strncpy(dbparams.port, optarg, FSAL_MAX_DBPORT_STR_LEN);
00262           break;
00263         case 'L':
00264           strncpy(dbparams.login, optarg, FSAL_MAX_DB_LOGIN_LEN);
00265           break;
00266         case 'D':
00267           strncpy(dbparams.dbname, optarg, FSAL_MAX_DB_NAME_LEN);
00268           break;
00269         case 'K':
00270           strncpy(dbparams.passwdfile, optarg, PATH_MAX);
00271           break;
00272         default:
00273           /* display the help */
00274           fprintf(stderr, usage, exec_name);
00275           exit(0);
00276           break;
00277         }
00278     }
00279 
00280   if(optind == argc)
00281     {
00282       fprintf(stderr, "No operation specified.\n");
00283       fprintf(stderr, usage, exec_name);
00284       exit(0);
00285     }
00286   if(optind < argc)
00287     {
00288       if(!strcmp(argv[optind], "test_connection"))
00289         {
00290           op = OP_TESTCONN;
00291         }
00292       else if(!strcmp(argv[optind], "empty_database"))
00293         {
00294           op = OP_EMPTYDB;
00295         }
00296       else if(!strcmp(argv[optind], "find"))
00297         {
00298           op = OP_FIND;
00299         }
00300       else if(!strcmp(argv[optind], "populate"))
00301         {
00302           op = OP_POPULATE;
00303           optind++;
00304           if(optind < argc)
00305             {
00306               strncpy(path, argv[optind], MAXPATHLEN);
00307             }
00308           else
00309             {
00310               fputs("Operation 'populate' need a parameter", stderr);
00311               fprintf(stderr, usage, exec_name);
00312               exit(-1);
00313             }
00314         }
00315       else
00316         {
00317           fprintf(stderr, "Unknown operation : %s\n", argv[optind]);
00318           fprintf(stderr, usage, exec_name);
00319           exit(-1);
00320         }
00321     }
00322 
00323   /* Connecting to database */
00324   if(*(dbparams.passwdfile) != '\0')
00325     {
00326       rc = setenv("PGPASSFILE", dbparams.passwdfile, 1);
00327       if(rc != 0)
00328         fputs("Could not set POSTGRESQL keytab path.", stderr);
00329     }
00330 
00331   fprintf(stderr, "Opening database connection to %s...\n", dbparams.host);
00332   statusdb = fsal_posixdb_connect(&dbparams, &p_conn);
00333   if(FSAL_POSIXDB_IS_ERROR(statusdb))
00334     {
00335       fprintf(stderr, "Error %i. exiting.\n", statusdb.minor);
00336       exit(-1);
00337     }
00338   else
00339     {
00340       fprintf(stderr, "Connected.\n");
00341     }
00342 
00343   /* Execute the operation */
00344   switch (op)
00345     {
00346     case OP_TESTCONN:
00347       /* nothing to do */
00348       break;
00349     case OP_EMPTYDB:
00350       emptydb(p_conn);
00351       break;
00352     case OP_FIND:
00353       find(p_conn);
00354       break;
00355     case OP_POPULATE:
00356       populatedb(p_conn, path);
00357       break;
00358     default:
00359       puts("Bad operation !!");
00360       fprintf(stderr, usage, exec_name);
00361     }
00362 
00363   fsal_posixdb_disconnect(p_conn);
00364 
00365   exit(0);
00366 }