~ubuntu-branches/ubuntu/wily/trafficserver/wily

« back to all changes in this revision

Viewing changes to mgmt/Rollback.cc

  • Committer: Package Import Robot
  • Author(s): Adam Conrad
  • Date: 2012-12-17 22:28:16 UTC
  • mfrom: (5.1.8 raring-proposed)
  • Revision ID: package-import@ubuntu.com-20121217222816-7xwjsx5k76zkb63d
Tags: 3.2.0-1ubuntu1
* Revert FreeBSD strerror_r() fixes that give errors with glibc 2.16.
* Apply patch from Konstantinos Margaritis to define barriers on ARM.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/** @file
2
2
 
3
 
  A brief file description
 
3
  This file contains code for class to allow rollback of configuration files 
4
4
 
5
5
  @section license License
6
6
 
21
21
  limitations under the License.
22
22
 */
23
23
 
24
 
/****************************************************************************/
25
24
#include "libts.h"
26
25
#include "LocalManager.h"
27
26
#include "Rollback.h"
31
30
#include "ExpandingArray.h"
32
31
#include "MgmtSocket.h"
33
32
 
34
 
/****************************************************************************
35
 
 *
36
 
 *  Rollback.cc - code  for class to allow rollback of configuration
37
 
 *                  files
38
 
 *
39
 
 *
40
 
 ****************************************************************************/
41
33
 
42
34
#define MAX_VERSION_DIGITS 11
43
35
#define DEFAULT_BACKUPS 2
76
68
  // Copy the file name
77
69
  fileNameLen = strlen(baseFileName);
78
70
  fileName = new char[fileNameLen + 1];
79
 
  ink_strncpy(fileName, baseFileName, fileNameLen + 1);
 
71
  ink_strlcpy(fileName, baseFileName, fileNameLen + 1);
80
72
 
81
73
 
82
74
  // Get the configuration directory - SHOULD BE CENTRALIZED SOMEWHERE
156
148
      }
157
149
 
158
150
      if (needZeroLength == true) {
159
 
#ifndef _WIN32
160
151
        int fd = openFile(ACTIVE_VERSION, O_RDWR | O_CREAT);
161
 
#else
162
 
        int fd = openFile(ACTIVE_VERSION, O_RDWR | O_CREAT | O_BINARY);
163
 
#endif
164
152
        if (fd >= 0) {
165
 
          alarmMsg = (char *) xmalloc(2048);
 
153
          alarmMsg = (char *)ats_malloc(2048);
166
154
          snprintf(alarmMsg, 2048, "Created zero length place holder for config file %s", fileName);
167
155
          mgmt_log(stderr, "[RollBack::Rollback] %s\n", alarmMsg);
168
156
          lmgmt->alarm_keeper->signalAlarm(MGMT_ALARM_CONFIG_UPDATE_FAILED, alarmMsg);
169
 
          xfree(alarmMsg);
 
157
          ats_free(alarmMsg);
170
158
          closeFile(fd);
171
159
        } else {
172
160
          mgmt_fatal(stderr,
223
211
  testFD = openFile(ACTIVE_VERSION, O_RDWR, &testErrno);
224
212
  if (testFD < 0) {
225
213
    // We failed to open read-write
226
 
    alarmMsg = (char *) xmalloc(2048);
 
214
    alarmMsg = (char *)ats_malloc(2048);
227
215
    testFD = openFile(ACTIVE_VERSION, O_RDONLY, &testErrno);
228
216
 
229
217
    if (testFD < 0) {
240
228
      lmgmt->alarm_keeper->signalAlarm(MGMT_ALARM_CONFIG_UPDATE_FAILED, alarmMsg);
241
229
      closeFile(testFD);
242
230
    }
243
 
    xfree(alarmMsg);
 
231
    ats_free(alarmMsg);
244
232
  } else {
245
233
    closeFile(testFD);
246
234
  }
376
364
    }
377
365
    mgmt_log(stderr, "[Rollback::openFile] Open of %s failed: %s\n", fileName, strerror(errno));
378
366
  }
379
 
#ifndef _WIN32                  // no need to set close-on-exec on NT
 
367
 
380
368
  fcntl(fd, F_SETFD, 1);
381
 
#endif
382
369
 
383
370
  delete[]filePath;
384
371
 
388
375
int
389
376
Rollback::closeFile(int fd)
390
377
{
391
 
#ifndef _WIN32
392
378
  if (fsync(fd) == -1) {
393
379
    // INKqa11574: SGI fsync will return EBADF error if the file was
394
380
    // open w/o write access (e.g. read-only).  Do not print an error
398
384
      mgmt_log(stderr, "[Rollback::closeFile] fsync failed for file '%s' (%d: %s)\n", fileName, errno, strerror(errno));
399
385
    }
400
386
  }
401
 
#endif /* _WIN32 */
402
387
  return (close(fd));
403
388
}
404
389
 
