From owner-svn-src-user@FreeBSD.ORG Fri Oct 29 09:50:28 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id EF32F106566C; Fri, 29 Oct 2010 09:50:28 +0000 (UTC) (envelope-from ae@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id DCFF38FC1A; Fri, 29 Oct 2010 09:50:28 +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 o9T9oSVY092992; Fri, 29 Oct 2010 09:50:28 GMT (envelope-from ae@svn.freebsd.org) Received: (from ae@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o9T9oSMV092985; Fri, 29 Oct 2010 09:50:28 GMT (envelope-from ae@svn.freebsd.org) Message-Id: <201010290950.o9T9oSMV092985@svn.freebsd.org> From: "Andrey V. Elsukov" Date: Fri, 29 Oct 2010 09:50:28 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r214507 - user/ae/usr.sbin/sade X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 29 Oct 2010 09:50:29 -0000 Author: ae Date: Fri Oct 29 09:50:28 2010 New Revision: 214507 URL: http://svn.freebsd.org/changeset/base/214507 Log: Move and refactor filesystem related code from fs.c, fsed.c and libsade.h to ufsed.c. It is not yet finished. Allow navigation with Up/Down keys in another dialogs in parted. Connect ufsed.c to the build. Added: user/ae/usr.sbin/sade/ufsed.c (contents, props changed) Deleted: user/ae/usr.sbin/sade/fs.c user/ae/usr.sbin/sade/fsed.c Modified: user/ae/usr.sbin/sade/Makefile user/ae/usr.sbin/sade/libsade.h user/ae/usr.sbin/sade/menus.c user/ae/usr.sbin/sade/parted.c user/ae/usr.sbin/sade/sade.h Modified: user/ae/usr.sbin/sade/Makefile ============================================================================== --- user/ae/usr.sbin/sade/Makefile Fri Oct 29 09:35:36 2010 (r214506) +++ user/ae/usr.sbin/sade/Makefile Fri Oct 29 09:50:28 2010 (r214507) @@ -6,9 +6,9 @@ SRCPATH?= ../../../../head PROG= sade NO_MAN= -LIBSADE=devices.c parts.c util.c fs.c +LIBSADE=devices.c parts.c util.c -SRCS= main.c parted.c menus.c customdlg.c history.c fsed.c \ +SRCS= main.c parted.c menus.c customdlg.c history.c ufsed.c \ getmntopts.c SRCS+= ${LIBSADE} Modified: user/ae/usr.sbin/sade/libsade.h ============================================================================== --- user/ae/usr.sbin/sade/libsade.h Fri Oct 29 09:35:36 2010 (r214506) +++ user/ae/usr.sbin/sade/libsade.h Fri Oct 29 09:50:28 2010 (r214507) @@ -33,16 +33,10 @@ __FBSDID("$FreeBSD$"); #include #include -#include -#include -#include -#include -#include #include TAILQ_HEAD(de_devlist, de_device); TAILQ_HEAD(de_partlist, de_part); -TAILQ_HEAD(de_fslist, de_fs); struct de_device { char *de_name; /* device name */ @@ -75,46 +69,6 @@ struct de_part { void *de_private; /* partition private data */ }; -enum de_fstype { - UNKNOWN, EMPTY, SWAP, UFS, ZFS -}; - -struct de_fs { - TAILQ_ENTRY(de_fs) de_fs; /* file system list entry */ - enum de_fstype de_type; /* file system type */ - char *de_parttype; /* partition type */ - char *de_partname; /* partition name */ - char *de_mntfrom; /* device name */ - char *de_mntto; /* file system mount path */ - char *de_mounted; /* where it is mounted now */ - char *de_mntops; /* mount options */ - off_t de_size; /* file system size */ - int de_freq; /* dump frequency */ - int de_pass; /* pass number on parallel fsck */ - - char *de_devname; /* parent device name */ - char *de_scheme; /* partition scheme name */ - - u_int de_flags; /* file system flags */ - void *de_private; /* file system private data */ -}; - -struct de_ufs_priv { - char de_volname[MAXVOLLEN]; /* Volume label */ - int32_t de_id[2]; /* unique filesystem id */ -#define HAS_UFSID(ppriv) \ - ((ppriv)->de_id[0] != 0 || (ppriv)->de_id[1] != 0) - - int de_ufs1:1; /* UFS1 fs type */ - int de_su:1; /* Soft Updates enabled */ - int de_suj:1; /* Journalled Soft Updates enabled */ - int de_gj:1; /* GEOM Journal enabled */ - - int de_acl:1; /* POSIX.1e ACL enabled */ - int de_nfs4acl:1; /* NFSv4 ACL enabled */ - int de_mac:1; /* MAC multilabel enabled */ -}; - /* device related functions */ int de_devlist_get(struct de_devlist *pd); int de_devlist_partitioned_get(struct de_devlist *pd); @@ -148,13 +102,6 @@ int de_part_mod(struct de_device *pdev, const char *label, int idx); int de_part_bootcode(struct de_part *ppart, const char *path); -/* file system related */ -const char *de_fstypestr(enum de_fstype type); -int de_fslist_get(struct de_fslist *fslist); -void de_fslist_free(struct de_fslist *fslist); -int de_fslist_count(struct de_fslist *fslist); - - /* geom helpers */ struct gclass *find_class(struct gmesh *mesh, const char *name); struct ggeom *find_geom(struct gclass *classp, const char *name); Modified: user/ae/usr.sbin/sade/menus.c ============================================================================== --- user/ae/usr.sbin/sade/menus.c Fri Oct 29 09:35:36 2010 (r214506) +++ user/ae/usr.sbin/sade/menus.c Fri Oct 29 09:50:28 2010 (r214507) @@ -289,7 +289,7 @@ open_parts(dialogMenuItem *pitem) static int open_fs(dialogMenuItem *pitem) { - fsed_open(); + ufsed_open(); return (DITEM_SUCCESS); } Modified: user/ae/usr.sbin/sade/parted.c ============================================================================== --- user/ae/usr.sbin/sade/parted.c Fri Oct 29 09:35:36 2010 (r214506) +++ user/ae/usr.sbin/sade/parted.c Fri Oct 29 09:50:28 2010 (r214507) @@ -333,12 +333,13 @@ again: q = 1; else if (item == btnOk) q = 2; - else if (item == ltType) { - dlg_edit_set_value(&dlg, eType, - dlg_list_get_choice(&dlg, ltType)); - dlg_focus_next(&dlg); - } else + else { + if (item == ltType) + dlg_edit_set_value(&dlg, eType, + dlg_list_get_choice(&dlg, ltType)); dlg_focus_next(&dlg); + } + break; case KEY_UP: dlg_focus_prev(&dlg); break; @@ -426,18 +427,18 @@ again: q = 1; else if (item == btnOk) q = 2; - else if (item == ltType) { - dlg_edit_set_value(&dlg, eType, - dlg_list_get_choice(&dlg, ltType)); - dlg_focus_next(&dlg); - } else + else { + if (item == ltType) + dlg_edit_set_value(&dlg, eType, + dlg_list_get_choice(&dlg, ltType)); dlg_focus_next(&dlg); + } + break; case KEY_UP: + dlg_focus_prev(&dlg); + break; case KEY_DOWN: - if (item == btnCancel) - dlg_focus_prev(&dlg); - if (item == btnOk) - dlg_focus_next(&dlg); + dlg_focus_next(&dlg); break; } } while (q == 0); Modified: user/ae/usr.sbin/sade/sade.h ============================================================================== --- user/ae/usr.sbin/sade/sade.h Fri Oct 29 09:35:36 2010 (r214506) +++ user/ae/usr.sbin/sade/sade.h Fri Oct 29 09:50:28 2010 (r214507) @@ -63,7 +63,7 @@ void dmenu_open_errormsg(char *msg); int dmenu_open_yesno(char *msg); int dmenu_open_noyes(char *msg); int parted_open(struct de_device *pdev, int level); -int fsed_open(void); +int ufsed_open(void); WINDOW *savescr(void); void restorescr(WINDOW *win); char *hscroll_str(char *buf, int w, const char *str, int sc, int flag); Added: user/ae/usr.sbin/sade/ufsed.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ user/ae/usr.sbin/sade/ufsed.c Fri Oct 29 09:50:28 2010 (r214507) @@ -0,0 +1,443 @@ +/*- + * Copyright (c) 2010 Andrey V. Elsukov + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "customdlg.h" +#include "mntopts.h" + + +static char *ask_recreate_msg = + "WARNING: Selected partition already contains a file system!\n\n" + "Are you absolutely sure you want to recreate it?"; +static char *custom_newfs_title = "Please enter custom parameters for newfs:"; +static char *undo_msg = "Are you SURE you want to undo everything?"; +static char *write_confirm_msg = + "WARNING: You are about to save all your changes to device.\n" + "After that you will can not undo your changes.\n\n" + "Are you absolutely sure you want to continue?"; +static char *pending_write_msg = + "WARNING: There are some changes pending of write to device.\n\n" + "Would you like to save these changes?"; + +TAILQ_HEAD(ufslist, ufsinfo); +struct ufsinfo { + TAILQ_ENTRY(ufsinfo) entry; + char *devname; /* parent device name */ + char *scheme; /* partitioning scheme */ + char *partname; /* partition name */ + off_t size; /* partition size */ + + /* UFS Info */ + char *fsmnt; /* last mounted path */ + char *volname; /* volume label */ + int32_t id[2]; /* UFS ID */ +#define HAS_UFSID(pfs) \ + ((pfs)->id[0] != 0 || (pfs)->id[1] != 0) + + int32_t flags; /* FS_XX flags */ + int32_t magic; /* magic number */ + + struct fstab *fstabent; /* fstab entry */ + char *mntonname; /* current mountpoint */ +}; + +static int ufslist_add(struct ufslist *, struct de_device *, struct de_part *); +static void ufslist_free(struct ufslist *); +static int ufslist_count(struct ufslist *); +static int ufslist_get(struct ufslist *); + +static int ufsinspect(struct ufsinfo *); + +static int +ufslist_add(struct ufslist *fslist, struct de_device *pdev, + struct de_part *ppart) +{ + struct ufsinfo *pfs; + + assert(fslist != NULL); + assert(pdev != NULL); + assert(ppart != NULL); + assert(pdev->de_sectorsize > 0); + + pfs = malloc(sizeof(*pfs)); + if (pfs == NULL) + return (ENOMEM); + bzero(pfs, sizeof(*pfs)); + pfs->devname = strdup(pdev->de_name); + pfs->scheme = strdup(pdev->de_scheme); + pfs->partname = strdup(ppart->de_name); + pfs->size = (ppart->de_end - ppart->de_start) * pdev->de_sectorsize; + TAILQ_INSERT_TAIL(fslist, pfs, entry); + ufsinspect(pfs); + return (0); +} + +static void +ufslist_free(struct ufslist *fslist) +{ + struct ufsinfo *pfs; + + while (!TAILQ_EMPTY(fslist)) { + pfs = TAILQ_FIRST(fslist); + free(pfs->devname); + free(pfs->scheme); + free(pfs->partname); + free(pfs->fsmnt); + free(pfs->volname); + TAILQ_REMOVE(fslist, pfs, entry); + free(pfs); + } +} + +static int +ufslist_count(struct ufslist *fslist) +{ + struct ufsinfo *pfs; + int count; + + count = 0; + TAILQ_FOREACH(pfs, fslist, entry) { + count++; + } + return (count); +} + +static int +ufslist_get(struct ufslist *fslist) +{ + struct de_devlist devices; + struct de_device *pdev; + struct de_part *ppart; + int error; + + assert(fslist != NULL); + + error = de_devlist_partitioned_get(&devices); + if (error) + return (error); + + TAILQ_INIT(fslist); + TAILQ_FOREACH(pdev, &devices, de_device) { + error = de_partlist_get(pdev); + if (error) + break; + TAILQ_FOREACH(ppart, &pdev->de_part, de_part) { + /* skip empty chunks */ + if (ppart->de_type == NULL) + continue; + if (strcmp(ppart->de_type, "freebsd-ufs") != 0) + continue; + error = ufslist_add(fslist, pdev, ppart); + if (error) + break; + } + de_dev_partlist_free(pdev); + if (error) + break; + } + de_devlist_free(&devices); + return (error); +} + +static int +ufsinspect(struct ufsinfo *pfs) +{ + struct uufsd disk; + int error; + + bzero(&disk, sizeof(disk)); + error = ufs_disk_fillout(&disk, pfs->partname); + if (error != -1) { + pfs->id[0] = disk.d_fs.fs_id[0]; + pfs->id[1] = disk.d_fs.fs_id[1]; + pfs->flags = disk.d_fs.fs_flags; + pfs->magic = disk.d_fs.fs_magic; + if (disk.d_fs.fs_volname[0] != '\0') + pfs->volname = strndup(disk.d_fs.fs_volname, + MAXVOLLEN); + if (disk.d_fs.fs_fsmnt[0] != '\0') + pfs->fsmnt = strndup(disk.d_fs.fs_fsmnt, + MAXMNTLEN); + } + ufs_disk_close(&disk); + return (error); +} + +static void +set_statusline(char *msg) +{ + if (msg) { + attrset(title_attr); + mvprintw(LINES - 1, 0, msg); + attrset(A_NORMAL); + beep(); + } else { + move(LINES - 1, 0); + clrtoeol(); + } +} + +enum hist_cmd_type { + NEWFS, TUNEFS +}; + +struct hist_cmd_entry { + enum hist_cmd_type type; + struct de_fs *pfs; + char *args; +}; + +static int +ufsed_history_rollback(void *pentry) +{ + return (0); +} + +static int +ufsed_history_play(void *pentry) +{ + return (0); +} + +static int +ufslist_reread(struct ufslist *fslist) +{ + int error; + + ufslist_free(fslist); + error = ufslist_get(fslist); + + return (error); +} + +#define FSED_MENU_TOP 4 +#define FSED_BOTTOM_HEIGHT 7 +#define LABEL(l) ((l) ? (l): "-") + +int +ufsed_open(void) +{ + struct ufslist fslist; + struct ufsinfo *pfs, *selected; + int count, height, row, i, key, ret; + int sc = 0, ch = 0, q = 0; + history_t hist; + WINDOW *win; + char *msg, *tmps; + int error; + + error = ufslist_get(&fslist); + if (error) + return (error); + if (TAILQ_EMPTY(&fslist)) { + dmenu_open_errormsg("Suitable partitions are not found! " + "Create partitions and try again."); + return (0); + } + msg = NULL; + getmnt_silent = 1; /* make getmntopts() silent */ + hist = history_init(); + win = savescr(); + keypad(stdscr, TRUE); + dialog_clear_norefresh(); clear(); + count = ufslist_count(&fslist); +resize: + if (LINES > VTY_STATUS_LINE) + height = LINES - 1; + else + height = VTY_STATUS_LINE; + height -= FSED_MENU_TOP + FSED_BOTTOM_HEIGHT; + do { + attrset(A_NORMAL); + mvprintw(0, 0, "%-12s", "Device:"); + clrtobot(); attrset(A_REVERSE); + mvprintw(0, 61, "File Systems Editor"); + attrset(A_NORMAL); + mvprintw(2, 0, "%-20s%6s%11s", "Device", "Size", "FS Info"); + row = FSED_MENU_TOP - 1; + if (sc > 0) + mvprintw(row, 11, "^(-)"); + else { + move(row, 0); + clrtoeol(); + } + i = 0; + TAILQ_FOREACH(pfs, &fslist, entry) { + if (i++ < sc) + continue; + if (++row - FSED_MENU_TOP > height - 1) + break; + if (ch == row - FSED_MENU_TOP) { + attrset(A_REVERSE); + selected = pfs; + } + mvprintw(row, 0, "%-20s%6s", LABEL(pfs->partname), + fmtsize(pfs->size)); + if (ch == row - FSED_MENU_TOP) + attrset(A_NORMAL); + } + attrset(A_REVERSE); + mvprintw(0, 12, "%s, %s scheme", selected->devname, + selected->scheme); + attrset(A_NORMAL); + if (sc + height < count) + mvprintw(height + FSED_MENU_TOP, 11, "v(+)"); + else { + move(height + FSED_MENU_TOP, 0); + clrtoeol(); + } + switch (selected->magic) { + case FS_UFS1_MAGIC: + tmps = "UFS1"; + break; + case FS_UFS2_MAGIC: + tmps = "UFS2"; + break; + default: + tmps = "unknown"; + } + mvprintw(FSED_MENU_TOP, 30, "%-20s%s", "File System:", tmps); + if (selected->magic == FS_UFS1_MAGIC || + selected->magic == FS_UFS2_MAGIC) { + mvprintw(FSED_MENU_TOP + 1, 30, "%-20s%s", + "last mountpoint:", + LABEL(selected->fsmnt)); + mvprintw(FSED_MENU_TOP + 2, 30, "%-20s%08x%08x", + "UFS id:", selected->id[0], selected->id[1]); + mvprintw(FSED_MENU_TOP + 3, 30, "%-20s%s", + "volume label:", LABEL(selected->volname)); +#define FS_STATUS(pfs, flag) \ + ((((pfs)->flags & (flag)) != 0) ? "enabled": "disabled") + mvprintw(FSED_MENU_TOP + 4, 30, "%-20s%s", + "POSIX.1e ACLs:", FS_STATUS(selected, FS_ACLS)); + mvprintw(FSED_MENU_TOP + 5, 30, "%-20s%s", + "NFSv4 ACLs:", FS_STATUS(selected, FS_NFS4ACLS)); + mvprintw(FSED_MENU_TOP + 6, 30, "%-20s%s", + "MAC multilabel:", + FS_STATUS(selected, FS_MULTILABEL)); + mvprintw(FSED_MENU_TOP + 7, 30, "%-20s%s", + "soft updates:", + FS_STATUS(selected, FS_DOSOFTDEP)); + mvprintw(FSED_MENU_TOP + 8, 30, "%-20s%s", + "SU journaling:", + FS_STATUS(selected, FS_SUJ)); + mvprintw(FSED_MENU_TOP + 9, 30, "%-20s%s", + "gjournal:", FS_STATUS(selected, FS_GJOURNAL)); + } + mvprintw(height + FSED_MENU_TOP + 1, 0, + "The following commands are supported:"); + mvprintw(height + FSED_MENU_TOP + 3, 0, + "C = Create File System M = Modify File System Q = Finish"); + mvprintw(height + FSED_MENU_TOP + 4, 0, + "U = Undo All Changes W = Write Changes"); + mvprintw(height + FSED_MENU_TOP + 8, 0, + "Use F1 or ? to get more help, arrow keys to select"); + set_statusline(msg); + if (msg) + msg = NULL; + + key = toupper(getch()); + switch (key) { + case '\r': + case '\n': + break; + case KEY_ESC: + case 'Q': + q = 1; + break; + case 'W': + if (history_isempty(hist)) { + msg = "Nothing to save."; + break; + } + if (dmenu_open_noyes(write_confirm_msg)) + break; + error = history_play(hist, ufsed_history_play); + if (error != 0) { + /* XXX: report about completed commands */ + history_rollback(hist, ufsed_history_rollback); + } + error = ufslist_reread(&fslist); + break; + case 'U': + if (history_isempty(hist)) { + msg = "Nothing to undo."; + break; + } + if (dmenu_open_noyes(undo_msg)) + break; + history_rollback(hist, ufsed_history_rollback); + error = ufslist_reread(&fslist); + break; + case KEY_UP: + case KEY_DOWN: + case KEY_PPAGE: + case KEY_HOME: + case KEY_NPAGE: + case KEY_END: + dlg_list_handle_move(key, &ch, &sc, count, + height); + break; + case KEY_RESIZE: + sc = ch = 0; + goto resize; + default: + msg = "Type F1 or ? for help"; + }; + } while (q == 0); + if (!history_isempty(hist)) + history_rollback(hist, ufsed_history_rollback); + history_free(hist); + restorescr(win); + ufslist_free(&fslist); + return (0); +} +