Changeset 2569

Show
Ignore:
Timestamp:
07/22/07 19:24:29 (1 year ago)
Author:
dhozac
Message:

Add exclude list support for vclone.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/lib_internal/Makefile-files

    r2255 r2569  
    102102                                lib_internal/util-lockfile.c \ 
    103103                                lib_internal/util-safechdir.c \ 
     104                                lib_internal/mkdir.c \ 
    104105                                $(command_SRCS) \ 
    105106                                $(filecfg_SRCS) 
  • trunk/lib_internal/matchlist-compare.c

    r1423 r2569  
    3838  } 
    3939 
    40   return stINCLUDE; 
     40  return list->skip_depth > 0 ? stEXCLUDE : stINCLUDE; 
    4141} 
  • trunk/lib_internal/testsuite

    • Property svn:ignore changed from
      .deps
      .dirstamp
      .libs
      .libs
      .nfs0*
      command
      copy
      filecfg-ml
      isnumber
      isnumber-gnu
      sigbus
      sigbus-gnu
      to
      .deps
      .dirstamp
      .libs
      .libs
      .nfs0*
      command
      copy
      filecfg-ml
      isnumber
      isnumber-gnu
      sigbus
      sigbus-gnu
      matchlist
      matchlist-gnu
  • trunk/lib_internal/testsuite/Makefile-files

    r2545 r2569  
    2424                                lib_internal/testsuite/isnumber-gnu \ 
    2525                                lib_internal/testsuite/sigbus \ 
    26                                 lib_internal/testsuite/sigbus-gnu 
     26                                lib_internal/testsuite/sigbus-gnu \ 
     27                                lib_internal/testsuite/matchlist \ 
     28                                lib_internal/testsuite/matchlist-gnu 
    2729TESTS +=                        lib_internal/testsuite/filecfg-ml \ 
    2830                                lib_internal/testsuite/copy-check \ 
     
    3032                                lib_internal/testsuite/isnumber-gnu \ 
    3133                                lib_internal/testsuite/sigbus \ 
    32                                 lib_internal/testsuite/sigbus-gnu 
     34                                lib_internal/testsuite/sigbus-gnu \ 
     35                                lib_internal/testsuite/matchlist \ 
     36                                lib_internal/testsuite/matchlist-gnu 
    3337endif 
    3438 
    3539DIETPROGS +=                    lib_internal/testsuite/isnumber \ 
    36                                 lib_internal/testsuite/sigbus 
     40                                lib_internal/testsuite/sigbus \ 
     41                                lib_internal/testsuite/matchlist 
    3742 
    3843EXTRA_DIST +=                   lib_internal/testsuite/copy-check 
     
    6772lib_internal_testsuite_sigbus_gnu_SOURCES =     lib_internal/testsuite/sigbus.c 
    6873lib_internal_testsuite_sigbus_gnu_CPPFLAGS =    $(AM_CPPFLAGS)          # see note above 
     74 
     75lib_internal_testsuite_matchlist_SOURCES =      lib_internal/testsuite/matchlist.c 
     76lib_internal_testsuite_matchlist_LDADD =        $(LIBINTERNAL) 
     77lib_internal_testsuite_matchlist_CPPFLAGS =     $(AM_CPPFLAGS)          # see note above 
     78 
     79lib_internal_testsuite_matchlist_gnu_SOURCES =  lib_internal/testsuite/matchlist.c 
     80lib_internal_testsuite_matchlist_gnu_LDADD =    $(LIBINTERNAL_GLIBC) 
     81lib_internal_testsuite_matchlist_gnu_CPPFLAGS = $(AM_CPPFLAGS)          # see note above 
  • trunk/lib_internal/util.h

    r2255 r2569  
    3838bool            isNumber(char const *, signed long *result, bool is_strict); 
    3939bool            isNumberUnsigned(char const *, unsigned long *result, bool is_strict); 
     40bool            mkdirRecursive(char const *); 
    4041 
    4142#endif  //  H_UTILVSERVER_LIB_INTERNAL_UTIL_H 
  • trunk/src/vclone.c

    r2559 r2569  
    2626#include "lib_internal/pathinfo.h" 
    2727#include "lib_internal/unify.h" 
     28#include "lib_internal/matchlist.h" 
    2829 
    2930#include <unistd.h> 
     
    5051struct WalkdownInfo 
    5152{ 
    52     PathInfo    state; 
    53     PathInfo    src; 
    54     PathInfo    dst; 
     53    PathInfo            state; 
     54    PathInfo            src; 
     55    PathInfo            dst; 
     56    struct MatchList    excludes; 
    5557}; 
    5658 
     
    5860    unsigned int        verbosity; 
    5961    xid_t               xid; 
     62    const char *        exclude_list; 
    6063}; 
    6164 
     
    6770struct option const 
    6871CMDLINE_OPTIONS[] = { 
    69   { "help",     no_argument,       0, CMD_HELP }, 
    70   { "version",  no_argument,       0, CMD_VERSION }, 
    71   { "xid",      required_argument, 0, CMD_XID }, 
     72  { "help",         no_argument,       0, CMD_HELP }, 
     73  { "version",      no_argument,       0, CMD_VERSION }, 
     74  { "xid",          required_argument, 0, CMD_XID }, 
     75  { "exclude-from", required_argument, 0, 'X' }, 
    7276  { 0,0,0,0 } 
    7377}; 
     
    8286  WRITE_STR(fd, cmd); 
    8387  WRITE_MSG(fd, 
    84             " [--xid <xid>] <source> <absolute path to destination>\n\n" 
     88            " [--xid <xid>] [--exclude-from <exclude-list>]\n" 
     89            "         <source> <absolute path to destination>\n\n" 
    8590            "Please report bugs to " PACKAGE_BUGREPORT "\n"); 
    8691  exit(res); 
     
    108113#include "vserver-visitdir.hc" 
    109114 
     115static bool 
     116handleDirEntry(const PathInfo *src_path, const PathInfo *basename, 
     117              bool *is_dir, struct stat *st) 
     118{ 
     119  bool res = false; 
     120 
     121  *is_dir = false; 
     122 
     123  if (lstat(basename->d, st)==-1) 
     124    PERROR_Q(ENSC_WRAPPERS_PREFIX "lstat", src_path->d); 
     125  else { 
     126    PathInfo            dst_path = global_info.dst; 
     127    char                dst_path_buf[ENSC_PI_APPSZ(dst_path, *src_path)]; 
     128 
     129    if (S_ISDIR(st->st_mode)) 
     130      *is_dir = true; 
     131 
     132    if (MatchList_compare(&global_info.excludes, src_path->d) != stINCLUDE) { 
     133      if (Global_getVerbosity() > 1) { 
     134        WRITE_MSG(1, "  skipping '"); 
     135        Vwrite(1, src_path->d, src_path->l); 
     136        WRITE_MSG(1, "' (excluded)\n"); 
     137      } 
     138      return false; 
     139    } 
     140 
     141    PathInfo_append(&dst_path, src_path, dst_path_buf); 
     142 
     143    /* skip files that already exist */ 
     144    if (access(dst_path.d, F_OK)!=-1) { 
     145      if (Global_getVerbosity() > 1) { 
     146        WRITE_MSG(1, "  skipping '"); 
     147        Vwrite(1, src_path->d, src_path->l); 
     148        WRITE_MSG(1, "' (exists in destination)\n"); 
     149      } 
     150      res = true; 
     151    } 
     152    else { 
     153      /* create directory that might have been skipped */ 
     154      if (global_info.excludes.skip_depth > 0) { 
     155        if (Global_getVerbosity() > 4) { 
     156          WRITE_MSG(1, "  creating directories for '"); 
     157          Vwrite(1, dst_path.d, dst_path.l); 
     158          WRITE_MSG(1, "'\n"); 
     159        } 
     160        if (mkdirRecursive(dst_path.d) == -1) 
     161          PERROR_Q(ENSC_WRAPPERS_PREFIX "mkdirRecursive", dst_path.d); 
     162      } 
     163 
     164      /* already unified file */ 
     165      if (S_ISREG(st->st_mode) && Unify_isIUnlinkable(basename->d) == unifyBUSY) { 
     166        if (Global_getVerbosity() > 2) { 
     167          WRITE_MSG(1, "  linking unified file '"); 
     168          Vwrite(1, src_path->d, src_path->l); 
     169          WRITE_MSG(1, "'\n"); 
     170        } 
     171        Elink(basename->d, dst_path.d); 
     172        res = true; 
     173      } 
     174      /* something we have to copy */ 
     175      else { 
     176        if (Global_getVerbosity() > 2) { 
     177          WRITE_MSG(1, "  copying non-unified file '"); 
     178          Vwrite(1, src_path->d, src_path->l); 
     179          WRITE_MSG(1, "'\n"); 
     180        } 
     181        if (!Unify_copy(basename->d, st, dst_path.d)) 
     182          PERROR_Q(ENSC_WRAPPERS_PREFIX "Unify_copy", dst_path.d); 
     183        else if (global_args->xid != VC_NOCTX && 
     184                 vc_set_iattr(dst_path.d, global_args->xid, 0, VC_IATTR_XID) == -1) 
     185          PERROR_Q(ENSC_WRAPPERS_PREFIX "vc_set_iattr", dst_path.d); 
     186        else 
     187          res = true; 
     188      } 
     189    } 
     190  } 
     191 
     192  return res; 
     193} 
     194 
     195/* returns 1 on error, 0 on success */ 
    110196static uint64_t 
    111197visitDirEntry(struct dirent const *ent) 
     
    122208  char                          path_buf[ENSC_PI_APPSZ(src_path, src_d_path)]; 
    123209  struct stat                   f_stat = { .st_dev = 0 }; 
     210  bool                          is_dir; 
    124211 
    125212  PathInfo_append(&src_path, &src_d_path, path_buf); 
    126213 
    127    
    128   if (lstat(dirname, &f_stat)==-1) 
    129     perror(ENSC_WRAPPERS_PREFIX "lstat()"); 
    130   else { 
    131     PathInfo            dst_path = global_info.dst; 
    132     char                dst_path_buf[ENSC_PI_APPSZ(dst_path, src_path)]; 
    133  
    134     PathInfo_append(&dst_path, &src_path, dst_path_buf); 
    135  
    136     /* skip files that already exist */ 
    137     if (access(dst_path.d, F_OK)!=-1) 
    138       res = 0; 
    139     else if (S_ISREG(f_stat.st_mode) && Unify_isIUnlinkable(src_d_path.d) == unifyBUSY) { 
    140       Elink(src_d_path.d, dst_path.d); 
    141       res = 0; 
    142     } 
    143     else { 
    144       if (!Unify_copy(src_d_path.d, &f_stat, dst_path.d)) 
    145         perror(ENSC_WRAPPERS_PREFIX "Unify_copy()"); 
    146       else if (vc_set_iattr(dst_path.d, global_args->xid, 0, VC_IATTR_XID) == -1) 
    147         perror(ENSC_WRAPPERS_PREFIX "vc_set_iattr()"); 
    148       else 
    149         res = 0; 
    150     } 
    151     if (S_ISDIR(f_stat.st_mode)) 
    152       res = visitDir(dirname, &f_stat); 
     214  if (handleDirEntry(&src_path, &src_d_path, &is_dir, &f_stat)) 
     215    res = 0; 
     216 
     217  if (is_dir) { 
     218    if (res || global_info.excludes.skip_depth > 0) 
     219      global_info.excludes.skip_depth++; 
     220    res = res + visitDir(dirname, &f_stat); 
     221    if (global_info.excludes.skip_depth > 0) 
     222      global_info.excludes.skip_depth--; 
    153223  } 
    154224 
     
    161231    .verbosity          =  0, 
    162232    .xid                = VC_NOCTX, 
     233    .exclude_list       = NULL, 
    163234  }; 
    164235  uint64_t              res; 
     
    167238  global_args = &args; 
    168239  while (1) { 
    169     int         c = getopt_long(argc, argv, "+v", 
     240    int         c = getopt_long(argc, argv, "+vX:", 
    170241                                CMDLINE_OPTIONS, 0); 
    171242    if (c==-1) break; 
     
    175246      case CMD_VERSION  :  showVersion(); 
    176247      case 'v'          :  args.verbosity++; break; 
     248      case 'X'          :  args.exclude_list = optarg; break; 
    177249      case CMD_XID      :  args.xid = Evc_xidopt2xid(optarg,true); break; 
    178250      default           : 
     
    213285  ENSC_PI_SETSTR(global_info.dst, argv[optind+1]); 
    214286 
     287  if (global_args->exclude_list) 
     288    MatchList_initManually(&global_info.excludes, 0, strdup(argv[optind]), 
     289                           global_args->exclude_list); 
     290  else 
     291    MatchList_init(&global_info.excludes, argv[optind], 0); 
     292 
    215293  if (global_args->verbosity>3) 
    216294    WRITE_MSG(1, "Starting to traverse directories...\n"); 
     
    218296  Echdir(global_info.src.d); 
    219297  res = visitDir("/", 0); 
     298 
     299  MatchList_destroy(&global_info.excludes); 
    220300   
    221301  return res>0 ? 1 : 0; 
  • trunk/src/vhashify.c

    r2475 r2569  
    394394} 
    395395 
    396 static enum { mkdirFAIL, mkdirSUCCESS, mkdirSKIP } 
    397 mkdirSingle(char const *path, char *end_ptr, int good_err) 
    398 { 
    399   *end_ptr = '\0'; 
    400   if (mkdir(path, 0700)!=-1 || errno==EEXIST) { 
    401     *end_ptr = '/'; 
    402     return mkdirSUCCESS; 
    403   } 
    404   else if (errno==good_err) { 
    405     *end_ptr = '/'; 
    406     return mkdirSKIP; 
    407   } 
    408   else { 
    409     int         old_errno = errno; 
    410     WRITE_MSG(2, "mkdir('"); 
    411     WRITE_STR(2, path); 
    412     errno = old_errno; 
    413     perror("')"); 
    414     return mkdirFAIL; 
    415   } 
    416 } 
    417  
    418 static char * 
    419 rstrchr(char *str, char c) 
    420 { 
    421   while (*str!=c) --str; 
    422   return str; 
    423 } 
    424  
    425 static bool 
    426 mkdirRecursive(char const *path) 
    427 { 
    428   if (path[0]!='/')      return false; // only absolute paths 
    429  
    430   char                  buf[strlen(path)+1]; 
    431   char *                ptr = buf + sizeof(buf) - 2; 
    432  
    433   strcpy(buf, path); 
    434  
    435   while (ptr>buf && (ptr = rstrchr(ptr, '/'))!=0) { 
    436     switch (mkdirSingle(buf, ptr, ENOENT)) { 
    437       case mkdirSUCCESS         :  break; 
    438       case mkdirSKIP            :  --ptr; continue; 
    439       case mkdirFAIL            :  return false; 
    440     } 
    441  
    442     break;      // implied by mkdirSUCCESS 
    443   } 
    444  
    445   assert(ptr!=0); 
    446   ++ptr; 
    447  
    448   while ((ptr=strchr(ptr, '/'))!=0) { 
    449     switch (mkdirSingle(buf, ptr, 0)) { 
    450       case mkdirSKIP            : 
    451       case mkdirFAIL            :  return false; 
    452       case mkdirSUCCESS         :  ++ptr; continue; 
    453     } 
    454   } 
    455  
    456   return true; 
    457 } 
    458  
    459396static bool 
    460397resolveCollisions(char *result, PathInfo const *root, HashPath d_path, 
     
    498435    if (!global_args->dry_run) { 
    499436      *ptr = '\0'; 
    500       if (!mkdirRecursive(result)) 
     437      if (!mkdirRecursive(result)) { 
     438        PERROR_Q("mkdir", result); 
    501439        return false; 
     440      } 
    502441      *ptr = '-'; 
    503442 
     
    505444 
    506445      if (fd==-1) { 
    507         int             old_errno = errno; 
    508         WRITE_MSG(2, "open('"); 
    509         WRITE_STR(2, buf); 
    510         errno = old_errno; 
    511         perror("')"); 
     446        PERROR_Q("open", buf); 
    512447        return false; 
    513448      }