494
479
 
495
480
  // Create the new configuration file
496
481
  // TODO: Make sure they are not created in Sysconfigdir!
497
 
#ifndef _WIN32
498
482
  diskFD = openFile(newVersion, O_WRONLY | O_CREAT | O_TRUNC);
499
 
#else
500
 
  diskFD = openFile(newVersion, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY);
501
 
#endif
502
483
 
503
484
  if (diskFD < 0) {
504
485
    // Could not create the new file.  The operation is aborted
514
495
    returnCode = SYS_CALL_ERROR_ROLLBACK;
515
496
    goto UPDATE_CLEANUP;
516
497
  }
517
 
#ifndef _WIN32
518
498
 
519
499
  // Now that we got a the new version on the disk lets do some renaming
520
500
  if (link(activeVersion, currentVersion_local) < 0) {
541
521
    returnCode = SYS_CALL_ERROR_ROLLBACK;
542
522
    goto UPDATE_CLEANUP;
543
523
  }
544
 
#else
545
 
 
546
 
  // have to use CopyFile() because there is no sym link on NT
547
 
  if (strcmp(activeVersion, currentVersion_local) != 0) {
548
 
    if (CopyFile(activeVersion, currentVersion_local, FALSE) == FALSE) {
549
 
      mgmt_log(stderr, "[Rollback::internalUpdate] CopyFile failed : %s\n", ink_last_err());
550
 
      DWORD lastError = GetLastError();
551
 
      if (lastError == ERROR_FILE_NOT_FOUND || lastError == ERROR_PATH_NOT_FOUND) {
552
 
        mgmt_log(stderr,
553
 
                 "[Rollback::internalUpdate] The active version of %s was lost.\n\tThe updated copy was installed.\n",
554
 
                 fileName);
555
 
        failedLink = true;
556
 
      } else {
557
 
        returnCode = SYS_CALL_ERROR_ROLLBACK;
558
 
        goto UPDATE_CLEANUP;
559
 
      }
560
 
    }
561
 
  }
562
 
 
563
 
  if (MoveFileEx(nextVersion, activeVersion, MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH) == FALSE) {
564
 
    mgmt_log(stderr, "[Rollback::internalUpdate] MoveFileEx failed : %s\n", ink_last_err());
565
 
    mgmt_log(stderr, "[Rollback::internalUpdate] Unable to create new version of %s.  Using prior version\n", fileName);
566
 
 
567
 
    returnCode = SYS_CALL_ERROR_ROLLBACK;
568
 
    goto UPDATE_CLEANUP;
569
 
  }
570
 
#endif
571
524
 
572
525
  // Now we need to get the modification time off of the new active file
