Skip to content

Commit d8a2df2

Browse files
authored
HDFS-15498. Show snapshots deletion status in snapList cmd. (#2181)
1 parent 528a799 commit d8a2df2

File tree

5 files changed

+46
-11
lines changed

5 files changed

+46
-11
lines changed

hadoop-hdfs-project/hadoop-hdfs-client/src/main/java/org/apache/hadoop/hdfs/protocol/SnapshotStatus.java

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ public class SnapshotStatus {
4040
*/
4141
private final int snapshotID;
4242

43+
/**
44+
* Whether the snapshot is deleted or not.
45+
*/
46+
private final boolean isDeleted;
47+
4348
/**
4449
* Full path of the parent.
4550
*/
@@ -50,7 +55,7 @@ public SnapshotStatus(long modificationTime, long accessTime,
5055
EnumSet<HdfsFileStatus.Flags> flags,
5156
String owner, String group, byte[] localName,
5257
long inodeId, int childrenNum, int snapshotID,
53-
byte[] parentFullPath) {
58+
boolean isDeleted, byte[] parentFullPath) {
5459
this.dirStatus = new HdfsFileStatus.Builder()
5560
.isdir(true)
5661
.mtime(modificationTime)
@@ -64,13 +69,7 @@ public SnapshotStatus(long modificationTime, long accessTime,
6469
.children(childrenNum)
6570
.build();
6671
this.snapshotID = snapshotID;
67-
this.parentFullPath = parentFullPath;
68-
}
69-
70-
public SnapshotStatus(HdfsFileStatus dirStatus,
71-
int snapshotNumber, byte[] parentFullPath) {
72-
this.dirStatus = dirStatus;
73-
this.snapshotID = snapshotNumber;
72+
this.isDeleted = isDeleted;
7473
this.parentFullPath = parentFullPath;
7574
}
7675

@@ -89,6 +88,13 @@ public int getSnapshotID() {
8988
return snapshotID;
9089
}
9190

91+
/**
92+
* @return whether snapshot is deleted
93+
*/
94+
public boolean isDeleted() {
95+
return isDeleted;
96+
}
97+
9298
/**
9399
* @return The basic information of the directory
94100
*/
@@ -143,6 +149,7 @@ public static void print(SnapshotStatus[] stats,
143149
+ "%" + maxLen + "s "
144150
+ "%s " // mod time
145151
+ "%" + maxSnapshotID + "s "
152+
+ "%s " // deletion status
146153
+ "%s"; // path
147154
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
148155

@@ -155,6 +162,7 @@ public static void print(SnapshotStatus[] stats,
155162
String.valueOf(status.dirStatus.getLen()),
156163
dateFormat.format(new Date(status.dirStatus.getModificationTime())),
157164
status.snapshotID,
165+
status.isDeleted ? "DELETED" : "ACTIVE",
158166
getSnapshotPath(DFSUtilClient.bytes2String(status.parentFullPath),
159167
status.dirStatus.getLocalName())
160168
);
@@ -166,22 +174,29 @@ private static int maxLength(int n, Object value) {
166174
return Math.max(n, String.valueOf(value).length());
167175
}
168176

177+
/**
178+
* To be used to for collection of snapshot jmx.
179+
*/
169180
public static class Bean {
170181
private final String path;
171182
private final int snapshotID;
172183
private final long modificationTime;
173184
private final short permission;
174185
private final String owner;
175186
private final String group;
187+
private final boolean isDeleted;
188+
176189

177190
public Bean(String path, int snapshotID, long
178-
modificationTime, short permission, String owner, String group) {
191+
modificationTime, short permission, String owner, String group,
192+
boolean isDeleted) {
179193
this.path = path;
180194
this.snapshotID = snapshotID;
181195
this.modificationTime = modificationTime;
182196
this.permission = permission;
183197
this.owner = owner;
184198
this.group = group;
199+
this.isDeleted = isDeleted;
185200
}
186201

187202
public String getPath() {
@@ -207,6 +222,10 @@ public String getOwner() {
207222
public String getGroup() {
208223
return group;
209224
}
225+
226+
public boolean isDeleted() {
227+
return isDeleted;
228+
}
210229
}
211230

212231
static String getSnapshotPath(String snapshottableDir,

hadoop-hdfs-project/hadoop-hdfs-client/src/main/java/org/apache/hadoop/hdfs/protocolPB/PBHelperClient.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1711,6 +1711,7 @@ public static SnapshotStatus convert(
17111711
status.getFileId(),
17121712
status.getChildrenNum(),
17131713
sdirStatusProto.getSnapshotID(),
1714+
sdirStatusProto.getIsDeleted(),
17141715
sdirStatusProto.getParentFullpath().toByteArray());
17151716
}
17161717

@@ -2425,6 +2426,7 @@ public static HdfsProtos.SnapshotStatusProto convert(SnapshotStatus status) {
24252426
.newBuilder()
24262427
.setSnapshotID(status.getSnapshotID())
24272428
.setParentFullpath(parentFullPathBytes)
2429+
.setIsDeleted(status.isDeleted())
24282430
.setDirStatus(fs);
24292431
return builder.build();
24302432
}

hadoop-hdfs-project/hadoop-hdfs-client/src/main/proto/hdfs.proto

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,7 @@ message SnapshotStatusProto {
574574
// Fields specific for snapshot directory
575575
required uint32 snapshotID = 2;
576576
required bytes parent_fullpath = 3;
577+
required bool isDeleted = 4;
577578
}
578579

579580

hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/snapshot/SnapshotManager.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -599,7 +599,8 @@ public SnapshotStatus[] getSnapshotListing(INodesInPath iip)
599599
// It is expensive to build the snapshot tree for the directory
600600
// and determine the child count.
601601
dir.getChildrenNum(Snapshot.CURRENT_STATE_ID),
602-
s.getId(), DFSUtil.string2Bytes(dir.getParent().getFullPathName()));
602+
s.getId(), s.getRoot().isMarkedAsDeleted(),
603+
DFSUtil.string2Bytes(dir.getParent().getFullPathName()));
603604

604605
}
605606
return statuses;

hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/snapshot/TestListSnapshot.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,10 @@
3030
import org.junit.Before;
3131
import org.junit.Test;
3232

33+
import static org.apache.hadoop.hdfs.server.namenode.snapshot.SnapshotManager.
34+
DFS_NAMENODE_SNAPSHOT_DELETION_ORDERED;
3335
import static org.junit.Assert.assertTrue;
36+
import static org.junit.Assert.assertFalse;
3437
import static org.junit.Assert.assertEquals;
3538
import static org.junit.Assert.assertNull;
3639

@@ -51,6 +54,7 @@ public class TestListSnapshot {
5154
@Before
5255
public void setUp() throws Exception {
5356
conf = new Configuration();
57+
conf.setBoolean(DFS_NAMENODE_SNAPSHOT_DELETION_ORDERED, true);
5458
cluster = new MiniDFSCluster.Builder(conf).numDataNodes(REPLICATION)
5559
.build();
5660
cluster.waitActive();
@@ -128,7 +132,15 @@ public void testListSnapshot() throws Exception {
128132
snapshotStatuses[2].getFullPath());
129133
hdfs.deleteSnapshot(dir1, "s2");
130134
snapshotStatuses = hdfs.getSnapshotListing(dir1);
131-
// There are now 2 snapshots for dir1
135+
// There are now 2 active snapshots for dir1 and one is marked deleted
136+
assertEquals(3, snapshotStatuses.length);
137+
assertTrue(snapshotStatuses[2].isDeleted());
138+
assertFalse(snapshotStatuses[1].isDeleted());
139+
assertFalse(snapshotStatuses[0].isDeleted());
140+
// delete the 1st snapshot
141+
hdfs.deleteSnapshot(dir1, "s0");
142+
snapshotStatuses = hdfs.getSnapshotListing(dir1);
143+
// There are now 2 snapshots now as the 1st one is deleted in order
132144
assertEquals(2, snapshotStatuses.length);
133145
}
134146
}

0 commit comments

Comments
 (0)