replace tape library body layout
This commit is contained in:
@@ -75,7 +75,21 @@ func (s *DiskService) DiscoverDisks(ctx context.Context) ([]PhysicalDisk, error)
|
||||
}
|
||||
|
||||
devicePath := "/dev/" + device.Name
|
||||
|
||||
|
||||
// Skip ZFS volume block devices (zd* devices are ZFS volumes exported as block devices)
|
||||
// These are not physical disks and should not appear in physical disk list
|
||||
if strings.HasPrefix(device.Name, "zd") {
|
||||
s.logger.Debug("Skipping ZFS volume block device", "device", devicePath)
|
||||
continue
|
||||
}
|
||||
|
||||
// Skip devices under /dev/zvol (ZFS volume devices in zvol directory)
|
||||
// These are virtual block devices created from ZFS volumes, not physical hardware
|
||||
if strings.HasPrefix(devicePath, "/dev/zvol/") {
|
||||
s.logger.Debug("Skipping ZFS volume device", "device", devicePath)
|
||||
continue
|
||||
}
|
||||
|
||||
// Skip OS disk (disk that has root or boot partition)
|
||||
if s.isOSDisk(ctx, devicePath) {
|
||||
s.logger.Debug("Skipping OS disk", "device", devicePath)
|
||||
@@ -113,8 +127,8 @@ func (s *DiskService) DiscoverDisks(ctx context.Context) ([]PhysicalDisk, error)
|
||||
// getDiskInfo retrieves detailed information about a disk
|
||||
func (s *DiskService) getDiskInfo(ctx context.Context, devicePath string) (*PhysicalDisk, error) {
|
||||
disk := &PhysicalDisk{
|
||||
DevicePath: devicePath,
|
||||
HealthStatus: "unknown",
|
||||
DevicePath: devicePath,
|
||||
HealthStatus: "unknown",
|
||||
HealthDetails: make(map[string]interface{}),
|
||||
}
|
||||
|
||||
@@ -129,7 +143,7 @@ func (s *DiskService) getDiskInfo(ctx context.Context, devicePath string) (*Phys
|
||||
disk.Vendor = props["ID_VENDOR"]
|
||||
disk.Model = props["ID_MODEL"]
|
||||
disk.SerialNumber = props["ID_SERIAL_SHORT"]
|
||||
|
||||
|
||||
if props["ID_ATA_ROTATION_RATE"] == "0" {
|
||||
disk.IsSSD = true
|
||||
}
|
||||
@@ -258,11 +272,15 @@ func (s *DiskService) isOSDisk(ctx context.Context, devicePath string) bool {
|
||||
|
||||
// SyncDisksToDatabase syncs discovered disks to the database
|
||||
func (s *DiskService) SyncDisksToDatabase(ctx context.Context) error {
|
||||
s.logger.Info("Starting disk discovery and sync")
|
||||
disks, err := s.DiscoverDisks(ctx)
|
||||
if err != nil {
|
||||
s.logger.Error("Failed to discover disks", "error", err)
|
||||
return fmt.Errorf("failed to discover disks: %w", err)
|
||||
}
|
||||
|
||||
s.logger.Info("Discovered disks", "count", len(disks))
|
||||
|
||||
for _, disk := range disks {
|
||||
// Check if disk exists
|
||||
var existingID string
|
||||
@@ -300,10 +318,80 @@ func (s *DiskService) SyncDisksToDatabase(ctx context.Context) error {
|
||||
disk.HealthStatus, healthDetailsJSON, disk.IsUsed, existingID)
|
||||
if err != nil {
|
||||
s.logger.Error("Failed to update disk", "device", disk.DevicePath, "error", err)
|
||||
} else {
|
||||
s.logger.Debug("Updated disk", "device", disk.DevicePath)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
s.logger.Info("Disk sync completed", "total_disks", len(disks))
|
||||
return nil
|
||||
}
|
||||
|
||||
// ListDisksFromDatabase retrieves all physical disks from the database
|
||||
func (s *DiskService) ListDisksFromDatabase(ctx context.Context) ([]PhysicalDisk, error) {
|
||||
query := `
|
||||
SELECT
|
||||
id, device_path, vendor, model, serial_number, size_bytes,
|
||||
sector_size, is_ssd, health_status, health_details, is_used,
|
||||
created_at, updated_at
|
||||
FROM physical_disks
|
||||
ORDER BY device_path
|
||||
`
|
||||
|
||||
rows, err := s.db.QueryContext(ctx, query)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to query disks: %w", err)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var disks []PhysicalDisk
|
||||
for rows.Next() {
|
||||
var disk PhysicalDisk
|
||||
var healthDetailsJSON []byte
|
||||
var attachedToPool sql.NullString
|
||||
|
||||
err := rows.Scan(
|
||||
&disk.ID, &disk.DevicePath, &disk.Vendor, &disk.Model,
|
||||
&disk.SerialNumber, &disk.SizeBytes, &disk.SectorSize,
|
||||
&disk.IsSSD, &disk.HealthStatus, &healthDetailsJSON,
|
||||
&disk.IsUsed, &disk.CreatedAt, &disk.UpdatedAt,
|
||||
)
|
||||
if err != nil {
|
||||
s.logger.Warn("Failed to scan disk row", "error", err)
|
||||
continue
|
||||
}
|
||||
|
||||
// Parse health details JSON
|
||||
if len(healthDetailsJSON) > 0 {
|
||||
if err := json.Unmarshal(healthDetailsJSON, &disk.HealthDetails); err != nil {
|
||||
s.logger.Warn("Failed to parse health details", "error", err)
|
||||
disk.HealthDetails = make(map[string]interface{})
|
||||
}
|
||||
} else {
|
||||
disk.HealthDetails = make(map[string]interface{})
|
||||
}
|
||||
|
||||
// Get ZFS pool attachment if disk is used
|
||||
if disk.IsUsed {
|
||||
err := s.db.QueryRowContext(ctx,
|
||||
`SELECT zp.name FROM zfs_pools zp
|
||||
INNER JOIN zfs_pool_disks zpd ON zp.id = zpd.pool_id
|
||||
WHERE zpd.disk_id = $1
|
||||
LIMIT 1`,
|
||||
disk.ID,
|
||||
).Scan(&attachedToPool)
|
||||
if err == nil && attachedToPool.Valid {
|
||||
disk.AttachedToPool = attachedToPool.String
|
||||
}
|
||||
}
|
||||
|
||||
disks = append(disks, disk)
|
||||
}
|
||||
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, fmt.Errorf("error iterating disk rows: %w", err)
|
||||
}
|
||||
|
||||
return disks, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user