Copilot commented on code in PR #12465:
URL: https://github.com/apache/cloudstack/pull/12465#discussion_r2704662833


##########
plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java:
##########
@@ -1873,6 +1882,31 @@ public Answer createSnapshot(final CreateObjectCommand 
cmd) {
         }
     }
 
+    private long getRdbSnapshotSize(String poolPath, String diskName, String 
snapshotName, String rbdMonitor, String authUser, String authSecret) {
+        logger.debug("Get RBD snapshot size for {}/{}@{}", poolPath, diskName, 
snapshotName);
+        //cmd: rbd du <pool>/<disk-name>@<snapshot-name> --format json 
--mon-host <monitor-host> --id <user> --key <key> 2>/dev/null
+        String snapshotDetailsInJson = 
Script.runSimpleBashScript(String.format("rbd du %s/%s@%s --format json 
--mon-host %s --id %s --key %s 2>/dev/null", poolPath, diskName, snapshotName, 
rbdMonitor, authUser, authSecret));
+        if (StringUtils.isNotBlank(snapshotDetailsInJson)) {
+            ObjectMapper mapper = new ObjectMapper();
+            try {
+                JsonNode root = mapper.readTree(snapshotDetailsInJson);
+                for (JsonNode image : root.path("images")) {
+                    if (snapshotName.equals(image.path("snapshot").asText())) {
+                        long usedSizeInBytes = 
image.path("used_size").asLong();
+                        if (usedSizeInBytes > 0) {
+                            logger.debug("RBD snapshot {}/{}@{} used size in 
bytes: {}", poolPath, diskName, snapshotName, usedSizeInBytes);
+                            return usedSizeInBytes;
+                        }
+                    }
+                }
+            } catch (JsonProcessingException e) {
+                logger.error("Unable to get the RBD snapshot size", e);
+            }

Review Comment:
   When the rbd command fails or returns null/empty output, the method silently 
returns 0 without logging any details about the command execution failure. This 
makes it difficult to distinguish between a genuine 0-size snapshot and a 
failed command. Consider adding a debug or warning log when 
snapshotDetailsInJson is blank to help troubleshoot issues.
   ```suggestion
               }
           } else {
               logger.warn("Failed to get RBD snapshot size for {}/{}@{}: 'rbd 
du' returned no output or an empty result", poolPath, diskName, snapshotName);
   ```



##########
plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java:
##########
@@ -43,6 +43,10 @@
 
 import javax.naming.ConfigurationException;
 
+import com.ceph.rbd.jna.RbdImageInfo;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import org.apache.cloudstack.agent.directdownload.DirectDownloadAnswer;
 import org.apache.cloudstack.agent.directdownload.DirectDownloadCommand;

Review Comment:
   The import 'com.ceph.rbd.jna.RbdImageInfo' is added but never used in the 
code. Remove this unused import to keep the code clean.
   ```suggestion
   import com.fasterxml.jackson.core.JsonProcessingException;
   import com.fasterxml.jackson.databind.JsonNode;
   import com.fasterxml.jackson.databind.ObjectMapper;
   import org.apache.cloudstack.agent.directdownload.DirectDownloadAnswer;
   import org.apache.cloudstack.agent.directdownload.DirectDownloadCommand;
   import org.apache.cloudstack.agent.directdownload.DirectDownloadCommand;
   ```



##########
plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java:
##########
@@ -1873,6 +1882,31 @@ public Answer createSnapshot(final CreateObjectCommand 
cmd) {
         }
     }
 
+    private long getRdbSnapshotSize(String poolPath, String diskName, String 
snapshotName, String rbdMonitor, String authUser, String authSecret) {

Review Comment:
   Method name has a typo: 'getRdbSnapshotSize' should be 'getRbdSnapshotSize' 
(RBD stands for RADOS Block Device). This inconsistency makes the code harder 
to maintain and understand.



##########
plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java:
##########
@@ -1873,6 +1882,31 @@ public Answer createSnapshot(final CreateObjectCommand 
cmd) {
         }
     }
 
+    private long getRdbSnapshotSize(String poolPath, String diskName, String 
snapshotName, String rbdMonitor, String authUser, String authSecret) {
+        logger.debug("Get RBD snapshot size for {}/{}@{}", poolPath, diskName, 
snapshotName);
+        //cmd: rbd du <pool>/<disk-name>@<snapshot-name> --format json 
--mon-host <monitor-host> --id <user> --key <key> 2>/dev/null
+        String snapshotDetailsInJson = 
Script.runSimpleBashScript(String.format("rbd du %s/%s@%s --format json 
--mon-host %s --id %s --key %s 2>/dev/null", poolPath, diskName, snapshotName, 
rbdMonitor, authUser, authSecret));

Review Comment:
   The command construction using String.format with user-controlled parameters 
(poolPath, diskName, snapshotName, rbdMonitor, authUser, authSecret) is 
vulnerable to command injection. If any of these parameters contain shell 
metacharacters like semicolons, pipes, backticks, or dollar signs, they could 
be used to execute arbitrary commands. Consider using a more secure approach 
such as:
   1. Using Script.runSimpleBashScriptWithParameters or similar method that 
properly escapes arguments
   2. Validating and sanitizing input parameters before using them in shell 
commands
   3. Using the Java RBD bindings (like the existing Rbd/RbdImage classes) 
instead of shell commands
   ```suggestion
           String snapshotDetailsInJson = 
Script.runSimpleBashScriptWithParameters(
                   "rbd du %s/%s@%s --format json --mon-host %s --id %s --key 
%s 2>/dev/null",
                   poolPath, diskName, snapshotName, rbdMonitor, authUser, 
authSecret);
   ```



##########
plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java:
##########
@@ -1873,6 +1882,31 @@ public Answer createSnapshot(final CreateObjectCommand 
cmd) {
         }
     }
 
+    private long getRdbSnapshotSize(String poolPath, String diskName, String 
snapshotName, String rbdMonitor, String authUser, String authSecret) {
+        logger.debug("Get RBD snapshot size for {}/{}@{}", poolPath, diskName, 
snapshotName);
+        //cmd: rbd du <pool>/<disk-name>@<snapshot-name> --format json 
--mon-host <monitor-host> --id <user> --key <key> 2>/dev/null
+        String snapshotDetailsInJson = 
Script.runSimpleBashScript(String.format("rbd du %s/%s@%s --format json 
--mon-host %s --id %s --key %s 2>/dev/null", poolPath, diskName, snapshotName, 
rbdMonitor, authUser, authSecret));
+        if (StringUtils.isNotBlank(snapshotDetailsInJson)) {
+            ObjectMapper mapper = new ObjectMapper();
+            try {
+                JsonNode root = mapper.readTree(snapshotDetailsInJson);
+                for (JsonNode image : root.path("images")) {
+                    if (snapshotName.equals(image.path("snapshot").asText())) {
+                        long usedSizeInBytes = 
image.path("used_size").asLong();
+                        if (usedSizeInBytes > 0) {
+                            logger.debug("RBD snapshot {}/{}@{} used size in 
bytes: {}", poolPath, diskName, snapshotName, usedSizeInBytes);
+                            return usedSizeInBytes;
+                        }
+                    }
+                }
+            } catch (JsonProcessingException e) {
+                logger.error("Unable to get the RBD snapshot size", e);

Review Comment:
   The error handling silently logs an error and returns 0 when JSON parsing 
fails. This makes debugging difficult and could mask underlying issues. 
Consider logging the actual JSON content that failed to parse (taking care not 
to log sensitive credentials) to help with troubleshooting.
   ```suggestion
                   logger.error("Unable to get the RBD snapshot size. RBD JSON 
output: {}", snapshotDetailsInJson, e);
   ```



##########
plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java:
##########
@@ -1873,6 +1882,31 @@ public Answer createSnapshot(final CreateObjectCommand 
cmd) {
         }
     }
 
+    private long getRdbSnapshotSize(String poolPath, String diskName, String 
snapshotName, String rbdMonitor, String authUser, String authSecret) {
+        logger.debug("Get RBD snapshot size for {}/{}@{}", poolPath, diskName, 
snapshotName);
+        //cmd: rbd du <pool>/<disk-name>@<snapshot-name> --format json 
--mon-host <monitor-host> --id <user> --key <key> 2>/dev/null
+        String snapshotDetailsInJson = 
Script.runSimpleBashScript(String.format("rbd du %s/%s@%s --format json 
--mon-host %s --id %s --key %s 2>/dev/null", poolPath, diskName, snapshotName, 
rbdMonitor, authUser, authSecret));
+        if (StringUtils.isNotBlank(snapshotDetailsInJson)) {
+            ObjectMapper mapper = new ObjectMapper();
+            try {
+                JsonNode root = mapper.readTree(snapshotDetailsInJson);
+                for (JsonNode image : root.path("images")) {
+                    if (snapshotName.equals(image.path("snapshot").asText())) {
+                        long usedSizeInBytes = 
image.path("used_size").asLong();
+                        if (usedSizeInBytes > 0) {
+                            logger.debug("RBD snapshot {}/{}@{} used size in 
bytes: {}", poolPath, diskName, snapshotName, usedSizeInBytes);
+                            return usedSizeInBytes;
+                        }
+                    }
+                }
+            } catch (JsonProcessingException e) {
+                logger.error("Unable to get the RBD snapshot size", e);
+            }
+        }
+
+        return 0;
+    }

Review Comment:
   The method uses shell commands to get RBD snapshot size, while the 
createSnapshot method already uses Java RBD bindings (Rbd, RbdImage). Consider 
using RbdImage.stat() or similar Java API methods to get snapshot size 
information instead of relying on shell commands. This would be more consistent 
with the existing code, avoid command injection risks, and be more maintainable.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to