573
526
  if (statFile(ACTIVE_VERSION, &fileInfo) >= 0) {
619
572
  //   to manipulate the disk, the error might not get
620
573
  //   written to disk
621
574
  if (returnCode != OK_ROLLBACK) {
622
 
    alarmMsg = (char *) xmalloc(1024);
 
575
    alarmMsg = (char *)ats_malloc(1024);
623
576
    snprintf(alarmMsg, 1024, "[TrafficManager] Configuration File Update Failed: %s", strerror(errno));
624
577
    lmgmt->alarm_keeper->signalAlarm(MGMT_ALARM_CONFIG_UPDATE_FAILED, alarmMsg);
625
 
    xfree(alarmMsg);
 
578
    ats_free(alarmMsg);
626
579
 
627
580
    // Remove both the link from currentVersion_local
628
581
    // to the active version and the new version
668
621
  if (version == currentVersion) {
669
622
    version = ACTIVE_VERSION;
670
623
  }
671
 
#ifndef _WIN32
672
624
  diskFD = openFile(version, O_RDONLY);
673
 
#else
674
 
  // - Specify O_BINARY on WIN32 because we don't want the CR-LF
675
 
  //   sequences to be translated.
676
 
  // - If we don't open with O_BINARY, the size we get from fstat()
677
 
  //   would not match with # bytes read from the file.
678
 
  diskFD = openFile(version, O_RDONLY | O_BINARY);
679
 
#endif
680
625
 
681
626
  if (diskFD < 0) {
682
627
    returnCode = FILE_NOT_FOUND_ROLLBACK;
794
739
  int count = 0;
795
740
  version_t highestSeen = 0, version = 0;
796
741
 
797
 
#ifndef _WIN32
798
 
 
799
742
  DIR *dir;
800
743
  struct dirent *dirEntrySpace;
801
744
  struct dirent *entryPtr;
810
753
  // The fun of Solaris - readdir_r requires a buffer passed into it
811
754
  //   The man page says this obscene expression gives us the proper
812
755
  //     size
813
 
  dirEntrySpace = (struct dirent *) xmalloc(sizeof(struct dirent) + pathconf(".", _PC_NAME_MAX) + 1);
 
756
  dirEntrySpace = (struct dirent *)ats_malloc(sizeof(struct dirent) + pathconf(".", _PC_NAME_MAX) + 1);
814
757
 
815
758
  while (readdir_r(dir, dirEntrySpace, &entryPtr) == 0) {
816
759
    if (!entryPtr)
828
771
 
829
772
  }
830
773
 
831
 
  xfree(dirEntrySpace);
 
774
  ats_free(dirEntrySpace);
832
775
  closedir(dir);
833
776
 
834
 
#else
835
 
 
836
 
  char *searchPattern;
837
 
  WIN32_FIND_DATA W32FD;
838
 
 
839
 
  // Append '*' as a wildcard for FindFirstFile()
840
 
  size_t configDirLen = strlen(configDir) + 2;
841
 
  searchPattern = new char[configDirLen];
842
 
  snprintf(searchPattern, configDirLen, "%s*", configDir);
843
 
  HANDLE hDInfo = FindFirstFile(searchPattern, &W32FD);
844
 
 
845
 
  if (INVALID_HANDLE_VALUE == hDInfo) {
846
 
    mgmt_log(stderr, "[Rollback::findVersions_ml] FindFirstFile failed for %s: %s\n", searchPattern, ink_last_err());
847
 
    delete[]searchPattern;
848
 
    return INVALID_VERSION;
849
 
  }
850
 
  delete[]searchPattern;
851
 
 
852
 
  while (FindNextFile(hDInfo, &W32FD)) {
853
 
 
854
 
    if ((version = extractVersionInfo(listNames, W32FD.cFileName))
855
 
        != INVALID_VERSION) {
856
 
      count++;
857
 
 
858
 
      if (version > highestSeen) {
859
 
        highestSeen = version;
860
 
      }
861
 
 
862
 
    }
863
 
 
864
 
  }
865
 
 
866
 
  FindClose(hDInfo);
867
 
 
868
 
#endif // !_WIN32
869
 
 
870
777
  numVersions = count;
871
778
  return highestSeen;
872
779
}
912
819
            versionInfo *verInfo;
913
820
 
914
821
            if (statFile(version, &fileInfo) >= 0) {
915
 
              verInfo = (versionInfo *) xmalloc(sizeof(versionInfo));
 
822
              verInfo = (versionInfo *)ats_malloc(sizeof(versionInfo));
916
823
              verInfo->version = version;
917
824
              verInfo->modTime = fileInfo.st_mtime;
918
825
              listNames->addEntry((void *) verInfo);