Print this page
4833 Remove volrmmount
4845 rm(u)mount don't always print mount/unmount errors
4846 HAL partition names don't match real parition names
Reviewed by: Dan McDonald <danmcd@omniti.com>
Reviewed by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
   1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.


  25  */
  26 
  27 /*
  28  * rmf_misc.c :
  29  *      Miscelleneous routines for rmformat.
  30  */
  31 
  32 #include <sys/types.h>
  33 #include <stdio.h>
  34 #include <sys/mnttab.h>
  35 #include <volmgt.h>
  36 #include <sys/dkio.h>
  37 #include <sys/fdio.h>
  38 #include <sys/vtoc.h>
  39 #include <sys/termios.h>
  40 #include <sys/mount.h>
  41 #include <ctype.h>
  42 #include <signal.h>
  43 #include <sys/wait.h>
  44 #include <dirent.h>


  70 static struct   uscsi_cmd uscmd;
  71 static char     ucdb[16];
  72 uchar_t         uscsi_status, rqstatus, rqresid;
  73 int             total_devices_found = 0;
  74 int             removable_found = 0;
  75 
  76 extern char     *global_intr_msg;
  77 extern int      vol_running;
  78 extern char     *dev_name;
  79 extern int32_t  m_flag;
  80 
  81 /*
  82  * ON-private functions from libvolmgt
  83  */
  84 int     _dev_mounted(char *path);
  85 
  86 /*
  87  * Function prototypes.
  88  */
  89 static int              my_umount(char *mountp);
  90 static int              my_volrmmount(char *real_name);
  91 static int              vol_name_to_dev_node(char *vname, char *found);
  92 static int              vol_lookup(char *supplied, char *found);
  93 static device_t         *get_device(char *user_supplied, char *node);
  94 static char             *get_physical_name(char *path);
  95 static int              lookup_device(char *supplied, char *found);
  96 static void             fini_device(device_t *dev);
  97 static int              is_cd(char *node);
  98 void                    *my_zalloc(size_t size);
  99 void                    err_msg(char *fmt, ...);
 100 int                     inquiry(int fd, uchar_t *inq);
 101 struct uscsi_cmd        *get_uscsi_cmd(void);
 102 int                     uscsi(int fd, struct uscsi_cmd *scmd);
 103 int                     get_mode_page(int fd, int page_no, int pc, int buf_len,
 104                             uchar_t *buffer);
 105 int                     mode_sense(int fd, uchar_t pc, int dbd, int page_len,
 106                             uchar_t *buffer);
 107 uint16_t                read_scsi16(void *addr);
 108 int                     check_device(device_t *dev, int cond);
 109 static void             get_media_info(device_t *t_dev, char *sdev,
 110                             char *pname, char *sn);


 206                 buf = fgets(re_passwd, (size_t)256, in);
 207                 rewind(in);
 208                 (void) fputc('\n', out);
 209                 if ((buf == NULL) || strcmp(passwd, re_passwd)) {
 210                         (void) fputs("passwords did not match\n", out);
 211                         (void) fputs("Try again\n", out);
 212                 } else {
 213                         break;
 214                 }
 215         }
 216         wp->sm_passwd_len = len;
 217         (void) strncpy(wp->sm_passwd, passwd, wp->sm_passwd_len);
 218         wp->sm_version = SMWP_STATE_V_1;
 219 
 220         /* Restore echoing.  */
 221         if (echo_off)
 222                 (void) tcsetattr(fileno(in), TCSAFLUSH, &tio);
 223 
 224 }
 225 
 226 int32_t
 227 check_and_unmount_vold(char *device_name, int32_t flag)
 228 {
 229         char *real_name;
 230         char *nm;
 231         char tmp_path_name[PATH_MAX];
 232         struct stat stat_buf;
 233         int32_t ret_val = 0;
 234         struct  mnttab  *mntp;
 235         FILE    *fp;
 236         int nl;
 237 
 238         DPRINTF1("Device name %s\n", device_name);
 239 
 240         if (volmgt_running() == 0) {
 241                 DPRINTF("Vold not running\n");
 242                 return (0);
 243         }
 244         if ((nm = volmgt_symname(device_name)) == NULL) {
 245                 DPRINTF("path not managed\n");
 246                 real_name = media_findname(device_name);
 247         } else {
 248                 DPRINTF1("path managed as %s\n", nm);
 249                 real_name = media_findname(nm);
 250                 DPRINTF1("real name %s\n", real_name);
 251         }
 252 
 253         if (real_name == NULL)
 254                 return (-1);
 255 
 256         /*
 257          * To find out whether the device has been mounted by
 258          * volume manager...
 259          *
 260          * Convert the real name to a block device address.
 261          * Do a partial match with the mnttab entries.
 262          * Make sure the match is in the beginning to avoid if
 263          * anybody puts a label similiar to volume manager path names.
 264          * Then use "volrmmount -e <dev_name>" if -U flag is set.
 265          */
 266 
 267         nl = strlen("/vol/dev/");
 268 
 269         if (strncmp(real_name, "/vol/dev/", nl) != 0)
 270                         return (0);
 271         if (real_name[nl] == 'r') {
 272                 (void) snprintf(tmp_path_name, PATH_MAX, "%s%s", "/vol/dev/",
 273                     &real_name[nl + 1]);
 274         } else {
 275                 (void) snprintf(tmp_path_name, PATH_MAX, "%s", real_name);
 276         }
 277         DPRINTF1("%s \n", tmp_path_name);
 278         ret_val = stat(tmp_path_name, &stat_buf);
 279         if (ret_val < 0) {
 280                 PERROR("Could not stat");
 281                 return (-1);
 282         }
 283 
 284         fp = fopen("/etc/mnttab", "r");
 285 
 286         if (fp == NULL) {
 287                 PERROR("Could not open /etc/mnttab");
 288                 return (-1);
 289         }
 290 
 291         mntp = (struct mnttab *)malloc(sizeof (struct mnttab));
 292         if (mntp == NULL) {
 293                 PERROR("malloc failed");
 294                 (void) fclose(fp);
 295                 return (-1);
 296         }
 297         errno = 0;
 298         while (getmntent(fp, mntp) == 0) {
 299                 if (errno != 0) {
 300                         PERROR("Error with mnttab");
 301                         (void) fclose(fp);
 302                         return (-1);
 303                 }
 304                 /* Is it a probable entry? */
 305                 DPRINTF1(" %s \n", mntp->mnt_special);
 306                 if (strstr(mntp->mnt_special, tmp_path_name) !=
 307                     mntp->mnt_special) {
 308                         /* Skip to next entry */
 309                         continue;
 310                 } else {
 311                         DPRINTF1("Found!! %s\n", mntp->mnt_special);
 312                         ret_val = 1;
 313                         break;
 314                 }
 315         }
 316 
 317         if (ret_val == 1) {
 318                 if (flag) {
 319                         if (my_volrmmount(real_name) < 0) {
 320                                 ret_val = -1;
 321                         }
 322                 } else {
 323                         ret_val = -1;
 324                 }
 325         }
 326         (void) fclose(fp);
 327         free(mntp);
 328         return (ret_val);
 329 }
 330 
 331 /*
 332  * This routine checks if a device has mounted partitions. The
 333  * device name is assumed to be /dev/rdsk/cNtNdNsN. So, this can
 334  * be used for SCSI and PCMCIA cards.
 335  * Returns
 336  *       0 : if not mounted
 337  *       1 : if successfully unmounted
 338  *      -1 : Any error or umount failed
 339  */
 340 
 341 int32_t
 342 check_and_unmount_scsi(char *device_name, int32_t flag)
 343 {
 344 
 345         struct  mnttab  *mntrefp;
 346         struct  mnttab  *mntp;
 347         FILE    *fp;
 348         char block_dev_name[PATH_MAX];
 349         char tmp_name[PATH_MAX];
 350         int32_t  i, j;


1050                         perror("exec failed");
1051                         /* Turn off the privileges */
1052                         (void) __priv_bracket(PRIV_OFF);
1053                         exit(-1);
1054                 }
1055         }
1056 
1057         /* wait for the umount command to exit */
1058         rval = 0;
1059         if (waitpid(pid, &rval, 0) == pid) {
1060                 if (WIFEXITED(rval)) {
1061                         if (WEXITSTATUS(rval) == 0) {
1062                                 DPRINTF("umount : Success\n");
1063                                 return (1);
1064                         }
1065                 }
1066         }
1067         return (-1);
1068 }
1069 
1070 static int
1071 my_volrmmount(char *real_name)
1072 {
1073         int pid, rval;
1074 
1075         /* Turn on the privileges. */
1076         (void) __priv_bracket(PRIV_ON);
1077 
1078         pid = fork();
1079 
1080         /* Turn off the privileges. */
1081         (void) __priv_bracket(PRIV_OFF);
1082 
1083         /* create a child to unmount the path */
1084         if (pid < 0) {
1085                 PERROR("fork failed");
1086                 exit(0);
1087         }
1088 
1089         if (pid == 0) {
1090                 /* the child */
1091                 /* get rid of those nasty err messages */
1092                 DPRINTF1("call_unmount_prog: calling %s \n",
1093                     "/usr/bin/volrmmount");
1094 
1095                 /* Turn on the privileges. */
1096                 (void) __priv_bracket(PRIV_ON);
1097                 if (execl("/usr/bin/volrmmount", "/usr/bin/volrmmount", "-e",
1098                     real_name, NULL) < 0) {
1099                         PERROR("volrmmount exec failed");
1100                         /* Turn off the privileges */
1101                         (void) __priv_bracket(PRIV_OFF);
1102                         exit(-1);
1103                 }
1104         } else if (waitpid(pid, &rval, 0) == pid) {
1105                 if (WIFEXITED(rval)) {
1106                         if (WEXITSTATUS(rval) == 0) {
1107                                 DPRINTF("volrmmount: Success\n");
1108                                 return (1);
1109                         }
1110                 }
1111         }
1112         return (-1);
1113 }
1114 
1115 int
1116 find_device(int defer, char *tmpstr)
1117 {
1118         DIR *dir;
1119         struct dirent *dirent;
1120         char sdev[PATH_MAX], dev[PATH_MAX], *pname;
1121         device_t *t_dev;
1122         int removable = 0;
1123         int device_type = 0;
1124         int hotpluggable = 0;
1125         struct dk_minfo mediainfo;
1126         static int found = 0;
1127 
1128         dir = opendir("/dev/rdsk");
1129         if (dir == NULL)
1130                 return (-1);
1131 
1132         total_devices_found = 0;
1133         while ((dirent = readdir(dir)) != NULL) {
1134                 if (dirent->d_name[0] == '.') {


1143 #else /* x86 */
1144                 if (vol_running) {
1145                         if (!(strstr(sdev, "s2") || strstr(sdev, "p0"))) {
1146                                 continue;
1147                         }
1148                 } else {
1149                         if (!strstr(sdev, "p0")) {
1150                                 continue;
1151                         }
1152                 }
1153 #endif
1154                 if (!lookup_device(sdev, dev)) {
1155                         continue;
1156                 }
1157                 if ((t_dev = get_device(NULL, dev)) == NULL) {
1158                         continue;
1159                 }
1160                 total_devices_found++;
1161 
1162                 if ((!defer) && !found) {
1163                         char *sn, *tmpbuf;
1164                         /*
1165                          * dev_name is an optional command line input.
1166                          */
1167                         if (dev_name) {
1168                                 if (strstr(dirent->d_name, tmpstr)) {
1169                                         found = 1;
1170                                 } else if (!vol_running) {
1171                                         continue;
1172                                 }
1173                         }
1174                         /*
1175                          * volmgt_symname() returns NULL if the device
1176                          * is not managed by volmgt.
1177                          */
1178                         sn = volmgt_symname(sdev);
1179 
1180                         if (vol_running && (sn != NULL)) {
1181                                 if (strstr(sn, "dev") == NULL) {
1182                                         tmpbuf = (char *)my_zalloc(PATH_MAX);
1183                                         (void) strcpy(tmpbuf,


   1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  *
  21  *

  22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  *
  25  * Copyright 2014 Andrew Stormont.
  26  */
  27 
  28 /*
  29  * rmf_misc.c :
  30  *      Miscelleneous routines for rmformat.
  31  */
  32 
  33 #include <sys/types.h>
  34 #include <stdio.h>
  35 #include <sys/mnttab.h>
  36 #include <volmgt.h>
  37 #include <sys/dkio.h>
  38 #include <sys/fdio.h>
  39 #include <sys/vtoc.h>
  40 #include <sys/termios.h>
  41 #include <sys/mount.h>
  42 #include <ctype.h>
  43 #include <signal.h>
  44 #include <sys/wait.h>
  45 #include <dirent.h>


  71 static struct   uscsi_cmd uscmd;
  72 static char     ucdb[16];
  73 uchar_t         uscsi_status, rqstatus, rqresid;
  74 int             total_devices_found = 0;
  75 int             removable_found = 0;
  76 
  77 extern char     *global_intr_msg;
  78 extern int      vol_running;
  79 extern char     *dev_name;
  80 extern int32_t  m_flag;
  81 
  82 /*
  83  * ON-private functions from libvolmgt
  84  */
  85 int     _dev_mounted(char *path);
  86 
  87 /*
  88  * Function prototypes.
  89  */
  90 static int              my_umount(char *mountp);

  91 static int              vol_name_to_dev_node(char *vname, char *found);
  92 static int              vol_lookup(char *supplied, char *found);
  93 static device_t         *get_device(char *user_supplied, char *node);
  94 static char             *get_physical_name(char *path);
  95 static int              lookup_device(char *supplied, char *found);
  96 static void             fini_device(device_t *dev);
  97 static int              is_cd(char *node);
  98 void                    *my_zalloc(size_t size);
  99 void                    err_msg(char *fmt, ...);
 100 int                     inquiry(int fd, uchar_t *inq);
 101 struct uscsi_cmd        *get_uscsi_cmd(void);
 102 int                     uscsi(int fd, struct uscsi_cmd *scmd);
 103 int                     get_mode_page(int fd, int page_no, int pc, int buf_len,
 104                             uchar_t *buffer);
 105 int                     mode_sense(int fd, uchar_t pc, int dbd, int page_len,
 106                             uchar_t *buffer);
 107 uint16_t                read_scsi16(void *addr);
 108 int                     check_device(device_t *dev, int cond);
 109 static void             get_media_info(device_t *t_dev, char *sdev,
 110                             char *pname, char *sn);


 206                 buf = fgets(re_passwd, (size_t)256, in);
 207                 rewind(in);
 208                 (void) fputc('\n', out);
 209                 if ((buf == NULL) || strcmp(passwd, re_passwd)) {
 210                         (void) fputs("passwords did not match\n", out);
 211                         (void) fputs("Try again\n", out);
 212                 } else {
 213                         break;
 214                 }
 215         }
 216         wp->sm_passwd_len = len;
 217         (void) strncpy(wp->sm_passwd, passwd, wp->sm_passwd_len);
 218         wp->sm_version = SMWP_STATE_V_1;
 219 
 220         /* Restore echoing.  */
 221         if (echo_off)
 222                 (void) tcsetattr(fileno(in), TCSAFLUSH, &tio);
 223 
 224 }
 225 









































































































 226 /*
 227  * This routine checks if a device has mounted partitions. The
 228  * device name is assumed to be /dev/rdsk/cNtNdNsN. So, this can
 229  * be used for SCSI and PCMCIA cards.
 230  * Returns
 231  *       0 : if not mounted
 232  *       1 : if successfully unmounted
 233  *      -1 : Any error or umount failed
 234  */
 235 
 236 int32_t
 237 check_and_unmount_scsi(char *device_name, int32_t flag)
 238 {
 239 
 240         struct  mnttab  *mntrefp;
 241         struct  mnttab  *mntp;
 242         FILE    *fp;
 243         char block_dev_name[PATH_MAX];
 244         char tmp_name[PATH_MAX];
 245         int32_t  i, j;


 945                         perror("exec failed");
 946                         /* Turn off the privileges */
 947                         (void) __priv_bracket(PRIV_OFF);
 948                         exit(-1);
 949                 }
 950         }
 951 
 952         /* wait for the umount command to exit */
 953         rval = 0;
 954         if (waitpid(pid, &rval, 0) == pid) {
 955                 if (WIFEXITED(rval)) {
 956                         if (WEXITSTATUS(rval) == 0) {
 957                                 DPRINTF("umount : Success\n");
 958                                 return (1);
 959                         }
 960                 }
 961         }
 962         return (-1);
 963 }
 964 













































 965 int
 966 find_device(int defer, char *tmpstr)
 967 {
 968         DIR *dir;
 969         struct dirent *dirent;
 970         char sdev[PATH_MAX], dev[PATH_MAX], *pname;
 971         device_t *t_dev;
 972         int removable = 0;
 973         int device_type = 0;
 974         int hotpluggable = 0;
 975         struct dk_minfo mediainfo;
 976         static int found = 0;
 977 
 978         dir = opendir("/dev/rdsk");
 979         if (dir == NULL)
 980                 return (-1);
 981 
 982         total_devices_found = 0;
 983         while ((dirent = readdir(dir)) != NULL) {
 984                 if (dirent->d_name[0] == '.') {


 993 #else /* x86 */
 994                 if (vol_running) {
 995                         if (!(strstr(sdev, "s2") || strstr(sdev, "p0"))) {
 996                                 continue;
 997                         }
 998                 } else {
 999                         if (!strstr(sdev, "p0")) {
1000                                 continue;
1001                         }
1002                 }
1003 #endif
1004                 if (!lookup_device(sdev, dev)) {
1005                         continue;
1006                 }
1007                 if ((t_dev = get_device(NULL, dev)) == NULL) {
1008                         continue;
1009                 }
1010                 total_devices_found++;
1011 
1012                 if ((!defer) && !found) {
1013                         char *sn, *tmpbuf = NULL;
1014                         /*
1015                          * dev_name is an optional command line input.
1016                          */
1017                         if (dev_name) {
1018                                 if (strstr(dirent->d_name, tmpstr)) {
1019                                         found = 1;
1020                                 } else if (!vol_running) {
1021                                         continue;
1022                                 }
1023                         }
1024                         /*
1025                          * volmgt_symname() returns NULL if the device
1026                          * is not managed by volmgt.
1027                          */
1028                         sn = volmgt_symname(sdev);
1029 
1030                         if (vol_running && (sn != NULL)) {
1031                                 if (strstr(sn, "dev") == NULL) {
1032                                         tmpbuf = (char *)my_zalloc(PATH_MAX);
1033                                         (void) strcpy(tmpbuf,