Commit 262ecf2a authored by Giuseppe Lo Presti's avatar Giuseppe Lo Presti
Browse files

Merge branch 'v2_1_14Version'

parents 0c1d777c cb081e97
......@@ -27,6 +27,77 @@
+ /etc/grid-security/castor-gridftp-dsi/castor-gridftp-dsi-key.pem
-------------
- 2.1.14-14 -
-------------
Summary
-------
This is a minor release bringing a number of bug fixes.
Stager
------
#104810 Draining has problems when used with --file-mask=NOTONTAPE
#104671 listtransfers not working when a transfermanagerd is down
#104601 RFE: modify/enterSvcClass should check consistency of the GCPolicies when DiskPools are shared
#104562 bad handling of long arguments in printmigrationroute and printrecalluser
Repack
------
#104856 RFE: make the timeout to expire old requests different for failed vs. successful ones
#104892 Concurrent repack of dual copy files does not generate two racing recall jobs
Clients
-------
#104523 RFE: add -n option on nsls to avoid resolution of user and group names
#104849 RFE: expose stager timeouts on rfcp
Upgrade Instructions from 2.1.14-13
-----------------------------------
Stager
------
The upgrade of the stager to 2.1.14-14 can be performed online while the system is running.
Instructions
------------
1. Upgrade the STAGER database using the stager_2.1.14-13_to_2.1.14-14.sql
upgrade script available from:
- http://cern.ch/castor/DIST/CERN/savannah/CASTOR.pkg/2.1.14-*/2.1.14-14/dbupgrades
2. Upgrade the software on the head nodes.
Note: All daemons involved in the upgrade will be restarted automatically.
3. Upgrade the software on the diskservers.
Note: All daemons involved in the upgrade will be restarted automatically.
4. Test the instance by running the test suite available from:
- http://cern.ch/castor/DIST/CERN/savannah/CASTOR.pkg/2.1.14-*/2.1.14-14/testsuite
5. Congratulations you have successfully upgraded to the 2.1.14-13 release
of CASTOR.
Central services (CUPV, VMGR, VDQM, Nameserver)
-----------------------------------------------
The upgrade of the central services to 2.1.14-14 can be performed online while
the system is running.
Instructions
------------
1. Apply the appropriate database upgrade script from:
- http://cern.ch/castor/DIST/CERN/savannah/CASTOR.pkg/2.1.14-*/2.1.14-14/dbupgrades
2. Update the software to use the 2.1.14-14 RPMs. Note: All
daemons involved in the upgrade will be restarted automatically.
3. Upgrade complete.
-------------
- 2.1.14-13 -
-------------
......
......@@ -116,7 +116,7 @@ CREATE DATABASE LINK remotens
INSERT INTO CastorConfig
VALUES ('general', 'owner', sys_context('USERENV', 'CURRENT_USER'), 'The database owner of the schema');
INSERT INTO CastorConfig
VALUES ('cleaning', 'terminatedRequestsTimeout', '120', 'Maximum timeout for successful and failed requests in hours');
VALUES ('cleaning', 'failedRequestsTimeout', '168', 'Maximum timeout before removing failed requests from the database in hours');
INSERT INTO CastorConfig
VALUES ('cleaning', 'outOfDateStageOutDCsTimeout', '72', 'Timeout for STAGEOUT diskCopies in hours');
INSERT INTO CastorConfig
......
......@@ -277,6 +277,8 @@ AS
REPACK_STARTED CONSTANT VARCHAR2(2048) := 'repackManager: Repack process started';
REPACK_JOB_STATS CONSTANT VARCHAR2(2048) := 'repackManager: Repack processes statistics';
REPACK_UNEXPECTED_EXCEPTION CONSTANT VARCHAR2(2048) := 'handleRepackRequest: unexpected exception caught';
REPACK_COMPLETED CONSTANT VARCHAR2(2048) := 'Repack completed successfully';
REPACK_FAILED CONSTANT VARCHAR2(2048) := 'Repack ended with failures';
DRAINING_REFILL CONSTANT VARCHAR2(2048) := 'drainRunner: Creating new replication jobs';
......
......@@ -608,22 +608,23 @@ END;
/* Search and delete old archived/failed subrequests and their requests */
CREATE OR REPLACE PROCEDURE deleteTerminatedRequests AS
timeOut INTEGER;
rateDependentTimeOut INTEGER;
failuresTimeOut INTEGER;
successesTimeOut INTEGER;
rate INTEGER;
srIds "numList";
ct NUMBER;
BEGIN
-- select requested timeout from configuration table
timeOut := 3600*TO_NUMBER(getConfigOption('cleaning', 'terminatedRequestsTimeout', '120'));
-- select requested timeout for failed requests from configuration table
failuresTimeOut := 3600*TO_NUMBER(getConfigOption('cleaning', 'failedRequestsTimeout', '168')); -- 1 week
-- compute a rate-dependent timeout for the successful requests by looking at the
-- last half-hour of activity: keep max 1M of them regardless the above configured timeOut.
SELECT 1800 * 1000000 / (count(*)+1) INTO rateDependentTimeOut
-- last half-hour of activity: keep max 1M of them.
SELECT 1800 * 1000000 / (count(*)+1) INTO successesTimeOut
FROM SubRequest
WHERE status = dconst.SUBREQUEST_ARCHIVED
AND lastModificationTime > getTime() - 1800;
IF rateDependentTimeOut > timeOut THEN
rateDependentTimeOut := timeOut;
IF successesTimeOut > failuresTimeOut THEN
-- in case of light load, don't keep successful request for longer than failed ones
successesTimeOut := failuresTimeOut;
END IF;
-- Delete castorFiles if nothing is left for them. Here we use
......@@ -634,10 +635,10 @@ BEGIN
INSERT /*+ APPEND */ INTO DeleteTermReqHelper (srId, cfId)
(SELECT SR.id, castorFile FROM SubRequest SR
WHERE (SR.status = dconst.SUBREQUEST_ARCHIVED
AND SR.lastModificationTime < getTime() - rateDependentTimeOut)
AND SR.lastModificationTime < getTime() - successesTimeOut)
-- failed subrequests are kept according to the configured timeout
OR (SR.status = dconst.SUBREQUEST_FAILED_FINISHED
AND reqType != 119 AND SR.lastModificationTime < getTime() - timeOut)); -- StageRepackRequest
AND reqType != 119 AND SR.lastModificationTime < getTime() - failuresTimeOut)); -- StageRepackRequest
COMMIT; -- needed otherwise the next statement raises
-- ORA-12838: cannot read/modify an object after modifying it in parallel
-- 2nd part, separated from above for efficiency reasons
......@@ -646,7 +647,7 @@ BEGIN
WHERE SR.status = dconst.SUBREQUEST_FAILED_FINISHED
-- only for the Repack case, we keep all failed subrequests around until
-- the whole Repack request is over for more than <timeOut> seconds
AND reqType = 119 AND R.lastModificationTime < getTime() - timeOut -- StageRepackRequest
AND reqType = 119 AND R.lastModificationTime < getTime() - failuresTimeOut -- StageRepackRequest
AND R.id = SR.request);
COMMIT;
SELECT count(*) INTO ct FROM DeleteTermReqHelper;
......@@ -706,12 +707,17 @@ BEGIN
-- Finally deal with Repack: this case is different because StageRepackRequests may be empty
-- at the beginning. Therefore we only drop repacks that are in a completed state
-- for more than <timeOut> seconds. FINISHED, FAILED, ABORTED
bulkDelete('SELECT id FROM StageRepackRequest R WHERE status IN (2, 3, 5)
-- for more than the requested time.
-- First failed ones (status FAILED, ABORTED)
bulkDelete('SELECT id FROM StageRepackRequest R WHERE status IN (3, 5)
AND NOT EXISTS (SELECT 1 FROM SubRequest WHERE request = R.id)
AND lastModificationTime < getTime() - ' || timeOut || ';',
AND lastModificationTime < getTime() - ' || failuresTimeOut || ';',
'StageRepackRequest');
-- Then successful ones (status FINISHED)
bulkDelete('SELECT id FROM StageRepackRequest R WHERE status = 2
AND NOT EXISTS (SELECT 1 FROM SubRequest WHERE request = R.id)
AND lastModificationTime < getTime() - ' || successesTimeOut || ';',
'StageRepackRequest');
END;
/
......
......@@ -252,10 +252,11 @@ BEGIN
WHERE DiskCopy.dataPool = DiskServer.DataPool
AND DiskServer.hwOnline = 1));
IF varNbCopies = 0 THEN
-- find out whether this file is already being recalled
SELECT count(*) INTO varWasRecalled FROM RecallJob WHERE castorfile = cfId AND ROWNUM < 2;
-- find out whether this file is already being recalled from this tape
SELECT count(*) INTO varWasRecalled FROM RecallJob WHERE castorfile = cfId AND vid != varRepackVID;
IF varWasRecalled = 0 THEN
-- trigger recall
-- trigger recall: if we have dual copy files, this may trigger a second recall,
-- which will race with the first as it happens for user-driven recalls
triggerRepackRecall(cfId, segment.fileid, nsHostName, segment.blockid,
segment.fseq, segment.copyNb, varEuid, varEgid,
varRecallGroupId, svcClassId, varRepackVID, segment.segSize,
......@@ -542,23 +543,23 @@ END;
/* PL/SQL procedure called when a repack request is over: see archiveSubReq */
CREATE OR REPLACE PROCEDURE handleEndOfRepack(inReqId INTEGER) AS
nbLeftSegs INTEGER;
varNbLeftSegs INTEGER;
varStartTime NUMBER;
varReqUuid VARCHAR2(40);
varVID VARCHAR2(10);
BEGIN
-- check if any segment is left in the original tape
SELECT 1 INTO nbLeftSegs FROM Cns_seg_metadata@RemoteNS
WHERE vid = (SELECT repackVID FROM StageRepackRequest WHERE id = inReqId)
AND ROWNUM < 2;
-- we found at least one segment, final status is FAILED
UPDATE StageRepackRequest
SET status = tconst.REPACK_FAILED,
lastModificationTime = getTime()
WHERE id = inReqId;
EXCEPTION WHEN NO_DATA_FOUND THEN
-- no segments found, repack was successful
-- check how many segments are left in the original tape
SELECT count(*) INTO varNbLeftSegs FROM Cns_seg_metadata@RemoteNS
WHERE vid = (SELECT repackVID FROM StageRepackRequest WHERE id = inReqId);
-- update request
UPDATE StageRepackRequest
SET status = tconst.REPACK_FINISHED,
SET status = CASE varNbLeftSegs WHEN 0 THEN tconst.REPACK_FINISHED ELSE tconst.REPACK_FAILED END,
lastModificationTime = getTime()
WHERE id = inReqId;
WHERE id = inReqId
RETURNING creationTime, reqId, repackVID INTO varStartTime, varReqUuid, varVID;
-- log successful or unsuccessful completion
logToDLF(varReqUuid, dlf.LVL_SYSTEM, CASE varNbLeftSegs WHEN 0 THEN dlf.REPACK_COMPLETED ELSE dlf.REPACK_FAILED END, 0, '',
'repackd', 'TPVID=' || varVID || ' nbLeftSegments=' || TO_CHAR(varNbLeftSegs) || ' elapsedTime=' || TO_CHAR(TRUNC(getTime() - varStartTime)));
END;
/
......
......@@ -904,7 +904,6 @@ BEGIN
WHERE SR.castorFile = inCfId
AND SR.status IN (dconst.SUBREQUEST_WAITTAPERECALL, dconst.SUBREQUEST_WAITSUBREQ);
END IF;
-- commit
COMMIT;
END;
/
......@@ -1227,7 +1226,7 @@ BEGIN
END IF;
ELSE
-- log "startRecallMounts: not allowed to start new recall mount. Maximum nb of drives has been reached"
logToDLF(NULL, dlf.LVL_DEBUG, dlf.RECMOUNT_NOACTION_NODRIVE, 0, '',
logToDLF(NULL, dlf.LVL_SYSTEM, dlf.RECMOUNT_NOACTION_NODRIVE, 0, '',
'tapegatewayd', 'recallGroup=' || rg.name);
END IF;
COMMIT;
......
......@@ -60,7 +60,7 @@ try:
nvl(sum(mj.filesize), 0) total_size,
sum((case when mj.status = 1 then mj.filesize else 0 end)) size_migrating,
(select count(*) from migrationmount mm where mm.tapepool = tp.id) migrations,
(select count(*) from migrationmount mm where mm.tapepool = tp.id and mm.status in (2, 3)) migrations_queued,
(select count(*) from migrationmount mm where mm.tapepool = tp.id and mm.status = 2) migrations_queued,
(select count(*) from migrationmount mm where mm.tapepool = tp.id and mm.status = 3) migrations_running,
nvl(min(gettime() - mj.creationtime), 0) min_age,
nvl(max(gettime() - mj.creationtime), 0) max_age
......
......@@ -126,7 +126,7 @@ if eflag and not maxNbErrors:
maxNbErrors = 10
_repackRequestStatuses = ['STARTING', 'ONGOING', 'FINISHED', 'FAILED', 'ABORTING', 'ABORTED', 'SUBMITTED']
def _printStatusLine(subTime, lastModTime, user, machine, vid, status, total, size, toRecall, toMigr, failed, migrated):
def _printStatusLine(subTime, lastModTime, user, vid, status, total, size, toRecall, toMigr, failed, migrated):
'''prints one status line'''
# dealing with global status
status = _repackRequestStatuses[status]
......@@ -149,30 +149,30 @@ def _printStatusLine(subTime, lastModTime, user, machine, vid, status, total, si
if total > 0 and status != 'STARTING':
# Completion % takes into account each operation (recall and migration) as 1, so that e.g. a tape with half files recalled and none migrated counts as 25% done;
# no weight is given to recalls vs. migrations nor is the file size taken into account.
print '%-18s%13s%17s%29s%9s%11d%12s%10d%10d%10d%10d%7d%%%11s' % (subTime, repackTime, user, machine, vid, total, size, toRecall, toMigr, failed, migrated, 100-(2*toRecall+toMigr)*50.0/total, status)
print '%-18s%13s%17s%9s%11d%12s%10d%10d%10d%10d%7d%%%11s' % (subTime, repackTime, user, vid, total, size, toRecall, toMigr, failed, migrated, 100-(2*toRecall+toMigr)*50.0/total, status)
else:
print '%-18s%13s%17s%29s%9s%11d%12s%10d%10d%10d%10d N/A %11s' % (subTime, repackTime, user, machine, vid, total, size, toRecall, toMigr, failed, migrated, status)
print '%-18s%13s%17s%9s%11d%12s%10d%10d%10d%10d N/A %11s' % (subTime, repackTime, user, vid, total, size, toRecall, toMigr, failed, migrated, status)
except TypeError:
# case of reporting without details
print '%-18s%13s%17s%29s%9s%11d%12s%11s' % (subTime, repackTime, user, machine, vid, total, size, status)
print '%-18s%13s%17s%9s%11d%12s%11s' % (subTime, repackTime, user, vid, total, size, status)
def _displaySummary(rows):
'''prints a summary of all repack requests according to the given criteria'''
# print out results
print '='*120
print 'SubmitTime RepackTime User Machine Vid Total Size Status'
print '-'*120
print '='*91
print 'SubmitTime RepackTime User Vid Total Size Status'
print '-'*91
sumTotal = sumSize = 0
globalStatus = 2 # FINISHED
shownVids = set()
count = 0
for subTime, lastModTime, user, machine, vid, status, total, totsize in rows:
for subTime, lastModTime, user, vid, status, total, totsize in rows:
if not vids and vid in shownVids:
# when showing full statistics skip the less recent requests for each VID
continue
shownVids.add(vid)
_printStatusLine(subTime, lastModTime, user, machine, vid, status, total, totsize, '-', '-', '-', '-')
_printStatusLine(subTime, lastModTime, user, vid, status, total, totsize, '-', '-', '-', '-')
sumTotal += total
count += 1
if totsize > 0:
......@@ -182,28 +182,28 @@ def _displaySummary(rows):
globalStatus = 0 # STARTING
if (status == 1 or status == 4) and globalStatus == 2:
globalStatus = 1 # ONGOING
print '-'*120
print '-'*91
# when showing full statistics, print out summary line
if not vids and sumTotal > 0:
_printStatusLine(time.time(), 0, '-', 'TOTAL', count, globalStatus, sumTotal, sumSize, '-', '-', '-', '-')
_printStatusLine(time.time(), 0, 'TOTAL', count, globalStatus, sumTotal, sumSize, '-', '-', '-', '-')
def _displayDetailed(rows):
'''prints the details of all repack requests according to the given criteria'''
# print out results
print '='*168
print 'SubmitTime RepackTime User Machine Vid Total Size toRecall toMigr Failed Migrated Compl% Status'
print '-'*168
print '='*139
print 'SubmitTime RepackTime User Vid Total Size toRecall toMigr Failed Migrated Compl% Status'
print '-'*139
sumTotal = sumSize = sumToRecall = sumToMigr = sumFailed = sumMigrated = 0
globalStatus = 2 # FINISHED
shownVids = set()
count = 0
for subTime, lastModTime, user, machine, vid, status, total, totsize, toRecall, toMigr, failed in rows:
for subTime, lastModTime, user, vid, status, total, totsize, toRecall, toMigr, failed in rows:
if not vids and vid in shownVids:
# when showing full statistics skip the less recent requests for each VID
continue
shownVids.add(vid)
migrated = total - toRecall - toMigr - failed
_printStatusLine(subTime, lastModTime, user, machine, vid, status, total, totsize, toRecall, toMigr, failed, migrated)
_printStatusLine(subTime, lastModTime, user, vid, status, total, totsize, toRecall, toMigr, failed, migrated)
sumTotal += total
if totsize > 0:
# it may have returned None
......@@ -217,10 +217,10 @@ def _displayDetailed(rows):
globalStatus = 0 # STARTING
if (status == 1 or status == 4) and globalStatus == 2:
globalStatus = 1 # ONGOING
print '-'*168
print '-'*139
# when showing full statistics, print out summary line
if not vids and sumTotal > 0:
_printStatusLine(time.time(), 0, '-', 'TOTAL', count, globalStatus, sumTotal, sumSize, sumToRecall, sumToMigr, sumFailed, sumMigrated)
_printStatusLine(time.time(), 0, 'TOTAL', count, globalStatus, sumTotal, sumSize, sumToRecall, sumToMigr, sumFailed, sumMigrated)
def displayStatus(detailed):
'''displays the ongoing repacks. If vids is not empty, the output is limited to these tapes'''
......@@ -231,7 +231,7 @@ def displayStatus(detailed):
if not detailed:
stGetStatus = '''
SELECT creationTime, lastModificationTime, username,
machine, repackVID, status, fileCount total, totalSize totsize
repackVID, status, fileCount total, totalSize totsize
FROM StageRepackRequest
'''
# query only the requested VIDs. This requires hard parsing but it's still more efficient
......@@ -241,7 +241,7 @@ def displayStatus(detailed):
else:
stGetStatus = '''
SELECT StageRepackRequest.creationTime, StageRepackRequest.lastModificationTime, StageRepackRequest.username,
StageRepackRequest.machine, StageRepackRequest.repackVID, StageRepackRequest.status,
StageRepackRequest.repackVID, StageRepackRequest.status,
StageRepackRequest.fileCount total, StageRepackRequest.totalSize totsize,
SUM(CASE WHEN SubRequest.status IN (4, 5) THEN 1 ELSE 0 END) toRecall,
SUM(CASE SubRequest.status WHEN 12 THEN 1 ELSE 0 END) toMigr,
......@@ -254,7 +254,7 @@ def displayStatus(detailed):
stGetStatus += "AND StageRepackRequest.repackVID IN ('" + "','".join(vids) + "')"
stGetStatus += '''
GROUP BY StageRepackRequest.creationTime, StageRepackRequest.lastModificationTime, StageRepackRequest.username,
StageRepackRequest.machine, StageRepackRequest.repackVID, StageRepackRequest.status,
StageRepackRequest.repackVID, StageRepackRequest.status,
StageRepackRequest.fileCount, StageRepackRequest.totalSize'''
stGetStatus += ' ORDER BY StageRepackRequest.creationTime DESC'
# go to DB and get back the data
......
......@@ -27,24 +27,12 @@ rfcp \- Remote file copy
.IR directory
.br
.P
On Windows only:
.br
.B rfcp
[
.BI -a
] [
.BI -b
] [
.BI -s " size"
] [
.BI -v2
]
.BI @ command_file
.SH DESCRIPTION
.IX "\fLrfcp\fR"
The remote file I/O copy program provides an interface to the
.B shift
remote file I/O daemon (rfiod) for transferring files between remote and/or
remote file I/O daemon (rfiod) and to CASTOR for transferring files between remote and/or
local hosts. Each
.IR filename
or
......@@ -55,7 +43,7 @@ argument is either a remote file name of the form:
.LP
or a local file name (not containing the :/ character combination). The standard input is supported with the
.BI \-
character. Then directory in output is not supported.
character. In this case a directory in output is not supported.
.LP
For castor files the new TURL sintax may be used, with the following variants:
.LP
......@@ -73,16 +61,6 @@ Of course the old RFIO sintax (rfio://[diskserver][:port]/path) is still valid.
.SH OPTIONS
.TP
.BI \-a
tells
.B rfcp
that the source file is ASCII text (Windows/NT only)
.TP
.BI \-b
tells
.B rfcp
that the source is a binary file (Windows/NT only)
.TP
.BI \-s " size"
If specified, only
.I size
......@@ -99,16 +77,10 @@ If specified, forces the RFIO V.2 protocol. Otherwise, V.3 is used and rfio3 is
.br
2 System error.
.br
3 Unknown error.
.br
16 Device or resource busy.
.br
28 No space left on device.
.br
196 Request killed.
.br
198 Stager not active.
.br
200 Bad checksum.
.br
In addition, errors from the
......@@ -125,7 +97,7 @@ If the service class is not specified on the command-line, then
will use the value of the \fBSTAGE_SVCCLASS\fP environment variable if it is
set. Please note the environment variable name \fBSTAGE_SVCCLASS\fP does not
contain the letter \fBR\fP, unlike the corresponding configuration parameter
in the castor configuration file \fB/etc/castor.conf\fP, see below.
in the castor configuration file \fB/etc/castor/castor.conf\fP, see below.
.TP
.BI RFIO_TRACE
Setting this environment variable to 3 causes the rfcp command to print a
......@@ -137,7 +109,7 @@ debugging trace to standard out.
If the service class is not specified on the command-line or by the environment
variable \fBSTAGE_SVCCLASS\fP, then \fBrfcp\fP will use the value of the
configuration parameter \fBSTAGER SVCCLASS\fP specified in the castor
configuration file \fB/etc/castor.conf\fP. If the service class is not
configuration file \fB/etc/castor/castor.conf\fP. If the service class is not
specified using any of these three methods, then the default value of
"\fBdefault\fP" will be used. Please note the name of the castor configuration
parameter \fBSTAGER SVCCLASS\fP contains the letter \fBR\fP, unlike the
......
......@@ -221,7 +221,6 @@ int rfio_HsmIf_mkdir(const char *path, mode_t mode) {
int rfio_HsmIf_open(const char *path, int flags, mode_t mode, int mode64, int streaming) {
int rc = -1;
int ret;
int save_serrno, save_errno;
struct Cns_filestat st;
int* auxVal;
char ** auxPoint;
......@@ -280,81 +279,50 @@ int rfio_HsmIf_open(const char *path, int flags, mode_t mode, int mode64, int st
struct stage_io_fileresp *response = NULL;
char *url = NULL;
for (;;) {
TRACE(3,"rfio","Calling stage_open with: %s 0x%x 0x%x",
path, flags, mode);
rc = stage_open(NULL,
mover_protocol_rfio,
path,
flags,
mode,
0,
&response,
NULL,
&opts);
save_errno = errno;
save_serrno = serrno;
if (rc < 0) {
if ( (save_serrno == SECOMERR) ||
(save_serrno == SETIMEDOUT) ||
(save_serrno == ECONNREFUSED) ||
(save_errno == ECONNREFUSED)
) {
int retrySleepTime;
retrySleepTime = 1 + (int)(10.0*rand()/(RAND_MAX+1.0));
sleep(retrySleepTime);
continue;
}
/* Free resources */
rc = -1;
goto end;
} else {
break;
}
}
TRACE(3,"rfio","Calling stage_open with: %s 0%o 0%o",
path, flags, mode);
rc = stage_open(NULL,
mover_protocol_rfio,
path,
flags,
mode,
0,
&response,
NULL,
&opts);
if (response == NULL) {
TRACE(3,"rfio","Received NULL response");
serrno = SEINTERNAL;
rc = -1;
goto end;
}
if (response->errorCode != 0) {
else if (response->errorCode != 0) {
TRACE(3,"rfio","stage_open error: %d/%s",
response->errorCode, response->errorMessage);
serrno = response->errorCode;
rc = -1;
goto end;
}
url = stage_geturl(response);
if (url == NULL) {
rc = -1;
goto end;
}
/*
* Warning, this is a special case for castor2 when a file is recreated
* with O_TRUNC but without O_CREAT: the correct behaviour is to
* recreate the castorfile and schedule access to the new diskcopy.
* However, because of there is no O_CREAT the mover open will fail
* to create the new diskcopy. We must therefore add O_CREAT but
* only after stage_open() has processed the request and recreated
* the castorfile.
*/
if ( (flags & O_TRUNC) == O_TRUNC ) flags |= O_CREAT;
if (mode64) {
rc = rfio_open64(url, flags, mode);
} else {
rc = rfio_open(url, flags, mode);
else {
url = stage_geturl(response);
/*
* Warning, this is a special case for castor2 when a file is recreated
* with O_TRUNC but without O_CREAT: the correct behaviour is to
* recreate the castorfile and schedule access to the new diskcopy.
* However, because of there is no O_CREAT the mover open will fail
* to create the new diskcopy. We must therefore add O_CREAT but
* only after stage_open() has processed the request and recreated
* the castorfile.
*/
if ( (flags & O_TRUNC) == O_TRUNC ) flags |= O_CREAT;
if (mode64) {
rc = rfio_open64(url, flags, mode);
} else {
rc = rfio_open(url, flags, mode);
}
}
end:
/* Free response structure. Note: This logic should really as an API
/* Free response structure. Note: this logic should really be an API
* of the stager client library
*/
if (response != NULL) {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment