From owner-svn-src-projects@FreeBSD.ORG Thu Jan 13 18:53:31 2011 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 2E447106564A; Thu, 13 Jan 2011 18:53:31 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 1D6118FC16; Thu, 13 Jan 2011 18:53:31 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id p0DIrVl6060317; Thu, 13 Jan 2011 18:53:31 GMT (envelope-from mav@svn.freebsd.org) Received: (from mav@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id p0DIrVX6060315; Thu, 13 Jan 2011 18:53:31 GMT (envelope-from mav@svn.freebsd.org) Message-Id: <201101131853.p0DIrVX6060315@svn.freebsd.org> From: Alexander Motin Date: Thu, 13 Jan 2011 18:53:30 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r217372 - projects/graid/head/sys/geom/raid X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 13 Jan 2011 18:53:31 -0000 Author: mav Date: Thu Jan 13 18:53:30 2011 New Revision: 217372 URL: http://svn.freebsd.org/changeset/base/217372 Log: Add initial implementation for `graid insert`. It adds specified disks to the array instead of missing ones. Modified: projects/graid/head/sys/geom/raid/md_intel.c Modified: projects/graid/head/sys/geom/raid/md_intel.c ============================================================================== --- projects/graid/head/sys/geom/raid/md_intel.c Thu Jan 13 18:52:13 2011 (r217371) +++ projects/graid/head/sys/geom/raid/md_intel.c Thu Jan 13 18:53:30 2011 (r217372) @@ -995,7 +995,7 @@ g_raid_md_ctl_intel(struct g_raid_md_obj size = pp->mediasize; if (sectorsize < pp->sectorsize) sectorsize = pp->sectorsize; - pd->pd_disk_meta.id = 0xffffffff; + pd->pd_disk_meta.id = 0; pd->pd_disk_meta.flags = INTEL_F_ASSIGNED | INTEL_F_ONLINE; } if (error != 0) @@ -1133,6 +1133,119 @@ g_raid_md_ctl_intel(struct g_raid_md_obj g_raid_destroy_node(sc, 0); return (error); } + if (strcmp(verb, "insert") == 0) { + if (*nargs < 2) { + gctl_error(req, "Invalid number of arguments."); + return (-1); + } + for (i = 1; i < *nargs; i++) { + /* Look for empty disk slot. */ + LIST_FOREACH(disk, &sc->sc_disks, d_next) { + pd = (struct g_raid_md_intel_perdisk *) + disk->d_md_data; + if (pd->pd_disk_pos < 0) + continue; + if (disk->d_state == G_RAID_DISK_S_OFFLINE) + break; + } + if (disk == NULL) { + gctl_error(req, "No missing disks."); + error = -2; + break; + } + + /* Get disk name. */ + snprintf(arg, sizeof(arg), "arg%d", i); + diskname = gctl_get_asciiparam(req, arg); + if (diskname == NULL) { + gctl_error(req, "No disk name (%s).", arg); + error = -3; + break; + } + if (strncmp(diskname, "/dev/", 5) == 0) + diskname += 5; + + /* Try to find provider with specified name. */ + g_topology_lock(); + pp = g_provider_by_name(diskname); + if (pp == NULL) { + gctl_error(req, "Provider '%s' not found.", + diskname); + g_topology_unlock(); + error = -4; + break; + } + cp = g_new_consumer(sc->sc_geom); + if (g_attach(cp, pp) != 0) { + gctl_error(req, "Can't attach provider '%s'.", + diskname); + g_destroy_consumer(cp); + g_topology_unlock(); + error = -5; + break; + } + if (g_access(cp, 1, 1, 1) != 0) { + gctl_error(req, "Can't open provider '%s'.", + diskname); + g_detach(cp); + g_destroy_consumer(cp); + g_topology_unlock(); + error = -6; + break; + } + g_topology_unlock(); + + /* Make sure disk is big enough. */ + LIST_FOREACH(sd, &disk->d_subdisks, sd_next) { + if (sd->sd_offset + sd->sd_size + 4096 > + pp->mediasize) { + gctl_error(req, + "Disk '%s' too small.", + diskname); + g_topology_lock(); + g_raid_kill_consumer(sc, cp); + g_topology_unlock(); + error = -7; + break; + } + } + + /* Read disk metadata. */ + error = g_raid_md_get_label(cp, + &pd->pd_disk_meta.serial[0], INTEL_SERIAL_LEN); + if (error != 0) { + gctl_error(req, + "Can't get serial for provider '%s'.", + diskname); + g_topology_lock(); + g_raid_kill_consumer(sc, cp); + g_topology_unlock(); + error = -8; + break; + } + + cp->private = disk; + disk->d_consumer = cp; + pd->pd_disk_meta.sectors = pp->mediasize / pp->sectorsize; + if (size > pp->mediasize) + size = pp->mediasize; + if (sectorsize < pp->sectorsize) + sectorsize = pp->sectorsize; + pd->pd_disk_meta.id = 0; + pd->pd_disk_meta.flags = INTEL_F_ASSIGNED | INTEL_F_ONLINE; + + /* Welcome the "new" disk. */ + g_raid_change_disk_state(disk, G_RAID_DISK_S_ACTIVE); + LIST_FOREACH(sd, &disk->d_subdisks, sd_next) { + g_raid_event_send(sd, G_RAID_SUBDISK_E_NEW, + G_RAID_EVENT_SUBDISK); + } + } + + /* Write updated metadata to all disks. */ + g_raid_md_write_intel(md); + return (error); + } return (-100); }