hds: check available PCI slot before mounts
authorJinhyung Choi <jinh0.choi@samsung.com>
Thu, 7 Jan 2016 05:55:58 +0000 (14:55 +0900)
committerSeokYeon Hwang <syeon.hwang@samsung.com>
Wed, 13 Jan 2016 01:19:54 +0000 (10:19 +0900)
PCI slot max is 32 and reserved slot for hidden is 4.
ECS sends the number of available PCI slot when the status is requested.
Also, it checks the available PCI slot before HDS tries to attach 9p device.

Change-Id: I24b12bf07574420753de2330ac8dbde6b6547915
Signed-off-by: Jinhyung Choi <jinh0.choi@samsung.com>
tizen/src/ecs/ecs_hds.c
tizen/src/ecs/ecs_hds.h
tizen/src/util/hds.c
tizen/src/util/hds.h

index 7faf988..c7c4d39 100644 (file)
 
 MULTI_DEBUG_CHANNEL(qemu, hds);
 
+// send # of available PCI slot
+static void ecs_hds_send_available_pci(char* cmd)
+{
+    int n_possible;
+    int n_hidden;
+    int n_available = 0;
+    char slot_data [OUT_BUF_SIZE];
+
+    n_possible = hds_get_pci_available_slot_num();
+    if (n_possible > 0) {
+        n_hidden = hds_get_num_hidden_conn();
+
+        if (n_hidden > ECS_HDS_HIDDEN_RESERVED) {
+            n_hidden = 0;
+        } else {
+            n_hidden = ECS_HDS_HIDDEN_RESERVED - n_hidden;
+        }
+
+        n_available = n_possible - n_hidden;
+        if (n_available < 0){
+            n_available = 0;
+        }
+    }
+
+    snprintf(slot_data, sizeof(slot_data), "%d", n_available);
+    make_send_device_ntf(cmd, ECS_HDS_MSG_GROUP, ECS_HDS_ACTION_PCI, slot_data);
+}
+
+static bool check_pci_slot(enum hds_level level)
+{
+    int n_possible;
+    int n_hidden;
+
+    n_possible = hds_get_pci_available_slot_num();
+    if (n_possible <= 0) {
+        return false;
+    }
+
+    g_assert(n_possible > 0);
+
+    if (level == hds_level_hidden) {
+        return true;
+    }
+
+    n_hidden = hds_get_num_hidden_conn();
+
+    if (n_hidden < ECS_HDS_HIDDEN_RESERVED) {
+        n_hidden = ECS_HDS_HIDDEN_RESERVED - n_hidden;
+
+        n_possible = n_possible - n_hidden;
+        if (n_possible <= 0){
+            return false;
+        }
+    }
+
+    return true;
+}
+
 static void ecs_hds_do_status(char* cmd, type_group group)
 {
     char* data = get_hds_lists();
     LOG_INFO("hds status: %s\n", data);
     make_send_device_ntf(cmd, group, ECS_HDS_ACTION_STATE, data);
+
+    ecs_hds_send_available_pci(cmd);
 }
 
 static void ecs_hds_do_mount(char* cmd, type_group group, char *data)
@@ -88,6 +148,13 @@ static void ecs_hds_do_mount(char* cmd, type_group group, char *data)
         level = atoi(level_token);
     }
 
+    // check available PCI slot num
+    if (!check_pci_slot(level)) {
+        LOG_WARNING("No available pci slot.\n");
+        make_send_device_ntf(cmd, group, ECS_HDS_ACT_MOUNT_NO_SPACE, NULL);
+        return;
+    }
+
     hds_id = new_hds_list(host, guest, level);
     if (hds_id != NULL) {
         LOG_INFO("do attach tag: %s, host: %s, guest: %s, level: %d\n", hds_id, host, guest, level);
index 8cf3e03..de8a130 100644 (file)
 
 #include "ecs.h"
 
+#define ECS_HDS_HIDDEN_RESERVED 4
+
 #define ECS_HDS_MSG_GROUP       100
 
 #define ECS_HDS_ACTION_MOUNT    1
 #define ECS_HDS_ACTION_UMOUNT   2
+#define ECS_HDS_ACTION_PCI      98
 #define ECS_HDS_ACTION_STATE    99
 
 enum hds_act_result {
@@ -46,6 +49,7 @@ enum hds_act_result {
     ECS_HDS_ACT_MOUNT_NOT_VALID_PATH = 12,
     ECS_HDS_ACT_MOUNT_DUP_HOST_PATH = 21,
     ECS_HDS_ACT_MOUNT_DUP_GUEST_PATH = 22,
+    ECS_HDS_ACT_MOUNT_NO_SPACE = 23,
     ECS_HDS_ACT_UMOUNT_SUCCESS = 3,
     ECS_HDS_ACT_UMOUNT_FAIL = 4,
     ECS_HDS_ACT_UMOUNT_DETACH_FAIL = 5,
index 5eed1cb..0e45748 100644 (file)
@@ -296,3 +296,19 @@ int hds_get_pci_available_slot_num(void)
 
     return PCI_SLOT_MAX - pci_num;
 }
+
+int hds_get_num_hidden_conn(void)
+{
+    int count = 0;
+    hds_list *list, *next;
+
+    QTAILQ_FOREACH_SAFE(list, &lists, next, next)
+    {
+        if (list->level == hds_level_hidden) {
+            count++;
+        }
+    }
+
+    return count;
+}
+
index af4141a..e2e21f6 100644 (file)
@@ -59,6 +59,8 @@ bool hds_is_host_path_used(const char* path);
 bool hds_is_guest_path_used(const char* path);
 
 char* get_hds_lists(void);
+
 int hds_get_pci_available_slot_num(void);
+int hds_get_num_hidden_conn(void);
 
 #endif // _HDS_