"SfR Fresh" - the SfR Freeware/Shareware Archive

Member "chironfs-1.1.1/src/chiron-conf.c" of archive chironfs-1.1.1.tar.gz:


As a special service "SfR Fresh" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. That can be also achieved for any archive member file by clicking within an archive contents listing on the first character of the file(path) respectively on the according byte size field.
    1 /* Copyright 2005-2008, Luis Furquim
    2  *
    3  *
    4  * This program is free software; you can redistribute it and/or modify
    5  * it under the terms of the GNU General Public License version 3 as
    6  * published by the Free Software Foundation.
    7  *
    8  * This program is distributed in the hope that it will be useful,
    9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   11  * GNU General Public License for more details.
   12  *
   13  * You should have received a copy of the GNU General Public License
   14  * along with this program; if not, write to the Free Software
   15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   16  *
   17  */
   18 
   19 
   20 #define _GNU_SOURCE /* for access to canonicalize_file_name() inside stdlib.h
   21            and the constant O_NOFOLLOW inside fcntl.h */
   22 
   23 #include <stdlib.h>
   24 #include <stdio.h>
   25 #include <string.h>
   26 #include <stdarg.h>
   27 #include <errno.h>
   28 
   29 #include <unistd.h>
   30 #include <sys/stat.h>
   31 #include <sys/types.h>
   32 #include <sys/statvfs.h>
   33 #include <fcntl.h>
   34 #include <dlfcn.h>
   35 
   36 #include <libgen.h>
   37 //
   38 // The lines below are from a patch contributed by Antti Kantee
   39 // to make ChironFS run on NetBSD
   40 // Yen-Ming Lee has sent another patch, porting ChironFS to
   41 // FreeBSD very similar to it
   42 //
   43 #ifdef __linux__
   44 #include <linux/limits.h>
   45 #else
   46 #include <limits.h>
   47 #endif
   48 //
   49 // End of BSD patch
   50 //
   51 #include <string.h>
   52 #include <stdint.h>
   53 #include <sys/resource.h>
   54 
   55 //
   56 // The line below is from a patch contributed by Yen-Ming Lee
   57 // to make ChironFS run on FreeBSD
   58 //  But it works in Linux and NetBSD as well
   59 //
   60 #include <sys/sysctl.h>
   61 //
   62 // End of Yen-Ming Lee patch
   63 //
   64 
   65 #include "chiron-types.h"
   66 #include "chirondbg.h"
   67 #include "chironfs.h"
   68 #include "chironfn.h"
   69 
   70 
   71 void print_paths()
   72 {
   73    int i, j;
   74    dbg(("\n(%s):",mount_point));
   75    for(i=0;i<max_replica;++i) {
   76       dbg(("\n   (%s)",paths[i].path));
   77    }
   78    dbg(("\nHIGH\n"));
   79    for(i=0;i<max_replica_high;++i) {
   80       dbg(("\n("));
   81       for(j=0;j<max_replica_high;++j) {
   82          dbg(("%d ",round_robin_high[i][j]));
   83       }
   84       dbg((")"));
   85    }
   86    dbg(("\nLOW\n"));
   87    for(i=0;i<max_replica_low;++i) {
   88       dbg(("\n("));
   89       for(j=0;j<max_replica_low;++j) {
   90          dbg(("%d ",round_robin_low[i][j]));
   91       }
   92       dbg((")"));
   93    }
   94    dbg(("\n"));
   95 }
   96 
   97 void free_paths()
   98 {
   99    int i;
  100    if (mount_point!=NULL) {
  101       free(mount_point);
  102    }
  103    if (paths[0].path!=NULL) {
  104       if (strcmp(paths[0].path,".")) {
  105          free(paths[0].path);
  106          paths[0].path = NULL;
  107       }
  108    }
  109    for(i=1;i<max_replica;++i) {
  110       if (paths[i].path!=NULL) {
  111          free(paths[i].path);
  112          paths[i].path = NULL;
  113       }
  114    }
  115    free(paths);
  116    if (logfd!=NULL) {
  117       fclose(logfd);
  118       logfd = NULL;
  119    }
  120 }
  121 
  122 void free_tab_fd()
  123 {
  124 //   int i;
  125 //      while (i<max_replica) {
  126 //         free(tab_fd.fd[i++]);
  127 //      }
  128       free(tab_fd.fd);
  129 }
  130 
  131 void free_round_robin(int **rr, int max_rep)
  132 {
  133    int i;
  134    if (rr!=NULL) {
  135       for(i=0;i<max_rep;++i) {
  136          if (rr[i]!=NULL) {
  137             free(rr[i]);
  138             rr[i] = NULL;
  139          }
  140       }
  141       free(rr);
  142    }
  143 }
  144 
  145 
  146 void opt_parse(char *fo, char**logname, char**argvbuf)
  147 {
  148    int    opt, start, dest;
  149    size_t i, len;
  150 
  151    start = opt = i = 0;
  152    len   = strlen(fo);
  153    do {
  154       if ((!fo[i]) || (fo[i]==',')) {
  155          if (!strncmp(fo+start,"log",3)) {
  156             fo[i] = 0;
  157             (*logname) = chiron_realpath(fo+start+4);
  158             if ((*logname)==NULL) {
  159                print_err(errno,fo+start+4);
  160                exit(errno);
  161             }
  162                                                                      dbg(("\nlog=%s", fo+start));
  163             if (start) {
  164                dest = start-1;
  165             } else {
  166                dest = start;
  167             }
  168             sprintf(fo+dest,"%s",fo+start+4+strlen(*logname));
  169             len -= i - start + 1;
  170             i = start - 1;
  171          } else if (!strncmp(fo+start,"fsname",6)) {
  172             fo[i] = 0;
  173             (*argvbuf) = strdup(fo+start);
  174             if ((*argvbuf)==NULL) {
  175                print_err(CHIRONFS_ERR_LOW_MEMORY,"fsname allocation");
  176                exit(CHIRONFS_ERR_LOW_MEMORY);
  177             }
  178                                                                      dbg(("\nfsname=%s", fo+start));
  179             if (start) {
  180                dest = start-1;
  181             } else {
  182                dest = start;
  183             }
  184             sprintf(fo+dest,"%s",fo+start+strlen(*argvbuf));
  185             len -= i - start + 1;
  186             i = start - 1;
  187          } else if (!strncmp(fo+start,"quiet",5)) {
  188             fo[i] = 0;
  189             quiet_mode = 1;
  190             sprintf(fo+start,"%s",fo+6);
  191             i = start - 1;
  192          } else {
  193             start = i + 1;
  194          }
  195       }
  196       i++;
  197                                                                            dbg(("\n%s",fo));
  198    } while (i<=len);
  199 }
  200 
  201 int **mk_round_robin(int *tmp_list,int dim)
  202 {
  203    int **round_robin, j, i;
  204 
  205    round_robin = calloc(dim,sizeof(int *));
  206    if (round_robin!=NULL) {
  207       for(i=0;i<dim;++i) {
  208          round_robin[i] = calloc(dim,sizeof(int));
  209          if (round_robin[i]==NULL) {
  210             while (i) {
  211                free(round_robin[--i]);
  212             }
  213             free(round_robin);
  214             return(NULL);
  215          }
  216          for(j=0;j<dim;++j) {
  217             if ((j+i)<dim) {
  218                round_robin[i][j] = tmp_list[j+i];
  219             } else {
  220                round_robin[i][j] = tmp_list[j+i-dim];
  221             }
  222          }
  223       }
  224    }
  225    return(round_robin);
  226 }
  227 
  228 
  229 #ifndef __linux__
  230 
  231 /*
  232  * This function was originally written by Antti Kantee
  233  * Changed by Luis Otavio de Colla Furquim to test the return
  234  * result from malloc and, in case of failure, return NULL
  235  * without calling realpath.
  236  * Yen-Ming Lee has sent another patch, porting ChironFS to
  237  * FreeBSD also solving this problem
  238  */
  239 char *do_realpath(const char *path, char *resolvedpath)
  240 {
  241 
  242    if (resolvedpath == NULL) {
  243       if (!(resolvedpath = malloc(PATH_MAX))) {
  244          return(NULL);
  245       }
  246    }
  247    return realpath(path, resolvedpath);
  248 }
  249 
  250 #endif
  251 
  252 
  253 
  254 int do_mount(char *filesystems, char *mountpoint)
  255 {
  256    int    i, start, res, errno, rep_on_mount=0, err;
  257    int    *tmp_high, *tmp_low;
  258    unsigned long tmpfd;
  259    struct rlimit rlp;
  260    int    oldval;
  261    size_t oldlenp = sizeof(oldval);
  262    int    sysctl_names[] = {
  263 #ifdef __linux__
  264       CTL_FS, FS_MAXFILE
  265 #else
  266       CTL_KERN, KERN_MAXFILES
  267 #endif
  268    };
  269 
  270 
  271 
  272 
  273    for(max_replica=1,i=0;filesystems[i];++i) {
  274       if (filesystems[i]=='=') {
  275         ++max_replica;
  276          filesystems[i] = 0;
  277       }
  278    }
  279 
  280    if (mountpoint[0]==':') {
  281       max_replica++;
  282    }
  283 
  284    res = sysctl (sysctl_names, 2, &oldval, &oldlenp, NULL, 0);
  285    if (res) {
  286       print_err(errno,"reading system parameter 'max open files'");
  287       FD_BUF_SIZE = 4096;
  288    } else {
  289       FD_BUF_SIZE = (long long unsigned int) oldval;
  290    }
  291 
  292    tmpfd = (FD_BUF_SIZE >>= 1);
  293 
  294    if (getrlimit(CHIRON_LIMIT,&rlp)) {
  295       print_err(errno,"reading nofile resource limit");
  296       exit(errno);
  297    }
  298                                                          dbg(("\n1cur:%d\tmax:%d",rlp.rlim_cur,rlp.rlim_max));
  299    rlp.rlim_max = tmpfd;
  300                                                          dbg(("\n2cur:%d\tmax:%d",rlp.rlim_cur,rlp.rlim_max));
  301    if (rlp.rlim_cur<rlp.rlim_max) {
  302       rlp.rlim_cur = rlp.rlim_max;
  303                                                          dbg(("\n3cur:%d\tmax:%d",rlp.rlim_cur,rlp.rlim_max));
  304       if (setrlimit(RLIMIT_NOFILE,&rlp)) {
  305                                                          dbg(("\n4cur:%d\tmax:%d",rlp.rlim_cur,rlp.rlim_max));
  306          if (getrlimit(RLIMIT_NOFILE,&rlp)) {
  307             print_err(errno,"reading nofile resource limit, second attempt");
  308             exit(errno);
  309          }
  310       }
  311    }
  312                                                          dbg(("\n5cur:%d\tmax:%d",rlp.rlim_cur,rlp.rlim_max));
  313 
  314                                                          dbg(("\n1tmpfd:%d",tmpfd));
  315    tmpfd = (rlp.rlim_cur<tmpfd)
  316          ? rlp.rlim_cur
  317          : tmpfd;
  318                                                          dbg(("\n2tmpfd:%d",tmpfd));
  319 
  320    tmpfd = (tmpfd - 6) / max_replica;
  321 
  322                                                          dbg(("\n3tmpfd:%d",tmpfd));
  323    while (tmpfd) {
  324       qt_hash_bits++;
  325       hash_mask = hash_mask<<1 | 1;
  326       tmpfd >>= 1;
  327    }
  328    hash_mask >>= 1;
  329    FD_BUF_SIZE = hash_mask;
  330                                                          dbg(("\nhash_mask:%x",hash_mask));
  331 
  332    tab_fd.fd = calloc(FD_BUF_SIZE,sizeof(int *));
  333    if (tab_fd.fd==NULL) {
  334       print_err(CHIRONFS_ERR_LOW_MEMORY,"file descriptor hash table allocation");
  335       exit(CHIRONFS_ERR_LOW_MEMORY);
  336    }
  337 
  338    for(i=0;((unsigned)i)<FD_BUF_SIZE;++i) {
  339       tab_fd.fd[i] = NULL;
  340    }
  341 
  342    paths = calloc(max_replica,sizeof(path_t));
  343    if (paths==NULL) {
  344       free_paths();
  345       free_tab_fd();
  346       print_err(errno,"replica info allocation");
  347       exit(errno);
  348    }
  349    for(i=0;i<max_replica;++i) {
  350       paths[i].path     = NULL;
  351       paths[i].disabled = (time_t)0;
  352       paths[i].priority = 0;
  353    }
  354 
  355    tmp_high = calloc(max_replica,sizeof(int));
  356    if (tmp_high==NULL) {
  357       free_paths();
  358       free_tab_fd();
  359       print_err(errno,"high priority round robin table allocation");
  360       exit(errno);
  361    }
  362 
  363    tmp_low = calloc(max_replica,sizeof(int));
  364    if (tmp_low==NULL) {
  365       free_paths();
  366       free(tmp_high);
  367       free_tab_fd();
  368       print_err(errno,"low priority round robin table allocation");
  369       exit(errno);
  370    }
  371 
  372    if (mountpoint[0]==':') {
  373       mount_point = do_realpath(mountpoint+1,NULL);
  374       rep_on_mount = i = 1;
  375       tmp_high[max_replica_high++] = 0;
  376    } else {
  377       mount_point = do_realpath(mountpoint,NULL);
  378       i = 0;
  379    }
  380    if (mount_point==NULL) {
  381       err = errno;
  382       free_tab_fd();
  383       print_err(err,mountpoint);
  384       exit(err);
  385    }
  386 
  387    start = 0;
  388    for(;i<max_replica;++i) {
  389       if (filesystems[start]==':') {
  390          start++;
  391          paths[i].priority = 1;
  392          tmp_low[max_replica_low++] = i;
  393       } else {
  394          tmp_high[max_replica_high++] = i;
  395       }
  396 
  397       paths[i].path = do_realpath(filesystems+start, NULL);
  398       if (paths[i].path==NULL) {
  399          free_paths();
  400          free_tab_fd();
  401          free(tmp_high);
  402          free(tmp_low);
  403          print_err(errno,filesystems+start);
  404          exit(errno);
  405       }
  406       // just to store it and avoid future recalculations
  407       paths[i].pathlen = strlen(paths[i].path);
  408       start += strlen(filesystems+start) + 1;
  409       if (paths[i].priority) {
  410          call_log("replica priority low",paths[i].path,0);
  411                                              dbg(("\nreplica low: %s",paths[i].path));
  412       } else {
  413          call_log("replica priority high",paths[i].path,0);
  414                                              dbg(("\nreplica high: %s",paths[i].path));
  415       }
  416    }
  417 
  418    if (rep_on_mount) {
  419       paths[0].path = currdir;
  420       chdir(mount_point);
  421    }
  422 
  423    if (logname!=NULL) {
  424       attach_log();
  425    }
  426 
  427    round_robin_high = mk_round_robin(tmp_high,max_replica_high);
  428    if (round_robin_high==NULL) {
  429       free_paths();
  430       free_tab_fd();
  431       free(tmp_high);
  432       free(tmp_low);
  433       print_err(CHIRONFS_ERR_LOW_MEMORY,"high priority round robin state table allocation");
  434       exit(CHIRONFS_ERR_LOW_MEMORY);
  435    }
  436    free(tmp_high);
  437 
  438    round_robin_low = mk_round_robin(tmp_low,max_replica_low);
  439    if (round_robin_low==NULL) {
  440       free_paths();
  441       free(tmp_low);
  442       free_round_robin(round_robin_high,max_replica_high);
  443       free_tab_fd();
  444       print_err(CHIRONFS_ERR_LOW_MEMORY,"low priority round robin state table allocation");
  445       exit(CHIRONFS_ERR_LOW_MEMORY);
  446    }
  447    free(tmp_low);
  448 
  449    print_paths();
  450 
  451    return(0);
  452 }
  453 
  454