1 /*
2 Copyright (c) 2003, 2021, Oracle and/or its affiliates.
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 2.0,
6 as published by the Free Software Foundation.
7
8 This program is also distributed with certain software (including
9 but not limited to OpenSSL) that is licensed under separate terms,
10 as designated in a particular file or component or in included license
11 documentation. The authors of MySQL hereby grant you an additional
12 permission to link the program and your derivative works with the
13 separately licensed software that they have included with MySQL.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License, version 2.0, for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24
25 #include <ndb_global.h>
26
27 #include "Filename.hpp"
28 #include "ErrorHandlingMacros.hpp"
29 #include "RefConvert.hpp"
30 #include "DebuggerNames.hpp"
31 #include "Ndbfs.hpp"
32
33 #include <signaldata/FsOpenReq.hpp>
34
35 #define JAM_FILE_ID 383
36
37
38 static const char* fileExtension[] = {
39 ".Data",
40 ".FragLog",
41 ".LocLog",
42 ".FragList",
43 ".TableList",
44 ".SchemaLog",
45 ".sysfile",
46 ".log",
47 ".ctl"
48 };
49
50 static const Uint32 noOfExtensions = sizeof(fileExtension)/sizeof(char*);
51
Filename()52 Filename::Filename()
53 {
54 }
55
~Filename()56 Filename::~Filename(){
57 }
58
59 void
set(Ndbfs * fs,BlockReference blockReference,const Uint32 filenumber[4],bool dir,SegmentedSectionPtr ptr)60 Filename::set(Ndbfs* fs,
61 BlockReference blockReference,
62 const Uint32 filenumber[4], bool dir,
63 SegmentedSectionPtr ptr)
64 {
65 char buf[PATH_MAX];
66
67 const Uint32 type = FsOpenReq::getSuffix(filenumber);
68 const Uint32 version = FsOpenReq::getVersion(filenumber);
69
70 size_t sz;
71 if (version == 2)
72 {
73 sz = BaseString::snprintf(theName, sizeof(theName), "%s",
74 fs->get_base_path(FsOpenReq::BP_BACKUP).c_str());
75 m_base_name = theName + fs->get_base_path(FsOpenReq::BP_BACKUP).length();
76 }
77 else
78 {
79 sz = BaseString::snprintf(theName, sizeof(theName), "%s",
80 fs->get_base_path(FsOpenReq::BP_FS).c_str());
81 m_base_name = theName + fs->get_base_path(FsOpenReq::BP_FS).length();
82 }
83
84 switch(version){
85 case 1 :{
86 const Uint32 diskNo = FsOpenReq::v1_getDisk(filenumber);
87 const Uint32 table = FsOpenReq::v1_getTable(filenumber);
88 const Uint32 frag = FsOpenReq::v1_getFragment(filenumber);
89 const Uint32 S_val = FsOpenReq::v1_getS(filenumber);
90 const Uint32 P_val = FsOpenReq::v1_getP(filenumber);
91
92 if (diskNo < 0xff){
93 BaseString::snprintf(buf, sizeof(buf), "D%d%s", diskNo, DIR_SEPARATOR);
94 strcat(theName, buf);
95 }
96
97 {
98 const char* blockName = getBlockName( refToMain(blockReference) );
99 if (blockName == NULL){
100 ERROR_SET(ecError, NDBD_EXIT_AFS_PARAMETER,"","No Block Name");
101 return;
102 }
103 BaseString::snprintf(buf, sizeof(buf), "%s%s", blockName, DIR_SEPARATOR);
104 strcat(theName, buf);
105 }
106
107 if (table < 0xffffffff){
108 BaseString::snprintf(buf, sizeof(buf), "T%d%s", table, DIR_SEPARATOR);
109 strcat(theName, buf);
110 }
111
112 if (frag < 0xffffffff){
113 BaseString::snprintf(buf, sizeof(buf), "F%d%s", frag, DIR_SEPARATOR);
114 strcat(theName, buf);
115 }
116
117
118 if (S_val < 0xffffffff){
119 BaseString::snprintf(buf, sizeof(buf), "S%d", S_val);
120 strcat(theName, buf);
121 }
122
123 if (P_val < 0xff){
124 BaseString::snprintf(buf, sizeof(buf), "P%d", P_val);
125 strcat(theName, buf);
126 }
127
128 }
129 break;
130 case 2:{
131 const Uint32 seq = FsOpenReq::v2_getSequence(filenumber);
132 const Uint32 nodeId = FsOpenReq::v2_getNodeId(filenumber);
133 const Uint32 count = FsOpenReq::v2_getCount(filenumber);
134
135 BaseString::snprintf(buf, sizeof(buf), "BACKUP%sBACKUP-%u%s",
136 DIR_SEPARATOR, seq, DIR_SEPARATOR);
137 strcat(theName, buf);
138 if(count == 0xffffffff) {
139 BaseString::snprintf(buf, sizeof(buf), "BACKUP-%u.%d",
140 seq, nodeId); strcat(theName, buf);
141 } else {
142 BaseString::snprintf(buf, sizeof(buf), "BACKUP-%u-%d.%d",
143 seq, count, nodeId); strcat(theName, buf);
144 }
145 break;
146 }
147 break;
148 case 3:{
149 const Uint32 diskNo = FsOpenReq::v1_getDisk(filenumber);
150
151 if(diskNo == 0xFF){
152 ERROR_SET(ecError, NDBD_EXIT_AFS_PARAMETER,"","Invalid disk specification");
153 }
154
155 BaseString::snprintf(buf, sizeof(buf), "D%d%s", diskNo, DIR_SEPARATOR);
156 strcat(theName, buf);
157 }
158 break;
159 case 4:
160 {
161 char buf[PATH_MAX];
162 copy((Uint32*)&buf[0], ptr);
163 if(buf[0] == DIR_SEPARATOR[0])
164 {
165 strncpy(theName, buf, PATH_MAX);
166 m_base_name = theName;
167 }
168 else
169 {
170 #ifdef NDB_WIN32
171 char* b= buf;
172 while((b= strchr(b, '/')) && b)
173 {
174 *b= '\\';
175 }
176 #endif
177 Uint32 bp = FsOpenReq::v4_getBasePath(filenumber);
178 BaseString::snprintf(theName, sizeof(theName), "%s%s",
179 fs->get_base_path(bp).c_str(), buf);
180 m_base_name = theName + fs->get_base_path(bp).length();
181 }
182 return; // No extension
183 }
184 case 5:
185 {
186 Uint32 tableId = FsOpenReq::v5_getTableId(filenumber);
187 Uint32 lcpNo = FsOpenReq::v5_getLcpNo(filenumber);
188 Uint32 fragId = FsOpenReq::v5_getFragmentId(filenumber);
189 BaseString::snprintf(buf, sizeof(buf), "LCP%s%d%sT%dF%d", DIR_SEPARATOR, lcpNo, DIR_SEPARATOR, tableId, fragId);
190 strcat(theName, buf);
191 break;
192 }
193 case 6:
194 {
195 Uint32 bp = FsOpenReq::v5_getLcpNo(filenumber);
196 sz = BaseString::snprintf(theName, sizeof(theName), "%s",
197 fs->get_base_path(bp).c_str());
198 break;
199 }
200 default:
201 ERROR_SET(ecError, NDBD_EXIT_AFS_PARAMETER,"","Wrong version");
202 }
203 if (type >= noOfExtensions){
204 ERROR_SET(ecError, NDBD_EXIT_AFS_PARAMETER,"","File Type doesn't exist");
205 return;
206 }
207 strcat(theName, fileExtension[type]);
208
209 if(dir == true){
210 for(int l = (int)strlen(theName) - 1; l >= 0; l--){
211 if(theName[l] == DIR_SEPARATOR[0]){
212 theName[l] = 0;
213 break;
214 }
215 }
216 }
217 }
218