|
Server : Apache/2.2.17 (Unix) mod_ssl/2.2.17 OpenSSL/0.9.8e-fips-rhel5 DAV/2 PHP/5.2.17 System : Linux localhost 2.6.18-419.el5 #1 SMP Fri Feb 24 22:47:42 UTC 2017 x86_64 User : nobody ( 99) PHP Version : 5.2.17 Disable Function : NONE Directory : /proc/21573/task/21573/root/usr/share/hwbrowser/ |
Upload File : |
#
# DeviceDisk.py: displays disks
#
# by Matt Wilson <msw@redhat.com>
# heavily adapted by Jonathan Blandford <jrb@redhat.com>
#
# Copyright 2001 Red Hat, Inc.
#
# This software may be freely redistributed under the terms of the GNU
# library public license.
#
# You should have received a copy of the GNU Library Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
import gtk
import gnome.ui
try:
import gnomecanvas
except ImportError:
import gnome.canvas as gnomecanvas
import string
import copy
import parted
import math
import kudzu
import gobject
##
## I18N
##
from rhpl.translate import _, N_
import rhpl.translate as translate
domain = 'hwbrowser'
translate.textdomain (domain)
gtk.glade.bindtextdomain(domain)
STRIPE_HEIGHT = 32.0
LOGICAL_INSET = 3.0
CANVAS_WIDTH = 400
CANVAS_HEIGHT = 200
TREE_SPACING = 2
MODE_ADD = 1
MODE_EDIT = 2
DEVICE_COLUMN=0
START_COLUMN=1
END_COLUMN=2
SIZE_COLUMN=3
TYPE_COLUMN=4
PARTITION_COLUMN=5
xml = None
hardware = None
# XXX this is made up and used by the size spinner; should just be set with
# a callback
MAX_PART_SIZE = 1024*1024*1024
def start_sector_to_cyl(device, sector):
return int(math.floor((float(sector)
/ (device.heads * device.sectors)) + 1))
def end_sector_to_cyl(device, sector):
return int(math.ceil(float((sector + 1))
/ (device.heads * device.sectors)))
def start_cyl_to_sector(device, cyl):
return long((cyl - 1) * (device.heads * device.sectors))
def end_cyl_to_sector(device, cyl):
return long(((cyl) * (device.heads * device.sectors)) - 1)
def get_partition_name(partition):
if (partition.geom.dev.type == parted.DEVICE_DAC960
or partition.geom.dev.type == parted.DEVICE_CPQARRAY):
return "%sp%d" % (partition.geom.dev.path[5:],
partition.num)
return "%s%d" % (partition.geom.dev.path[5:],
partition.num)
class DiskStripeSlice:
def eventHandler(self, widget, event):
if event.type == gtk.gdk.BUTTON_PRESS:
if event.button == 1:
self.parent.selectSlice(self.partition, 1)
return True
def shutDown(self):
self.parent = None
if self.group:
self.group.destroy()
self.group = None
del self.partition
def select(self):
if self.partition.type != parted.PARTITION_EXTENDED:
self.group.raise_to_top()
self.box.set(outline_color="red")
self.box.set(fill_color=self.selectColor())
def deselect(self):
self.box.set(outline_color="black", fill_color=self.fillColor())
def getPartition(self):
return self.partition
def fillColor(self):
if self.partition.type & parted.PARTITION_FREESPACE:
return "grey88"
return "LightSteelBlue"
def selectColor(self):
if self.partition.type & parted.PARTITION_FREESPACE:
return "cornsilk2"
return "cornsilk1"
def hideOrShowText(self):
if self.box.get_bounds()[2] < self.text.get_bounds()[2]:
self.text.hide()
else:
self.text.show()
def sliceText(self):
if self.partition.type & parted.PARTITION_EXTENDED:
return ""
if self.partition.type & parted.PARTITION_FREESPACE:
rc = "Free\n"
else:
rc = "%s\n" % (get_partition_name(self.partition),)
rc = rc + "%d MB" \
% (self.partition.geom.length
* self.parent.getDisk().sector_size
/ 1024.0 / 1024.0,)
return rc
def getDeviceName(self):
return get_partition_name(self.partition)
def update(self):
disk = self.parent.getDisk()
totalSectors = float(disk.heads
* disk.sectors
* disk.cylinders)
if totalSectors == 0:
totalSectors = float(disk.length)
xoffset = self.partition.geom.start / totalSectors * CANVAS_WIDTH
xlength = self.partition.geom.length / totalSectors * CANVAS_WIDTH
if self.partition.type & parted.PARTITION_LOGICAL:
yoffset = 0.0 + LOGICAL_INSET
yheight = STRIPE_HEIGHT - (LOGICAL_INSET * 2)
texty = 0.0
else:
yoffset = 0.0
yheight = STRIPE_HEIGHT
texty = LOGICAL_INSET
self.group.set(x=xoffset, y=yoffset)
self.box.set(x1=0.0, y1=0.0, x2=xlength,
y2=yheight, fill_color=self.fillColor(),
outline_color='black', width_units=1.0)
self.text.set(x=2.0, y=texty + 2.0, text=self.sliceText(),
fill_color='black',
anchor=gtk.ANCHOR_NW, clip=True,
clip_width=xlength-1, clip_height=yheight-1)
self.hideOrShowText()
def __init__(self, parent, partition):
self.text = None
self.partition = partition
self.parent = parent
pgroup = parent.getGroup()
self.group = pgroup.add(gnomecanvas.CanvasGroup)
self.box = self.group.add (gnomecanvas.CanvasRect)
self.group.connect("event", self.eventHandler)
self.text = self.group.add (gnomecanvas.CanvasText, font="helvetica")
self.update()
class DiskStripe:
def __init__(self, drive, disk, group, ctree, canvas):
self.disk = disk
self.group = group;
self.tree = ctree
self.drive = drive
self.canvas = canvas
self.slices = []
self.hash = {}
self.selected = None
group.add (gnomecanvas.CanvasRect, x1=0.0, y1=10.0, x2=CANVAS_WIDTH,
y2=STRIPE_HEIGHT, fill_color='green',
outline_color='grey71', width_units=1.0)
group.lower_to_bottom()
def shutDown(self):
return
while self.slices:
slice = self.slices.pop()
slice.shutDown()
if self.group:
self.group.destroy()
self.group = None
del self.disk
def holds(self, partition):
return self.hash.has_key (partition)
def getSlice(self, partition):
return self.hash[partition]
def getDisk(self):
return self.disk
def getDrive(self):
return self.drive
def getGroup (self):
return self.group
def getCanvas (self):
return self.canvas
def selectSlice(self, partition, updateTree=0):
self.deselect()
slice = self.hash[partition]
slice.select()
# update selection of the tree
if updateTree:
self.tree.get_selection ().unselect_all ()
def foreach_func (model, path, iter, partition):
test_part = model.get_value (iter, PARTITION_COLUMN)
if test_part == partition:
self.tree.get_selection().select_path (path)
return True
return False
self.tree.get_model().foreach (foreach_func, partition)
self.selected = slice
def deselect(self):
if self.selected:
self.selected.deselect ()
self.selected = None
def add (self, partition):
stripe = DiskStripeSlice(self, partition)
self.slices.append(stripe)
self.hash[partition] = stripe
class DiskStripeGraph:
def __init__(self, canvas, ctree):
self.canvas = canvas
self.diskStripes = []
self.textlabels = []
self.ctree = ctree
self.next_ypos = 0.0
# canvas.root().add ('rect', x1=0.0, y1=0.0, x2=10.0, y2=10.0, fill_color='black')
def __del__(self):
self.shutDown()
def shutDown(self):
# remove any circular references so we can clean up
while self.diskStripes:
stripe = self.diskStripes.pop()
stripe.shutDown()
while self.textlabels:
lab = self.textlabels.pop()
lab.destroy()
self.next_ypos = 0.0
def getCanvas(self):
return self.canvas
def unselectAll(self):
for stripe in self.diskStripes:
stripe.deselect()
def selectSlice(self, partition):
for stripe in self.diskStripes:
stripe.deselect()
if stripe.holds(partition):
stripe.selectSlice(partition)
def getSlice(self, partition):
for stripe in self.diskStripes:
if stripe.holds(partition):
return stripe.getSlice(partition)
def getDisk(self, partition):
for stripe in self.diskStripes:
if stripe.holds(partition):
return stripe.getDisk()
def add (self, disk):
yoff = self.next_ypos
text = self.canvas.root().add (gnomecanvas.CanvasText, x=0.0, y=yoff, font="helvetica")
drivetext = "Drive %s (Geom: %s/%s/%s) (Model: %s)" % (disk.path,
disk.cylinders,
disk.heads,
disk.sectors,
disk.model)
text.set(text=drivetext, fill_color='black', anchor=gtk.ANCHOR_NW)
(xxx1, yyy1, xxx2, yyy2) = text.get_bounds()
textheight = 4 + yyy2 - yyy1
group = self.canvas.root().add(gnomecanvas.CanvasGroup, x=0, y=yoff+textheight)
stripe = DiskStripe (disk.path, disk, group, self.ctree, self.canvas)
self.diskStripes.append(stripe)
self.next_ypos = self.next_ypos + STRIPE_HEIGHT+textheight+10
return stripe
def on_disk_tree_select_row (selection, graph):
(model, iter) = selection.get_selected ()
if iter:
partition = model.get_value (iter, PARTITION_COLUMN)
if partition:
graph.selectSlice(partition)
return
graph.unselectAll ()
def populate (tree_view, devices, graph):
tree_view.get_selection().connect ("changed", on_disk_tree_select_row, graph)
model = tree_view.get_model ()
for device in devices:
# add a device stripe to the graph
stripe = graph.add (device)
graph.getCanvas().update_now()
# add a parent node to the tree
parent_iter = model.append (None)
model.set (parent_iter,
DEVICE_COLUMN, device.path,
START_COLUMN, "",
END_COLUMN, "",
SIZE_COLUMN, "",
TYPE_COLUMN, "",
PARTITION_COLUMN, None)
extended_parent = None
try:
#FIXME: we should really handle devises that don't have partitions
disk = parted.PedDisk.new (device)
except:
continue
part = disk.next_partition ()
while part:
if part.type & parted.PARTITION_METADATA:
part = disk.next_partition (part)
continue
slice = stripe.add (part)
text = [""] * 5
if part.type & parted.PARTITION_FREESPACE:
device_text = ""
else:
device_text = get_partition_name (part)
start_text = str (start_sector_to_cyl(device, part.geom.start))
end_text = str (end_sector_to_cyl(device, part.geom.end))
size = part.geom.length*device.sector_size / 1024.0 / 1024.0
if size < 1.0:
size_text = "< 1"
else:
size_text = "%8.0f" % (size)
if part.type & parted.PARTITION_FREESPACE:
type_text = _("Free space")
elif part.type & parted.PARTITION_EXTENDED:
type_text = _("Extended")
elif part.get_flag(parted.PARTITION_RAID) == 1:
type_text = _("software RAID component")
elif part.get_flag(parted.PARTITION_LVM) == 1:
type_text = _("LVM Physical Volume")
elif part.fs_type:
type_text = part.fs_type.name
else:
type_text = _("No filesystem")
type_text
if part.type & parted.PARTITION_EXTENDED:
extended_parent = model.append (parent_iter)
model.set (extended_parent,
DEVICE_COLUMN, device_text,
START_COLUMN, start_text,
END_COLUMN, end_text,
SIZE_COLUMN, size_text,
TYPE_COLUMN, type_text,
PARTITION_COLUMN, part)
elif part.type & parted.PARTITION_LOGICAL:
if not extended_parent:
raise RuntimeError, ("crossed logical partition before extended")
logical = model.append (extended_parent)
model.set (logical,
DEVICE_COLUMN, device_text,
START_COLUMN, start_text,
END_COLUMN, end_text,
SIZE_COLUMN, size_text,
TYPE_COLUMN, type_text,
PARTITION_COLUMN, part)
elif part.type & parted.PARTITION_FREESPACE:
# found freespace
physical = model.append(parent_iter)
model.set (physical,
DEVICE_COLUMN, device_text,
START_COLUMN, start_text,
END_COLUMN, end_text,
SIZE_COLUMN, size_text,
TYPE_COLUMN, type_text,
PARTITION_COLUMN, part)
else:
if (device_text[:3] == "hda" or device_text[:3] == "sda") and device_text[3] in ["1", "2", "3", "4"]:
#looks like I found a primary. For some reason, parted.PARTITION_PRIMARY doesn't seem to be working
physical = model.append(parent_iter)
else:
if extended_parent:
physical = model.append(extended_parent)
else:
physical = model.append(parent_iter)
model.set (physical,
DEVICE_COLUMN, device_text,
START_COLUMN, start_text,
END_COLUMN, end_text,
SIZE_COLUMN, size_text,
TYPE_COLUMN, type_text,
PARTITION_COLUMN, part)
part = disk.next_partition (part)
tree_view.expand_all ()
tree_view.get_selection ().set_mode (gtk.SELECTION_BROWSE)
canvas = graph.getCanvas()
apply(canvas.set_scroll_region, canvas.root().get_bounds())
def initialize (global_xml, global_hardware):
global xml, hardware
xml = global_xml
hardware = global_hardware
tree_view = xml.get_widget ('disk_treeview')
model = gtk.TreeStore (gobject.TYPE_STRING,
gobject.TYPE_STRING,
gobject.TYPE_STRING,
gobject.TYPE_STRING,
gobject.TYPE_STRING,
gobject.TYPE_PYOBJECT)
tree_view.set_model (model)
renderer = gtk.CellRendererText ()
column = gtk.TreeViewColumn ()
column.set_title (_("Device"))
column.pack_start (renderer, True)
column.add_attribute (renderer, "text", DEVICE_COLUMN)
tree_view.append_column (column)
renderer = gtk.CellRendererText ()
column = gtk.TreeViewColumn ()
column.set_title (_("Start"))
column.pack_start (renderer, True)
column.add_attribute (renderer, "text", START_COLUMN)
tree_view.append_column (column)
renderer = gtk.CellRendererText ()
column = gtk.TreeViewColumn ()
column.set_title (_("End"))
column.pack_start (renderer, True)
column.add_attribute (renderer, "text", END_COLUMN)
tree_view.append_column (column)
renderer = gtk.CellRendererText ()
renderer.set_property ("xalign", 1.0)
column = gtk.TreeViewColumn ()
column.set_title (_("Size (MB)"))
column.pack_start (renderer, True)
column.add_attribute (renderer, "text", SIZE_COLUMN)
tree_view.append_column (column)
renderer = gtk.CellRendererText ()
column = gtk.TreeViewColumn ()
column.set_title (_("Type"))
column.pack_start (renderer, True)
column.add_attribute (renderer, "text", TYPE_COLUMN)
tree_view.append_column (column)
disks = []
try:
hardware [kudzu.CLASS_HD]
except:
return
for device in hardware [kudzu.CLASS_HD]:
try:
disk = parted.PedDevice.get ('/dev/' + device.kudzu_device.device)
except:
continue
disks.append (disk)
if disks == []:
return
scrolled_window = xml.get_widget ('scrolledwindow6')
hadjustment = gtk.Adjustment(0, 0, 500, 10, 10, 200)
scrolled_window.set_hadjustment(hadjustment)
vadjustment = gtk.Adjustment(0, 0, 500, 10, 10, 200)
scrolled_window.set_vadjustment(vadjustment)
graph = DiskStripeGraph (xml.get_widget ('disk_canvas'), tree_view)
populate (tree_view, disks, graph)