Changeset 52f2c89 in mainline
- Timestamp:
- 2013-06-24T22:29:44Z (11 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 9bdfde73
- Parents:
- 44c4886 (diff), 6317b33 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- uspace
- Files:
-
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/hdisk/common.h
r44c4886 r52f2c89 39 39 #include <libgpt.h> 40 40 41 typedef enum { 42 LYT_NONE, 43 LYT_MBR, 44 LYT_GPT, 45 } layouts_t; 46 41 47 union label_data { 42 48 mbr_label_t *mbr; … … 44 50 }; 45 51 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 46 68 #endif 47 69 -
uspace/app/hdisk/func_gpt.c
r44c4886 r52f2c89 34 34 35 35 #include <stdio.h> 36 #include <str.h> 36 37 #include <errno.h> 37 38 #include <str_error.h> … … 43 44 static int set_gpt_partition(tinput_t *, gpt_part_t *); 44 45 45 int add_gpt_part(tinput_t * in, union label_data * data) 46 { 47 gpt_part_t * p = gpt_alloc_partition(data->gpt->parts); 46 47 int construct_gpt_label(label_t *this) 48 { 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); 48 66 if (p == NULL) { 49 67 return ENOMEM; 50 68 } 51 69 52 70 return set_gpt_partition(in, p); 53 71 } 54 72 55 int delete_gpt_part(tinput_t * in, union label_data * data) 56 { 73 int delete_gpt_part(label_t *this, tinput_t *in) 74 { 75 int rc; 57 76 size_t idx; 58 77 59 78 printf("Number of the partition to delete (counted from 0): "); 60 79 idx = get_input_size_t(in); 61 62 if (gpt_remove_partition(data->gpt->parts, idx) == -1) { 80 81 rc = gpt_remove_partition(this->data.gpt, idx); 82 if (rc != EOK) { 63 83 printf("Warning: running low on memory, not resizing...\n"); 64 } 65 66 return EOK; 67 } 68 69 int destroy_gpt_label(union label_data *data) 70 { 71 return EOK; 72 } 73 74 int new_gpt_label(union label_data *data) 75 { 76 data->gpt->gpt = gpt_alloc_gpt_header(); 77 data->gpt->parts = gpt_alloc_partitions(); 78 return EOK; 79 } 80 81 int print_gpt_parts(union label_data *data) 84 return rc; 85 } 86 87 return EOK; 88 } 89 90 int destroy_gpt_label(label_t *this) 91 { 92 gpt_free_label(this->data.gpt); 93 return EOK; 94 } 95 96 int new_gpt_label(label_t *this) 97 { 98 this->data.gpt = gpt_alloc_label(); 99 return EOK; 100 } 101 102 int print_gpt_parts(label_t *this) 82 103 { 83 104 //int rc; … … 87 108 size_t i = 0; 88 109 89 gpt_part_foreach(data->gpt->parts, iter) { 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 90 119 //printf("\t%10u %10u %10u %3d\n", iter->start_addr, iter->start_addr + iter->length, 91 120 // iter->length, gpt_get_part_type(iter), gpt_get_part_name(iter)); 92 printf("%3u \t%10llu %10llu %10llu %3d %s\n", i, gpt_get_start_lba(iter), gpt_get_end_lba(iter),121 printf("%3u %10llu %10llu %10llu %3d %s\n", i-1, gpt_get_start_lba(iter), gpt_get_end_lba(iter), 93 122 gpt_get_end_lba(iter) - gpt_get_start_lba(iter), gpt_get_part_type(iter), 94 123 gpt_get_part_name(iter)); 95 i++; 96 } 97 124 } 125 98 126 //return rc; 99 127 return EOK; 100 128 } 101 129 102 int read_gpt_parts(service_id_t dev_handle, union label_data *data) 103 { 104 return EOK; 105 } 106 107 int write_gpt_parts(service_id_t dev_handle, union label_data * data) 108 { 109 int rc; 110 111 rc = gpt_write_partitions(data->gpt->parts, data->gpt->gpt, dev_handle); 130 int read_gpt_parts(label_t *this, service_id_t dev_handle) 131 { 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 return EOK; 147 } 148 149 int write_gpt_parts(label_t *this, service_id_t dev_handle) 150 { 151 int rc; 152 153 rc = gpt_write_partitions(this->data.gpt, dev_handle); 112 154 if (rc != EOK) { 113 155 printf("Error: Writing partitions failed: %d (%s)\n", rc, str_error(rc)); 114 156 return rc; 115 157 } 116 117 rc = gpt_write_ gpt_header(data->gpt->gpt, dev_handle);118 if (rc != EOK) { 119 printf("Error: Writing partitionsfailed: %d (%s)\n", rc, str_error(rc));120 return rc; 121 } 122 123 return EOK; 124 } 125 126 int extra_gpt_funcs( tinput_t * in, service_id_t dev_handle, union label_data * data)158 159 rc = gpt_write_header(this->data.gpt, dev_handle); 160 if (rc != EOK) { 161 printf("Error: Writing header failed: %d (%s)\n", rc, str_error(rc)); 162 return rc; 163 } 164 165 return EOK; 166 } 167 168 int extra_gpt_funcs(label_t *this, tinput_t *in, service_id_t dev_handle) 127 169 { 128 170 printf("Not implemented.\n"); … … 130 172 } 131 173 132 static int set_gpt_partition(tinput_t * in, gpt_part_t *p)133 { 134 //int rc;135 174 static int set_gpt_partition(tinput_t *in, gpt_part_t *p) 175 { 176 int rc; 177 136 178 uint64_t sa, ea; 137 179 138 180 printf("Set starting address (number): "); 139 181 sa = get_input_uint64(in); 140 182 141 183 printf("Set end addres (number): "); 142 184 ea = get_input_uint64(in); 143 185 144 186 if (ea <= sa) { 145 187 printf("Invalid value.\n"); 146 188 return EINVAL; 147 189 } 148 149 150 //p->start_addr = sa; 190 151 191 gpt_set_start_lba(p, sa); 152 //p->length = ea - sa;153 192 gpt_set_end_lba(p, ea); 154 155 return EOK; 156 } 157 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 204 return EOK; 205 } 206 -
uspace/app/hdisk/func_gpt.h
r44c4886 r52f2c89 42 42 #include "common.h" 43 43 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 *); 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); 52 53 53 54 #endif -
uspace/app/hdisk/func_mbr.c
r44c4886 r52f2c89 41 41 #include "input.h" 42 42 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) 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) 46 63 { 47 64 int rc; 48 65 49 66 mbr_part_t *part = mbr_alloc_partition(); 50 51 set_mbr_partition(in, part );52 53 rc = mbr_add_partition( data->mbr, part);54 if (rc != E OK) {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)67 68 set_mbr_partition(in, part, this->alignment); 69 70 rc = mbr_add_partition(this->data.mbr, part); 71 if (rc != ERR_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) 62 79 { 63 80 int rc; 64 81 size_t idx; 65 82 66 83 printf("Number of the partition to delete (counted from 0): "); 67 84 idx = get_input_size_t(in); … … 70 87 return errno; 71 88 72 rc = mbr_remove_partition( data->mbr, idx);89 rc = mbr_remove_partition(this->data.mbr, idx); 73 90 if(rc != EOK) { 74 91 printf("Error: something.\n"); 75 92 } 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)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) 90 107 return ENOMEM; 91 108 else … … 94 111 95 112 /** Print current partition scheme */ 96 int print_mbr_parts( union label_data *data)113 int print_mbr_parts(label_t *this) 97 114 { 98 115 int num = 0; 99 100 printf("Current partition scheme :\n");116 117 printf("Current partition scheme (MBR):\n"); 101 118 //printf("\t\tBootable:\tStart:\tEnd:\tLength:\tType:\n"); 102 119 printf("\t\t%10s %10s %10s %10s %7s\n", "Bootable:", "Start:", "End:", "Length:", "Type:"); 103 120 104 121 mbr_part_t *it; 105 mbr_part_foreach(data->mbr->parts, 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) { 106 126 if (it->type == PT_UNUSED) 107 127 continue; 108 128 109 129 printf("\tP%d:\t", num); 110 130 if (mbr_get_flag(it, ST_BOOT)) … … 112 132 else 113 133 printf(" "); 114 134 115 135 printf("\t%10u %10u %10u %7u\n", it->start_addr, it->start_addr + it->length, it->length, it->type); 116 117 ++num;118 } 119 136 137 //++num; 138 } 139 120 140 printf("%d partitions found.\n", num); 121 141 … … 123 143 } 124 144 125 int read_mbr_parts( service_id_t dev_handle, union label_data *data)145 int read_mbr_parts(label_t *this, service_id_t dev_handle) 126 146 { 127 147 int rc; 128 printf("mbr\n"); 129 rc = mbr_read_mbr(data->mbr, dev_handle); 148 rc = mbr_read_mbr(this->data.mbr, dev_handle); 130 149 if (rc != EOK) 131 150 return rc; 132 printf("ismbr\n");133 if (!mbr_is_mbr( data->mbr))151 152 if (!mbr_is_mbr(this->data.mbr)) 134 153 return EINVAL; 135 printf("parts\n");136 rc = mbr_read_partitions( data->mbr);154 155 rc = mbr_read_partitions(this->data.mbr); 137 156 if (rc != EOK) 138 157 return rc; 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);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); 146 165 if (rc != EOK) { 147 166 printf("Error occured during writing: ERR: %d: %s\n", rc, str_error(rc)); … … 151 170 } 152 171 153 int extra_mbr_funcs( tinput_t *in, service_id_t dev_handle, union label_data *data)172 int extra_mbr_funcs(label_t *this, tinput_t *in, service_id_t dev_handle) 154 173 { 155 174 printf("Not implemented.\n"); … … 157 176 } 158 177 159 static int set_mbr_partition(tinput_t *in, mbr_part_t *p )178 static int set_mbr_partition(tinput_t *in, mbr_part_t *p, unsigned int alignment) 160 179 { 161 180 int c; … … 174 193 break; 175 194 default: 176 printf("Invalid type. Cancelled. ");195 printf("Invalid type. Cancelled.\n"); 177 196 return EINVAL; 178 197 } 198 199 printf("ST_LOGIC: %d, %hd\n", mbr_get_flag(p, ST_LOGIC), p->status); 179 200 180 201 printf("Set type (0-255): "); … … 200 221 if (sa == 0 && errno != EOK) 201 222 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 } 202 228 203 229 printf("Set end addres (number): "); … … 206 232 return errno; 207 233 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 208 240 if(ea < sa) { 209 241 printf("Invalid value. Canceled.\n"); -
uspace/app/hdisk/func_mbr.h
r44c4886 r52f2c89 42 42 #include "common.h" 43 43 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 *); 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); 52 53 53 54 #endif -
uspace/app/hdisk/func_none.c
r44c4886 r52f2c89 41 41 42 42 43 int add_none_part(tinput_t *in, union label_data *data) 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) 44 60 { 45 61 not_implemented(); … … 47 63 } 48 64 49 int delete_none_part( tinput_t *in, union label_data *data)65 int delete_none_part(label_t *this, tinput_t * in) 50 66 { 51 67 not_implemented(); … … 53 69 } 54 70 55 int destroy_none_label(union label_data *data) 71 int destroy_none_label(label_t *this) 72 { 73 return EOK; 74 } 75 76 int new_none_label(label_t *this) 56 77 { 57 78 not_implemented(); … … 59 80 } 60 81 61 int new_none_label(union label_data *data)82 int print_none_parts(label_t *this) 62 83 { 63 84 not_implemented(); … … 65 86 } 66 87 67 int print_none_parts(union label_data *data)88 int read_none_parts(label_t *this, service_id_t dev_handle) 68 89 { 69 90 not_implemented(); … … 71 92 } 72 93 73 int read_none_parts(service_id_t dev_handle, union label_data *data)94 int write_none_parts(label_t *this, service_id_t dev_handle) 74 95 { 75 96 not_implemented(); … … 77 98 } 78 99 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) 100 int extra_none_funcs(label_t *this, tinput_t * in, service_id_t dev_handle) 86 101 { 87 102 not_implemented(); -
uspace/app/hdisk/func_none.h
r44c4886 r52f2c89 41 41 #include "common.h" 42 42 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 *); 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); 51 52 52 53 #endif -
uspace/app/hdisk/hdisk.c
r44c4886 r52f2c89 56 56 void print_help(void); 57 57 void select_label_format(tinput_t *); 58 void fill_label_funcs(void);58 void construct_label(layouts_t); 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);65 61 int try_read_mbr(service_id_t); 66 67 int construct_gpt_label(void);68 62 int try_read_gpt(service_id_t); 63 void set_alignment(tinput_t *); 69 64 70 65 … … 87 82 } 88 83 89 printf("Init.\n");90 84 init_label(); 91 85 … … 115 109 mbr_free_mbr(mbr);*/ 116 110 117 printf("Try MBR.\n");118 111 rc = try_read_mbr(dev_handle); 119 112 if (rc == EOK) … … 140 133 */ 141 134 142 printf("Try GPT.\n");143 135 rc = try_read_gpt(dev_handle); 144 136 if (rc == EOK) … … 149 141 150 142 interact: 151 printf("interact.\n");143 152 144 rc = interact(dev_handle); 153 145 … … 161 153 { 162 154 int input; 163 tinput_t * 155 tinput_t *in; 164 156 165 157 in = tinput_new(); … … 179 171 switch(input) { 180 172 case 'a': 181 label.add_part(in, &label.data); 182 break; 183 case 'b': 184 label.add_part(in, &label.data); 173 label.add_part(&label, in); 185 174 break; 186 175 case 'd': 187 label.delete_part( in, &label.data);176 label.delete_part(&label, in); 188 177 break; 189 178 case 'e': 190 label.extra_funcs( in, dev_handle, &label.data);179 label.extra_funcs(&label, in, dev_handle); 191 180 break; 192 181 case 'f': … … 197 186 print_help(); 198 187 break; 188 case 'l': 189 set_alignment(in); 190 break; 199 191 case 'n': 192 printf("Discarding label...\n"); 200 193 free_label(); 201 label.new_label(&label .data);194 label.new_label(&label); 202 195 break; 203 196 case 'p': 204 label.print_parts(&label .data);197 label.print_parts(&label); 205 198 break; 206 199 case 'q': 207 200 putchar('\n'); 208 201 goto end; 202 case 'r': 203 label.read_parts(&label, dev_handle); 209 204 case 'w': 210 label.write_parts( dev_handle, &label.data);205 label.write_parts(&label, dev_handle); 211 206 break; 212 207 default: … … 228 223 "\t 'd' \t\t Delete partition.\n" 229 224 "\t 'e' \t\t Extra functions (per label format).\n" 230 "\t 'f' \t\t Switch the format of the partition label. "225 "\t 'f' \t\t Switch the format of the partition label.\n" 231 226 "\t 'h' \t\t Prints help. See help for more.\n" 232 227 "\t 'l' \t\t Set alignment.\n" 233 228 "\t 'n' \t\t Create new label (discarding the old one).\n" 234 229 "\t 'p' \t\t Prints label contents.\n" 230 "\t 'q' \t\t Quit.\n" 231 "\t 'r' \t\t Read label from disk.\n" 235 232 "\t 'w' \t\t Write label to disk.\n" 236 "\t 'q' \t\t Quit.\n"237 233 ); 238 234 … … 244 240 "1) MBR\n" 245 241 "2) GPT\n" 246 242 ); 247 243 248 244 uint8_t val = get_input_uint8(in); … … 250 246 case 0: 251 247 free_label(); 252 label.layout = LYT_NONE; 253 fill_label_funcs(); 248 construct_label(LYT_NONE); 254 249 break; 255 250 case 1: 256 251 free_label(); 257 label.layout = LYT_MBR; 258 fill_label_funcs(); 252 construct_label(LYT_MBR); 259 253 break; 260 254 case 2: 261 255 free_label(); 256 construct_label(LYT_GPT); 257 break; 258 } 259 } 260 261 void construct_label(layouts_t layout) 262 { 263 switch(layout) { 264 case LYT_MBR: 265 label.layout = LYT_MBR; 266 construct_mbr_label(&label); 267 break; 268 case LYT_GPT: 262 269 label.layout = LYT_GPT; 263 fill_label_funcs(); 264 break; 265 } 266 } 267 268 void fill_label_funcs(void) 269 { 270 switch(label.layout) { 271 case LYT_MBR: 272 construct_mbr_label(); 273 break; 274 case LYT_GPT: 275 construct_gpt_label(); 270 construct_gpt_label(&label); 276 271 break; 277 272 default: 278 construct_none_label(); 273 label.layout = LYT_NONE; 274 construct_none_label(&label); 279 275 break; 280 276 } … … 283 279 void free_label(void) 284 280 { 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); 281 label.destroy_label(&label); 299 282 } 300 283 301 284 int try_read(service_id_t dev_handle) 302 285 { 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); 286 return label.read_parts(&label, dev_handle); 334 287 } 335 288 336 289 int try_read_mbr(service_id_t dev_handle) 337 290 { 338 label.layout = LYT_MBR;291 construct_label(LYT_MBR); 339 292 return try_read(dev_handle); 340 293 } 341 294 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 355 295 int try_read_gpt(service_id_t dev_handle) 356 296 { 357 label.layout = LYT_GPT;297 construct_label(LYT_GPT); 358 298 return try_read(dev_handle); 359 299 } 360 300 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 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 -
uspace/app/hdisk/hdisk.h
r44c4886 r52f2c89 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 56 37 #define init_label() \ 57 38 label.layout = LYT_NONE -
uspace/lib/gpt/global.c
r44c4886 r52f2c89 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
r44c4886 r52f2c89 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 * 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 * p);56 static int reduce_part_array(gpt_partitions_t * p);55 static int extend_part_array(gpt_partitions_t *); 56 static int reduce_part_array(gpt_partitions_t *); 57 57 static long long nearest_larger_int(double a); 58 58 static uint8_t get_byte(const char *); 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 )181 if (rc != EOK && rc != EEXIST) 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 302 size_t fill = label->parts->fill > GPT_MIN_PART_NUM ? label->parts->fill : GPT_MIN_PART_NUM; 303 303 304 label->gpt->header->pe_array_crc32 = compute_crc32( 304 305 (uint8_t *) label->parts->part_array, 305 label->parts->fill * e_size);306 fill * e_size); 306 307 307 308 /* comm_size of 4096 is ignored */ 308 309 rc = block_init(EXCHANGE_ATOMIC, dev_handle, 4096); 309 if (rc != EOK )310 return rc; 311 310 if (rc != EOK && rc != EEXIST) 311 return rc; 312 312 313 rc = block_get_bsize(dev_handle, &b_size); 313 314 if (rc != EOK) 314 315 goto fail; 315 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 316 327 /* Write to main GPT partition array location */ 317 328 rc = block_write_direct(dev_handle, uint64_t_le2host(label->gpt->header->entry_lba), … … 320 331 if (rc != EOK) 321 332 goto fail; 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 333 335 334 return gpt_write_header(label, dev_handle); 336 335 … … 347 346 * This returns a memory block (zero-filled) and needs gpt_add_partition() 348 347 * to be called to insert it into a partition array. 349 * Requires you to call gpt_free_partition after use.348 * Requires you to call gpt_free_partition afterwards. 350 349 */ 351 350 gpt_part_t * gpt_alloc_partition(void) … … 367 366 * 368 367 * Note: use either gpt_alloc_partition or gpt_get_partition. 369 * This one return a pointer to a structure already inside the array, so370 * there's no need to call gpt_add_partition().368 * This one returns a pointer to the first empty structure already 369 * inside the array, so don't call gpt_add_partition() afterwards. 371 370 * This is the one you will usually want. 372 371 */ 373 372 gpt_part_t * gpt_get_partition(gpt_label_t *label) 374 373 { 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++; 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; 381 415 } 382 416 … … 415 449 int gpt_remove_partition(gpt_label_t *label, size_t idx) 416 450 { 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 */ 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.*/ 426 465 if (label->parts->fill < (label->parts->arr_size / 2) - GPT_IGNORE_FILL_NUM) { 427 466 if (reduce_part_array(label->parts) == ENOMEM) … … 448 487 { 449 488 size_t i; 489 450 490 for (i = 0; gpt_ptypes[i].guid != NULL; i++) { 451 if (bcmp(p->part_type, gpt_ptypes[i].guid, 16) == 0) { 452 break; 453 } 454 } 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 455 513 return i; 456 514 } … … 516 574 517 575 /** Copy partition name */ 518 void gpt_set_part_name(gpt_part_t * p, char * name[], size_t length)576 void gpt_set_part_name(gpt_part_t *p, char *name, size_t length) 519 577 { 520 578 if (length >= 72) … … 645 703 } 646 704 647 648 649 650 651 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 -
uspace/lib/gpt/libgpt.h
r44c4886 r52f2c89 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 0 54 57 55 58 /** GPT header signature ("EFI PART" in ASCII) */ … … 149 152 extern gpt_part_t * gpt_alloc_partition (void); 150 153 extern gpt_part_t * gpt_get_partition (gpt_label_t *); 154 extern gpt_part_t * gpt_get_partition_at(gpt_label_t *, size_t); 151 155 extern int gpt_add_partition (gpt_label_t *, gpt_part_t *); 152 156 extern int gpt_remove_partition(gpt_label_t *, size_t); … … 159 163 extern uint64_t gpt_get_end_lba (gpt_part_t *); 160 164 extern unsigned char * gpt_get_part_name(gpt_part_t *); 161 extern void gpt_set_part_name(gpt_part_t *, char * [], size_t);165 extern void gpt_set_part_name(gpt_part_t *, char *, size_t); 162 166 extern bool gpt_get_flag (gpt_part_t *, GPT_ATTR); 163 167 extern void gpt_set_flag (gpt_part_t *, GPT_ATTR, bool); … … 165 169 166 170 167 #define gpt_part_foreach( parts, iterator) \168 for(gpt_part_t * iterator = ( parts)->part_array; \169 iterator < ( parts)->part_array + (parts)->fill; ++iterator)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) 170 174 171 175 extern void gpt_free_gpt(gpt_t *); -
uspace/lib/mbr/libmbr.c
r44c4886 r52f2c89 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); 54 56 55 57 /** Allocate and initialize mbr_label_t structure */ … … 168 170 mbr_part_t *ext = NULL; 169 171 //mbr_partitions_t *parts; 170 printf("check\n");172 171 173 if (label->parts != NULL) 172 174 mbr_free_partitions(label->parts); 173 printf("check2\n");175 174 176 label->parts = mbr_alloc_partitions(); 175 177 if (label->parts == NULL) { 176 178 return ENOMEM; 177 179 } 178 printf("primary\n");180 179 181 /* Generate the primary partitions */ 180 182 for (i = 0; i < N_PRIMARY; ++i) { 181 183 if (label->mbr->raw_data.pte[i].ptype == PT_UNUSED) 182 184 continue; 183 printf("pcheck1\n");185 184 186 p = mbr_alloc_partition(); 185 187 if (p == NULL) { … … 188 190 return ENOMEM; 189 191 } 190 printf("pcheck2\n");192 191 193 rc_ext = decode_part(&(label->mbr->raw_data.pte[i]), p, 0); 192 194 mbr_set_flag(p, ST_LOGIC, false); … … 198 200 return EINVAL; 199 201 } 200 printf("pcheck3\n");202 201 203 if (rc_ext) { 202 204 ext = p; 203 label->parts->l_extended = list_nth(&(label->parts->list), i); 204 } 205 printf("pcheck4\n"); 206 } 207 printf("logical\n"); 205 label->parts->l_extended = &p->link; 206 } 207 } 208 208 209 /* Fill in the primary partitions and generate logical ones, if any */ 209 210 rc = decode_logical(label, ext); 210 211 if (rc != EOK) { 211 printf(LIBMBR_NAME ": Error occured during decoding the MBR.\n" \212 LIBMBR_NAME ": Partition list may be incomplete.\n" );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)); 213 214 return rc; 214 215 } 215 printf("finish\n");216 216 217 return EOK; 217 218 } … … 225 226 int mbr_write_partitions(mbr_label_t *label, service_id_t dev_handle) 226 227 { 228 if (label->parts == NULL) 229 return EOK; 230 231 if (label->mbr == NULL) 232 label->mbr = mbr_alloc_mbr(); 233 227 234 int i = 0; 228 235 int rc; … … 240 247 241 248 /* Encoding primary partitions */ 242 for (i = 0; i < label->parts->n_primary; i++) {249 for (i = 0; i < N_PRIMARY; i++) { 243 250 p = list_get_instance(l, mbr_part_t, link); 244 251 encode_part(p, &(label->mbr->raw_data.pte[i]), 0, false); … … 253 260 } 254 261 255 if (ext == NULL) 262 if (ext == NULL) { 263 rc = EOK; 256 264 goto end; 265 } 257 266 258 267 uint32_t base = ext->start_addr; 259 mbr_part_t * 268 mbr_part_t *prev_p; 260 269 261 270 /* Note for future changes: Some thought has been put into design … … 281 290 } 282 291 free(tmp); 292 rc = EOK; 283 293 goto end; 284 294 } 285 295 286 296 prev_p = p; 297 298 /* Check EBR addresses 299 * This piece of code saves previous EBR placements from other 300 * 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 have 315 * the EBR aligned as well as the partition itself. Parted reserves 316 * 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); 287 332 288 333 /* Encoding and writing logical partitions */ … … 290 335 p = list_get_instance(l, mbr_part_t, link); 291 336 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 have295 * the EBR aligned as well as the partition itself. Parted reserves296 * 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 }304 337 305 338 encode_part(p, &(p->ebr->pte[0]), p->ebr_addr, false); … … 390 423 mbr_err_val mbr_add_partition(mbr_label_t *label, mbr_part_t *p) 391 424 { 392 int rc; 393 mbr_partitions_t *parts = label->parts; 394 425 int rc1, rc2; 395 426 aoff64_t nblocks; 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));427 428 rc1 = block_init(EXCHANGE_ATOMIC, label->device, 512); 429 if (rc1 != EOK && rc1 != EEXIST) { 430 printf(LIBMBR_NAME ": Error during libblock init: %d - %s.\n", rc1, str_error(rc1)); 400 431 return ERR_LIBBLOCK; 401 432 } 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)); 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)); 407 441 return ERR_LIBBLOCK; 408 442 } 409 printf("add3.\n"); 410 if (mbr_get_flag(p, ST_LOGIC)) { 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)) 411 454 /* adding logical partition */ 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 { 455 return mbr_add_logical(label, p); 456 else 454 457 /* adding primary */ 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; 458 return mbr_add_primary(label, p); 495 459 } 496 460 … … 569 533 void mbr_set_flag(mbr_part_t *p, MBR_FLAGS flag, bool value) 570 534 { 571 uint 8_t status = p->status;535 uint16_t status = p->status; 572 536 573 537 if (value) … … 579 543 } 580 544 581 /** Get next aligned address (in sectors!)*/545 /** Get next aligned address */ 582 546 uint32_t mbr_get_next_aligned(uint32_t addr, unsigned int alignment) 583 547 { 584 548 uint32_t div = addr / alignment; 585 549 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 else 557 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 else 566 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 else 575 return NULL; 586 576 } 587 577 … … 627 617 trgt->type = src->ptype; 628 618 629 /* Checking only 0x80; otherwise writing will fix to 0x00 */ 630 trgt->status = (trgt->status & 0xFF00) | src->status; 619 trgt->status = (trgt->status & 0xFF00) | (uint16_t) src->status; 631 620 632 621 trgt->start_addr = uint32_t_le2host(src->first_lba) + base; … … 691 680 692 681 while (ebr->pte[1].ptype != PT_UNUSED) { 682 693 683 ebr = alloc_br(); 694 684 if (ebr == NULL) { … … 712 702 goto free_ebr_end; 713 703 } 714 715 704 716 705 decode_part(&(ebr->pte[0]), p, addr); … … 759 748 trgt->length = host2uint32_t_le(src->length); 760 749 } 750 751 if (trgt->ptype == PT_UNUSED) 752 memset(trgt, 0, sizeof(pt_entry_t)); 761 753 } else { 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; 754 memset(trgt, 0, sizeof(pt_entry_t)); 772 755 } 773 756 } … … 779 762 static int check_overlap(mbr_part_t * p1, mbr_part_t * p2) 780 763 { 781 if (p1->start_addr < p2->start_addr && p1->start_addr + p1->length < p2->start_addr) {764 if (p1->start_addr < p2->start_addr && p1->start_addr + p1->length <= p2->start_addr) { 782 765 return 0; 783 } else if (p1->start_addr > p2->start_addr && p2->start_addr + p2->length < p1->start_addr) {766 } else if (p1->start_addr > p2->start_addr && p2->start_addr + p2->length <= p1->start_addr) { 784 767 return 0; 785 768 } … … 812 795 } 813 796 814 815 816 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 -
uspace/lib/mbr/libmbr.h
r44c4886 r52f2c89 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 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); \ 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); \ 219 222 iterator = list_get_instance(iterator->link.next, mbr_part_t, link)) 220 223
Note:
See TracChangeset
for help on using the changeset viewer.