Changes in / [6317b33:cb328ab] in mainline
- Location:
- uspace
- Files:
-
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/hdisk/common.h
r6317b33 rcb328ab 39 39 #include <libgpt.h> 40 40 41 typedef enum {42 LYT_NONE,43 LYT_MBR,44 LYT_GPT,45 } layouts_t;46 47 41 union label_data { 48 42 mbr_label_t *mbr; … … 50 44 }; 51 45 52 typedef struct label label_t;53 54 struct label {55 layouts_t layout;56 union label_data data;57 unsigned int alignment;58 int (* destroy_label)(label_t *);59 int (* add_part) (label_t *, tinput_t *);60 int (* delete_part) (label_t *, tinput_t *);61 int (* new_label) (label_t *);62 int (* print_parts) (label_t *);63 int (* read_parts) (label_t *, service_id_t);64 int (* write_parts) (label_t *, service_id_t);65 int (* extra_funcs) (label_t *, tinput_t *, service_id_t);66 };67 68 46 #endif 69 47 -
uspace/app/hdisk/func_gpt.c
r6317b33 rcb328ab 34 34 35 35 #include <stdio.h> 36 #include <str.h>37 36 #include <errno.h> 38 37 #include <str_error.h> … … 44 43 static int set_gpt_partition(tinput_t *, gpt_part_t *); 45 44 46 47 int construct_gpt_label(label_t *this) 45 int add_gpt_part(tinput_t * in, union label_data * data) 48 46 { 49 this->layout = LYT_GPT; 50 this->alignment = 1; 51 52 this->add_part = add_gpt_part; 53 this->delete_part = delete_gpt_part; 54 this->new_label = new_gpt_label; 55 this->print_parts = print_gpt_parts; 56 this->read_parts = read_gpt_parts; 57 this->write_parts = write_gpt_parts; 58 this->extra_funcs = extra_gpt_funcs; 59 60 return this->new_label(this); 61 } 62 63 int add_gpt_part(label_t *this, tinput_t *in) 64 { 65 gpt_part_t * p = gpt_get_partition(this->data.gpt); 47 gpt_part_t * p = gpt_alloc_partition(data->gpt->parts); 66 48 if (p == NULL) { 67 49 return ENOMEM; 68 50 } 69 51 70 52 return set_gpt_partition(in, p); 71 53 } 72 54 73 int delete_gpt_part( label_t *this, tinput_t *in)55 int delete_gpt_part(tinput_t * in, union label_data * data) 74 56 { 75 int rc;76 57 size_t idx; 77 58 78 59 printf("Number of the partition to delete (counted from 0): "); 79 60 idx = get_input_size_t(in); 80 81 rc = gpt_remove_partition(this->data.gpt, idx); 82 if (rc != EOK) { 61 62 if (gpt_remove_partition(data->gpt->parts, idx) == -1) { 83 63 printf("Warning: running low on memory, not resizing...\n"); 84 return rc;85 64 } 86 65 87 66 return EOK; 88 67 } 89 68 90 int destroy_gpt_label( label_t *this)69 int destroy_gpt_label(union label_data *data) 91 70 { 92 gpt_free_label(this->data.gpt);93 71 return EOK; 94 72 } 95 73 96 int new_gpt_label( label_t *this)74 int new_gpt_label(union label_data *data) 97 75 { 98 this->data.gpt = gpt_alloc_label(); 76 data->gpt->gpt = gpt_alloc_gpt_header(); 77 data->gpt->parts = gpt_alloc_partitions(); 99 78 return EOK; 100 79 } 101 80 102 int print_gpt_parts( label_t *this)81 int print_gpt_parts(union label_data *data) 103 82 { 104 83 //int rc; … … 108 87 size_t i = 0; 109 88 110 gpt_part_foreach(this->data.gpt, iter) { 111 i++; 112 //FIXMEE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 113 if (gpt_get_part_type(iter) == GPT_PTE_UNUSED) 114 continue; 115 116 if (i % 20 == 0) 117 printf("%15s %10s %10s Type: Name:\n", "Start:", "End:", "Length:"); 118 89 gpt_part_foreach(data->gpt->parts, iter) { 119 90 //printf("\t%10u %10u %10u %3d\n", iter->start_addr, iter->start_addr + iter->length, 120 91 // iter->length, gpt_get_part_type(iter), gpt_get_part_name(iter)); 121 printf("%3u %10llu %10llu %10llu %3d %s\n", i-1, gpt_get_start_lba(iter), gpt_get_end_lba(iter),92 printf("%3u\t%10llu %10llu %10llu %3d %s\n", i, gpt_get_start_lba(iter), gpt_get_end_lba(iter), 122 93 gpt_get_end_lba(iter) - gpt_get_start_lba(iter), gpt_get_part_type(iter), 123 94 gpt_get_part_name(iter)); 95 i++; 124 96 } 125 97 126 98 //return rc; 127 99 return EOK; 128 100 } 129 101 130 int read_gpt_parts( label_t *this, service_id_t dev_handle)102 int read_gpt_parts(service_id_t dev_handle, union label_data *data) 131 103 { 132 int rc;133 134 rc = gpt_read_header(this->data.gpt, dev_handle);135 if (rc != EOK) {136 printf("Error: Reading header failed: %d (%s)\n", rc, str_error(rc));137 return rc;138 }139 140 rc = gpt_read_partitions(this->data.gpt);141 if (rc != EOK) {142 printf("Error: Reading partitions failed: %d (%s)\n", rc, str_error(rc));143 return rc;144 }145 146 104 return EOK; 147 105 } 148 106 149 int write_gpt_parts( label_t *this, service_id_t dev_handle)107 int write_gpt_parts(service_id_t dev_handle, union label_data * data) 150 108 { 151 109 int rc; 152 153 rc = gpt_write_partitions( this->data.gpt, dev_handle);110 111 rc = gpt_write_partitions(data->gpt->parts, data->gpt->gpt, dev_handle); 154 112 if (rc != EOK) { 155 113 printf("Error: Writing partitions failed: %d (%s)\n", rc, str_error(rc)); 156 114 return rc; 157 115 } 158 159 rc = gpt_write_ header(this->data.gpt, dev_handle);116 117 rc = gpt_write_gpt_header(data->gpt->gpt, dev_handle); 160 118 if (rc != EOK) { 161 printf("Error: Writing headerfailed: %d (%s)\n", rc, str_error(rc));119 printf("Error: Writing partitions failed: %d (%s)\n", rc, str_error(rc)); 162 120 return rc; 163 121 } 164 122 165 123 return EOK; 166 124 } 167 125 168 int extra_gpt_funcs( label_t *this, tinput_t *in, service_id_t dev_handle)126 int extra_gpt_funcs(tinput_t * in, service_id_t dev_handle, union label_data * data) 169 127 { 170 128 printf("Not implemented.\n"); … … 172 130 } 173 131 174 static int set_gpt_partition(tinput_t * in, gpt_part_t *p)132 static int set_gpt_partition(tinput_t * in, gpt_part_t * p) 175 133 { 176 int rc;177 134 //int rc; 135 178 136 uint64_t sa, ea; 179 137 180 138 printf("Set starting address (number): "); 181 139 sa = get_input_uint64(in); 182 140 183 141 printf("Set end addres (number): "); 184 142 ea = get_input_uint64(in); 185 143 186 144 if (ea <= sa) { 187 145 printf("Invalid value.\n"); 188 146 return EINVAL; 189 147 } 190 148 149 150 //p->start_addr = sa; 191 151 gpt_set_start_lba(p, sa); 152 //p->length = ea - sa; 192 153 gpt_set_end_lba(p, ea); 193 194 195 char *name; 196 rc = get_input_line(in, &name); 197 if (rc != EOK) { 198 printf("Error reading name: %d (%s)\n", rc, str_error(rc)); 199 return rc; 200 } 201 202 gpt_set_part_name(p, name, str_size(name)); 203 154 204 155 return EOK; 205 156 } -
uspace/app/hdisk/func_gpt.h
r6317b33 rcb328ab 42 42 #include "common.h" 43 43 44 extern int construct_gpt_label(label_t *); 45 extern int add_gpt_part (label_t *, tinput_t *); 46 extern int delete_gpt_part (label_t *, tinput_t *); 47 extern int destroy_gpt_label(label_t *); 48 extern int new_gpt_label (label_t *); 49 extern int print_gpt_parts (label_t *); 50 extern int read_gpt_parts (label_t *, service_id_t); 51 extern int write_gpt_parts (label_t *, service_id_t); 52 extern int extra_gpt_funcs (label_t *, tinput_t *, service_id_t); 44 extern int add_gpt_part(tinput_t *, union label_data *); 45 extern int delete_gpt_part(tinput_t *, union label_data *); 46 extern int destroy_gpt_label(union label_data *); 47 extern int new_gpt_label(union label_data *); 48 extern int print_gpt_parts(union label_data *); 49 extern int read_gpt_parts(service_id_t, union label_data *); 50 extern int write_gpt_parts(service_id_t, union label_data *); 51 extern int extra_gpt_funcs(tinput_t *, service_id_t, union label_data *); 53 52 54 53 #endif -
uspace/app/hdisk/func_mbr.c
r6317b33 rcb328ab 41 41 #include "input.h" 42 42 43 static int set_mbr_partition(tinput_t *in, mbr_part_t *p, unsigned int alignment); 44 45 int construct_mbr_label(label_t *this) 46 { 47 this->layout = LYT_MBR; 48 this->alignment = 1; 49 50 this->add_part = add_mbr_part; 51 this->delete_part = delete_mbr_part; 52 this->destroy_label = destroy_mbr_label; 53 this->new_label = new_mbr_label; 54 this->print_parts = print_mbr_parts; 55 this->read_parts = read_mbr_parts; 56 this->write_parts = write_mbr_parts; 57 this->extra_funcs = extra_mbr_funcs; 58 59 return this->new_label(this); 60 } 61 62 int add_mbr_part(label_t *this, tinput_t *in) 43 static int set_mbr_partition(tinput_t *in, mbr_part_t *p); 44 45 int add_mbr_part(tinput_t *in, union label_data *data) 63 46 { 64 47 int rc; 65 48 66 49 mbr_part_t *part = mbr_alloc_partition(); 67 68 set_mbr_partition(in, part , this->alignment);69 70 rc = mbr_add_partition( this->data.mbr, part);71 if (rc != E RR_OK) {72 printf("Error adding partition : %d\n", rc);73 } 74 75 return EOK; 76 } 77 78 int delete_mbr_part( label_t *this, tinput_t *in)50 51 set_mbr_partition(in, part); 52 53 rc = mbr_add_partition(data->mbr, part); 54 if (rc != EOK) { 55 printf("Error adding partition.\n"); 56 } 57 58 return EOK; 59 } 60 61 int delete_mbr_part(tinput_t *in, union label_data *data) 79 62 { 80 63 int rc; 81 64 size_t idx; 82 65 83 66 printf("Number of the partition to delete (counted from 0): "); 84 67 idx = get_input_size_t(in); … … 87 70 return errno; 88 71 89 rc = mbr_remove_partition( this->data.mbr, idx);72 rc = mbr_remove_partition(data->mbr, idx); 90 73 if(rc != EOK) { 91 74 printf("Error: something.\n"); 92 75 } 93 94 return EOK; 95 } 96 97 int destroy_mbr_label( label_t *this)98 { 99 mbr_free_label( this->data.mbr);100 return EOK; 101 } 102 103 int new_mbr_label( label_t *this)104 { 105 this->data.mbr = mbr_alloc_label();106 if ( this->data.mbr == NULL)76 77 return EOK; 78 } 79 80 int destroy_mbr_label(union label_data *data) 81 { 82 mbr_free_label(data->mbr); 83 return EOK; 84 } 85 86 int new_mbr_label(union label_data *data) 87 { 88 data->mbr = mbr_alloc_label(); 89 if (data->mbr == NULL) 107 90 return ENOMEM; 108 91 else … … 111 94 112 95 /** Print current partition scheme */ 113 int print_mbr_parts( label_t *this)96 int print_mbr_parts(union label_data *data) 114 97 { 115 98 int num = 0; 116 117 printf("Current partition scheme (MBR):\n");99 100 printf("Current partition scheme:\n"); 118 101 //printf("\t\tBootable:\tStart:\tEnd:\tLength:\tType:\n"); 119 102 printf("\t\t%10s %10s %10s %10s %7s\n", "Bootable:", "Start:", "End:", "Length:", "Type:"); 120 103 121 104 mbr_part_t *it; 122 //mbr_part_foreach(data->mbr, it) { 123 124 for (it = mbr_get_first_partition(this->data.mbr); it != NULL; 125 it = mbr_get_next_partition(this->data.mbr, it), ++num) { 105 mbr_part_foreach(data->mbr->parts, it) { 126 106 if (it->type == PT_UNUSED) 127 107 continue; 128 108 129 109 printf("\tP%d:\t", num); 130 110 if (mbr_get_flag(it, ST_BOOT)) … … 132 112 else 133 113 printf(" "); 134 114 135 115 printf("\t%10u %10u %10u %7u\n", it->start_addr, it->start_addr + it->length, it->length, it->type); 136 137 //++num;138 } 139 116 117 ++num; 118 } 119 140 120 printf("%d partitions found.\n", num); 141 121 … … 143 123 } 144 124 145 int read_mbr_parts( label_t *this, service_id_t dev_handle)125 int read_mbr_parts(service_id_t dev_handle, union label_data *data) 146 126 { 147 127 int rc; 148 rc = mbr_read_mbr(this->data.mbr, dev_handle); 128 printf("mbr\n"); 129 rc = mbr_read_mbr(data->mbr, dev_handle); 149 130 if (rc != EOK) 150 131 return rc; 151 152 if (!mbr_is_mbr( this->data.mbr))132 printf("ismbr\n"); 133 if (!mbr_is_mbr(data->mbr)) 153 134 return EINVAL; 154 155 rc = mbr_read_partitions( this->data.mbr);135 printf("parts\n"); 136 rc = mbr_read_partitions(data->mbr); 156 137 if (rc != EOK) 157 138 return rc; 158 159 return EOK; 160 } 161 162 int write_mbr_parts( label_t *this, service_id_t dev_handle)163 { 164 int rc = mbr_write_partitions( this->data.mbr, dev_handle);139 printf("end\n"); 140 return EOK; 141 } 142 143 int write_mbr_parts(service_id_t dev_handle, union label_data *data) 144 { 145 int rc = mbr_write_partitions(data->mbr, dev_handle); 165 146 if (rc != EOK) { 166 147 printf("Error occured during writing: ERR: %d: %s\n", rc, str_error(rc)); … … 170 151 } 171 152 172 int extra_mbr_funcs( label_t *this, tinput_t *in, service_id_t dev_handle)153 int extra_mbr_funcs(tinput_t *in, service_id_t dev_handle, union label_data *data) 173 154 { 174 155 printf("Not implemented.\n"); … … 176 157 } 177 158 178 static int set_mbr_partition(tinput_t *in, mbr_part_t *p , unsigned int alignment)159 static int set_mbr_partition(tinput_t *in, mbr_part_t *p) 179 160 { 180 161 int c; … … 193 174 break; 194 175 default: 195 printf("Invalid type. Cancelled. \n");176 printf("Invalid type. Cancelled."); 196 177 return EINVAL; 197 178 } 198 199 printf("ST_LOGIC: %d, %hd\n", mbr_get_flag(p, ST_LOGIC), p->status);200 179 201 180 printf("Set type (0-255): "); … … 221 200 if (sa == 0 && errno != EOK) 222 201 return errno; 223 224 if (alignment != 0 && alignment != 1) {225 sa = mbr_get_next_aligned(sa, alignment);226 printf("Starting address was aligned to %u.\n", sa);227 }228 202 229 203 printf("Set end addres (number): "); … … 232 206 return errno; 233 207 234 /* Align ending address, not in use */235 /*if (alignment != 0 && alignment != 1) {236 ea = mbr_get_next_aligned(ea, alignment) - alignment;237 printf("Starting address was aligned to %u.\n", ea);238 }*/239 240 208 if(ea < sa) { 241 209 printf("Invalid value. Canceled.\n"); -
uspace/app/hdisk/func_mbr.h
r6317b33 rcb328ab 42 42 #include "common.h" 43 43 44 extern int construct_mbr_label(label_t *); 45 extern int add_mbr_part (label_t *, tinput_t *); 46 extern int delete_mbr_part (label_t *, tinput_t *); 47 extern int destroy_mbr_label(label_t *); 48 extern int new_mbr_label (label_t *); 49 extern int print_mbr_parts (label_t *); 50 extern int read_mbr_parts (label_t *, service_id_t); 51 extern int write_mbr_parts (label_t *, service_id_t); 52 extern int extra_mbr_funcs (label_t *, tinput_t *, service_id_t); 44 extern int add_mbr_part(tinput_t *, union label_data *); 45 extern int delete_mbr_part(tinput_t *, union label_data *); 46 extern int destroy_mbr_label(union label_data *); 47 extern int new_mbr_label(union label_data *); 48 extern int print_mbr_parts(union label_data *); 49 extern int read_mbr_parts(service_id_t, union label_data *); 50 extern int write_mbr_parts(service_id_t, union label_data *); 51 extern int extra_mbr_funcs(tinput_t *, service_id_t, union label_data *); 53 52 54 53 #endif -
uspace/app/hdisk/func_none.c
r6317b33 rcb328ab 41 41 42 42 43 int construct_none_label(label_t *this) 44 { 45 this->layout = LYT_NONE; 46 47 this->add_part = add_none_part; 48 this->delete_part = delete_none_part; 49 this->destroy_label = destroy_none_label; 50 this->new_label = new_none_label; 51 this->print_parts = print_none_parts; 52 this->read_parts = read_none_parts; 53 this->write_parts = write_none_parts; 54 this->extra_funcs = extra_none_funcs; 55 56 return EOK; 57 } 58 59 int add_none_part(label_t *this, tinput_t * in) 43 int add_none_part(tinput_t *in, union label_data *data) 60 44 { 61 45 not_implemented(); … … 63 47 } 64 48 65 int delete_none_part( label_t *this, tinput_t * in)49 int delete_none_part(tinput_t *in, union label_data *data) 66 50 { 67 51 not_implemented(); … … 69 53 } 70 54 71 int destroy_none_label(label_t *this) 72 { 73 return EOK; 74 } 75 76 int new_none_label(label_t *this) 55 int destroy_none_label(union label_data *data) 77 56 { 78 57 not_implemented(); … … 80 59 } 81 60 82 int print_none_parts(label_t *this)61 int new_none_label(union label_data *data) 83 62 { 84 63 not_implemented(); … … 86 65 } 87 66 88 int read_none_parts(label_t *this, service_id_t dev_handle)67 int print_none_parts(union label_data *data) 89 68 { 90 69 not_implemented(); … … 92 71 } 93 72 94 int write_none_parts(label_t *this, service_id_t dev_handle)73 int read_none_parts(service_id_t dev_handle, union label_data *data) 95 74 { 96 75 not_implemented(); … … 98 77 } 99 78 100 int extra_none_funcs(label_t *this, tinput_t * in, service_id_t dev_handle) 79 int write_none_parts(service_id_t dev_handle, union label_data *data) 80 { 81 not_implemented(); 82 return EOK; 83 } 84 85 int extra_none_funcs(tinput_t *in, service_id_t dev_handle, union label_data *data) 101 86 { 102 87 not_implemented(); -
uspace/app/hdisk/func_none.h
r6317b33 rcb328ab 41 41 #include "common.h" 42 42 43 extern int construct_none_label(label_t *); 44 extern int add_none_part (label_t *, tinput_t *); 45 extern int delete_none_part (label_t *, tinput_t *); 46 extern int destroy_none_label(label_t *); 47 extern int new_none_label (label_t *); 48 extern int print_none_parts (label_t *); 49 extern int read_none_parts (label_t *, service_id_t); 50 extern int write_none_parts (label_t *, service_id_t); 51 extern int extra_none_funcs (label_t *, tinput_t *, service_id_t); 43 extern int add_none_part(tinput_t *, union label_data *); 44 extern int delete_none_part(tinput_t *, union label_data *); 45 extern int destroy_none_label(union label_data *); 46 extern int new_none_label(union label_data *); 47 extern int print_none_parts(union label_data *); 48 extern int read_none_parts(service_id_t, union label_data *); 49 extern int write_none_parts(service_id_t, union label_data *); 50 extern int extra_none_funcs(tinput_t *, service_id_t, union label_data *); 52 51 53 52 #endif -
uspace/app/hdisk/hdisk.c
r6317b33 rcb328ab 56 56 void print_help(void); 57 57 void select_label_format(tinput_t *); 58 void construct_label(layouts_t);58 void fill_label_funcs(void); 59 59 void free_label(void); 60 60 int try_read(service_id_t); 61 62 int construct_none_label(void); 63 64 int construct_mbr_label(void); 61 65 int try_read_mbr(service_id_t); 66 67 int construct_gpt_label(void); 62 68 int try_read_gpt(service_id_t); 63 void set_alignment(tinput_t *);64 69 65 70 … … 82 87 } 83 88 89 printf("Init.\n"); 84 90 init_label(); 85 91 … … 109 115 mbr_free_mbr(mbr);*/ 110 116 117 printf("Try MBR.\n"); 111 118 rc = try_read_mbr(dev_handle); 112 119 if (rc == EOK) … … 133 140 */ 134 141 142 printf("Try GPT.\n"); 135 143 rc = try_read_gpt(dev_handle); 136 144 if (rc == EOK) … … 141 149 142 150 interact: 143 151 printf("interact.\n"); 144 152 rc = interact(dev_handle); 145 153 … … 153 161 { 154 162 int input; 155 tinput_t * in;163 tinput_t * in; 156 164 157 165 in = tinput_new(); … … 171 179 switch(input) { 172 180 case 'a': 173 label.add_part(&label, in); 181 label.add_part(in, &label.data); 182 break; 183 case 'b': 184 label.add_part(in, &label.data); 174 185 break; 175 186 case 'd': 176 label.delete_part( &label, in);187 label.delete_part(in, &label.data); 177 188 break; 178 189 case 'e': 179 label.extra_funcs( &label, in, dev_handle);190 label.extra_funcs(in, dev_handle, &label.data); 180 191 break; 181 192 case 'f': … … 186 197 print_help(); 187 198 break; 188 case 'l':189 set_alignment(in);190 break;191 199 case 'n': 192 printf("Discarding label...\n");193 200 free_label(); 194 label.new_label(&label );201 label.new_label(&label.data); 195 202 break; 196 203 case 'p': 197 label.print_parts(&label );204 label.print_parts(&label.data); 198 205 break; 199 206 case 'q': 200 207 putchar('\n'); 201 208 goto end; 202 case 'r':203 label.read_parts(&label, dev_handle);204 209 case 'w': 205 label.write_parts( &label, dev_handle);210 label.write_parts(dev_handle, &label.data); 206 211 break; 207 212 default: … … 223 228 "\t 'd' \t\t Delete partition.\n" 224 229 "\t 'e' \t\t Extra functions (per label format).\n" 225 "\t 'f' \t\t Switch the format of the partition label. \n"230 "\t 'f' \t\t Switch the format of the partition label." 226 231 "\t 'h' \t\t Prints help. See help for more.\n" 227 232 "\t 'l' \t\t Set alignment.\n" 228 233 "\t 'n' \t\t Create new label (discarding the old one).\n" 229 234 "\t 'p' \t\t Prints label contents.\n" 235 "\t 'w' \t\t Write label to disk.\n" 230 236 "\t 'q' \t\t Quit.\n" 231 "\t 'r' \t\t Read label from disk.\n"232 "\t 'w' \t\t Write label to disk.\n"233 237 ); 234 238 … … 240 244 "1) MBR\n" 241 245 "2) GPT\n" 242 246 ); 243 247 244 248 uint8_t val = get_input_uint8(in); … … 246 250 case 0: 247 251 free_label(); 248 construct_label(LYT_NONE); 252 label.layout = LYT_NONE; 253 fill_label_funcs(); 249 254 break; 250 255 case 1: 251 256 free_label(); 252 construct_label(LYT_MBR); 257 label.layout = LYT_MBR; 258 fill_label_funcs(); 253 259 break; 254 260 case 2: 255 261 free_label(); 256 construct_label(LYT_GPT); 257 break; 258 } 259 } 260 261 void construct_label(layouts_t layout) 262 { 263 switch(layout) { 262 label.layout = LYT_GPT; 263 fill_label_funcs(); 264 break; 265 } 266 } 267 268 void fill_label_funcs(void) 269 { 270 switch(label.layout) { 264 271 case LYT_MBR: 265 label.layout = LYT_MBR; 266 construct_mbr_label(&label); 272 construct_mbr_label(); 267 273 break; 268 274 case LYT_GPT: 269 label.layout = LYT_GPT; 270 construct_gpt_label(&label); 275 construct_gpt_label(); 271 276 break; 272 277 default: 273 label.layout = LYT_NONE; 274 construct_none_label(&label); 278 construct_none_label(); 275 279 break; 276 280 } … … 279 283 void free_label(void) 280 284 { 281 label.destroy_label(&label); 285 /* 286 switch(label.layout) { 287 case LYT_MBR: 288 destroy_mbr_label(&label); 289 break; 290 case LYT_GPT: 291 destroy_gpt_label(&label); 292 break; 293 default: 294 break; 295 } 296 */ 297 298 label.destroy_label(&label.data); 282 299 } 283 300 284 301 int try_read(service_id_t dev_handle) 285 302 { 286 return label.read_parts(&label, dev_handle); 303 fill_label_funcs(); 304 printf("read_parts\n"); 305 return label.read_parts(dev_handle, &label.data); 306 } 307 308 int construct_none_label() 309 { 310 label.add_part = add_none_part; 311 label.delete_part = delete_none_part; 312 label.destroy_label = destroy_none_label; 313 label.new_label = new_none_label; 314 label.print_parts = print_none_parts; 315 label.read_parts = read_none_parts; 316 label.write_parts = write_none_parts; 317 label.extra_funcs = extra_none_funcs; 318 319 return EOK; 320 } 321 322 int construct_mbr_label() 323 { 324 label.add_part = add_mbr_part; 325 label.delete_part = delete_mbr_part; 326 label.destroy_label = destroy_mbr_label; 327 label.new_label = new_mbr_label; 328 label.print_parts = print_mbr_parts; 329 label.read_parts = read_mbr_parts; 330 label.write_parts = write_mbr_parts; 331 label.extra_funcs = extra_mbr_funcs; 332 333 return label.new_label(&label.data); 287 334 } 288 335 289 336 int try_read_mbr(service_id_t dev_handle) 290 337 { 291 construct_label(LYT_MBR);338 label.layout = LYT_MBR; 292 339 return try_read(dev_handle); 293 340 } 294 341 342 int construct_gpt_label() 343 { 344 label.add_part = add_gpt_part; 345 label.delete_part = delete_gpt_part; 346 label.new_label = new_gpt_label; 347 label.print_parts = print_gpt_parts; 348 label.read_parts = read_gpt_parts; 349 label.write_parts = write_gpt_parts; 350 label.extra_funcs = extra_gpt_funcs; 351 352 return label.new_label(&label.data); 353 } 354 295 355 int try_read_gpt(service_id_t dev_handle) 296 356 { 297 construct_label(LYT_GPT);357 label.layout = LYT_GPT; 298 358 return try_read(dev_handle); 299 359 } 300 360 301 void set_alignment(tinput_t *in) 302 { 303 printf("Set alignment to sectors: "); 304 label.alignment = get_input_uint32(in); 305 printf("Alignment set to %u sectors.\n", label.alignment); 306 } 307 308 309 310 311 312 313 314 315 316 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 -
uspace/app/hdisk/hdisk.h
r6317b33 rcb328ab 35 35 #include "common.h" 36 36 37 typedef enum { 38 LYT_NONE, 39 LYT_MBR, 40 LYT_GPT, 41 } layouts_t; 42 43 typedef struct label { 44 layouts_t layout; 45 union label_data data; 46 int (* add_part) (tinput_t *, union label_data *); 47 int (* delete_part) (tinput_t *, union label_data *); 48 int (* destroy_label)( union label_data *); 49 int (* new_label) ( union label_data *); 50 int (* print_parts) ( union label_data *); 51 int (* read_parts) (service_id_t, union label_data *); 52 int (* write_parts) (service_id_t, union label_data *); 53 int (* extra_funcs) (tinput_t *, service_id_t, union label_data *); 54 } label_t; 55 37 56 #define init_label() \ 38 57 label.layout = LYT_NONE -
uspace/lib/gpt/global.c
r6317b33 rcb328ab 41 41 42 42 const struct partition_type gpt_ptypes[] = { 43 { "Unused entry", "00000000 " "0000" "0000" "0000" "000000000000" },44 { "MBR partition scheme", "024DEE41 " "33E7" "11D3" "9D69" "0008C781F39F" },45 { "EFI System", "C12A7328 " "F81F" "11D2" "BA4B" "00A0C93EC93B" },46 { "BIOS Boot", "21686148 " "6449" "6E6F" "744E" "656564454649" },47 { "Windows Reserved", "E3C9E316 " "0B5C" "4DB8" "817D" "F92DF00215AE" },48 { "Windows Basic data", "EBD0A0A2 " "B9E5" "4433" "87C0" "68B6B72699C7" },49 { "Windows LDM metadata", "5808C8AA " "7E8F" "42E0" "85D2" "E1E90434CFB3" },50 { "Windows LDM data", "AF9B60A0 " "1431" "4F62" "BC68" "3311714A69AD" },51 { "Windows Recovery Environment", "DE94BBA4 " "06D1" "4D40" "A16A" "BFD50179D6AC" },52 { "Windows IBM GPFS", "37AFFC90 " "EF7D" "4E96" "91C3" "2D7AE055B174" },53 { "Windows Cluster metadata", "DB97DBA9 " "0840" "4BAE" "97F0" "FFB9A327C7E1" },54 { "HP-UX Data", "75894C1E " "3AEB" "11D3" "B7C1" "7B03A0000000" },55 { "HP-UX Service", "E2A1E728 " "32E3" "11D6" "A682" "7B03A0000000" },56 { "Linux filesystem data", "EBD0A0A2 " "B9E5" "4433" "87C0" "68B6B72699C7" },57 { "Linux filesystem data", "0FC63DAF " "8483" "4772" "8E79" "3D69D8477DE4" },58 { "Linux RAID", "A19D880F " "05FC" "4D3B" "A006" "743F0F84911E" },59 { "Linux Swap", "0657FD6D " "A4AB" "43C4" "84E5" "0933C84B4F4F" },60 { "Linux LVM", "E6D6D379 " "F507" "44C2" "A23C" "238F2A3DF928" },61 { "Linux Reserved", "8DA63339 " "0007" "60C0" "C436" "083AC8230908" },62 { "FreeBSD Boot", "83BD6B9D " "7F41" "11DC" "BE0B" "001560B84F0F" },63 { "FreeBSD Data", "516E7CB4 " "6ECF" "11D6" "8FF8" "00022D09712B" },64 { "FreeBSD Swap", "516E7CB5 " "6ECF" "11D6" "8FF8" "00022D09712B" },65 { "FreeBSD UFS", "516E7CB6 " "6ECF" "11D6" "8FF8" "00022D09712B" },66 { "FreeBSD Vinum VM", "516E7CB8 " "6ECF" "11D6" "8FF8" "00022D09712B" },67 { "FreeBSD ZFS", "516E7CBA " "6ECF" "11D6" "8FF8" "00022D09712B" },68 { "Mac OS X HFS+", "48465300 " "0000" "11AA" "AA11" "00306543ECAC" },69 { "Mac OS X UFS", "55465300 " "0000" "11AA" "AA11" "00306543ECAC" },70 { "Mac OS X ZFS", "6A898CC3 " "1DD2" "11B2" "99A6" "080020736631" },71 { "Mac OS X RAID", "52414944 " "0000" "11AA" "AA11" "00306543ECAC" },72 { "Mac OS X RAID, offline", "52414944 " "5F4F" "11AA" "AA11" "00306543ECAC" },73 { "Mac OS X Boot", "426F6F74 " "0000" "11AA" "AA11" "00306543ECAC" },74 { "Mac OS X Label", "4C616265 " "6C00" "11AA" "AA11" "00306543ECAC" },75 { "Mac OS X TV Recovery", "5265636F " "7665" "11AA" "AA11" "00306543ECAC" },76 { "Mac OS X Core Storage", "53746F72 " "6167" "11AA" "AA11" "00306543ECAC" },77 { "Solaris Boot", "6A82CB45 " "1DD2" "11B2" "99A6" "080020736631" },78 { "Solaris Root", "6A85CF4D " "1DD2" "11B2" "99A6" "080020736631" },79 { "Solaris Swap", "6A87C46F " "1DD2" "11B2" "99A6" "080020736631" },80 { "Solaris Backup", "6A8B642B " "1DD2" "11B2" "99A6" "080020736631" },81 { "Solaris /usr", "6A898CC3 " "1DD2" "11B2" "99A6" "080020736631" },82 { "Solaris /var", "6A8EF2E9 " "1DD2" "11B2" "99A6" "080020736631" },83 { "Solaris /home", "6A90BA39 " "1DD2" "11B2" "99A6" "080020736631" },84 { "Solaris Alternate sector", "6A9283A5 " "1DD2" "11B2" "99A6" "080020736631" },85 { "Solaris Reserved", "6A945A3B " "1DD2" "11B2" "99A6" "080020736631" },86 { "Solaris Reserved", "6A9630D1 " "1DD2" "11B2" "99A6" "080020736631" },87 { "Solaris Reserved", "6A980767 " "1DD2" "11B2" "99A6" "080020736631" },88 { "Solaris Reserved", "6A96237F " "1DD2" "11B2" "99A6" "080020736631" },89 { "Solaris Reserved", "6A8D2AC7 " "1DD2" "11B2" "99A6" "080020736631" },90 { "NetBSD Swap", "49F48D32 " "B10E" "11DC" "B99B" "0019D1879648" },91 { "NetBSD FFS", "49F48D5A " "B10E" "11DC" "B99B" "0019D1879648" },92 { "NetBSD LFS", "49F48D82 " "B10E" "11DC" "B99B" "0019D1879648" },93 { "NetBSD RAID", "49F48DAA " "B10E" "11DC" "B99B" "0019D1879648" },94 { "NetBSD Concatenated", "2DB519C4 " "B10F" "11DC" "B99B" "0019D1879648" },95 { "NetBSD Encrypted", "2DB519EC " "B10F" "11DC" "B99B" "0019D1879648" },96 { "ChromeOS ChromeOS kernel", "FE3A2A5D " "4F32" "41A7" "B725" "ACCC3285A309" },97 { "ChromeOS rootfs", "3CB8E202 " "3B7E" "47DD" "8A3C" "7FF2A13CFCEC" },98 { "ChromeOS future use", "2E0A753D " "9E48" "43B0" "8337" "B15192CB1B5E" },99 { "MidnightBSD Boot", "85D5E45E " "237C" "11E1" "B4B3" "E89A8F7FC3A7" },100 { "MidnightBSD Data", "85D5E45A " "237C" "11E1" "B4B3" "E89A8F7FC3A7" },101 { "MidnightBSD Swap", "85D5E45B " "237C" "11E1" "B4B3" "E89A8F7FC3A7" },102 { "MidnightBSD UFS", "0394Ef8B " "237E" "11E1" "B4B3" "E89A8F7FC3A7" },103 { "MidnightBSD Vinum VM", "85D5E45C " "237C" "11E1" "B4B3" "E89A8F7FC3A7" },104 { "MidnightBSD ZFS", "85D5E45D " "237C" "11E1" "B4B3" "E89A8F7FC3A7" },105 { "Uknown", NULL} /* keep this as the last one! gpt_get_part_type depends on it! */43 { "Unused entry", "00000000-0000-0000-0000-000000000000" }, 44 { "MBR partition scheme", "024DEE41-33E7-11D3-9D69-0008C781F39F" }, 45 { "EFI System", "C12A7328-F81F-11D2-BA4B-00A0C93EC93B" }, 46 { "BIOS Boot", "21686148-6449-6E6F-744E-656564454649" }, 47 { "Windows Reserved", "E3C9E316-0B5C-4DB8-817D-F92DF00215AE" }, 48 { "Windows Basic data", "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7" }, 49 { "Windows LDM metadata", "5808C8AA-7E8F-42E0-85D2-E1E90434CFB3" }, 50 { "Windows LDM data", "AF9B60A0-1431-4F62-BC68-3311714A69AD" }, 51 { "Windows Recovery Environment", "DE94BBA4-06D1-4D40-A16A-BFD50179D6AC" }, 52 { "Windows IBM GPFS", "37AFFC90-EF7D-4E96-91C3-2D7AE055B174" }, 53 { "Windows Cluster metadata", "DB97DBA9-0840-4BAE-97F0-FFB9A327C7E1" }, 54 { "HP-UX Data", "75894C1E-3AEB-11D3-B7C1-7B03A0000000" }, 55 { "HP-UX Service", "E2A1E728-32E3-11D6-A682-7B03A0000000" }, 56 { "Linux filesystem data", "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7" }, 57 { "Linux filesystem data", "0FC63DAF-8483-4772-8E79-3D69D8477DE4" }, 58 { "Linux RAID", "A19D880F-05FC-4D3B-A006-743F0F84911E" }, 59 { "Linux Swap", "0657FD6D-A4AB-43C4-84E5-0933C84B4F4F" }, 60 { "Linux LVM", "E6D6D379-F507-44C2-A23C-238F2A3DF928" }, 61 { "Linux Reserved", "8DA63339-0007-60C0-C436-083AC8230908" }, 62 { "FreeBSD Boot", "83BD6B9D-7F41-11DC-BE0B-001560B84F0F" }, 63 { "FreeBSD Data", "516E7CB4-6ECF-11D6-8FF8-00022D09712B" }, 64 { "FreeBSD Swap", "516E7CB5-6ECF-11D6-8FF8-00022D09712B" }, 65 { "FreeBSD UFS", "516E7CB6-6ECF-11D6-8FF8-00022D09712B" }, 66 { "FreeBSD Vinum VM", "516E7CB8-6ECF-11D6-8FF8-00022D09712B" }, 67 { "FreeBSD ZFS", "516E7CBA-6ECF-11D6-8FF8-00022D09712B" }, 68 { "Mac OS X HFS+", "48465300-0000-11AA-AA11-00306543ECAC" }, 69 { "Mac OS X UFS", "55465300-0000-11AA-AA11-00306543ECAC" }, 70 { "Mac OS X ZFS", "6A898CC3-1DD2-11B2-99A6-080020736631" }, 71 { "Mac OS X RAID", "52414944-0000-11AA-AA11-00306543ECAC" }, 72 { "Mac OS X RAID, offline", "52414944-5F4F-11AA-AA11-00306543ECAC" }, 73 { "Mac OS X Boot", "426F6F74-0000-11AA-AA11-00306543ECAC" }, 74 { "Mac OS X Label", "4C616265-6C00-11AA-AA11-00306543ECAC" }, 75 { "Mac OS X TV Recovery", "5265636F-7665-11AA-AA11-00306543ECAC" }, 76 { "Mac OS X Core Storage", "53746F72-6167-11AA-AA11-00306543ECAC" }, 77 { "Solaris Boot", "6A82CB45-1DD2-11B2-99A6-080020736631" }, 78 { "Solaris Root", "6A85CF4D-1DD2-11B2-99A6-080020736631" }, 79 { "Solaris Swap", "6A87C46F-1DD2-11B2-99A6-080020736631" }, 80 { "Solaris Backup", "6A8B642B-1DD2-11B2-99A6-080020736631" }, 81 { "Solaris /usr", "6A898CC3-1DD2-11B2-99A6-080020736631" }, 82 { "Solaris /var", "6A8EF2E9-1DD2-11B2-99A6-080020736631" }, 83 { "Solaris /home", "6A90BA39-1DD2-11B2-99A6-080020736631" }, 84 { "Solaris Alternate sector", "6A9283A5-1DD2-11B2-99A6-080020736631" }, 85 { "Solaris Reserved", "6A945A3B-1DD2-11B2-99A6-080020736631" }, 86 { "Solaris Reserved", "6A9630D1-1DD2-11B2-99A6-080020736631" }, 87 { "Solaris Reserved", "6A980767-1DD2-11B2-99A6-080020736631" }, 88 { "Solaris Reserved", "6A96237F-1DD2-11B2-99A6-080020736631" }, 89 { "Solaris Reserved", "6A8D2AC7-1DD2-11B2-99A6-080020736631" }, 90 { "NetBSD Swap", "49F48D32-B10E-11DC-B99B-0019D1879648" }, 91 { "NetBSD FFS", "49F48D5A-B10E-11DC-B99B-0019D1879648" }, 92 { "NetBSD LFS", "49F48D82-B10E-11DC-B99B-0019D1879648" }, 93 { "NetBSD RAID", "49F48DAA-B10E-11DC-B99B-0019D1879648" }, 94 { "NetBSD Concatenated", "2DB519C4-B10F-11DC-B99B-0019D1879648" }, 95 { "NetBSD Encrypted", "2DB519EC-B10F-11DC-B99B-0019D1879648" }, 96 { "ChromeOS ChromeOS kernel", "FE3A2A5D-4F32-41A7-B725-ACCC3285A309" }, 97 { "ChromeOS rootfs", "3CB8E202-3B7E-47DD-8A3C-7FF2A13CFCEC" }, 98 { "ChromeOS future use", "2E0A753D-9E48-43B0-8337-B15192CB1B5E" }, 99 { "MidnightBSD Boot", "85D5E45E-237C-11E1-B4B3-E89A8F7FC3A7" }, 100 { "MidnightBSD Data", "85D5E45A-237C-11E1-B4B3-E89A8F7FC3A7" }, 101 { "MidnightBSD Swap", "85D5E45B-237C-11E1-B4B3-E89A8F7FC3A7" }, 102 { "MidnightBSD UFS", "0394Ef8B-237E-11E1-B4B3-E89A8F7FC3A7" }, 103 { "MidnightBSD Vinum VM", "85D5E45C-237C-11E1-B4B3-E89A8F7FC3A7" }, 104 { "MidnightBSD ZFS", "85D5E45D-237C-11E1-B4B3-E89A8F7FC3A7" }, 105 { "Uknown", NULL} // keep this as the last one! gpt_get_part_type depends on it! 106 106 }; 107 108 109 -
uspace/lib/gpt/libgpt.c
r6317b33 rcb328ab 51 51 #include "libgpt.h" 52 52 53 static int load_and_check_header(service_id_t handle, aoff64_t addr, size_t b_size, gpt_header_t * header);53 static int load_and_check_header(service_id_t handle, aoff64_t addr, size_t b_size, gpt_header_t * header); 54 54 static gpt_partitions_t * alloc_part_array(uint32_t num); 55 static int extend_part_array(gpt_partitions_t * );56 static int reduce_part_array(gpt_partitions_t * );55 static int extend_part_array(gpt_partitions_t * p); 56 static int reduce_part_array(gpt_partitions_t * p); 57 57 static long long nearest_larger_int(double a); 58 static uint8_t get_byte(const char *); 58 59 59 60 60 /** Allocate memory for gpt label */ … … 179 179 180 180 rc = block_init(EXCHANGE_ATOMIC, dev_handle, b_size); 181 if (rc != EOK && rc != EEXIST)181 if (rc != EOK) 182 182 return rc; 183 183 … … 300 300 size_t b_size; 301 301 uint32_t e_size = uint32_t_le2host(label->gpt->header->entry_size); 302 size_t fill = label->parts->fill > GPT_MIN_PART_NUM ? label->parts->fill : GPT_MIN_PART_NUM; 303 302 304 303 label->gpt->header->pe_array_crc32 = compute_crc32( 305 304 (uint8_t *) label->parts->part_array, 306 fill * e_size);305 label->parts->fill * e_size); 307 306 308 307 /* comm_size of 4096 is ignored */ 309 308 rc = block_init(EXCHANGE_ATOMIC, dev_handle, 4096); 310 if (rc != EOK && rc != EEXIST)311 return rc; 312 309 if (rc != EOK) 310 return rc; 311 313 312 rc = block_get_bsize(dev_handle, &b_size); 314 313 if (rc != EOK) 315 314 goto fail; 316 317 aoff64_t n_blocks; 318 rc = block_get_nblocks(dev_handle, &n_blocks); 319 if (rc != EOK) 320 goto fail; 321 322 /* Write to backup GPT partition array location */ 323 //rc = block_write_direct(dev_handle, n_blocks - 1, GPT_HDR_BS, header->raw_data); 324 if (rc != EOK) 325 goto fail; 326 315 327 316 /* Write to main GPT partition array location */ 328 317 rc = block_write_direct(dev_handle, uint64_t_le2host(label->gpt->header->entry_lba), … … 331 320 if (rc != EOK) 332 321 goto fail; 333 322 323 aoff64_t n_blocks; 324 rc = block_get_nblocks(dev_handle, &n_blocks); 325 if (rc != EOK) 326 goto fail; 327 328 /* Write to backup GPT partition array location */ 329 //rc = block_write_direct(dev_handle, n_blocks - 1, GPT_HDR_BS, header->raw_data); 330 block_fini(dev_handle); 331 if (rc != EOK) 332 goto fail; 333 334 334 335 return gpt_write_header(label, dev_handle); 335 336 … … 346 347 * This returns a memory block (zero-filled) and needs gpt_add_partition() 347 348 * to be called to insert it into a partition array. 348 * Requires you to call gpt_free_partition after wards.349 * Requires you to call gpt_free_partition after use. 349 350 */ 350 351 gpt_part_t * gpt_alloc_partition(void) … … 366 367 * 367 368 * Note: use either gpt_alloc_partition or gpt_get_partition. 368 * This one return s a pointer to the first empty structure already369 * inside the array, so don't call gpt_add_partition() afterwards.369 * This one return a pointer to a structure already inside the array, so 370 * there's no need to call gpt_add_partition(). 370 371 * This is the one you will usually want. 371 372 */ 372 373 gpt_part_t * gpt_get_partition(gpt_label_t *label) 373 374 { 374 gpt_part_t *p; 375 376 /* Find the first empty entry */ 377 do { 378 if (label->parts->fill == label->parts->arr_size) { 379 if (extend_part_array(label->parts) == -1) 380 return NULL; 381 } 382 383 p = label->parts->part_array + label->parts->fill++; 384 385 } while (gpt_get_part_type(p) != GPT_PTE_UNUSED); 386 387 return p; 388 } 389 390 /** Get partition already inside the label 391 * 392 * @param label label to carrying the partition 393 * @param idx index of the partition 394 * 395 * @return returns pointer to the partition 396 * or NULL when out of range 397 * 398 * Note: For new partitions use either gpt_alloc_partition or 399 * gpt_get_partition unless you want a partition at a specific place. 400 * This returns a pointer to a structure already inside the array, 401 * so don't call gpt_add_partition() afterwards. 402 * This function is handy when you want to change already existing 403 * partition or to simply write somewhere in the middle. This works only 404 * for indexes smaller than either 128 or the actual number of filled 405 * entries. 406 */ 407 gpt_part_t * gpt_get_partition_at(gpt_label_t *label, size_t idx) 408 { 409 return NULL; 410 411 if (idx >= GPT_MIN_PART_NUM && idx >= label->parts->fill) 412 return NULL; 413 414 return label->parts->part_array + idx; 375 if (label->parts->fill == label->parts->arr_size) { 376 if (extend_part_array(label->parts) == -1) 377 return NULL; 378 } 379 380 return label->parts->part_array + label->parts->fill++; 415 381 } 416 382 … … 449 415 int gpt_remove_partition(gpt_label_t *label, size_t idx) 450 416 { 451 if (idx >= label->parts->fill) 452 return EINVAL; 453 454 /* FIXME! 455 * If we allow blank spots, we break the array. If we have more than 456 * 128 partitions in the array and then remove something from 457 * the first 128 partitions, we would forget to write the last one.*/ 458 memset(label->parts->part_array + idx, 0, sizeof(gpt_entry_t)); 459 460 label->parts->fill -= 1; 461 462 /* FIXME! 463 * We cannot reduce the array so simply. We may have some partitions 464 * there since we allow blank spots.*/ 417 if (idx != label->parts->fill - 1) { 418 memmove(label->parts->part_array + idx, 419 label->parts->part_array + idx + 1, 420 (label->parts->fill - 1) * sizeof(gpt_entry_t)); 421 label->parts->fill -= 1; 422 } 423 424 /* FIXME: This probably shouldn't be here, but instead 425 * in reduce_part_array() or similar */ 465 426 if (label->parts->fill < (label->parts->arr_size / 2) - GPT_IGNORE_FILL_NUM) { 466 427 if (reduce_part_array(label->parts) == ENOMEM) … … 487 448 { 488 449 size_t i; 489 490 450 for (i = 0; gpt_ptypes[i].guid != NULL; i++) { 491 if (p->part_type[3] == get_byte(gpt_ptypes[i].guid +0) && 492 p->part_type[2] == get_byte(gpt_ptypes[i].guid +2) && 493 p->part_type[1] == get_byte(gpt_ptypes[i].guid +4) && 494 p->part_type[0] == get_byte(gpt_ptypes[i].guid +6) && 495 496 p->part_type[5] == get_byte(gpt_ptypes[i].guid +8) && 497 p->part_type[4] == get_byte(gpt_ptypes[i].guid +10) && 498 499 p->part_type[7] == get_byte(gpt_ptypes[i].guid +12) && 500 p->part_type[6] == get_byte(gpt_ptypes[i].guid +14) && 501 502 p->part_type[8] == get_byte(gpt_ptypes[i].guid +16) && 503 p->part_type[9] == get_byte(gpt_ptypes[i].guid +18) && 504 p->part_type[10] == get_byte(gpt_ptypes[i].guid +20) && 505 p->part_type[11] == get_byte(gpt_ptypes[i].guid +22) && 506 p->part_type[12] == get_byte(gpt_ptypes[i].guid +24) && 507 p->part_type[13] == get_byte(gpt_ptypes[i].guid +26) && 508 p->part_type[14] == get_byte(gpt_ptypes[i].guid +28) && 509 p->part_type[15] == get_byte(gpt_ptypes[i].guid +30)) 510 break; 511 } 512 451 if (bcmp(p->part_type, gpt_ptypes[i].guid, 16) == 0) { 452 break; 453 } 454 } 513 455 return i; 514 456 } … … 574 516 575 517 /** Copy partition name */ 576 void gpt_set_part_name(gpt_part_t * p, char *name, size_t length)518 void gpt_set_part_name(gpt_part_t * p, char * name[], size_t length) 577 519 { 578 520 if (length >= 72) … … 703 645 } 704 646 705 static uint8_t get_byte(const char * c) 706 { 707 uint8_t val = 0; 708 char hex[3] = {*c, *(c+1), 0}; 709 710 errno = str_uint8_t(hex, NULL, 16, false, &val); 711 return val; 712 } 713 714 715 716 647 648 649 650 651 -
uspace/lib/gpt/libgpt.h
r6317b33 rcb328ab 52 52 /** How much fill we ignore before resizing partition array */ 53 53 #define GPT_IGNORE_FILL_NUM 10 54 55 /** Unused partition entry */56 #define GPT_PTE_UNUSED 057 54 58 55 /** GPT header signature ("EFI PART" in ASCII) */ … … 152 149 extern gpt_part_t * gpt_alloc_partition (void); 153 150 extern gpt_part_t * gpt_get_partition (gpt_label_t *); 154 extern gpt_part_t * gpt_get_partition_at(gpt_label_t *, size_t);155 151 extern int gpt_add_partition (gpt_label_t *, gpt_part_t *); 156 152 extern int gpt_remove_partition(gpt_label_t *, size_t); … … 163 159 extern uint64_t gpt_get_end_lba (gpt_part_t *); 164 160 extern unsigned char * gpt_get_part_name(gpt_part_t *); 165 extern void gpt_set_part_name(gpt_part_t *, char * , size_t);161 extern void gpt_set_part_name(gpt_part_t *, char *[], size_t); 166 162 extern bool gpt_get_flag (gpt_part_t *, GPT_ATTR); 167 163 extern void gpt_set_flag (gpt_part_t *, GPT_ATTR, bool); … … 169 165 170 166 171 #define gpt_part_foreach( label, iterator) \172 for(gpt_part_t * iterator = ( label)->parts->part_array; \173 iterator < ( label)->parts->part_array + (label)->parts->fill; ++iterator)167 #define gpt_part_foreach(parts, iterator) \ 168 for(gpt_part_t * iterator = (parts)->part_array; \ 169 iterator < (parts)->part_array + (parts)->fill; ++iterator) 174 170 175 171 extern void gpt_free_gpt(gpt_t *); -
uspace/lib/mbr/libmbr.c
r6317b33 rcb328ab 52 52 static int check_encaps(mbr_part_t *, mbr_part_t *); 53 53 static int check_preceeds(mbr_part_t *, mbr_part_t *); 54 static mbr_err_val mbr_add_primary(mbr_label_t *label, mbr_part_t *p);55 static mbr_err_val mbr_add_logical(mbr_label_t *label, mbr_part_t *p);56 54 57 55 /** Allocate and initialize mbr_label_t structure */ … … 170 168 mbr_part_t *ext = NULL; 171 169 //mbr_partitions_t *parts; 172 170 printf("check\n"); 173 171 if (label->parts != NULL) 174 172 mbr_free_partitions(label->parts); 175 173 printf("check2\n"); 176 174 label->parts = mbr_alloc_partitions(); 177 175 if (label->parts == NULL) { 178 176 return ENOMEM; 179 177 } 180 178 printf("primary\n"); 181 179 /* Generate the primary partitions */ 182 180 for (i = 0; i < N_PRIMARY; ++i) { 183 181 if (label->mbr->raw_data.pte[i].ptype == PT_UNUSED) 184 182 continue; 185 183 printf("pcheck1\n"); 186 184 p = mbr_alloc_partition(); 187 185 if (p == NULL) { … … 190 188 return ENOMEM; 191 189 } 192 190 printf("pcheck2\n"); 193 191 rc_ext = decode_part(&(label->mbr->raw_data.pte[i]), p, 0); 194 192 mbr_set_flag(p, ST_LOGIC, false); … … 200 198 return EINVAL; 201 199 } 202 200 printf("pcheck3\n"); 203 201 if (rc_ext) { 204 202 ext = p; 205 label->parts->l_extended = &p->link; 206 } 207 } 208 203 label->parts->l_extended = list_nth(&(label->parts->list), i); 204 } 205 printf("pcheck4\n"); 206 } 207 printf("logical\n"); 209 208 /* Fill in the primary partitions and generate logical ones, if any */ 210 209 rc = decode_logical(label, ext); 211 210 if (rc != EOK) { 212 printf(LIBMBR_NAME ": Error during decoding logical partitions: %d - %s.\n" \213 LIBMBR_NAME ": Partition list may be incomplete.\n" , rc, str_error(rc));211 printf(LIBMBR_NAME ": Error occured during decoding the MBR.\n" \ 212 LIBMBR_NAME ": Partition list may be incomplete.\n"); 214 213 return rc; 215 214 } 216 215 printf("finish\n"); 217 216 return EOK; 218 217 } … … 226 225 int mbr_write_partitions(mbr_label_t *label, service_id_t dev_handle) 227 226 { 228 if (label->parts == NULL)229 return EOK;230 231 if (label->mbr == NULL)232 label->mbr = mbr_alloc_mbr();233 234 227 int i = 0; 235 228 int rc; … … 247 240 248 241 /* Encoding primary partitions */ 249 for (i = 0; i < N_PRIMARY; i++) {242 for (i = 0; i < label->parts->n_primary; i++) { 250 243 p = list_get_instance(l, mbr_part_t, link); 251 244 encode_part(p, &(label->mbr->raw_data.pte[i]), 0, false); … … 260 253 } 261 254 262 if (ext == NULL) { 263 rc = EOK; 255 if (ext == NULL) 264 256 goto end; 265 }266 257 267 258 uint32_t base = ext->start_addr; 268 mbr_part_t * prev_p;259 mbr_part_t * prev_p; 269 260 270 261 /* Note for future changes: Some thought has been put into design … … 290 281 } 291 282 free(tmp); 292 rc = EOK;293 283 goto end; 294 284 } 295 285 296 286 prev_p = p; 297 298 /* Check EBR addresses299 * This piece of code saves previous EBR placements from other300 * software. But if our user modifies the logical partition chain,301 * we have to fix those placements if needed.*/302 link_t *l_ebr = l;303 link_t *l_iter;304 mbr_part_t *tmp = mbr_alloc_partition();305 tmp->length = 1;306 while (l_ebr != &(label->parts->list.head)) {307 p = list_get_instance(l_ebr, mbr_part_t, link);308 tmp->start_addr = p->ebr_addr;309 310 l_iter = l;311 while (l_iter != &(label->parts->list.head)) {312 /* Checking whether EBR address makes sense. If not, we take a guess.313 * So far this is simple, we just take the first preceeding sector.314 * Fdisk always reserves at least 2048 sectors (1MiB), so it can have315 * the EBR aligned as well as the partition itself. Parted reserves316 * minimum one sector, like we do.317 *318 * Note that we know there is at least one sector free from previous checks.319 * Also note that the user can set ebr_addr to their liking (if it's valid). */320 if (p->ebr_addr < base || p->ebr_addr >= base + ext->length ||321 check_overlap(tmp, list_get_instance(l_iter, mbr_part_t, link))) {322 p->ebr_addr = p->start_addr - 1;323 break;324 }325 326 l_iter = l_iter->next;327 }328 329 l_ebr = l_ebr->next;330 }331 mbr_free_partition(tmp);332 287 333 288 /* Encoding and writing logical partitions */ … … 335 290 p = list_get_instance(l, mbr_part_t, link); 336 291 292 /* Checking whether EBR address makes sense. If not, we take a guess. 293 * So far this is simple, we just take the first preceeding sector. 294 * Fdisk always reserves at least 2048 sectors (1MiB), so it can have 295 * the EBR aligned as well as the partition itself. Parted reserves 296 * minimum one sector, like we do. 297 * 298 * Note that we know there is at least one sector free from previous checks. 299 * Also note that the user can set ebr_addr to their liking (if it's valid). */ 300 if (p->ebr_addr >= p->start_addr || p->ebr_addr <= (prev_p->start_addr + prev_p->length)) { 301 p->ebr_addr = p->start_addr - 1; 302 DEBUG_PRINT_0(LIBMBR_NAME ": Warning: invalid EBR address.\n"); 303 } 337 304 338 305 encode_part(p, &(p->ebr->pte[0]), p->ebr_addr, false); … … 423 390 mbr_err_val mbr_add_partition(mbr_label_t *label, mbr_part_t *p) 424 391 { 425 int rc1, rc2; 392 int rc; 393 mbr_partitions_t *parts = label->parts; 394 426 395 aoff64_t nblocks; 427 428 rc 1= block_init(EXCHANGE_ATOMIC, label->device, 512);429 if (rc 1 != EOK && rc1 != EEXIST) {430 printf(LIBMBR_NAME ": Error during libblock init: %d - %s.\n", rc1, str_error(rc1));396 printf("add1.\n"); 397 rc = block_init(EXCHANGE_ATOMIC, label->device, 512); 398 if (rc != EOK) { 399 printf(LIBMBR_NAME ": Error while getting number of blocks: %d - %s.\n", rc, str_error(rc)); 431 400 return ERR_LIBBLOCK; 432 401 } 433 434 rc2 = block_get_nblocks(label->device, &nblocks); 435 436 if (rc1 != EEXIST) 437 block_fini(label->device); 438 439 if (rc2 != EOK) { 440 printf(LIBMBR_NAME ": Error while getting number of blocks: %d - %s.\n", rc2, str_error(rc2)); 402 printf("add2.\n"); 403 rc = block_get_nblocks(label->device, &nblocks); 404 block_fini(label->device); 405 if (rc != EOK) { 406 printf(LIBMBR_NAME ": Error while getting number of blocks: %d - %s.\n", rc, str_error(rc)); 441 407 return ERR_LIBBLOCK; 442 408 } 443 444 if ((aoff64_t) p->start_addr + p->length > nblocks) 445 return ERR_OUT_BOUNDS; 446 447 if (label->parts == NULL) { 448 label->parts = mbr_alloc_partitions(); 449 if (label->parts == NULL) 450 return ENOMEM; //FIXME! merge mbr_err_val into errno.h 451 } 452 453 if (mbr_get_flag(p, ST_LOGIC)) 409 printf("add3.\n"); 410 if (mbr_get_flag(p, ST_LOGIC)) { 454 411 /* adding logical partition */ 455 return mbr_add_logical(label, p); 456 else 412 413 /* is there any extended partition? */ 414 if (parts->l_extended == NULL) 415 return ERR_NO_EXTENDED; 416 417 /* is the logical partition inside the extended one? */ 418 mbr_part_t *ext = list_get_instance(parts->l_extended, mbr_part_t, link); 419 if (!check_encaps(p, ext)) 420 return ERR_OUT_BOUNDS; 421 422 /* find a place for the new partition in a sorted linked list */ 423 //mbr_part_t *last = list_get_instance(list_last(&(parts->list)), mbr_part_t, link); 424 mbr_part_t *iter; 425 //uint32_t ebr_space = 1; 426 mbr_part_foreach(parts, iter) { 427 if (mbr_get_flag(iter, ST_LOGIC)) { 428 if (check_overlap(p, iter)) 429 return ERR_OVERLAP; 430 if (check_preceeds(iter, p)) { 431 /* checking if there's at least one sector of space preceeding */ 432 if ((iter->start_addr + iter->length) >= p->start_addr - 1) 433 return ERR_NO_EBR; 434 } else { 435 /* checking if there's at least one sector of space following (for following partitions's EBR) */ 436 if ((p->start_addr + p->length) >= iter->start_addr - 1) 437 return ERR_NO_EBR; 438 } 439 } 440 } 441 442 /* alloc EBR if it's not already there */ 443 if (p->ebr == NULL) { 444 p->ebr = alloc_br(); 445 if (p->ebr == NULL) { 446 return ERR_NOMEM; 447 } 448 } 449 450 /* add it */ 451 list_append(&(p->link), &(parts->list)); 452 parts->n_logical += 1; 453 } else { 457 454 /* adding primary */ 458 return mbr_add_primary(label, p); 455 456 if (parts->n_primary == 4) { 457 return ERR_PRIMARY_FULL; 458 } 459 460 /* Check if partition makes space for MBR itself. */ 461 if (p->start_addr == 0 || ((aoff64_t) p->start_addr) + p->length >= nblocks) { 462 return ERR_OUT_BOUNDS; 463 } 464 printf("add4.\n"); 465 /* if it's extended, is there any other one? */ 466 if ((p->type == PT_EXTENDED || p->type == PT_EXTENDED_LBA) && parts->l_extended != NULL) { 467 return ERR_EXTENDED_PRESENT; 468 } 469 printf("add5.\n"); 470 /* find a place and add it */ 471 mbr_part_t *iter; 472 mbr_part_t *empty = NULL; 473 mbr_part_foreach(parts, iter) { 474 printf("type: %x\n", iter->type); 475 if (iter->type == PT_UNUSED) { 476 if (empty == NULL) 477 empty = iter; 478 } else if (check_overlap(p, iter)) 479 return ERR_OVERLAP; 480 } 481 printf("add6. %p, %p\n", empty, p); 482 list_insert_after(&(p->link), &(empty->link)); 483 printf("add6.1.\n"); 484 list_remove(&(empty->link)); 485 printf("add6.2.\n"); 486 free(empty); 487 printf("add7.\n"); 488 parts->n_primary += 1; 489 490 if (p->type == PT_EXTENDED || p->type == PT_EXTENDED_LBA) 491 parts->l_extended = &(p->link); 492 } 493 printf("add8.\n"); 494 return ERR_OK; 459 495 } 460 496 … … 533 569 void mbr_set_flag(mbr_part_t *p, MBR_FLAGS flag, bool value) 534 570 { 535 uint 16_t status = p->status;571 uint8_t status = p->status; 536 572 537 573 if (value) … … 543 579 } 544 580 545 /** Get next aligned address */581 /** Get next aligned address (in sectors!) */ 546 582 uint32_t mbr_get_next_aligned(uint32_t addr, unsigned int alignment) 547 583 { 548 584 uint32_t div = addr / alignment; 549 585 return (div + 1) * alignment; 550 }551 552 list_t * mbr_get_list(mbr_label_t *label)553 {554 if (label->parts != NULL)555 return &(label->parts->list);556 else557 return NULL;558 }559 560 mbr_part_t * mbr_get_first_partition(mbr_label_t *label)561 {562 list_t *list = mbr_get_list(label);563 if (list != NULL && !list_empty(list))564 return list_get_instance(list->head.next, mbr_part_t, link);565 else566 return NULL;567 }568 569 mbr_part_t * mbr_get_next_partition(mbr_label_t *label, mbr_part_t *p)570 {571 list_t *list = mbr_get_list(label);572 if (list != NULL && &(p->link) != list_last(list))573 return list_get_instance(p->link.next, mbr_part_t, link);574 else575 return NULL;576 586 } 577 587 … … 617 627 trgt->type = src->ptype; 618 628 619 trgt->status = (trgt->status & 0xFF00) | (uint16_t) src->status; 629 /* Checking only 0x80; otherwise writing will fix to 0x00 */ 630 trgt->status = (trgt->status & 0xFF00) | src->status; 620 631 621 632 trgt->start_addr = uint32_t_le2host(src->first_lba) + base; … … 680 691 681 692 while (ebr->pte[1].ptype != PT_UNUSED) { 682 683 693 ebr = alloc_br(); 684 694 if (ebr == NULL) { … … 702 712 goto free_ebr_end; 703 713 } 714 704 715 705 716 decode_part(&(ebr->pte[0]), p, addr); … … 748 759 trgt->length = host2uint32_t_le(src->length); 749 760 } 750 751 if (trgt->ptype == PT_UNUSED)752 memset(trgt, 0, sizeof(pt_entry_t));753 761 } else { 754 memset(trgt, 0, sizeof(pt_entry_t)); 762 trgt->status = 0; 763 trgt->first_chs[0] = 0; 764 trgt->first_chs[1] = 0; 765 trgt->first_chs[2] = 0; 766 trgt->ptype = 0; 767 trgt->last_chs[0] = 0; 768 trgt->last_chs[1] = 0; 769 trgt->last_chs[2] = 0; 770 trgt->first_lba = 0; 771 trgt->length = 0; 755 772 } 756 773 } … … 762 779 static int check_overlap(mbr_part_t * p1, mbr_part_t * p2) 763 780 { 764 if (p1->start_addr < p2->start_addr && p1->start_addr + p1->length < =p2->start_addr) {781 if (p1->start_addr < p2->start_addr && p1->start_addr + p1->length < p2->start_addr) { 765 782 return 0; 766 } else if (p1->start_addr > p2->start_addr && p2->start_addr + p2->length < =p1->start_addr) {783 } else if (p1->start_addr > p2->start_addr && p2->start_addr + p2->length < p1->start_addr) { 767 784 return 0; 768 785 } … … 795 812 } 796 813 797 mbr_err_val mbr_add_primary(mbr_label_t *label, mbr_part_t *p) 798 { 799 if (label->parts->n_primary == 4) { 800 return ERR_PRIMARY_FULL; 801 } 802 803 /* Check if partition makes space for MBR itself. */ 804 if (p->start_addr == 0) { 805 return ERR_OUT_BOUNDS; 806 } 807 808 /* if it's extended, is there any other one? */ 809 if ((p->type == PT_EXTENDED || p->type == PT_EXTENDED_LBA) && label->parts->l_extended != NULL) { 810 return ERR_EXTENDED_PRESENT; 811 } 812 813 /* find a place and add it */ 814 mbr_part_t *iter; 815 mbr_part_t *empty = NULL; 816 mbr_part_foreach(label, iter) { 817 if (iter->type == PT_UNUSED) { 818 if (empty == NULL) 819 empty = iter; 820 } else if (check_overlap(p, iter)) 821 return ERR_OVERLAP; 822 } 823 824 list_insert_after(&(p->link), &(empty->link)); 825 list_remove(&(empty->link)); 826 free(empty); 827 828 label->parts->n_primary += 1; 829 830 if (p->type == PT_EXTENDED || p->type == PT_EXTENDED_LBA) 831 label->parts->l_extended = &(p->link); 832 833 return EOK; 834 } 835 836 mbr_err_val mbr_add_logical(mbr_label_t *label, mbr_part_t *p) 837 { 838 /* is there any extended partition? */ 839 if (label->parts->l_extended == NULL) 840 return ERR_NO_EXTENDED; 841 842 /* is the logical partition inside the extended one? */ 843 mbr_part_t *ext = list_get_instance(label->parts->l_extended, mbr_part_t, link); 844 if (!check_encaps(p, ext)) 845 return ERR_OUT_BOUNDS; 846 847 /* find a place for the new partition in a sorted linked list */ 848 bool first_logical = true; 849 mbr_part_t *iter; 850 mbr_part_foreach(label, iter) { 851 if (mbr_get_flag(iter, ST_LOGIC)) { 852 if (check_overlap(p, iter)) 853 return ERR_OVERLAP; 854 if (check_preceeds(iter, p)) { 855 /* checking if there's at least one sector of space preceeding */ 856 if ((iter->start_addr + iter->length) >= p->start_addr - 1) 857 return ERR_NO_EBR; 858 } else if (first_logical){ 859 /* First logical partition's EBR is before every other 860 * logical partition. Thus we don't check if this partition 861 * leaves enough space for it. */ 862 first_logical = false; 863 } else { 864 /* checking if there's at least one sector of space following (for following partitions's EBR) */ 865 if ((p->start_addr + p->length) >= iter->start_addr - 1) 866 return ERR_NO_EBR; 867 } 868 } 869 } 870 871 /* alloc EBR if it's not already there */ 872 if (p->ebr == NULL) { 873 p->ebr = alloc_br(); 874 if (p->ebr == NULL) { 875 return ERR_NOMEM; 876 } 877 } 878 879 /* add it */ 880 list_append(&(p->link), &(label->parts->list)); 881 label->parts->n_logical += 1; 882 883 return EOK; 884 } 885 886 887 814 815 816 -
uspace/lib/mbr/libmbr.h
r6317b33 rcb328ab 213 213 extern void mbr_set_flag(mbr_part_t *, MBR_FLAGS, bool); 214 214 extern uint32_t mbr_get_next_aligned(uint32_t, unsigned int); 215 extern list_t * mbr_get_list(mbr_label_t *); 216 extern mbr_part_t * mbr_get_first_partition(mbr_label_t *); 217 extern mbr_part_t * mbr_get_next_partition(mbr_label_t *, mbr_part_t *); 218 219 #define mbr_part_foreach(label, iterator) \ 220 for (iterator = list_get_instance((label)->parts->list.head.next, mbr_part_t, link); \ 221 iterator != list_get_instance(&((label)->parts->list.head), mbr_part_t, link); \ 215 216 #define mbr_part_foreach(parts, iterator) \ 217 for (iterator = list_get_instance((parts)->list.head.next, mbr_part_t, link); \ 218 iterator != list_get_instance(&((parts)->list.head), mbr_part_t, link); \ 222 219 iterator = list_get_instance(iterator->link.next, mbr_part_t, link)) 223 220
Note:
See TracChangeset
for help on using the changeset viewer.